汇编动态调用导致分段错误

Assembly dynamic call causes segmentation fault

我正在做一个大学项目,所以我想在 MASM32 中编写一个 PE 感染器。 需要的功能之一是不直接调用需要的函数,而是动态查找它们的地址: 我在内存中搜索 kernel32 库,它的导出 table 我找到了 GetProcAddressName 函数,然后是 GetModuleHandle 函数,然后我加载了 user32 句柄,我将其与 GetProcAdsress 一起使用以获取对函数的访问权限;我的示例中的 MessageBoxA:

.386
.model flat, stdcall
option casemap:none

      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\masm32rt.inc

      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib

.code

start:
        mov ebx, dword ptr[esp]
        and ebx, 0ffff0000h
        .while word ptr[ebx] != 'ZM'
            dec ebx
        .endw
        mov kernelAddr, ebx

        mov eax, ebx
        add eax, 3Ch
        mov eax, dword ptr[eax]
        add eax, ebx
 pekernelFound:
        mov peKernelAddr, eax

        mov edx, kernelAddr
        mov ebx, eax
        add ebx, 78h
        mov ebx,  dword ptr[ebx]
        add ebx, edx

        mov ecx, ebx
        add ecx, 1ch
        mov ecx, dword ptr[ecx]
        add ecx, edx
        mov functionTableAddr, ecx

        mov ecx, ebx
        add ecx, 20h
        mov ecx, dword ptr[ecx]
        add ecx, edx
        mov functionNameTableAddr, ecx

        mov ecx, ebx
        add ecx, 24h
        mov ecx, dword ptr[ecx]
        add ecx, edx
        mov ordinalTableAddr, ecx

searchProcAddressFunc:     
        mov ebx, functionNameTableAddr
        mov esi, dword ptr[ebx]
        add esi, kernelAddr
        mov edi, offset GetProcAddressName
        mov edx, 1
        mov ecx, 0 ; l'index
        .while edx != 0
            mov al, byte ptr [esi]
            mov bl, byte ptr [edi]
            .if al != bl
                .while byte ptr [esi] != 0
                    inc esi
                .endw
                inc esi
                inc ecx 
                mov edi, offset GetProcAddressName
             .else
                .if byte ptr [esi] == 0
                    mov edx, 0 
                .else
                    inc esi
                    inc edi
                .endif
            .endif
        .endw

        mov eax, 2
        mul ecx
        mov ecx, eax
        add ecx, ordinalTableAddr
        xor eax, eax
        mov ax, word ptr [ecx]
        mov ecx, 4
        mul ecx
        add eax, functionTableAddr
        mov eax, dword ptr [eax]
        add eax, kernelAddr
        mov GetProcAddressAddr, eax

gettingGetModuleHandle:
        push offset GetModuleHandleName
        push kernelAddr
        call GetProcAddressAddr
        mov GetModuleHandleAddr, eax
        push offset User32DllName
        call GetModuleHandleAddr

gettingMessageBox:        
        mov user32Addr, eax
        push offset MessageBoxName
        push eax
        call GetProcAddressAddr
        mov MessageBoxAddr, eax

        push MB_OK
        push offset hello
        push offset hello
        push 0
        call  MessageBoxAddr

        push    0
    call    ExitProcess

        hello                       db      "Hello buddy", 0


        kernelAddr                  dd      ?
        user32Addr                  dd      ?
        peKernelAddr                dd      ?
        functionTableAddr           dd      ?
        functionNameTableAddr       dd      ?
        ordinalTableAddr            dd      ?

        GetProcAddressName          db      "GetProcAddress",0
        GetModuleHandleName         db      "GetModuleHandleA",0
        MessageBoxName              db      "MessageBoxA", 0
        MessageBoxAddr              dd      ?

        GetProcAddressAddr          dd      ?
        GetModuleHandleAddr         dd      ?

        User32DllName               db      "User32.dll",0
end start

结果是调用 MessageBoxAddr 时出现分段错误。 如果我调用原始函数除外,无论在哪里:

    push MB_OK
    push offset hello
    push offset hello
    push 0
    call  MessageBoxA

如果我将此示例放在之前或之后,两个调用都有效,这对我来说完全是胡说八道。

你有线索吗?谢谢

问题已解决: GetModuleHandle 函数仅在 lib 已经加载到内存中时才起作用,并给出它的句柄。

我改用 LoadLibraryA(找不到 LoadLibrary,我不知道为什么...),它运行良好。还是谢谢 :p