
; note: k32_base search is NT only

callbyhash_any: pop     esi
                lodsd
                pusha
                jmp     callbyhash2
callbyhash_k32: pop     esi
                lodsd
                pusha
; find kernel32 base
                mov     ebx, fs:[0030h] ; EAX=PEB base
                mov     ebx, [ebx+0Ch]  ; EAX=PEB_LDR_DATA
                mov     esi, [ebx+1Ch]  ; InitOrderModuleList 1st entry
                lodsd                   ; next entry
                mov     ebx, [eax+8]    ; K32 imagebase
; have base in EBX
callbyhash2:
                mov     ecx, [ebx+3Ch]  ; ECX = pe header
                mov     ecx, [ecx+ebx+78h] ; ECX = export rva
                add     ecx, ebx        ; ECX = export va
                xor     esi, esi        ; for each func, ESI = index
__search_cycle:
                lea     edx, [esi*4+ebx]
                add     edx, [ecx+20h]  ; ex_namepointersrva
                mov     edx, [edx]      ; name va
                add     edx, ebx        ; +imagebase
; calculate api hash
                xor     eax, eax
__calc_hash:
                rol     eax, 7
                xor     al, [edx]
                inc     edx
                cmp     byte ptr [edx], 0
                jne     __calc_hash
                cmp     eax, [esp+7*4]  ; compare hashs (PUSHA.EAX)
                je      __name_found
                inc     esi             ; index++
                cmp     esi, [ecx+18h]  ; ex_numofnamepointers
                jb      __search_cycle
; should never get here
__name_found:
                mov     edx, [ecx+24h]  ; ex_ordinaltablerva
                add     edx, ebx        ; +imagebase
                movzx   edx, word ptr [edx+esi*2] ; edx=current ordinal
                mov     eax, [ecx+1Ch]  ; ex_addresstablerva
                add     eax, ebx        ; +imagebase
                mov     eax, [eax+edx*4] ; eax=current address
                add     eax, ebx        ; +imagebase
                mov     [esp+4*7], eax  ; popa.eax
                popa
                call    eax
                or      eax, eax
                jmp     esi
