用ASM实现GetProcAddress()函数

来源:互联网 发布:清华大学软件学院考研 编辑:程序博客网 时间:2024/06/01 07:25

        用汇编实现的GetProcAddress()函数,GetProcAddress()是系统提供的API函数,通过遍历导出表来实现同样的功能,该代码可以获取转发函数的地址,如HeapAlloc()函数的地址。代码写的比较烂,注释也不多,凑乎看吧。

    .386    .model flat, stdcall    option casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.libMyGetProcAddress    Proto hModule : DWORD, lpProcName : LPSTR    .constszUserDll   db  'user32.dll', 0szMessageBox   db  'MessageBoxA', 0szKernelDll db  'kernel32.dll', 0szHeapAlloc db  'HeapAlloc', 0sz2         db  '2', 0    .codestart:    invoke LoadLibrary, offset szUserDll    push offset szMessageBox    push eax    call MyGetProcAddress    push 0    push 0    push 0    push 0    call eax    invoke GetModuleHandle, offset szKernelDll    push offset szHeapAlloc    push eax    call MyGetProcAddress        invoke GetModuleHandle, offset szKernelDll    push 1dh    push eax    call MyGetProcAddress    invoke ExitProcess, 0    MyGetProcAddress    Proc    hModule:DWORD,  \                             lpProcName:LPSTR    LOCAL lpBase : DWORD    LOCAL AddressOfFunctions : DWORD    LOCAL AddressOfNames     : DWORD    LOCAL AddressOfNameOrdinals : DWORD    LOCAL nBase  : DWORD    LOCAL NumberOfFunctions  : DWORD    LOCAL NumberOfNames      : DWORD    LOCAL ExpTabDir : DWORD    LOCAL szDll[260] : BYTE    cmp hModule, 0    je _EXIT        lea edi, szDll    mov ecx, 260_INIT:    mov byte ptr [edi], 0    inc edi    loop _INIT    mov eax, hModule    mov lpBase, eax    ; is pe header?    mov eax, lpBase    cmp word ptr [eax], IMAGE_DOS_SIGNATURE    jne _EXIT        mov esi, lpBase    assume esi : ptr IMAGE_DOS_HEADER    add esi, [esi].e_lfanew    assume esi : ptr IMAGE_NT_HEADERS    ; is nt headers?    cmp word ptr [esi], IMAGE_NT_SIGNATURE    jne _EXIT        ; locate OptionalHeader    add esi, 4    add esi, sizeof(IMAGE_FILE_HEADER)    assume esi : ptr IMAGE_OPTIONAL_HEADER    ; locate export table rva    lea esi, [esi].DataDirectory    mov ExpTabDir, esi        assume esi : ptr IMAGE_DATA_DIRECTORY    ; locate export table va    mov esi, [esi].VirtualAddress    add esi, lpBase    assume esi : ptr IMAGE_EXPORT_DIRECTORY    ; Get Export Data    mov eax, [esi].nBase    mov nBase, eax    mov eax, [esi].NumberOfFunctions    mov NumberOfFunctions, eax    mov eax, [esi].NumberOfNames    mov NumberOfNames, eax    ; Get AddressOfFunctions RVA    mov eax, [esi].AddressOfFunctions    add eax, lpBase    mov AddressOfFunctions, eax    ; Get AddressOfNames RVA    mov eax, [esi].AddressOfNames    add eax, lpBase    mov AddressOfNames, eax    ; Get AddressOfNameOrdinals RVA    mov eax, [esi].AddressOfNameOrdinals    add eax, lpBase    mov AddressOfNameOrdinals, eax    mov edx, NumberOfNames    mov esi, lpProcName        assume esi : nothing    .if esi & 0ffff0000h        ; is FunName Export        mov ecx, 0ffffffffh        mov edi, lpProcName        xor eax, eax        repnz scasb        not ecx        dec ecx        mov ebx, ecx                mov edx, 0        .while edx <= NumberOfNames            mov ecx, ebx            mov esi, [AddressOfNames]            mov esi, [esi]            add esi, lpBase                        ; 比较字符串            mov edi, lpProcName            repz cmpsb            jz @F            add AddressOfNames, 4            inc edx        .endw@@:        nop        nop            mov eax, 2        mul edx        add eax, [AddressOfNameOrdinals]        movzx eax, word ptr [eax]            mov edi, 4        mul edi        add eax, [AddressOfFunctions]        mov eax, [eax]        add eax, lpBase        ; is trans function        mov esi, ExpTabDir        assume esi : ptr IMAGE_DATA_DIRECTORY        mov ebx, [esi].VirtualAddress        add ebx, lpBase                mov ecx, [esi].isize        add ecx, ebx        .if eax < ebx || eax > ecx            ; not trans function            ret        .endif        push eax        mov ecx, 0ffffffffh        mov edi, eax        xor eax, eax        repnz scasb        not ecx        dec ecx        mov ebx, ecx        pop eax                mov esi, eax        lea edi, szDll        mov bl, byte ptr [esi]        mov byte ptr [edi], bl        _FINDDOT:        add esi, 1        add edi, 1        dec ecx        mov bl, byte ptr [esi]        mov byte ptr [edi], bl        cmp byte ptr [esi], '.'        jnz _FINDDOT        cmp ecx, 0        jz _EXIT        mov byte ptr [edi], 0        inc esi        lea edi, szDll        invoke LoadLibrary, edi                push esi        push eax        call MyGetProcAddress                        ret    .else        ; is Ordinal Export        mov eax, nBase        add eax, NumberOfFunctions        sub eax, 1        .if (esi < nBase) || (esi > eax)            xor eax, eax            ret        .endif        mov eax, esi        sub eax, nBase        mov edi, 4        mul edi                add eax, AddressOfFunctions        mov eax, [eax]        add eax, lpBase                ret    .endif    ret_EXIT:    mov eax, 0    retMyGetProcAddress endp    end start


原创粉丝点击