Search results for WinDbg (54)

SEMPRE ative a geração de PDBs, até em RELEASE!

Depuração de emergência: receita de bolo

0

Continuando o papo sobre o que fazer para analisar rapidamente um crash no servidor com o pacote WinDbg, na maioria das vezes a exceção lançada pelo processo está diretamente relacionada com um acesso indevido à memória, o que tem diversas vantagens sobre problemas mais complexos:

  • Possui localização precisa de onde ocorreu a violação (inclusive com nome do arquivo-fonte e linha).
  • Não corrompe a pilha (ou, se corrompe, não chega a afetá-la a ponto da thread ficar irreconhecível).
  • A thread que contém a janela de crash é a culpada imediata (basta olha a pilha!).
Bom, resumindo: basta olhar a pilha! Mas, para isso ser efetivo, precisaremos do PDB do executável que gerou o crash, pois através dele é possível puxar a tal localização da violação de acesso.

SEMPRE ative a geração de PDBs, até em RELEASE!

Se você mantiver executável (DLL também é executável) juntinho com seu PDB, sua vida será mais fácil e florida.

EXE e PDB, juntinhos, cantando e rodando.

Mesmo que, em alguns momentos trágicos, apareça uma tela indesejada.
Seu caminho a partir dessa tela pode ser analisar um dump gerado (visto no artigo anterior) ou podemos atachar o WinDbg diretamente no processo (visto aqui e agora):
WinDbg: "mas que bagunça é essa na memória desse processo?"
O comando mais útil na maioria dos casos é mostrar a pilha em modo verbose (kv e <enter>). Porém, antes disso, precisamos:
  1. Ajeitar o path dos símbolos.
  2. Recarregar o PDB do executável suspeito.
  3. Mostrar a pilha de todas as threads (até descobrir a culpada).
Todos esses comandos podem ser vistos abaixo. São, respectivamente, .symfix, .reload e novamente o kv (mas para todas threads).
0:001> .symfix
0:001> .reload /f CrashOnServer.exe
*** WARNING: Unable to verify checksum for C:\Users\wanderley.caloni\Documents\Projetos\Caloni\Posts\Debug\CrashOnServer.exe
0:001> kv
Child-SP RetAddr  : Args to Child               : Call Site
0030f918 77679198 : 00000000`00000000 `00000000 : ntdll!DbgBreakPoint
0030f920 775e244d : 00000000`00000000 `00000000 : ntdll!DbgUiRemoteBreakin+0x38
0030f950 00000000 : 00000000`00000000 `00000000 : ntdll!RtlUserThreadStart+0x25
0:001> ~* kv

   0  Id: 1dc.978 Suspend: 1 Teb: 00000000`7efdb000 Unfrozen
Child-SP RetAddr  : Args to Child                       : Call Site
0008ea48 751f282c : 00000000`77770190 00000000`001dfb50 : wow64cpu!CpupSyscallStub+0x9
0008ea50 7526d07e : 00000000`00000000 00000000`775b3501 : wow64cpu!WaitForMultipleObjects32+0x32
0008eb10 7526c549 : 00000000`00000000 00000000`7ffe0030 : wow64!RunCpuSimulation+0xa
0008eb60 775cae27 : 00000000`003b3710 00000000`7efdf000 : wow64!Wow64LdrpInitialize+0x429
0008f0b0 775c72f8 : 00000000`00000000 00000000`00000000 : ntdll!LdrpInitializeProcess+0x1780
0008f5b0 775b2ace : 00000000`0008f670 00000000`00000000 : ntdll! ?? ::FNODOBFM::`string'+0x2af20
0008f620 00000000 : 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe

Ops! Estamos rodando um processo 32 dentro de um SO 64 (Windows 7, por exemplo). Isso pode acontecer. Seguimos com o workaround .load wow64exts e .effmach x86:

0:001> .load wow64exts
0:001> .effmach x86
Effective machine: x86 compatible (x86)
0:001:x86> ~* kv

   0  Id: 1dc.978 Suspend: 1 Teb: 7efdb000 Unfrozen
ChildEBP RetAddr  Args to Child
001df24c 761a0bdd 00000002 001df29c 00000001 ntdll_77760000!NtWaitForMultipleObjects+0x15 (FPO: [5,0,0])
001df2e8 7727162d 001df29c 001df310 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100 (FPO: [Non-Fpo])
001df330 77271921 00000002 7efde000 00000000 KERNEL32!WaitForMultipleObjectsExImplementation+0xe0 (FPO: [Non-Fpo])
001df34c 77299b2d 00000002 001df380 00000000 KERNEL32!WaitForMultipleObjects+0x18 (FPO: [Non-Fpo])
001df3b8 77299bca 001df498 00000001 00000001 KERNEL32!WerpReportFaultInternal+0x186 (FPO: [Non-Fpo])
001df3cc 772998f8 001df498 00000001 001df468 KERNEL32!WerpReportFault+0x70 (FPO: [Non-Fpo])
001df3dc 77299875 001df498 00000001 38239b1e KERNEL32!BasepReportFault+0x20 (FPO: [Non-Fpo])
001df468 777d0df7 00000000 777d0cd4 00000000 KERNEL32!UnhandledExceptionFilter+0x1af (FPO: [Non-Fpo])
001df470 777d0cd4 00000000 001dfb34 7778c550 ntdll_77760000!__RtlUserThreadStart+0x62 (FPO: [SEH])
001df484 777d0b71 00000000 00000000 00000000 ntdll_77760000!_EH4_CallFilterFunc+0x12 (FPO: [Uses EBP] [0,0,4])
001df4ac 777a6ac9 fffffffe 001dfb24 001df5e8 ntdll_77760000!_except_handler4+0x8e (FPO: [Non-Fpo])
001df4d0 777a6a9b 001df598 001dfb24 001df5e8 ntdll_77760000!ExecuteHandler2+0x26
001df580 7777010f 001df598 001df5e8 001df598 ntdll_77760000!ExecuteHandler+0x24
001df584 001df598 001df5e8 001df598 001df5e8 ntdll_77760000!KiUserExceptionDispatcher+0xf (FPO: [2,0,0])
WARNING: Frame IP not in any known module. Following frames may be wrong.
001df9ac 010d141e 00000000 00000000 00000000 0x1df598
001dfa90 010d19af 00000001 00321410 00321c70 CrashOnServer!main+0x2e (FPO: [Non-Fpo]) (CONV: cdecl)
    [c:\users\wanderley.caloni\documents\projetos\caloni\posts\crashonserver\crashonserver.cpp @ 13]
