鱼C论坛

 找回密码
 立即注册

动态获取函数地址

已有 1188 次阅读2015-3-22 16:35 |个人分类:汇编

.586p
.model flat,stdcall
option casemap:none;
include    include\windows.inc
include    include\kernel32.inc
includelib lib\kernel32.lib
include    include\user32.inc
includelib lib\user32.lib

GetApiAddress PROTO:DWORD,:DWORD

.data
    Kernel32Addr dd ?
         ExportKernel dd ?
    GetProcAddr dd ?
         LoadLibraryAddr dd ?
    aGetProcAddr db "GetProcAddress", 0 
         GetProcAddLen equ  $-aGetProcAddr-1
    aLoadLibrary db "LoadLibraryA" , 0
         LoadLibraryLen equ $-aLoadLibrary-1
    szTitle db "检测结果", 0
    temp1 db "Kernel32.dll 基本地址:%8x" , 0dh , 0ah
    db       "LoadLibrary 地址:     %8x" ,0dh, 0ah
    db       "GetProcAddress 地址:  %8x" , 0dh , 0ah , 0
    temp2 db 0 dup(100)     
.code
main:
Start:
       mov  esi,[esp] ;获取得堆栈指针中ExitThread地址
       and  esi,0fffff000h ;因为kernel32.dll是以00001000为对齐大小
LoopFindKernel32:
       sub  esi,1000h
       cmp  word ptr[esi], 'ZM' ;判断这个地址的前两个字节是否是"MZ"
       jnz  short LoopFindKernel32
GetPeHeader:
       mov edi,dword ptr[esi+3ch]
       add edi, esi
       cmp word ptr[edi], 4550h ;定位到PE头
       jnz short LoopFindKernel32
     mov Kernel32Addr,esi
     invoke GetApiAddress,Kernel32Addr,addr aLoadLibrary ;获取LoadLibrary的地址
     mov LoadLibraryAddr,eax
     invoke GetApiAddress , Kernel32Addr, addr aGetProcAddr ;获得GetProcAddr的地址
     mov GetProcAddr , eax
         invoke wsprintf,addr temp2,addr temp1,Kernel32Addr,LoadLibraryAddr,GetProcAddr
         invoke MessageBoxA,0,addr temp2,addr szTitle,0
         invoke ExitProcess,0

GetApiAddress proc uses ecx ebx edx esi edi hModule:DWORD ,szApiName:DWORD
   LOCAL dwReturn:DWORD
   LOCAL dwApiLength:DWORD
   mov dwReturn,0
   mov esi,szApiName
   mov edx,esi
 Continue_Searching_Null:
   cmp byte ptr[esi],0
   jz  We_Got_The_Length
   inc esi
   jmp Continue_Searching_Null
 We_Got_The_Length:
   inc esi
   sub esi,edx
   mov dwApiLength ,esi ;获取API长度

   mov esi,hModule
   add esi,[esi+3ch]
   assume esi:ptr IMAGE_NT_HEADERS ;定位到PE头
   mov esi,[esi].OptionalHeader.DataDirectory.VirtualAddress ;定位到数据目录表的相对虚拟地址
   add esi,hModule
   assume esi:ptr IMAGE_EXPORT_DIRECTORY

   mov ebx,[esi].AddressOfNames ;导出表中函数名字的地址指针
   add ebx,hModule
   xor edx,edx
   .repeat
      push esi
      mov edi,[ebx]
      add edi,hModule
      mov esi,szApiName
      mov ecx,dwApiLength
      cld
      repz cmpsb ;让ds:si和es:di所指向的两个字节相等,则继续比较,如果不等,则停止循环
      .if ZERO? ;如果没有找到匹配的函数就继续循环
          pop esi
          jmp _Find_Index
      .endif
      pop esi
      add ebx,4
      inc edx
      .until edx >= [esi].NumberOfNames ;直到查找完所有的被掉用过的函数
      jmp _Exit
      
      _Find_Index: ;通过序号找到函数地址
         sub ebx,[esi].AddressOfNames
         sub ebx,hModule ;指向kernel32.dll名字
         shr ebx,1
         add ebx, [esi].AddressOfNameOrdinals
         
         add ebx,hModule ;指向输出序号数组
         movzx eax,word ptr [ebx]
         shl eax,2
         add eax,[esi].AddressOfFunctions
         add eax,hModule ;指向函数地址
         
         mov eax,[eax]
         add eax,hModule ;得到函数地址
         mov dwReturn,eax
        _Exit:
         mov eax,dwReturn
         ret
       GetApiAddress    endp
       end main
   


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 06:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

返回顶部