Hell yes !
I Did IT !
I just want to share my happyness!
I had nothing to prove.
But how motivating it was to study into this field. it was a balls to the wall.
I had no idea about this exam. no info about the possibles questions (no training material) so i bassicly read/tryed/study everything about win internals.
lot's of windbg , crash dump analyse. kernel drivers dev. apps designs
I scored 883 over 1000 in 43 minutes over 105 minutes !
im proud for a ex-linux user i was ;)
voila that's all ! im back to blogging in a few !
Support your local geek
debugging with windbg and ollydbg. reversing engineering malware, exploits and various binary with IDA. computer security under unix and windows. web security as a daily routine. various hacker tricks & tips. C ,ASM, java and groovy has a daily bread.the life of a Linux geek exploring windows API and Internals :)
Monday, January 25, 2010
Friday, January 23, 2009
showing exports symbols with windbg (updated!)
Like i talked about a complicated way of viewing exports symbols,
Here is the way of viewing symbols from an executable directly.
First we check with "lm"
0:002> lm
start end module name
003e0000 003fa000 WinsockHookDLL C (export symbols) C:\Program Files\Secway\SimpLite-MSN 2.2\Plugins\WinsockHookDLL.dll
00400000 004ea000 protect (no symbols)
Here our guility the modules named 'protect'.
How to get the export from the executable image?
you must unload it with the command ".reload /u"
0:002> .reload /u protect
Unloaded protect
now just reload the image and indicate where you want to store it
Remenber "lm" showed our executable was stored a 00400000
0:002> .reload /f /v protect.exe=00400000
0:002> lm
start end module name
003e0000 003fa000 WinsockHookDLL C (export symbols) C:\Program Files\Secway\SimpLite-MSN 2.2\Plugins\WinsockHookDLL.dll
00400000 004ea000 protect (export symbols) protect.exe
Done!
now you can start inspecting your symbols with x protect!*
0:002> x protect!*
00401066 protect!PSE_MemoryFree ()
00405eaf protect!PSA_Uninitialize ()
00406002 protect!PSA_GetLicenseStoragePath ()
004061aa protect!PSA_GetLicenseInformation ()
0040630d protect!PSA_GetFeaturesGrantedByLicense ()
00406455 protect!PSA_DisableFeaturesGrantedByLicense ()
Voila that's all ;)
Here is the way of viewing symbols from an executable directly.
First we check with "lm"
0:002> lm
start end module name
003e0000 003fa000 WinsockHookDLL C (export symbols) C:\Program Files\Secway\SimpLite-MSN 2.2\Plugins\WinsockHookDLL.dll
00400000 004ea000 protect (no symbols)
Here our guility the modules named 'protect'.
How to get the export from the executable image?
you must unload it with the command ".reload /u"
0:002> .reload /u protect
Unloaded protect
now just reload the image and indicate where you want to store it
Remenber "lm" showed our executable was stored a 00400000
0:002> .reload /f /v protect.exe=00400000
0:002> lm
start end module name
003e0000 003fa000 WinsockHookDLL C (export symbols) C:\Program Files\Secway\SimpLite-MSN 2.2\Plugins\WinsockHookDLL.dll
00400000 004ea000 protect (export symbols) protect.exe
Done!
now you can start inspecting your symbols with x protect!*
0:002> x protect!*
00401066 protect!PSE_MemoryFree (
00405eaf protect!PSA_Uninitialize (
00406002 protect!PSA_GetLicenseStoragePath (
004061aa protect!PSA_GetLicenseInformation (
0040630d protect!PSA_GetFeaturesGrantedByLicense (
00406455 protect!PSA_DisableFeaturesGrantedByLicense (
Voila that's all ;)
Thursday, January 22, 2009
windbg showing export table and import table from the memory
Here i want to describe a way to display the export table from a packed software with windbg.
As far i know windbg read the symbols for a modules in two way.
From the symbols file OR from the executable.
But what happen with .exe/dll packed whois constructing is export table at run time ?
Here i show the Quick/n/Dirty way of looking at your export table. when everything fail !
I take for my example a Packed protector. this .exe is launched from a game. the exe is packed/crypted
it extract himself and export is functions after he is loaded. YES I KNOW with ollydbg it would not be hard at all
I would just have to take a look at the 'search name in current module'.
But windbg is not that friendly ,it's a small price to pay for such a powerfull debugger.
But it's possible! ok let's start!
First run "!lm"
:002> lm
start end module name
00400000 004ea000 protect (no symbols)
00bf0000 00c0a000 WinsockHookDLL C (export symbols) C:\Program Files\Secway\SimpLite-MSN 2.2\Plugins\WinsockHookDLL.dll
00e50000 00e71000 btkeyind (export symbols) C:\Program Files\WIDCOMM\Bluetooth Software\btkeyind.dll
10000000 10035000 btmmhook (export symbols) C:\Windows\system32\btmmhook.dll
6e360000 6e3d2000 Riched20 (pdb symbols) C:\Program Files\Debugging Tools for Wi
Ok we found the module name now inspect the PE header.
For this we will use "dh", dh is a cool command for inspecting PE header in memory.
Very handy when you are searching an executable image in the process address space.
:001> !dh 00400000
FILE HEADER VALUES
14C machine (i386)
3 number of sections
493D4022 time date stamp Mon Dec 08 16:41:22 2008
25D85729 file pointer to symbol table
0 number of symbols
E0 size of optional header
D03 characteristics
Relocations stripped
Executable
32 bit word machine
RESERVED - UNKNOWN
RESERVED - UNKNOWN
OPTIONAL HEADER VALUES
10B magic #
8.00 linker version
3B000 size of code
14000 size of initialized data
9A000 size of uninitialized data
D5820 address of entry point
9B000 base of code
----- new -----
00400000 image base
1000 section alignment
200 file alignment
2 subsystem (Windows GUI)
4.00 operating system version
0.00 image version
4.00 subsystem version
EA000 size of image
1000 size of headers
7B291 checksum
00100000 size of stack reserve
00001000 size of stack commit
00100000 size of heap reserve
00001000 size of heap commit
B0E50 [ 9D0] address [size] of Export Directory
E90EC [ 1D8] address [size] of Import Directory
D6000 [ 130EC] address [size] of Resource Directory
0 [ 0] address [size] of Exception Directory
6EFE8 [ 1548] address [size] of Security Directory
0 [ 0] address [size] of Base Relocation Directory
0 [ 0] address [size] of Debug Directory
0 [ 0] address [size] of Description Directory
0 [ 0] address [size] of Special Directory
0 [ 0] address [size] of Thread Storage Directory
D59D4 [ 48] address [size] of Load Configuration Directory
0 [ 0] address [size] of Bound Import Directory
0 [ 0] address [size] of Import Address Table Directory
0 [ 0] address [size] of Delay Import Directory
0 [ 0] address [size] of COR20 Header Directory
0 [ 0] address [size] of Reserved Directory
Ok so we found the address of the export directory.
....
B0E50 [ 9D0] address [size] of Export Directory
....
So what interesting at this address ??
First of all. B0E50 point to nothing ! you have to add the ImageBase (a.k.a 0040000 in our example).
0:002> dd 00400000+B0E50 <== see the imagebase added
004b0e50 00000000 493d4021 00000000 000b113e
004b0e60 00000001 00000047 00000047 000b0e78
004b0e70 000b0f94 000b10b0 00006599 00006455
004b0e80 0002db8c 0000630d 0000696d 0000745e
004b0e90 00006d1a 000061aa 00006e50 000070bc
004b0ea0 00006002 000076ca 000071f2 00007328
004b0eb0 00006f86 00006be4 00007594 000066dd
004b0ec0 00006aa3 00006825 00005eaf 000082a4
Here we dump the IMAGE_EXPORT_DIRECTORY it self.
What mean all thous fields ?
For helping us we will take a look at the structure type (available everywhere (google))
public struct IMAGE_EXPORT_DIRECTORY
{
public UInt32 Characteristics; // 00000000
public UInt32 TimeDateStamp; // 493d4021
public UInt16 MajorVersion; // 0000
public UInt16 MinorVersion; // 0000
public UInt32 Name; // 000b113e (in memory 00400000+000b113e)
public UInt32 Base; // 00000001
public UInt32 NumberOfFunctions; // 00000047
public UInt32 NumberOfNames; // 00000047
public UInt32 AddressOfFunctions; // 000b0e78
public UInt32 AddressOfNames; // 000b0f94
public UInt32 AddressOfNameOrdinals; // 000b10b0
}
Now focus on thous ones.
public UInt32 NumberOfFunctions;
public UInt32 NumberOfNames;
public UInt32 AddressOfFunctions; // RVA from base of image
public UInt32 AddressOfNames; // RVA from base of image
public UInt32 AddressOfNameOrdinals; // RVA from base of image
First Step is to extract the 'names' of the functions exported.
AddressOfNames is our man. It contains the address of an array of RVA (address relative to the ImageBase) who will point to the names
of the functions exported.
in code it would be something like that
char *AddressOfNames[]
for (i = 0; i <>
FunctionName = AddressOfNames[ i ]
Now extract the RVA's convert em and print the name!
**Remenber** 'UInt32 AddressOfNames == 000b0f94 ' So for getting the real address add 0x0040000
0:002> .for ( r $t0 = 0; @$t0 < t0 =" @$t0">
004b114a "PSA_CheckFeaturesGrantedByLicense"
004b116c "PSA_DisableFeaturesGrantedByLicense"
004b1190 "PSA_DummyFunction"
004b11a2 "PSA_GetFeaturesGrantedByLicense" <== position 3
004b11c2 "PSA_GetLicenseCreationDateTime"
004b11e1 "PSA_GetLicenseExecutionTimeLimit"
004b1202 "PSA_GetLicenseExpirationDateTime"
004b1223 "PSA_GetLicenseInformation"
004b123d "PSA_GetLicenseLifeTimeLimit"
004b1259 "PSA_GetLicenseNumberOfRunsLimit"
004b1279 "PSA_GetLicenseStoragePath"
004b1293 "PSA_GetNumberOfConnections"
....
Here we get a nice list of function names!
But to which address in the executable code they below ?
For the associated the name to the address in the executable code there is a trick,
Let's take "PSA_GetFeaturesGrantedByLicense", this function is at position 3 [0, 1, 2, 3] into the Array of RVA of names.
you will then extract the value at position 3 in the AddressOfNameOrdinals Array
**NOTE**: this Array use 16 bits menbers
// pseudo code: index_address = UNSIGNED SHORT AddressOfNameOrdinals [ 3 ]
Dump this array!
0:002> .for ( r $t0 = 0; @$t0 < (0x11C/2) ; r $t0 = @$t0 + 2) { dw /c 2 00400000+b10b0+@$t0 l1 }
004b10b0 0000
004b10b2 0001
004b10b4 0002
004b10b6 0003 <== Our Index in AddressOfFunctions
Has you see the Index for our function is 3 too. Now let's see at AddressOfFunction[3].
0:002> .for ( r $t0 = 0; @$t0 < t0 =" @$t0" t1 =" poi(00400000+b0e78+@$t0)+0x00400000">
00406599
00406455
0042db8c
0040630d <== *Gottcha*! our function "PSA_GetFeaturesGrantedByLicense"
0040696d
0040745e
Now you know that's "PSA_GetFeaturesGrantedByLicense" is located at 0x0040630d
There really nothing complicated in the windbg commands i showed to you.
Just remenber to add 0x00400000 (ImageBase of our module) for converting RVA to real address in the process.
Beside that's the ".for" command in wingdb is working like in C.
For reversing purpose, i would add a breakpoint instead of a printf into each address exported.
You could ofcourse do all thous step in one command but i wanted to show it step by step.
Oh... for a reminder and because it's a VERY VERY COMMON question but there is not much information about it
for knowing wich functions are imported from a module.
(showing Import table)
BONUS !
*** How to display the import table of a process with windbg ? ***
Get the address of the import table directory with "!dh"
...
94BC0 [ 1000] address [size] of Import Address Table Directory
...
Retrieve the address of the IAT (Import Table Address) convert it to the real address in memory
/* IAT address is a RVA in the PE header (Relative Memory Address) */
and use the command "dps" (display symbols)
dps 0x00400000+94BC0 l1000/8
NOTE: the /8 mean to take a step of 8 when incrementing the address's displayed (we dont care of the second member of Image Import Name)
that's will print something like that...
...
005fb3cc 76aa52da ADVAPI32!CryptAcquireContextA
005fb3d0 76aa59cc ADVAPI32!CryptGenRandom
005fb3d4 76a99aa5 ADVAPI32!DeregisterEventSource
005fb3d8 76abf429 ADVAPI32!RegCloseKey
005fb3dc 76aad4e8 ADVAPI32!RegOpenKeyExA
005fb3e0 76aad639 ADVAPI32!RegQueryValueExA
005fb3e4 76a98696 ADVAPI32!RegisterEventSourceA
005fb3e8 76a8888d ADVAPI32!ReportEventA
005fb3ec 00000000
005fb3f0 00000000
005fb3f4 770f6ce7 GDI32!BitBlt
005fb3f8 770f693f GDI32!CreateCompatibleBitmap
005fb3fc 770f64cb GDI32!CreateCompatibleDC
005fb400 770fac01 GDI32!CreateDCA
005fb404 770f6a44 GDI32!DeleteDC
005fb408 770f5bed GDI32!DeleteObject
005fb40c 770fbeaa GDI32!GetBitmapBits
VOILA ! that's all !
I know i was suposed to talk about tracing (call flow tracing)
But this post was my surprise ;)
Get wired!
-anti
PS: Take a look of the wonderfull tutorial from Iczellion's it's unvaluable !!!!
Friday, January 16, 2009
API Tracing with windbg
Tracing your API call under window is one of the most needed task.
Under Linux this task is very well made with a proggie like strace.
But under windows this is not really easy.
about API tracing there is a lots of program who could do this task.
Free or not but i never been really happy with'em. and really why looking at something else
when you could make it in 30 seconds with a free and very solid debugger !
Here i call windbg !
So let's fire your favorite debugger (Word Windbg ;) )
Imagine you want to trace the call made to WinInet.dll
For this example we will use windows live mail. (wlmail.exe)
Load the executable
(172c.116c): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=0006fb08 edx=77859a94 esi=fffffffe edi=7785b6f8
eip=77847dfe esp=0006fb20 ebp=0006fb50 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!DbgBreakPoint:
77847dfe cc int 3
0:000> lm
start end module name
00400000 00428000 wlmail (deferred)
70300000 703e2000 UXCore (deferred)
72c50000 72ceb000 MSVCR80 (deferred)
74fe0000 7517e000 COMCTL32 (deferred)
75360000 75365000 MSIMG32 (deferred)
76db0000 76dce000 IMM32 (deferred)
76dd0000 76e6d000 USER32 (deferred)
76eb0000 76f76000 ADVAPI32 (deferred)
76f80000 770c4000 ole32 (deferred)
771a0000 77268000 MSCTF (deferred)
77270000 77332000 RPCRT4 (deferred)
77420000 774ad000 OLEAUT32 (deferred)
77540000 7758b000 GDI32 (deferred)
77590000 7763a000 msvcrt (deferred)
77670000 776c8000 SHLWAPI (deferred)
77800000 77927000 ntdll (pdb symbols) C:\Program Files\Debugging Tools for Windows\sym\ntdll.pdb\B958B2F91A5A46B889DAFAB4D140CF252\ntdll.pdb
77980000 77a5b000 kernel32 (deferred)
lm list the current modules loaded as you see there as you see our Module is not yet loaded.
So yet we have nothing we could trace.
the easy way is to set a Breakpoint at LoadLibrary waiting for wininet.dll like this
we will not miss anycall to wininet.
If you want to trace kernel32 or something else you could trace from here.
(If you want to trace the dll at the loading time (init routine for example) or tracing thread/process Creation you will have to do it in a different way but that's a another article)
Add your Breakpoint
0:000> bp kernel32!LoadLibraryW
0:000> bp kernel32!LoadLibraryA <--- shouldnt happen windows mostly call *W function
0:000> g
Breakpoint 0 hit
eax=00b30000 ebx=00000000 ecx=0006f324 edx=77859a94 esi=7784298c edi=00000000
eip=779a361f esp=0006f300 ebp=0006f324 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
kernel32!LoadLibraryW:
yet windbg didnt printed that's wininet is loaded so continue until it's loaded
...
0:000> g
ModLoad: 5e100000 5e373000 C:\Program Files\Windows Live\Mail\MSMAIL.DLL
ModLoad: 5a780000 5a7d8000 C:\Program Files\Windows Live\Mail\ContactsUX.dll
ModLoad: 59100000 5912c000 C:\Program Files\Windows Live\Mail\MSNCore.dll
ModLoad: 776d0000 777f9000 C:\Windows\system32\urlmon.dll
ModLoad: 77930000 77975000 C:\Windows\system32\iertutil.dll
ModLoad: 77340000 77410000 C:\Windows\system32\WININET.dll
HERE IS our dll !!!
Ok now it's time to trace !
If you want a simple trace you could use a command like "bm"
"bm" will add your breakpoint to the place who match your place
"bm" work like the command "x"
try to this command x wininet!*Internet*
0:000> x wininet!*Internet*
7734fee2 WININET!InternetIndicateStatus =
773bce38 WININET!INTERNET_CONNECT_HANDLE_OBJECT::ExpireDependents =
7734182f WININET!InternetDestroyThreadInfo =
773aa2be WININET!CFsm_InternetReadFile::CFsm_InternetReadFile =
773ab173 WININET!InternetShowSecurityInfoByURLW =
773ab959 WININET!INTERNET_FILE_HANDLE_OBJECT::INTERNET_FILE_HANDLE_OBJECT =
You could see all the symbols into this module.
so let's add our breakpoint for tracing !
0:000> bm wininet!*
No matching code symbols found, no breakpoints set.
If you are using public symbols, switch to full or export symbols.
??? hey what's wrong !
Ok windbg dont know how to put our breakpoint because per default it using the symbols file
for placing is breakpoint. but like wininet contains also "data" symbol and another kind of information that would be totally wrong to breakpoint (never try to breakpoint into a readonly memory map)
So for fixing this and use only the symbol's exported from the dll (PE export table)
we will have to do a little hack.
0:000> .sympath C:\somewhere_not_real
Symbol search path is: C:\somewhere_not_real
WARNING: Inaccessible path: 'C:\somewhere_not_real'
0:000> .reload -f wininet.dll
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\system32\WININET.dll -
dont mind of the ERROR this not an error :)
now check again with "x wininet!*" as you see there no more debugging symbol we are back to the straight "exported" symbol by the dll itself.
0:000> bm wininet!*
3: 77343f62 @!"WININET!InternetCrackUrlW"
4: 77346151 @!"WININET!InternetCanonicalizeUrlW"
5: 773481dd @!"WININET!GetUrlCacheEntryInfoExA"
6: 77348425 @!"WININET!GetUrlCacheEntryInfoA"
....
now try to run the code !
"g"
Ok now your code is breaking at each time you are calling a wininet functions!
But this is not really want you thinked when we talked about tracing ?
Exactly this is not very good...
So what's to do ?
bm and many of the command of windbg can run a command at each time they execute !
First we want to get ride of the "register" displayed at each time and the disassembly
.prompt_allow -reg -dis +ea
Try this !
bm wininet!* "ln . ; g"
at each time a breakpoint will be executed you will get the name of your location "ln ."
and continue the program !
here it's starting to get good to see exactly what is called !
But What if i want to get something more verbose ?
Like displaying the data Received or the URL opened or the data sent ? here is my collection
of breakpoint to add (dont mind i will explain the the diffcult one)
bp WININET!InternetConnectW ".echo InternetConnectW; du /c 64 poi(@esp+0x8) L100 ; g"
bp WININET!HttpOpenRequestW ".echo HttpOpenRequestW; du /c 64 poi(@esp+0x8); du /c 64 poi(@esp+0XC) L2000 ; g"
bp WININET!HttpSendRequestW ".echo HttpSendRequest->headerW; du /c 64 poi(@esp+0x8) L4000 ;.echo SendRequestA->Option; du /c 64 poi (@esp+0x10) L5500 ; g "
bp WININET!HttpAddRequestHeadersW ".echo HttpAddRequestHeadersW; du /c 64 poi(@esp+0x8) L4000; g"
bp WININET!GetUrlCacheEntryInfoW ".echo GetUrlCacheEntryInfoW; du /c 64 poi(@esp+0x8) L4000; g"
bp WININET!SetUrlCacheEntryInfoW ".echo SetUrlCacheEntryInfoW; du /c 64 poi (@esp+0x4) L4000; g"
bp WININET!RetrieveUrlCacheEntryStreamW ".echo RetrieveUrlCacheEntryStreamW; du /c 64 poi(@esp+0x4) L4000; g"
bp WININET!CreateUrlCacheEntryW ".echo CreateUrlCacheEntryW; du /c 64 poi (@esp+0x4) L4000; g"
bp WININET!InternetSetCookieW ".echo InternetSetCookieW ; .echo Cookiename; du /c 64 poi (@esp+0x8);.echo CookieValuee ; du /c 64 poi (@esp+0xC); g"
bp WININET!InternetConnectA ".echo InternetConnectA; da /c 64 poi(@esp+0x8) L100 ; g"
bp WININET!HttpOpenRequestA ".echo HttpOpenRequestA; da /c 64 poi(@esp+0x8); da poi(@esp+0XC) L2000 ; g"
bp WININET!HttpSendRequestA ".echo HttpSendRequest->headerA; da /c 64 poi(@esp+0x8) L4000 ; .echo SendRequestA->Option; da /c 64 poi (@esp+0x10) L5500 ; g "
bp WININET!HttpAddRequestHeadersA ".echo HttpAddRequestHeadersA; da /c 64 poi(@esp+0x8) L4000; g"
bp WININET!GetUrlCacheEntryInfoA ".echo GetUrlCacheEntryInfoA; da /c 64 poi(@esp+0x8) L4000; g"
bp WININET!SetUrlCacheEntryInfoA ".echo SetUrlCacheEntryInfoA; da /c 64 poi (@esp+0x4) L4000; g"
bp WININET!RetrieveUrlCacheEntryStreamA ".echo RetrieveUrlCacheEntryStreamA; da /c 64 poi (@esp+0x4) L4000; g"
bp WININET!CreateUrlCacheEntryA ".echo CreateUrlCacheEntryA; da /c 64 poi (@esp+0x4) L4000; g"
bp WININET!InternetWriteFile ".echo InternetWriteFile; da /c 64 poi(@esp+0x8) L4000 "
bp WININET!InternetReadFile ".echo InternetReadFile; r $t0 = poi(@esp+0x8); r $t1 = poi(@esp+0x10); g @$ra; da /c 64 @$t0 Lpoi(@$t1); g"
bp WININET!InternetReadFileExA ".echo InternetReadFileExA; r $t0 = poi(@esp+0x8);g @$ra; da /c 64 poi (@$t0+0x14) Lpoi(@$t0+0x18);.echo InternetReadFileEx_Header; da /c 64 poi(@$t0+0x8) Lpoi(@$t0+0xC); g"
bp WININET!ReadUrlCacheEntryStream ".echo ReadUrlCacheEntryStream; r $t0 = poi(@esp+0xC); r $t1 = poi(@esp+0x10); g @$ra; da /c 64 @$t0 Lpoi(@$t1); g"
bp WININET!InternetSetOptionA ".echo InternetSetOptionA; dw @esp+0x8; .echo stringifany; da /c 64 poi (@esp+0xC) L300; g"
Ok FIRST we used "bp" instead of "bm" simply because we want to have a special processing
for thous call only (other call to wininet could be simply "displayed" it will be ok for us )
Now let' take a look a this breakpoint
bp WININET!InternetReadFile ".echo InternetReadFile; r $t0 = poi(@esp+0x8); r $t1 = poi(@esp+0x10); g @$ra; da /c 64 @$t0 Lpoi(@$t1); g"
and is function prototype for reminder
BOOL InternetReadFile(
__in HINTERNET hFile,
__out LPVOID lpBuffer,
__in DWORD dwNumberOfBytesToRead,
__out LPDWORD lpdwNumberOfBytesRead
);
1).echo InternetReadFile
Here first i display the name of the breakpoint with .echo
2)r $t0 = poi (@esp+0x8)
here i assign to the pseudo register zero the value of the address where lpBuffer is pointing
(the Buffer that will contains the data after the execution of the function )
Why do i use @esp+0x8 and not @ebp+0x8
Because our breakpoint start at the very first instruction so the prolog of the function
has not been executed
you know push ebp ; push ebp, esp
So we gonna use the register @esp for referencing the argument of the function.
poi () mean " gimme the value at this address" (ie: ESP+0x8 ) or the C equivalent would be
*(esp+0x8)
3)r $t1 = poi(@esp+0x10) //lpdwNumberOfBytesRead
Here i assign to a pseudo register the address of the DWORD that will contains the actual numbers of data that has been 'read'
4) g @$ra;
Now we 'execute' the function UNTIL we reach the return address
The function would have filled our buffer and updated lpdwNumberOfBytesRead.
Now we are just before 'ret' so it's time to display the data
4) da /c 64 @$t0 Lpoi(@$t1)
"da" mean display ascii
/c 64 mean it will be displayed 64 by 64 characters
@$t0 it's the actual address of the buffer who contains the data
Lpoi(@$t1) L mean Length L100 would have display only 100 bytes
But i want to display the whole buffer remenber $t1 was pointing to the DWORD NumberOfBytesRead so Lpoi(@$t1) will get the value pointed by @$t1.
and we will display the right number of characters.
Here is the end of this first post !
Now you have enough knowledge for trace every API you want to :)
I hope you will be interested to look at windbg and discover all is magic power !
Next time i will talk about tracing with windbg !
Bye
-Antilove
Subscribe to:
Comments (Atom)