001dfae0 010d17df 001dfaf4 77273677 7efde000 CrashOnServer!__tmainCRTStartup+0x1bf (FPO: [Non-Fpo]) (CONV: cdecl)
    [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 555]
001dfae8 77273677 7efde000 001dfb34 77799f02 CrashOnServer!mainCRTStartup+0xf (FPO: [Non-Fpo]) (CONV: cdecl)
    [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 371]
001dfaf4 77799f02 7efde000 6b3e1b48 00000000 KERNEL32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
001dfb34 77799ed5 010d1109 7efde000 00000000 ntdll_77760000!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
001dfb4c 00000000 010d1109 7efde000 00000000 ntdll_77760000!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

#  1  Id: 1dc.1b0 Suspend: 1 Teb: 7efd8000 Unfrozen
ChildEBP RetAddr  Args to Child
0056ffe8 00000000 00000000 00000000 00000000 ntdll_77760000!RtlUserThreadStart (FPO: [0,2,0])

Nosso depurador favorito acusa uma pilha que contém a função WerpReportFault (Web Error Report, mas qualquer outra função com Exception no meio seria uma candidata). E, nessa mesma thread, a última linha nossa conhecida está no arquivo crashonserver.cpp:13. Isso nos revela o seguinte:

A raiz de todos os nossos problemas!

E essa situação, caro leitor, é 10% de tudo o que você precisa saber sobre WinDbg para resolver, mas que já resolve 90% dos casos. Belo custo-benefício, não?

Brendan Eich, Pai do JavaScript

Coders at Work: Brendan Eich, threads e depuração

0

"Proofs are hard. Most people are lazy. Larry Wall is right. Laziness should be a virtue. So that’s why I prefer automation. Proofs are something that academics love and most programmers hate." - Brendan Eich

 

Brendan Eich, Pai do JavaScript

Esse pequeno trecho da entrevista de Brendan Eich, de Coders at Work, revela parte das frustações que os programadores de linha de frente sofrem com os ambientes de depuração, muitas vezes aquém dos desafios atuais. Sinceramente, não sinto isso em meu dia-a-dia, e acho o Visual Studio um excelente depurador com interface (mas que perde feio para o WinDbg em casos mais hardcore). Porém, fica a percepção curiosa do criador do JavaScript.

Sobre SGI

"Diagnosing it was hard because it was timing-sensitive. It had to do with these machines being abused by terminal concentrators. People were hooking up a bunch of PTYs to real terminals. Students in a lab or a bunch of people in a mining software company in Brisbane, Australia in this sort of ’70s sea of cubes with a glass wall at ’70s sea of cubes with a glass wall at the end, behind which was a bunch of machines including the SGI two-processor machine. That was hard and I’m glad we found it. These bugs generally don’t linger for years but they are really hard to find. And you have to sort of suspend your life and think about them all the time and dream about them and so on. You end up doing very basic stuff, though. It’s like a lot of other bugs. You end up bisecting—you know “wolf fence.” You try to figure out by monitoring execution and the state of memory and try to bound the extent of the bug and control flow and data that can be addressed. If it’s a wild pointer store then you’re kinda screwed and you have to really start looking at harder-to-use tools, which have only come to the fore recently, thanks to those gigahertz processors, like Valgrind and Purify."

Ferramentas de Depuração Avançadas

Logo da Valgrind

"Instrumenting and having a checked model of the entire memory hierarchy is big. Robert O’Callahan, our big brain in New Zealand, did his own debugger based on the Valgrind framework, which efficiently logs every instruction so he can re-create the entire program state at any point. It’s not just a time-traveling debugger. It’s a full database so you see a data structure and there’s a field with a scrogged value and you can say, “Who wrote to that last?” and you get the full stack. You can reason from effects back to causes. Which is the whole game in debugging. So it’s very slow. It’s like a hundred times slower than real time, but there’s hope."

"Or you can use one of these faster recording VMs—they checkpoint only at system call and I/O boundaries. They can re-create corrupt program states at any boundary but to go in between those is harder. But if you use that you can probably close in quickly at near real time and then once you get to that stage you can transfer it into Rob’s Chronomancer and run it much slower and get all the program states and find the bug."

Depuradores da Indústria

"Debugging technology has been sadly underresearched. That’s another example where there’s a big gulf between industry and academia: the academics are doing proofs, sometimes by hand, more and more mechanized thanks to the POPLmark challenge and things like that. But in the real world we’re all in debuggers and they’re pieces of shit from the ’70s like GDB."

Mascote do GDB

 

"In the real world one big split is between people who use symbolic debuggers and people who use print statements." - Peter Seibel

 

"Yeah. So I use GDB, and I’m glad GDB, at least on the Mac, has a watch-point facility that mostly works. So I can watch an address and I can catch it changing from good bits to bad bits. That’s pretty helpful. Otherwise I’m using printfs to bisect. Once I get close enough usually I can just try things inside GDB or use some amount of command scripting. But it’s incredibly weak. The scripting language itself is weak. I think Van Jacobson added loops and I don’t even know if those made it into the real GDB, past the FSF hall monitors."

Multithreading

"But there’s so much more debugging can do for you and these attempts, like Chronomancer and Replay, are good. They certainly changed the game for me recently. But I don’t know about multithreading. There’s The multithreaded stuff, frankly, scares me because before I was married and had kids it took a lot of my life. And not everybody was ready to think about concurrency and all the possible combinations of orders that are out there for even small scenarios. Once you combine code with other people’s code it just gets out of control. You can’t possibly model the state space in your head. Most people aren’t up to it. I could be like one of these chestthumpers on Slashdot—when I blogged about “Threads suck” someone was saying, “Oh he doesn’t know anything. He’s not a real man.” Come on, you idiot. I got a trip to New Zealand and Australia. I got some perks. But it was definitely painful and it takes too long. As Oscar Wilde said of socialism, “It takes too many evenings.”

CrashOnServerCrash

Depuração de emergência

0

O programa está rodando no servidor do cliente, que é acessível por sessão remota do Windows, mas de repente ele capota. Existem aí duas possibilidades fora o debug remoto (que, nesse caso, não é possível):

  1. Analisar um dump gerado.
  2. Depurar localmente o problema.

Analisar um dump gerado

Para a primeira opção, basta abrir o Gerenciador de Tarefas, localizar o processo e gerar o dump através do menu de contexto.

