2017-02-16 16 views
1

저는 대학 프로젝트에서 작업 중이므로 MASM32에 PE 감염자를 코딩하려고합니다. 필요한 기능 중 하나는 직접 필요한 함수를 호출하는 것이 아니라 주소를 동적으로 찾는 것입니다. 메모리에서 kernel32 라이브러리를 검색하고 해당 내보내기 테이블에서 GetProcAddressName 함수를 찾은 다음 GetModuleHandle 함수를 찾고 다음으로이 함수를로드합니다. 함수에 접근하기 위해 GetProcAdsress와 함께 사용하는 user32 핸들; 내 예제의 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를 찾을 수 없으며 이유를 모르겠습니다 ...). 완벽하게 작동합니다. 어쨌든 고마워 :

+0

질문에 답변 해 주셔서 감사합니다. – fuz