Log in

View Full Version : Vista Problem


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.

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


rendari
March 4th, 2008, 19:20
Oh man, I wrote this code 2 years ago, and ever since then I've been c/ping it into my projects with little thought. Only now do I look back at it and realize how fucking stupid, high, and generally fucked up I must have been to write something like this. If this isn't the most fucked up way ever to grab exports from kernel32.dll, then you can fuck my sideways and call me sparky. I'm gonna go and rewrite the above piece of shit.

However, the problem I mentioned in my above post still stands. If I get a valid address to the GetProcAddress ascii, it still gives me the wrong RVA when I use it to index into other tables, despite the fact that it returns the correct LoadLibrary RVA when I ask it for LoadLibraryA, and on WinXP is returns both GetProcAddress and LoadLibrary without problems.

rendari
March 4th, 2008, 20:49
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+0Ch] ; takes address of names
jmp _Find_Hash_Loop_Begin

_Find_Hash_Loop:

add edx, 4

_Find_Hash_Loop_Begin:

mov eax, edx ; put in eax the current location. its the param to the hasher func.
mov eax, dword ptr[eax]
add eax, dword ptr[esi] ; add Kernel base to get pointer to ascii
mov ebx, edx
call _ComputeHash ; z0mbie hash it.
mov edx, ebx
cmp eax, ecx ; did we find the correct hash?
jne _Find_Hash_Loop

sub edx, dword ptr[esi+0Ch] ; sub it from AddressOfNames base to get index
mov eax, edx
mov ecx, 2
mov edx, 0
idiv ecx ; transform it to deal with words, not dwords
mov edx, eax
add edx, dword ptr[esi+010h] ; use the index with AddressOfOrdinals
mov eax, edx
xor edx, edx
mov dx, word ptr[eax] ; get ordinal
mov eax, 4
imul edx
mov edx, eax
add edx, dword ptr[esi+8] ; use it as index into AddressOfFunctions
mov eax, dword ptr[edx] ; get RVA of function
add eax, dword ptr[esi] ; and add kernel base to it to get Address of Function
; 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


There, that's the new code. Works fine on Vista, so problem solved I'll keep the crappy code in the original post so people can laugh at how stupid I was. Cheers

Woodmann
March 4th, 2008, 21:29
Hey,
Crappy code happens

It's the learning process that counts .

Woodmann