Com o dump e o Windbg em mãos, basta analisá-lo. Porém, se o seu processo é 32 bits e o servidor é 64 bits (geralmente é), o dump gerado será de 64 bits, EMBORA seja de um process 32. Ou seja, ao abri-lo, o sistema vai mostrar as threads de manipulação do SO para sistemas 32 (todos com o nosso amigo wow64cpu).

Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64
 Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [C:\Tests\CrashOnServer.DMP]
 User Mini Dump File with Full Memory: Only application data is available
Executable search path is:
 Windows 7 Version 7600 MP (2 procs) Free x64
 Product: WinNt, suite: SingleUserTS
 Machine Name:
 Debug session time: Tue Jul 26 09:26:23.000 2011 (UTC - 3:00)
 System Uptime: 0 days 0:35:47.425
 Process Uptime: 0 days 0:00:42.000
 ...........WARNING: MSVCR100D overlaps MSVCP100D
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -
 *** ERROR: Symbol file could not be found. Defaulted to export symbols for wow64cpu.dll -
 wow64cpu!TurboDispatchJumpAddressEnd+0x690:
 00000000`745d2dd9 c3 ret
 0:000> kv
 Child-SP RetAddr : Args to Child : Call Site
 00000000`001ce6c8 00000000`745d282c :  : wow64cpu!TurboDispatchJumpAddressEnd+0x690
 *** ERROR: Symbol file could not be found. Defaulted to export symbols for wow64.dll -
 00000000`001ce6d0 00000000`7464d07e :  : wow64cpu!TurboDispatchJumpAddressEnd+0xe3
 00000000`001ce790 00000000`7464c549 :  : wow64!Wow64SystemServiceEx+0x1ce
 00000000`001ce7e0 00000000`76deae27 :  : wow64!Wow64LdrpInitialize+0x429
 00000000`001ced30 00000000`76de72f8 :  : ntdll!LdrGetKnownDllSectionHandle+0x1a7
 00000000`001cf230 00000000`76dd2ace :  : ntdll!RtlInitCodePageTable+0xe8
 00000000`001cf2a0 00000000`00000000 : : ntdll!LdrInitializeThunk+0xe
Para entrar dentro do Inception, é necessário usar a extensão wow64exts e usar o comando ".effmach x86".
0:000> .load wow64exts
 0:000> .effmach x86
 Effective machine: x86 compatible (x86)
 0:000:x86> kv
 ChildEBP RetAddr Args to Child
 ..
 ..
 ..
 0035ec98 0035ecac 0035ecfc 0035ecac 0035ecfc ntdll_76f80000!KiUserExceptionDispatcher+0xf (FPO: [2,0,0])
 *** WARNING: Unable to verify checksum for CrashOnServer.exe
 WARNING: Frame IP not in any known module. Following frames may be wrong.
 0035f0bc 01181ca9 0035f198 0035f19c 00000000 0x35ecac
 0035f190 01181b7d 009d80a0 5fb4d717 00000000 CrashOnServer!Log::LogError+0x29
 0035fb08 01186f1f 00000001 009d1410 009d1c68 CrashOnServer!main+0x12d
 0035fb58 01186d4f 0035fb6c 76543677 7efde000 CrashOnServer!__tmainCRTStartup+0x1bf
 0035fb60 76543677 7efde000 0035fbac 76fb9f02 CrashOnServer!mainCRTStartup+0xf
 0035fb6c 76fb9f02 7efde000 771dc110 00000000 kernel32!BaseThreadInitThunk+0xe
 0035fbac 76fb9ed5 01181316 7efde000 00000000 ntdll_76f80000!__RtlUserThreadStart+0x70
 0035fbc4 00000000 01181316 7efde000 00000000 ntdll_76f80000!_RtlUserThreadStart+0x1b

Após esse último passo, siga para o último passo desse tutorial. Ou escolha a segunda opção:

Depurar localmente o problema

Para depurar localmente, supondo que seja um executável simples, você precisa dos seguintes itens:

  • Pasta do WinDbg copiado (a Debugging Tools instalada pelo SDK, ou sua pastinha particular guardada no PenDrive).
  • Símbolos dos binários envolvidos (em sincronia com os binários que iremos analisar).
  • Fontes da compilação dos binários (a versão exata seria ideal; grave o revno do controle de fonte pra facilitar).

Os fontes, no caso de uma conexão por Terminal Server, podem ser disponibilizados através do mapeamento de drives entre as máquinas. Os símbolos, no entanto, por serem usados extensivamente pelo WinDbg, é recomendável que estejam locais na máquina depurada, pois do contrário você terá que tomar uma quantidade excessiva de cafés para executar meia-dúzia de instruções.

Supondo que temos tudo isso, só precisamos executar alguns passos básicos para o setup:

1. Abrir o WinDbg e escolher File, Open Executable. Escolha o executável e pare por aí.

2. Na tela de comando do WinDbg (View, Command, ou Alt + 1) execute os comandos abaixo:

.symfix
.sympath+
.reload
.srcpath
.reload /f CrashOnServer.exe

3. Ao executar lm, o módulo cujo símbolo foi carregado deve conter o nome do pdb logo à frente.

0:000> .symfix c:\tools\symbols
 0:000> .sympath+ C:\Projetos\Caloni\Posts\Debug
 Symbol search path is: srv*;C:\Projetos\Caloni\Posts\Debug
 Expanded Symbol search path is: SRV*c:\tools\symbols*http://msdl.microsoft.com/download/symbols;c:\projetos\caloni\posts\debug
 0:000> .reload
 Reloading current modules
 ......
 0:000> .srcpath C:\Projetos\Caloni\Posts
 Source search path is: C:\Projetos\Caloni\Posts
 0:000> .reload /f CrashOnServer.exe
 *** WARNING: Unable to verify checksum for CrashOnServer.exe
 0:000> lm
 start end module name
 00000000`01170000 00000000`01193000 CrashOnServer C (private pdb symbols) C:\Projetos\Caloni\Posts\Debug\CrashOnServer.pdb
 00000000`745d0000 00000000`745d8000 wow64cpu (deferred)
 00000000`745e0000 00000000`7463c000 wow64win (deferred)
 00000000`74640000 00000000`7467f000 wow64 (deferred)
 00000000`76da0000 00000000`76f4c000 ntdll (pdb symbols) c:\tools\symbols\ntdll.pdb\\ntdll.pdb
 00000000`76f80000 00000000`77100000 ntdll32 (deferred)

4. Feito isso, está tudo OK. Podemos colocar breakpoints, monitorar variáveis, verificar stacks, etc.

Por último, execute o seguinte comando na tela de comandos do WinDbg:

.hh

E boa sorte =)

HouaissParaBabylon 1

TDC 2011

2

Estarei no TDC esse ano. A trilha é de C++, mas farei uma palestra sobre engenharia reversa. Para ser mais específico, falaremos sobre a análise do Dicionário Houaiss, cujo projeto venho mantendo nos últimos anos. Acho legal termos um espaço para falarmos de quando fazemos realmente a coisa, em vez de ficar sempre na teoria de como seria ou o que um programador precisa saber para começar a analisar um binário.

Se você gosta do tema e possui dúvidas a respeito, ou gostaria de mais detalhes sobre outros projetos, não deixe de comparecer. Antes e depois da palestra estarei disponível para conversarmos. O mais interessante de termos uma trilha em C++ é reunir pessoas envolvidas em torno da linguagem, não importando muito a área. Somos um grupo pequeno, e é importante que tenhamos um contato mais próximo de vez em quando.

C/C++ Caso de Uso: Engenharia Reversa com Windbg

Esta palestra é sobre desmontar e montar novamente. Iremos descobrir como as entradas do dicionário Houaiss eletrônico estão gravadas em um primeiro momento, para depois remontarmos essa informação de maneira que ela possa ser usada em um outro dicionário.

Ferramentas que serão usadas: Windows, WinDbg, Visual Studio (qualquer versão).

Conhecimentos necessários: C/C++, Assembly 8086, Win32 API.

Passo-a-passo da palestra:

  1. Sobre Pirataria. Como identificar brechas na licença para que você possa usufruir do seu trabalho de refatoração binária.
  2. Análise. Desmontando o dicionário Houaiss e desvendando seu funcionamento interno.
  3. Programação. Remontando a estrutura identificada pela Engenharia Reversa em um formato aberto.
  4. Sobre Fair Use. Explicando como abrir portas para o desenvolvimento de soluções baseada em nossa análise.

Outros conteúdos

Assuntos "similares" também nos esperam com Sergio Prado e programação segura e Rodrigo Almeida, abordando o desenvolvimento de microkernel. Além disso, também teremos Bruno Koga e Guilherme Andrade destrinchando o compilador LLVM para Objective-C, enquanto Antonio Ribeiro Alves Júnior explica sobre t100, um Middleware para Simulação Distribuída.

Nos vemos lá.

Comparando strings no WinDbg

2

O WinDbg fornece aos programadores diversos meios (muitos redundantes) de comparar valores inteiros em quaquer lugar da memória, em qualquer tamanho (8, 16, 32, 64 bits). Porém, quando precisamos comparar strings, que todos sabem ser uma sequência de bytes de tamanho arbitrário (se for em C, até o zero terminador).

Uma solução simples e rápida é comparar os 4 primeiros bytes de uma string, ou os 4 primeiros bytes que diferem de uma lista grande.

Por exemplo, imagine o seguinte código que abre todos os arquivos da pasta de sistema:

#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <stdio.h>
 
int main()
{
	CHAR sysPath[MAX_PATH];
	CHAR findPath[MAX_PATH];
 
	GetSystemDirectory(sysPath, MAX_PATH);
	sprintf(findPath, "%s\\*.*", sysPath);
 
	WIN32_FIND_DATA findData;
	HANDLE findH = FindFirstFile(findPath, &findData);
 
	if( findH != INVALID_HANDLE_VALUE )
	{
		do
		{
			CHAR filePath[MAX_PATH];
 
			sprintf(filePath, "%s\\%s", sysPath, findData.cFileName);
			HANDLE fileH = CreateFile(filePath, GENERIC_READ, 
				FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
 
			if( fileH )
			{
				CHAR firstBytes[4];
				DWORD wasRead = 0;
 
				if( ReadFile(fileH, firstBytes, 4, &wasRead, NULL) && wasRead == 4 )
				{
					printf("%s: %02X %02X %02X %02X\n", findData.cFileName,
						(int) firstBytes[0], (int) firstBytes[1], 
						(int) firstBytes[2], (int) firstBytes[3]);
				}
 
				CloseHandle(fileH);
			}
		}
		while( FindNextFile(findH, &findData) );
 
		FindClose(findH);
	}
}

Queremos colocar um breakpoint no momento em que o arquivo shell32.dll estiver sendo aberto. Para isso, devemos nos atentar para os parâmetros passados para a função CreateFile.

windbg strcmpwindbg1.exe

0:000> bp kernel32!CreateFileA

Breakpoint 0 hit

eax=001bf918 ebx=7efde000 ecx=001bf7e0 edx=001bf7e0 esi=001bf824 edi=001bfd90

eip=7663ca6e esp=001bf804 ebp=001bfd90 iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

kernel32!CreateFileA:

7663ca6e 8bff            mov     edi,edi

0:000> da poi(esp+4)

001bf918  "C:\Windows\system32\accessibilit"

001bf938  "ycpl.dll"

0:000> g

Breakpoint 0 hit

eax=001bf918 ebx=7efde000 ecx=001bf7e0 edx=001bf7e0 esi=001bf824 edi=001bfd90

eip=7663ca6e esp=001bf804 ebp=001bfd90 iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

kernel32!CreateFileA:

7663ca6e 8bff            mov     edi,edi

0:000> da poi(esp+4)

001bf918  "C:\Windows\system32\ACCTRES.dll"




O padrão aqui é que todo path passado para o CreateFile vai começar com c:\windows\system32, o que não é uma informação que podemos usar para buscar um arquivo específico.

Temos que nos atentar para o padrão de bits após esse path. Vamos dar uma olhada por dentro da string.

0:000> db 001bf918
001bf918  43 3a 5c 57 69 6e 64 6f-77 73 5c 73 79 73 74 65  C:\Windows\syste
001bf928  6d 33 32 5c 41 43 43 54-52 45 53 2e 64 6c 6c 00  m32\ACCTRES.dll.
001bf938  79 63 70 6c 2e 64 6c 6c-00 cc cc cc cc cc cc cc  ycpl.dll........

 

O nome do arquivo começa no offset 16+4 = 20, ou 14 em hexa. Dessa forma, podemos capturar o padrão de bits da seguinte maneira:

0:000> dd poi(esp+4)+14 l1
001bf92c  54434341

Para nos certificarmos que é realmente esse o padrão, e para já montarmos nosso próprio padrão para o shell32.dll, vamos alocar um pedaço de memória e verificar se a sequência de bits está correta.

0:000> dd poi(esp+4)+14 l1
001bf92c  54434341
0:000> .dvalloc 100
Allocated 1000 bytes starting at 00030000
0:000> ea 00030000 "ACCTRES.dll"
0:000> dd 00030000 l1
00030000  54434341

Ótimo. Os padrões bateram, então podemos colocar um breakpoint condicional partindo do padrão de bits do nome do arquivo que precisamos.

0:000> bp kernel32!CreateFileA "j (poi(poi(esp+4)+14)=6c656873) ''; 'g'"
breakpoint 0 redefined
0:000> g
eax=0021f48c ebx=7efde000 ecx=0021f354 edx=0021f354 esi=0021f398 edi=0021f904
eip=7663ca6e esp=0021f378 ebp=0021f904 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
kernel32!CreateFileA:
7663ca6e 8bff            mov     edi,edi
0:000> da poi(esp+4)
0021f48c  "C:\Windows\system32\shell32.dll"
Com isso, economizamos alguns minutos de puro tédio, verificando os nomes um a um conforme eles são abertos. Ou, dependendo da massa de dados, algumas décadas. Quem sabe. Pode ser muito mais útil um outro dia.
vtable1.png

VTable

2

Acho que na breve história desse blogue nunca contei a história do vtable. No máximo fizemos um hookzinho nos métodos de um componente COM. Mas só.

Não encontro uma analogia simples, assim, de cabeça. Então vou contar no cru, mesmo. Talvez seja até mais divertido.

A vtable foi um mecanismo criado para implementar o polimorfismo em C++ quando falamos de ponteiros para classes base cujos métodos virtuais foram sobrescritos por uma classe derivada.

A coisa fica mais simples quando explicamos que em C++ você só paga pelo que usa. Se você declarar uma classe que não tenha nenhum método virtual, os objetos dessa classe não precisarão de uma vtable. No entanto, você não conseguirá sobrescrever um método dessa classe através de uma derivada:

(more...)

Mudança

7

Fecha uma porta...

Desde que comecei a programar profissionalmente, lá por volta de 2001, sempre estive envolvido com uma ou duas empresas de Segurança da Informação, na época uma promissora carreira, com direito a hacking, engenharia reversa e outras diversões. Até programar por programar valia!

O tempo passou, completei uma década na área, e agora está realmente na hora de tentar programar coisa nova. Dessa forma, acompanhando minha própria tendência de investidor pessoa física na bolsa de valores, resolvi dar um novo salto em minhas aspirações nesse campo igualmente fascinante e apostar meu tempo de programação também no setor financeiro, onde C/C++ também corre na veia.

Aprendi muito nesse tempo todo com alguns amigos entusiastas (até demais) e programei muito código que gostaria que não tivesse meu nome nos comentários. Mas a vida (e o código) é assim: melhora com os erros.

... e abre outra!

A empresa que estou deixando agora está à caça de uma pessoa para se tornar minha versão 2.0. Dessa vez não é uma busca por talentos inexperientes, de forma que estaremos aceitando apenas pessoas que já se f... com larga experiência em programação Windows.

Segue a descrição da vaga, feita por mim mesmo, sozinho. Interessados: sem timidez, please.

Analista Programador C++

Conhecimentos avançados em Windows: serviços, DLLs, (drivers desejável).
Programação: libc, Win32 API, (STL/Boost e Assembly 8086 desejáveis).
Ferramentas: Visual Studio 2003, Bazaar, VMWare, (WinDbg desejável).
Funções: codificação, análise, reunião técnica, refatoração, (UML desejável).
Perfil: vontade de aprender, pró-atividade, comunicação.

(more...)

Patch de emergência 2

5

No artigo anterior fizemos um patch rapidinho na memória se aproveitando de um Sleep nojento que o código nos forneceu.

E se não houvesse Sleep?

As chances de estarmos escrevendo no momento em que a função está sendo executada são tremendas, de forma que não poderíamos sobrescrevê-la sem correr o risco de um crash.

Uma solução alternativa para isso é alocar um novo pedaço de memória para a versão corrigida e trocar o endereço de chamada na função main.

(more...)

Bahamas. Ahhhnnn...

Patch de emergência

8

Após um projeto muito bem sucedido, entregue no prazo e homologado em tempo recorde, você e sua equipe estão aproveitando suas devidas férias nas Bahamas, tomando água de coco na sombra de uma palmeira e apreciando a beleza natural da região. Ambas as belezas. =)

Club-med-beach-governors-harbour-eleuthera-bahamas

Mas eis que liga o seu gerente para o celular vermelho que te entregou no caso de emergências críticas e te avisa que um problema crítico foi detectado em um serviço crítico: o detector de pares. Consegue ver o erro?

Detector de Pares

Oh, meu Deus! (more...)

That's a Bingo!

Como achar o código-fonte sem símbolos

0

Continuo escovando bits. Dessa vez de forma mais nervosa. Se trata de um serviço que trava durante seu stop. Um colega muito esperto do suporte gerou um dump para mim, tornando as coisas mais fáceis. O problema era que não havia símbolos nem código-fonte que batessem exatamente com aquela compilação de 2004. Solução? Analisar as pilhas das threads restantes.

(more...)

crash-dump.png

Sétimo Encontro de Programadores C++

0

Mais um fim-de-semana no ócio e na vadiagem. Tenho que manter minhas qualidades de bom programador que sou: preguiçoso, impaciente e pretensioso.

Mas nem por isso deixei de terminar uma primeira versão do aplicativo que irei usar como base na minha palestra do nosso próximo encontro C++: Crash Dump Analysis. Se alguém tiver dicas de quais os problemas mais difíceis do Universo para analisar em um dump de memória, comente a respeito e veremos o que dá pra fazer.

crash-dump.png

Enquanto isso, continuo descobrindo maravilhas do WinDbg. Essa semana fiquei brincando de colocar breakpoint em user-mode, mas depurando o kernel, como fizeram os rapazes do Ntdebugging. A conclusão é que ele vale para todos os aplicativos abertos. Tente com o MessageBox!

!process 0 0 notepad.exe
.reload /user
bp user32!MessageBoxW

Mas devaneio. Talvez outra boa qualidade de um bom programador.

(more...)

windbg-tooltips.png

Novidades no Windbg 7

0

Semestre que vem deve sair uma nova versão do nosso depurador favorito. Alguns atrasos e novas definições do projeto fizeram com que tivéssemos mais um ou dois releases da finada versão 6 antes da revolução que será o Depurador 2010.

Entre as mudanças mais esperadas, e entre as mais inesperadas, encontramos essa pequena lista de novidades que, com certeza, deixarão o desenvolvedor de sistemas da Microsoft muito mais feliz:

(more...)

PEB "não-documentado"

Importando tipos de outros projetos

0

A engenharia reversa das entranhas do kernel não tem limites se você sabe o que está fazendo. No entanto, algumas facilidades do depurador podem ajudar a minimizar o tempo que gastamos para analisar uma simples estrutura. Por exemplo, o Process Environment Block de um processo específico.

windbg -kl

Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft Corporation. All rights reserved.

Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Symbol search path is: SRV*c:\tools\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
*******************************************************************************
WARNING: Local kernel debugging requires booting with kernel
debugging support (/debug or bcdedit -debug on) to work optimally.
*******************************************************************************
Windows XP Kernel Version 2600 (Service Pack 3) MP (2 procs) Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp3_gdr.090804-1435
Kernel base = 0x804d7000 PsLoadedModuleList = 0x8055d720
Debug session time: Mon Jan 11 10:36:50.061 2010 (GMT-2)
System Uptime: 5 days 1:05:24.958

Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft Corporation. All rights reserved.

lkd> !process 0 0 notepad.exe
PROCESS 89068700  SessionId: 0  Cid: 0ec4    Peb: 7ffda000  ParentCid: 0b0c
    DirBase: 0ac80a80  ObjectTable: e143a7d8  HandleCount: 152.
    Image: notepad.exe

O comando !peb traz inúmeras informações sobre essa estrutura. Mas talvez estivéssemos interessados em coisas não mostradas por esse comando, mas que existem na estrutura.

(more...)

crystallball.jpg

Devaneio nerd rápido sobre profecias

2

crystallball.jpgPara quem já analisou os dados de uma tela azul sabe que, quando o Windows acha um culpado (vulgo driver) a data de sua compilação é exibida em um formato conhecido como DateStamp ou TimeStamp. Nesse formato o que temos é um número hexadecimal que segue o formato de tempo do Unix, que no caso é o número de segundos desde o dia primeiro de Janeiro de 1970. Isso, por curiosidade, nos dá uma margem de 140 anos antes dos número se repetirem se usarmos 32 bits nessa contagem.

O comando .formats do WinDbg nos consegue trazer desse número a hora exata em que determinado componente foi compilado. Se, por exemplo, um driver faltoso apresentou um DateStamp igual a 49EE9758, podemos concluir que ele foi compilado no dia 22 de abril de 2009, uma linda quarta-feira.

0:000> .formats 49EE9758
Evaluate expression:
  Hex:     00000000`49ee9758
  Decimal: 1240373080
  Octal:   0000000000011173513530
  Binary:  00000000 00000000 00000000 00000000 01001001 11101110 10010111 01011000
  Chars:   ....I..X
  Time:    Wed Apr 22 01:04:40 2009
  Float:   low 1.95454e+006 high 0
  Double:  6.12826e-315

