📄 _getkernelapi.inc
字号:
;###########################################################################
;# 查找kernel32.dll中名为 _szApiName 的API函数地址 #
;###########################################################################
;# 查找过程示意图 #
;###########################################################################
;# ┌─────────┬─────────┬─────────┐ #
;# │ ... │ ... │ ... │ #
;# │ 00000928 │ 003A │A: 00004378 │ #
;# │ 00000924 │ 0039 │9: 00004374 │ #
;# │ 00000920 │ 0038 │8: 00004370 │ #
;# │ 0000091B │ 0037 │7: 0000436B │ #
;# │ 00000918 │ 0036 │6: 00004368 │ #
;# │F=>00000914 :API │ F=> 0035 :[7] │5: 00004364 │ #
;# │ 00000910 │ 0034 │4: 00004360 │ #
;# │ 0000090B │ 0033 │3: 0000435B │ #
;# │ 00000908 │ 0032 │2: 00004358 │ #
;# │ 00000904 │ 0031 │1: 00004354 │ #
;# │S=>00000900 │ S=>0000 │0:S=> 00004350 │ #
;# │ (每个四字节) │ (每个二字节) │ (每个四字节) │ #
;# ├─────────┼─────────┼─────────┤ #
;# │ AddressOfNames │Add..OfN..Ordinals│AddressOfFunctions│ #
;# └─────────┴─────────┴─────────┘ #
;# 内存中的查找过程: #
;# ① 获得AddressOfNames内存地址,由于AddressOfNames是指向导出函数 #
;# 名指针数组指针, 而指针数组每个成员为四字节,查找时就是查寻此 #
;# 指针数组,找到后将其内容减去指针数组的首元素,这其间会有一段偏移 #
;# ② 由于AddressOfNames指向的指针数据每个数据4字节,而 #
;# AddressOfNameOrdinals 指向的每个数据为2字节,再加上两者间一一对应#
;# 所以在 ① 中查出的偏移,是AddressOfNameOrdinals 的两倍,要得到 #
;# 其在内存中的位置,只需要加上 AddressOfNameOrdinals 指向的内容 #
;# 加上 文件在内存中的起始位置,再取其内容,就 找到API的函数入口序号 #
;# ③ 在二中查找到的序号,就是我们要查找的API函数在,AddressOfFunctions #
;# 中的位置,即第几个元素就是了.由于AddressOfFunctions 每个元素为 #
;# 四字节,所以 找到的序号 乘以 四 再加上 AddressOfFunctions 就是 #
;# 要查找的地址了. #
;# 示例: #
;# 如上表中,假设AddressOfName指向 00000900 处, 而要查找名为 API的函数 #
;# 的入口地址. 步骤: 首先从 AddressOfName 指向的位置开始依次找到其指向的 #
;# 内容为 API 为至,这儿为 00000914 , 按上面的查找过程 , 用找到的减去 #
;# AddressOfNames(即00000900), 为14 然后再除2,就算出了要查找函数的 #
;# AddressOfNamesOrdinals的偏移,加上AddressOfNamesOrdinals 就是指向序号的 #
;# 的单元了,然后再乘以4 就是AddressOfFunctions 偏移,加上AddressOfFunctions#
;# 查找就完成了,得到的就是API的入口地址了. #
;###########################################################################
_GetKernelApi PROC _szApiName
LOCAL @dwRet , @dwLen , @lpExportTable , @hKernel32
PUSHAD
MOV @hKernel32 , ESI
;########################################
;# 添加SEH结构化异常处理,防止出错提示 #
;########################################
ASSUME FS : NOTHING
PUSH EBP
LEA EAX , [EBX + @End]
PUSH EAX
LEA EAX , [EBX + _SEHHandler]
PUSH EAX
XOR ECX , ECX
PUSH FS : [ECX]
MOV FS : [ECX] , ESP
;########################################
;# 计算API函数名称的长度 #
;########################################
MOV EDI , _szApiName
XOR AL , AL
DEC ECX
REPNE SCASB
SUB EDI , _szApiName
MOV @dwLen , EDI
;########################################
;# 定位IMAGE_EXPORT_DIRECTORY #
;########################################
MOV ESI , @hKernel32
ADD ESI , DWORD PTR [ESI + IMAGE_DOS_HEADER.e_lfanew]
ASSUME ESI : PTR IMAGE_NT_HEADERS
MOV ESI , [ESI].OptionalHeader.DataDirectory.VirtualAddress
ADD ESI , @hKernel32
ASSUME ESI : PTR IMAGE_EXPORT_DIRECTORY
MOV @lpExportTable , ESI
;########################################
;# 以名称来查找API序号 #
;########################################
MOV EBX , [ESI].AddressOfNames
ADD EBX , @hKernel32
MOV DX , WORD PTR [ESI].NumberOfNames
@Find:
MOV ESI , _szApiName
MOV EDI , [EBX]
ADD EDI , @hKernel32
MOV ECX , @dwLen
REPE CMPSB
JZ @Found
ADD EBX , SIZEOF DWORD
DEC DX
JNE @Find
;########################################
;# 没有找到API,返回程序 #
;########################################
JMP @End
;########################################
;# 从 API名称 -> API序号 -> API地址 #
;########################################
@Found:
MOV ESI , @lpExportTable
SUB EBX , @hKernel32
SUB EBX , [ESI].AddressOfNames
SHR EBX , 1
ADD EBX , [ESI].AddressOfNameOrdinals
ADD EBX , @hKernel32
MOVZX EAX , WORD PTR [EBX]
SHL EAX , 2
ADD EAX , [ESI].AddressOfFunctions
ADD EAX , @hKernel32
MOV EAX , [EAX]
ADD EAX , @hKernel32
MOV @dwRet , EAX
ASSUME ESI : NOTHING
;########################################
;# 恢复原SEH处理 #
;########################################
@End:
XOR ECX , ECX
POP FS : [ECX]
ADD ESP , 0CH
POPAD
MOV EAX , @dwRet
ret
_GetKernelApi ENDP
;###########################################################################
;# 查找API函数结束 #
;###########################################################################
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -