2017-02-16 2 views
1

Я работаю над университетским проектом, поэтому я пытаюсь закодировать PE-реферат в MASM32. Одной из необходимых функций является не прямое вызов необходимых функций, а динамический поиск их адреса: Я ищу файл kernel32 lib в своей памяти, с его таблицей экспорта. Я нахожу функцию 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 

Если я помещаю этот образец до или после того, как оба вызова работает, что является полным нонсенсом для меня.

Есть ли у вас какие-либо выводы? Спасибо

ответ

1

Проблема решена: Функция GetModuleHandle работает только в том случае, если lib уже загружен в память и дает ее дескриптор.

Вместо этого я использую LoadLibraryA (LoadLibrary не найден, я не знаю, почему ...), и он отлично работает. Спасибо в любом случае: p

+0

Спасибо, что ответили на свой вопрос. – fuz