Quando fazemos algo muitas vezes seguidas temos o hábito inconsciente de observar certas idiossincrasias dos dados que sempre vem e vão. No caso dos Date Stamps, sempre me veio o fato deles iniciarem com 4 e estarem prestes a "virar o contador" para 5.

Isso aos poucos - entre uma tela azul e outra - me deixou curioso a respeito de quando seria o dia fatídico em que teríamos o DateStamp 50000000, um número cabalístico em nosso sistema decimal. E, imaginem só:

(more...)

O boot no Windows: Kernel

0

Finalmente chegamos em um pouco onde podemos usar o WinDbg.

Podemos espetar o depurador e fazê-lo parar assim que conectado. Se estiver rodando antes do próprio sistema operacional, teremos um sistema sem processos e sem threads, pois ele irá parar assim que o executivo puder enviar o sinal de início pela porta serial, após carregar na memória os módulos básicos.

windbg -k com:pipe,port=\\.\pipe\com_1 -b

(more...)

ntldr-phase.png

O boot no Windows: NTLDR

0

galinha-preta.jpgMinhas análises estão demorando muito para ser feitas. Talvez seja a hora de revelar o pouco que sei (e pesquisei) sobre o próximo processo de boot do Windows: o NTLDR.

O nosso amigo NT Loader pode ser entendido através da leitura do já citado Windows Internals ou através de uma outra leitura que estou fazendo atualmente e que pouquíssimos amigos blogueiros irão se lembrar: o livro da galinha preta; formalmente conhecido como Windows Nt File System Internals.

