rendari
March 4th, 2008, 18:55
Here is some classic import loading code that I am using. Locates the ASCII of the API in question in kernel32.dll with a z0mbie hash, then grabs its offset uses it as an index into AddressOfNameOrdinals, whose index is then used with AddressOfFunctions to grab the RVA of the procedure.
Now, the code below works fine on WinXP and Win2k, but on Win Vista it only returns the address of LoadLibrary correctly, but returns a wrong address to GetProcAddress. However, if I grab the next RVA in the AddressOfFunctions table, that turns out to be the correct RVA of GetProcAddress.
So, umm, what is going on here? Why is the RVA of GetProcAddress not where it's supposed to be? =/. Here is the code and the famous z0mbie hash. You can hash GetProcAddress, and then input that into the code I provided below and see what happens.
Now, the code below works fine on WinXP and Win2k, but on Win Vista it only returns the address of LoadLibrary correctly, but returns a wrong address to GetProcAddress. However, if I grab the next RVA in the AddressOfFunctions table, that turns out to be the correct RVA of GetProcAddress.
So, umm, what is going on here? Why is the RVA of GetProcAddress not where it's supposed to be? =/. Here is the code and the famous z0mbie hash. You can hash GetProcAddress, and then input that into the code I provided below and see what happens.
Code:
; param is EAX (meaning EAX contains the actual hash)
; uses hashing algo by z0mbie
; returns loc of API in EAX
_customGetProcAddress:
push edx ; saves edx
push ecx ; saves ecx
push ebx ; saves ebx
mov ecx, eax ; puts hash in ecx
mov edx, dword ptr[esi+010h] ; takes address of name ordinals
_Find_Hash_Loop:
inc edx
mov eax, edx ; put in eax the current location. its the param
mov ebx, edx ; put in ebx current loc also. We might need it later
call _ComputeHash
cmp eax, ecx ; did we find the correct hash?
jne _Find_Hash_Loop
mov eax, ebx ; put in eax the location of the API name
sub eax, dword ptr[esi] ; take away the base of kernel32
mov edx, dword ptr[esi+0Ch] ; get AddressOfNames
_Find_Name_Thingy_Loop:
cmp dword ptr[edx], eax
je _Found_Name_Thingy
add edx, 4
jmp _Find_Name_Thingy_Loop
_Found_Name_Thingy:
mov eax, dword ptr[esi+0Ch] ; take address of names
sub edx, eax ; sub it from edx to get index
mov eax, dword ptr[esi+8] ; get address of functions
add eax, edx ; add index to it
mov eax, dword ptr[eax] ; get the value there
add eax, dword ptr[esi] ; add to it kernel base
; thats it, that should be the function
pop ebx ; pop values
pop ecx
pop edx
ret ; and return. Address of func is in EAX.
; takes eax as input
; returns hash in eax
_ComputeHash:
mov edx, eax
xor eax, eax
_Hash_Loop:
rol eax, 7
xor al, byte ptr[edx]
inc edx
cmp byte ptr[edx], 0
jne _Hash_Loop
ret
ret