软件安全实验 查找kernel32.dll的首地址并显示

内容

利用win32汇编弹窗显示kernel32.dll的首地址和GetKernelBase函数的地址
在win7下编译通过,需要masm安装目录为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	"xxxxxxx",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 0,0

sGetProcAddress db "GetProcAddress",0
sLoadLibrary 	db "LoadLibrary",0

aGetProcAddress dd 0
aLoadLibrary 	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
	

欢迎指正

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值