Para os sabichões de plantão, inclusive os que me criticaram (?) no meu último texto humorístico sobre como Java é podre, eu sei que o bicho da capa não é uma galinha, mas um urubu. A troca de urubu por galinha vem do requisito básico para você fazer trabalhos esotéricos, como macumba e desenvolvimento de drivers: uma galinha preta na encruzilhada. Alguns usam um papel dentro da boca de um sapo, mas vai do gosto de cada um. =)

E, para os que leram o livro, devem entender que para explicar sobre o funcionamento do sistema de arquivos do Windows, parte intrínseca do funcionamento do próprio kernel, foi necessário ao autor explicar várias partes do kernel, inclusive sua inicialização; e é nessa parte que podemos aprender algo mais sobre o NT Loader.

(more...)

notepad-adplux-together.png

AdPlus no cliente, não você!

7

O AdPlus é uma das poderosas ferramentas do pacote Debugging Tools for Windows. Se trata basicamente de um script que serve para realizar múltiplas fotografias no estado de um programa em execução usando para isso os depuradores do próprio pacote. Quando alguma coisa estiver errada, principalmente um crash ou travamento, ele paralisa a execução e gera um dump final com toda a história contada desde o começo.

Ele pode ser usado na situação mais comum: o programa trava/quebra em um cliente específico e/ou em um momento específico que pode acontecer em cinco segundos ou daqui a quinze horas. Como você não pode ficar monitorando o tempo todo a execução do programa (haja indexadores no PerfMon!) então você precisa de alguém que monitore por você. Como seres humanos costumam ter deficit de atenção muito facilmente você vai lá no cliente (ou pede para alguém ir) e executa o AdPlus, que dá conta do recado:

