I just ran into another good blog by Roberto Farah regarding to how to edit memory using WinDBG and its usefulness -- WinDbg Live Programming: Fazendo um log das chamadas à MessageBox. Unfortunately, I do not understand the language used in the blog. However, the blog is just too good to ignore. I redo it on my own and add my own comment on it.
The blog shows how to capture the message text for the MessageBoxW and write it to the debugger console by editing the instruction in the memory.
Allocate 1000 bytes of memory. It would return the starting address of the allocated memory.
0:000> .dvalloc 1000
Allocated 1000 bytes starting at 00340000
Add CRLF in unicode to the beginning of the memory.
0:000> r $t0=0x00340000
0:000> ezu $t0 "\r\n"
Check the memory does start with CRLF.
0:000> db $t0 L0xF
00340000 0d 00 0a 00 00 00 00 00-00 00 00 00 00 00 00 ...............
Start editing the memory right after CRLF. Since the string is in unicode, 6 bytes are required. First push EAX onto the stack and call OutputDebugStringW, then push CRLF onto the stack and call OutputDebugStringW, finally add a debugbreak.
0:000> r $t1=$t0+0x6
0:000> a $t1
00340006 push eax
00340007 call kernel32!OutputDebugStringW
0034000c push 0x00340000
00340011 call kernel32!OutputDebugStringW
00340016 int 3
00340017
Check the memory after editing
0:000> u $t1
00340006 50 push eax
00340007 e8f9b3517c call kernel32!OutputDebugStringW (7c85b405)
0034000c 6800003400 push 340000h
00340011 e8efb3517c call kernel32!OutputDebugStringW (7c85b405)
00340016 cc int 3
00340017 0000 add byte ptr [eax],al
00340019 0000 add byte ptr [eax],al
0034001b 0000 add byte ptr [eax],al
0:000> db $t0
00340000 0d 00 0a 00 00 00 50 e8-f9 b3 51 7c 68 00 00 34 ......P...Q|h..4
00340010 00 e8 ef b3 51 7c cc 00-00 00 00 00 00 00 00 00 ....Q|..........
00340020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00340030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00340040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00340050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00340060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00340070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Set a breakpoint at the beginning of MessageBoxExW. At the breakpoint, store EIP to $t2, the second parameter to EAX, and the new address to EIP.
0:000> bp user32!MessageBoxExW "r $t2=@eip;r eax=poi(@esp+8);r eip=$t1;g"
Set a breakpoint at the debugbreak. When the new instructions have been executed, restore the original EIP.
0:000> bp $t0+0x16 "r eip=$t2;g"
0:000> g
The following is the source code.
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t wzBuffer[128];
DWORD dwInterval = 1000, dwCount = 3;
for(DWORD a = 0 ; a < dwCount ; a++)
{
wsprintf(wzBuffer, L"This is message box%d", a);
MessageBox(NULL, wzBuffer, L"LOG", MB_OK);
Sleep(dwInterval);
}
return 0;
}
Friday, January 22, 2010
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment