软件安全实验 通过导入表查找关键函数地址并显示

内容

根据函数名字和kernel32的导出表获得更多函数的地址并弹窗显示
在win7下成功编译运行,masm32安装目录需为c:\masm32

代码

.586
.model flat,stdcall
option casemap:none

include c:\masm32\include\windows.inc 
include c:\masm32\include\comctl32.inc 
includelib c:\masm32\lib\comctl32.lib 
include c:\masm32\include\kernel32.inc 
includelib c:\masm32\lib\kernel32.lib 
include c:\masm32\include\user32.inc 
includelib c:\masm32\lib\user32.lib 

GetApiA proto:DWORD,:DWORD			;函数原型

.code
VCode:
	szMsg						db	"xxxxx",0   
    val                         db  "abcdefgh",0        ;address of functions in Ascii
;--------------------------------------------------------------------------------------------------
;code start
;--------------------------------------------------------------------------------------------------
;------proc to save eax into Ascii value 'val' for messagebox-----------
binToAscii proc near	; change al into Ascii
    push eax
	and eax,0fh
	add al,30h
	cmp al,39h
	jbe @f
	add al,7
@@:
	stosb   ;save ax into [edi]
    pop eax
	ret
binToAscii endp

saveEax proc near   ;save eax to val in Ascii mode
	push ecx
	push edi
	push eax
	
	mov ecx,8
	cld
	lea edi,val
L1:	
	rol eax,4
	call binToAscii
	loop L1
	
	pop eax
	pop edi
	pop ecx
	ret
saveEax endp
;-------------------------------------------------------------------

_Start0:
	invoke InitCommonControls
	jmp _Start

K32_api_ordinal_retrieve proc Base:DWORD,sApi:DWORD   ;****从kernel32.dll中查找函数序号****
        push    edx                    ;保存edx   
        xor    eax,eax                ;此时esi=sApi
Next_Api:                              ;edi=AddressOfNames
        mov    esi,sApi
        xor    edx,edx
        dec    edx
Match_Api_name:
        mov    bl,byte  ptr [esi]
        inc    esi
        cmp    bl,0
        jz      foundit

        inc    edx

        push    eax
        mov    eax,[edi+eax*4]        ;AddressOfNames的指针,递增
        add    eax,Base                ;注意是RVA,一定要加Base值
        cmp    bl,byte  ptr [eax+edx]  ;逐字符比较 
        pop    eax
        jz      Match_Api_name          ;继续搜寻
        inc    eax                    ;不匹配,下一个api
        loop    Next_Api
        jmp    no_exist                ;若全部搜完,即未存在
foundit:
        pop    edx                    ;edx=AddressOfNameOrdinals
        shl    eax,1                  ;*2得到AddressOfNameOrdinals的指针
        movzx  eax,word  ptr [edx+eax] ;eax返回指向AddressOfFunctions的指针
        ret
no_exist:
        pop    edx
        xor    eax,eax

	ret
K32_api_ordinal_retrieve endp

GetApiA proc Base:DWORD,sApi:DWORD   ;已知DLL Base 及API函数名,查找该DLL的多个API地址*****
	local ADDRofFun:DWORD
       pushad
        mov    edi,Base
        add    edi,IMAGE_DOS_HEADER.e_lfanew
        mov    edi,[edi]                      ;现在edi=off PE_HEADER
        add    edi,Base                        ;得到IMAGE_NT_HEADERS的偏移                       

        mov    ebx,edi
        mov    edi,[edi+IMAGE_NT_HEADERS.OptionalHeader.DataDirectory.VirtualAddress]
        add    edi,Base                        ;得到edi=IMAGE_EXPORT_DIRECTORY入口
       
        mov    eax,[edi+1ch]                  ;AddressOfFunctions的地址
        add    eax,Base
        mov    ADDRofFun,eax
                                                ;ecx=NumberOfNames
        mov    ecx,[edi+18h]                 
        mov    edx,[edi+24h]                 
        add    edx,Base                        ;edx=AddressOfNameOrdinals

        mov    edi,[edi+20h]
        add    edi,Base                        ;edi=AddressOfNames
        invoke    K32_api_ordinal_retrieve,Base,sApi
        mov    ebx,ADDRofFun
        shl    eax,2                          ;要*4才得到偏移
        add    eax,ebx
        mov    eax,[eax]
        add    eax,Base                        ;加上Base!
        mov    [esp+7*4],eax                  ;eax返回api地址
        popad

	ret
GetApiA endp

appBase dd ?
k32Base dd ?
lpApiAddrs label near  
    dd offset sGetProcAddress  
    dd offset sLoadLibrary  
    dd offset sGetModuleHandle  
    dd offset sCreateFile  
    dd offset sCreateFileMapping  
    dd offset sMapViewOfFile  
    dd offset sUnmapViewOfFile  
    dd offset sCloseHandle  
    dd offset sGetFileSize  
    dd offset sSetEndOfFile  
    dd offset sSetFilePointer  
    dd offset sExitProcess  
    dd 0,0


sGetProcAddress db "GetProcAddress",0  
sLoadLibrary db "LoadLibrary",0  
sGetModuleHandle db "GetModuleHandle",0  
sCreateFile db "CreateFile",0  
sCreateFileMapping db "CreateFileMapping",0  
sMapViewOfFile db "MapViewOfFile",0  
sUnmapViewOfFile db "UnmapViewOfFile",0  
sCloseHandle db "CloseHandle",0  
sGetFileSize db "GetFileSize",0  
sSetEndOfFile db "SetEndOfFile",0  
sSetFilePointer db "SetFilePointer",0  
sExitProcess db "ExitProcess",0


aGetProcAddress dd 0  
aLoadLibrary dd 0  
aGetModuleHandle dd 0  
aCreateFile dd 0  
aCreateFileMapping dd 0  
aMapViewOfFile dd 0  
aUnmapViewOfFile dd 0  
aCloseHandle dd 0  
aGetFileSize dd 0  
aSetEndOfFile dd 0  
aSetFilePointer dd 0  
aExitProcess dd 0  
;
_Start:
	call _delta                         ;-----重定位-------
_delta:
	pop ebp
	sub ebp,offset _delta
	mov dword ptr[ebp+appBase],ebp
   mov    ecx,[esp]                      ;返回地址
        xor    edx,edx
getK32Base:
     assume fs:nothing

   mov eax,fs:[30h] ;获取PEB所在地址
   mov eax,[eax+0ch] ;获取PEB_LDR_DATA 结构指针

   mov esi,[eax+1ch] ;获取InInitializationOrderModuleList 链表头
   lodsd             ;获取双向链表当前节点后继的指针

   mov eax,[eax+8]   ;获取kernel32.dll的基地址
	mov [ebp+k32Base],eax

       
	lea edi,[ebp+aGetProcAddress]		;-----seach Kernel32.dll for two api address
	lea esi,[ebp+lpApiAddrs]	
lop_get:
	lodsd								;get api name address offset into eax
	cmp eax,0							;is it end?
	jz End_Get
	add eax,ebp							;get api name
	push eax							;arg of GetApiA
	push dword ptr[ebp+k32Base]			;arg of GetApiA
	call GetApiA 						;Call GetApiA to retrive two functions address from Kerenel32.dll
	stosd								;return value:eax 存入edi指向地址
	call 	saveEax						;Save Eax into val
    invoke MessageBox, NULL, addr val, addr szMsg, MB_OK	;MessageBox for two api ,here just use user32.dll 
	jmp lop_get
End_Get:
_Exit:
	push 0
    invoke ExitProcess, NULL 
	end _Start0
	

欢迎指正

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值