AdPlus.vbs -crash -sc notepad.exe

Esse notepad, viu! Sempre ele!

(more...)

O que andei fazendo nos últimos 10 anos

5

Essa semana me dediquei a atualizar meu currículo e tive a brilhante ideia de colocar um histórico técnico, o que resumindo é uma lista de coisas que fiz ou estive relacionado com durante minha breve estadia de dez anos no mundo da programação.

Daí pensei: "isso pode ser útil para as pessoas que leem". E por que não? Talvez você tenha alguma dúvida esperando para ser sanada e não encontra um maldito que saiba alguma coisa sobre. Talvez esse maldito até tenha um blogue em que possa compartilhar algum conhecimento que está inerte naquela cabeça oca de programador.

Sendo assim, abaixo segue um resumo da minha vida profissional, com as coisas que eu consegui me lembrar que fiz desde dezembro de 2000. O que eu não lembrei talvez não valha tanto a pena assim.

(more...)

Eu mesmo!

Autor

5

Wanderley Caloni é um programador C especializado em backend para Windows que decidiu ter seu próprio blogue técnico. Tenta mantê-lo atualizado com suas peripécias do dia-a-dia. Colaborador frequente do Grupo C/C++ Brasil, foi junto de Rodrigo Strauss um dos fundadores e participante do primeiro encontro de programadores C++ de São Paulo. Trabalhou por dez anos na área de Segurança da Informação, principalmente no Controle de Acesso a Usuários e Análise de Trojans. Atualmente tem trabalhado em projetos de desenvolvimento para a Área Financeira e é cinéfilo inveterado nas horas vagas, o que fez com que abrisse mais dois novos blogues.

