Código:
@@get_proc:
; [OnEntry]
; edx => crc32
; ebx => hModule
; [OnExit]
; eax => lpfnApi / NULL (OnError)
assume ebx:ptr IMAGE_DOS_HEADER
push edi
push esi
push ebp
mov edi,ebx
add edi,[ebx].e_lfanew
assume edi:ptr IMAGE_NT_HEADERS
mov edi,[edi].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
add edi,ebx
assume edi:ptr IMAGE_EXPORT_DIRECTORY
xor ecx,ecx
mov esi,[edi].AddressOfNames
add esi,ebx
mov ebp,[edi].NumberOfNames
@@apiname_loop:
lodsd
add eax,ebx
xchg eax,esi
push eax ; save AddressOfNames
push ecx
call @@strlen
xchg eax,ecx
push edx
call @@crc32
pop edx
pop ecx
pop esi
cmp eax,edx
jnz @@not_api_hash
mov esi,[edi].AddressOfNameOrdinals
add esi,ebx
shl ecx,1h
add esi,ecx
movzx ecx,word ptr [esi]
shl ecx,2h
mov esi,[edi].AddressOfFunctions
add esi,ebx
add esi,ecx
mov eax,dword ptr [esi]
; code here to check whether we are being forwarded (does the RVA fall into the .edata?)
mov ebp,ebx
add ebp,[ebx].e_lfanew
assume ebp:ptr IMAGE_NT_HEADERS
mov ecx,[ebp].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress ; thanks to Matt Pietrek
cmp eax,ecx
jb @@not_forwarded
add ecx,[ebp].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].isize
cmp eax,ecx
ja @@not_forwarded
@@get_forwarded:
pop ebp
add eax,ebx
xchg esi,eax
call @@strlen
push ecx
push GMEM_FIXED
call dword ptr [ebp + delta(f_globalalloc)]
xchg eax,edi
push edi ; there could be a bug: if someone makes a fwd api without a dot, the host will crash
@@:
lodsb
stosb
cmp al,'.'
jne @@not_dot
mov eax,'lld'
stosd
jmp @@match_dot
@@not_dot:
loop @B
@@match_dot:
call dword ptr [ebp + delta(f_loadlibrary)] ; I know the program won't be able to free the library (i don't know yet how ms loader does it)
push esi
push eax
call dword ptr [ebp + delta(f_getprocaddress)]
push eax
push edi
call dword ptr [ebp + delta(f_globalfree)]
pop eax
jmp @@fwd_api_found
@@not_forwarded:
add eax,ebx
jmp @@api_found
@@not_api_hash:
inc ecx
cmp ecx,ebp ; I need ecx as a counter
jbe @@apiname_loop
@@not_found:
xor eax,eax
@@api_found:
pop ebp
@@fwd_api_found:
pop esi
pop edi
ret
Código:
@@strlen:
; [OnEntry]
; esi => [StringA]
; [OnExit]
; eax => Length
xchg esi,edi
xor eax,eax
xor ecx,ecx
dec ecx
push edi
repnz scasb
pop edi
inc ecx
not ecx
xchg eax,ecx
xchg esi,edi
ret
.const
POLYNOM equ 0edb88320h
.code
@@crc32:
; [OnEntry]
; esi => [Mem]
; ecx => count
; [OnExit]
; eax => crc32
xor edx,edx
dec edx
@@crc_loop:
mov eax,edx
and eax,0ffh
xor al,byte ptr [esi]
push ecx
mov ecx,8h
@@:
test al,1h
jz @@bit_not_set
shr eax,1h
xor eax,POLYNOM
jmp @@bit_continue
@@bit_not_set:
shr eax,1h
@@bit_continue:
loop @B
pop ecx
inc esi
shr edx,8h
xor edx,eax
loop @@crc_loop
xchg eax,edx
not eax
ret
Tras tracear un poco veo que las llamadas van así:
- LoadLibraryA -> LoadLibraryExA -> KernelBase.749B6DEF -> ntdll.RtlAnsiStringToUnicodeString -> ...
Les agradezco cualquier ayuda/opinión/orientación sobre el tema
PD: Acabo de comprobar que en XP funciona perfectamente, puede ser por algo relacionado con WOW32? O tal vez es por Win7?
Ah, y perdon por un tema/post tan largo, es que no quiero que falte nada de info