内容
根据函数名字和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
欢迎指正