Também costuma dar pitacos sobre todos esses temas e outros mais em seu twitter pessoal.

Nas horas vagas, ele também programa. Mais.

Se, mesmo com esse resumo, você tiver mais alguma dúvida a respeito de algo que eu conheça, não hesite em falar comigo! Abaixo temos uma breve lista das coisas que eu andei fazendo na minha breve vida de programador. Para uma visão mais formal, eis os linques para meu currículo (ou em inglês).

  • Inventário de hardware (WMI/SMBIOS) e software (registro)
  • Proteção da área de transferência e PrintScreen através de hook de janelas e manipulação de mensagens globais
  • Escrita de alertas no log de eventos do sistema através de drivers
  • Comunicação user/kernel mode através de DeviceIoControl
  • Acesso remoto de desktop através de ferramenta similar ao VNC
  • Ferramenta de execução remota similar ao PsExec
  • Controle de impressão de documentos através de regex (Boost) usando hook do Shell
  • Gerenciamento de diretivas de acesso do sistema durante logon e logoff de usuários (registro e hooks)
  • Migração de base de dados CTree para SQL (classes OLE)
  • Autenticação Windows com serviço DCOM e GINA customizada ou Credential Provider (Vista)
  • Sincronismo remoto de base de dados CTree usando serviço DCOM
  • CD Linux bootável com scripts bash e ferramentas de criptografia de discos em linguagem C
  • Driver de criptografia de discos rígidos e armazenamento USB (PenDrives)
  • Análise de telas azuis ou dumps de memória usando WinDbg
  • Serviço COM de execução de aplicativos na conta de sistema
  • Customização da MBR (Master Boot Record) de acordo com características da BIOS
  • Biblioteca de criptografia Blowfish e SHA-1 em C++ e Assembly 16 bits
  • Driver de auditoria de acesso com memória compartilhada e eventos entre user e kernel
  • Hook de API em kernel mode para plataformas NT e 9X
  • Carregador de boot em Assembly 16 bits; depuração usando Debug.com
  • Proteção de executáveis através de autenticação em domínio configurado no resource dos arquivos
  • DLL de proteção à navegação em Internet Explorer 6/7 e Firefox 1/2 com injeção de código Assembly 32 bits
  • Biblioteca de proteção de código, strings e execução monitorada; uso de interrupções Win32
  • Biblioteca de geração de log centralizado através de memória mapeada e eventos globais
  • BHO (Broser Helper Object) e ActiveX para Internet Explorer 6/7 e plugin XPI para Mozilla/Firefox
  • Gerenciamento de projetos com Source Safe, Bazaar e scripts Batch
  • Depuração de kernel mode em plataforma NT usando SoftIce e WinDbg, em 9X usando SoftIce e WDeb98
  • Engenharia reversa de trojans feitos em C++, Visual Basic e Delphi usando WinDbg e IDA
  • Ferramenta de diagnóstico que lista arquivos, serviços, drivers, registro, partições, processos, etc da máquina
  • Monitoramento de jobs em Windows 2000+ para controle de instalação e atualização de produtos
  • Monitoramento da frequência de uso de aplicações usando hook de janelas invasiva e não-invasiva
  • Engenharia reversa do dicionário Houaiss e importação para o formato Babylon
  • Controle de build com Cruise Control .NET, servidor de símbolos com Debugging Tools for Windows
  • Documentação de projetos através de Doxygen e Wiki (Trac)
  • Interfaces de gerenciamento em C++ Builder 5/6 e bibliotecas Visual C++
  • Analisador de e-mails usando expressões regulares (ATL)
  • Interfaces de análise em Visual C++ (MFC /ATL/WTL)
  • Análise de logs e edição global de projetos utilizando regular expressions
  • Desenvolvimento de artigos através de blogue técnico e comunidade Code Project (esse você já sabia, não é?)

 

Depurando até o último segundo

12

Como depurar um programa que dá pau logo no final do desligamento de uma máquina?

No cenário em que isso se passa não existem usuários logados no momento, o que significa a impossibilidade de rodar qualquer programa em uma sessão prévia e mantê-lo no ar após o logoff. A não ser que se trate de um serviço.

(more...)

WinDbg.info

5

Para os perdidos e desatualizados como eu, notei hoje que Robert Kuster possui um saite onde mantém diversas informações sobre o WinDbg; uma espécie de continuação de sua famosa transparência "WinDbg. From A to Z".

Como eu descobri? Bom, ele me mandou um e-mail perguntando se poderia deixar sua tradução para inglês do meu artigo como Foreword para os slides =)

(more...)

Serviço do PsExec criado na máquina-alvo.

Como funciona o PsExec

14

Semana passada precisei reproduzir o comportamento da ferramenta PsExec em um projeto, o que me fez sentir alguma nostalgia dos tempos em que eu fazia engenharia reversa todo dia. Este breve relato (espero) reproduz os passos que segui para descobrir o que esse programa tão útil quanto perigoso faz.

Dados conhecidos

Sabe-se que o PsExec consegue executar um programa remotamente, ou seja, de uma máquina para outra, outra essa que chamaremos de máquina-alvo. O programa a ser executado geralmente deve estar disponível na própria máquina-alvo (condição ideal). Além da simples execução, para aplicativos console ele permite ainda a interação como se estivéssemos executando o programa remoto em nossa própria máquina local. Ele consegue isso redirecionando sua entrada e saída, o que o torna, como nos descreve o próprio autor, um "telnet light":

psexec \\maquina-alvo [-u admin-na-maquina-alvo] cmd.exe

Além desse comportamento já muito útil ainda existe um bônus que se trata de especificar um executável local que será copiado remotamente para a máquina-alvo e executado. Esse é o comportamento que espero imitar:

psexec \\maquina-alvo [-c c:\tests\myprogram.exe] [-u admin-na-maquina-alvo]
PsExec v1.72 - Execute processes remotely Copyright (C) 2001-2006 Mark Russinovich
Sysinternals - www.sysinternals.com
Microsoft Windows XP [versão 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

No teste acima o myprogram.exe é somente o cmd.exe renomeado. Um teste básico =)

(more...)

cmdtree.png

Reúna seus comandos mais usados no WinDbg com .cmdtree

0

Tudo começou com o artigo de Roberto Farah sobre o comando "escondido" do WinDbg .cmdtree. Logo depois meus outros colegas do fã-clube do WinDbg Volker von Einem e Dmitry Vostokov comentaram sobre a imensa utilidade desse comando.

E não é pra menos. É de longe o melhor comando não-documentado do ano. Tão bom que sou obrigado a comentar em português sobre ele, apesar dos três artigos já citados.

(more...)

taskmanagerpid.PNG

ProcessLeaker

0

O artigo anterior mostrava como detectar o leak de um processo gerado pela retenção e não-liberação de handles para o Windows Explorer. O problema fora causado por um serviço malcriado. No entanto, a título de demonstração, criei um pequeno programinha sem-vergonha para fazer as coisas parecerem difíceis. No entanto o programa é bem fácil:

(more...)

unico-explorer-no-sistema.PNG

Os processos-fantasma

0

Estava eu outro belo dia tentando achar um problema em um driver que controla criação de processos quando, por acaso, listo os processos na máquina pelo depurador de kernel, após ter dado alguns logons e logoffs, quando me vem a seguinte lista de processos do Windows Explorer:

PROCESS 815f0da0  SessionId: 0  Cid: 0694    Peb: 7ffd8000  ParentCid: 0100
    DirBase: 0d6e9000  ObjectTable: 00000000  HandleCount:   0.
    Image: explorer.exe

PROCESS 8164bda0  SessionId: 0  Cid: 03b0    Peb: 7ffdf000  ParentCid: 0100
    DirBase: 02673000  ObjectTable: 00000000  HandleCount:   0.
    Image: explorer.exe

PROCESS 815f7d50  SessionId: 0  Cid: 020c    Peb: 7ffd9000  ParentCid: 0100
    DirBase: 0bc7f000  ObjectTable: 00000000  HandleCount:   0.
    Image: explorer.exe

PROCESS 8164c698  SessionId: 0  Cid: 0794    Peb: 7ffde000  ParentCid: 0100
    DirBase: 0cb08000  ObjectTable: e1a40f20  HandleCount: 279.
    Image: explorer.exe

(more...)

createfileflags.png

Quando o navegador não quer largar um arquivo

4

De vez em quando gosto muito de um vídeo que estou assistindo. Gosto tanto que faço questão de guardar para assistir mais vezes depois. O problema é que o meu Firefox ou, para ser mais técnico, o plugin de vídeo que roda em cima do meu navegador, não permite isso. Ele simplesmente cria um arquivo temporário para exibir o vídeo e logo depois o apaga, utilizando uma técnica muito útil da função CreateFile, que bloqueia o acesso do arquivo temporário e apaga-o logo após o uso:

(more...)

caloni-first-year.png

Primeiro ano do novo Caloni.com.br

0

caloni-first-year.pngMelhor que ter feito aniversário de dois anos no antigo blogue foi ter feito o primeiro aninho nesse novo formato, mais atualizado, mais diversificado e mais antenado com o meu dia-a-dia real.

No dia 14 de junho de 2007 foram publicadas as boas vindas, e desde então o número de artigos tem se mantido sempre no formato três por semana, dois por semana, consecutivamente, distribuídos na segunda, quarta e sexta, terça e quinta. Esse jogo de xadrez tem me mantido bem ocupado, admito, mas no final até que vale a pena. Chegamos à marca de 130 artigos e 182 comentários dentro de 29 categorias.

(more...)

windbg-a-to-z.png

Aprendendo rapidamente conceitos essenciais do WinDbg

2

windbg-a-to-z.png Todo o poder e flexibilidade do pacote Debugging Tools da Microsoft pode ser ofuscado pela sua complexidade e curva de aprendizagem. Afinal de contas, usar o depurador do Visual Studio é muito fácil, quando se começa a usar, mas mesmo assim conheço muitos programadores que relutam em depurar passo-a-passo, preferindo a depuração por meio de "MessageBoxes" ou saídas na tela. Imagine, então, a dificuldade que não é para quem conseguiu às duras penas aprender a tornar um hábito a primeira passada do código novo em folha através do F10 começar a fazer coisas como configurar símbolos e digitar comandos exdrúxulos em uma tela em modo texto. Para piorar a questão, existem aqueles que defendem o uso unificado de uma ferramenta que faça tudo, como um telefone celular. Eu discordo. Quando a vantagem competitiva de uma ferramenta sobre outra é notável, nada pior que ficar preso em um ambiente legalzinho que faz o mínimo para você, mas não resolve o seu problema de deadlock.

(more...)

windbg-user-kernel.png

Kernel Mode >> User Mode

0

Existem algumas situações onde um depurador WYSIWYG é artigo de luxo.

Imagine o seguinte: temos um serviço que inicia automagicamente antes do login do Windows, e possivelmente antes mesmo do ambiente gráfico. Esse serviço tem algum problema que impede que ele funcione sob as circunstâncias de inicialização do sistema. O que fazer? Atachar o WinDbg no processo?

Mas que mané WinDbg? Que mané atachar? Nessa hora nós temos bem menos do que nossos sentidos são capazes de enxergar.

Nessas horas o único que pode nos ajudar é o kernel debugger.

(more...)

dimm.gif

Acessando memória física no WinDbg

0

dimm.gif

Como muitos devem saber, acessar memória virtual no WinDbg é coisa de criança, assim como em todo depurador decente. Se estamos falando de kernel mode então, nem se fala! A memória virtual é parte integrante do sistema operacional. Podemos saber mais sobre isso lendo o artigo do Strauss sobre gerenciamento de memória no Windows.

Porém, existem situações, como a que passei essa semana, onde é preciso saber e alterar o conteúdo da memória de verdade, mesmo. Quando eu falo "de verdade mesmo" estou falando em acessar a memória através do seu endereçamento real, que conta do zero até o final da sua memória RAM, sem divisão de processos e sem proteções de acesso.

Para isso é que serve um depurador de verdade, mesmo.

(more...)

Go to Top