Win32汇编实现API自搜索技术(软件安全实验二)

原理介绍

API自搜索技术原理

第一页
在这里插入图片描述
在这里插入图片描述

masm32

链接: masm32下载链接
说明:解压至本地配置环境变量即好,另附本次实验源码一份,masm32主目录下
在这里插入图片描述
环境变量配置如下图所示:
在这里插入图片描述

编译指令:ml -c -coff 文件名(.asm文件);
链接指令:link /subsystem:console 文件名(.obj文件);

展示部分

汇编源码展示

		.686
		.model flat,stdcall
		option casemap:none
		includelib lib\kernel32.lib		;包含API函数的导入库文件
ExitProcess	proto,:dword			;Windows函数声明
exit		macro dwexitcode
		invoke ExitProcess,dwexitcode
		endm
GetStdHandle	proto,:dword
WriteConsoleA	proto,:dword,:dword,:dword,:dword,:dword
WriteConsole	equ<WriteConsoleA>
ReadConsoleA	proto,:dword,:dword,:dword,:dword,:dword
ReadConsole	equ<ReadConsoleA>
STD_OUTPUT_HANDLE=-11				;Windows常量定义
STD_INPUT_HANDLE=-10				;Windows常量定义
GetConsoleMode	proto,:dword,:dword
SetConsoleMode	proto,:dword,:dword

		.data
arg		dword 0
msg1		byte 'kernel32.dll virtual address=0x',0
msg		byte 10,0		;字符串,10为换行
fname1		byte 'GetProcAddress',0
fname2		byte 'LoadLibraryA',0
attention		byte '######################Successfully find functions!########################',10,0
outsize		dword ?
inhandle		dword ?
savemode		dword ?
insize		dword ?
inbuffer		byte 255 dup(0)
		.code
start:		
		;Get kernel32.dll base addr
		assume fs:nothing
		mov eax,fs:[30h]			;PEB
		mov eax,[eax+0ch]			;PROCESS_MODULE_INFO
		mov esi,[eax+1ch]			;InInitOrder.flink
		lodsd				;eax=InInitOrder.blink
		mov ebp,[eax+8]			;ebp=kernel32.dll base address
		mov eax,offset msg1
		call dispmsg
		mov eax,ebp
		call dispx

		push esi
		mov esi,[ebp+03Ch]			;[esi]->PE头地址

		mov esi,[esi+ebp+078h]		
		add esi,ebp			;[esi]->导出表
		push esi				;压栈保存

		mov esi,[esi+020h]			
		add esi,ebp			;[esi]->存储导出函数函数名列表的首地址
		pop edi
		mov edi,[edi+01Ch]
		add edi,ebp			;[edi]->存储导出函数地址列表的首地址

		push eax
		mov eax,offset attention
		call dispmsg
		mov ecx,1000
forloop:
		lodsd				;mov eax,[esi], esi=esi+4
		add eax,ebp			;[eax]->导出函数函数名列表一个导出函数的名称
		mov ebx,[edi]
		add edi,4
		add ebx,ebp			;[ebx]->导出函数地址列表一个导出函数的地址


		;依次对比函数名称,找fname1和fname2
		push ebx				;ebx压栈保存
		mov  ebx,eax			;传入第一个字符串首地址
		mov edx,offset fname1		;传入第二个字符串首地址
		call cmpname			;两字符串相等,则edx=1
		test edx,1	
		jnz print				;打印输出函数名和函数地址
		pop ebx
			

		push ebx				;ebx压栈保存
		mov  ebx,eax			;传入第一个字符串首地址
		mov edx,offset fname2		;传入第二个字符串首地址
		call cmpname			;两字符串相等,则edx=1
		test edx,1	
		jnz print				;打印输出函数名和函数地址
		pop ebx
		loop forloop

		;获取句柄
		invoke GetStdHandle,STD_OUTPUT_HANDLE
		;显示信息,提示按任意键退出
		invoke WriteConsole,eax,addr msg,sizeof msg,addr outsize,0
		invoke GetStdHandle,STD_INPUT_HANDLE
		mov inhandle,eax
		invoke GetConsoleMode,inhandle,addr savemode	;获得控制台模式
		invoke SetConsoleMode,inhandle,0		;设置为单字符输入模式
		invoke ReadConsole,inhandle,addr inbuffer,1,addr insize,0	;输入字符
		invoke SetConsoleMode,inhandle,savemode	;恢复原控制台模式
		;退出
		exit 0
		invoke ExitProcess,0
		

		.data					;子程序DISPMSG使用的变量
_outsize		dword ?
_outhandle	dword ?
		.code
dispmsg		proc					;字符串显示子程序,入口参数:EAX=
		push eax
		push ebx
		push ecx
		push edx
		push eax
		invoke GetStdHandle,STD_OUTPUT_HANDLE
		mov _outhandle,eax				;句柄实例保存,以便后续调用
		pop ebx					;弹出字符串地址送入EBX
		xor ecx,ecx
		;计算字符串长度
dispm1:		mov al,[ebx+ecx]
		test al,al					;[al] and [al],不改变寄存器内容,同时修改ZF标志位
		jz dispm2
		inc ecx
		jmp dispm1
dispm2:		invoke WriteConsole,_outhandle,ebx,ecx,addr _outsize,0
		pop edx
		pop ecx
		pop ebx
		pop eax
		ret
dispmsg		endp


		.data					;子程序DISPX使用的变量
regd		byte 8 dup(0),10,0			;显示EAX中的16进制数,预留8个字节空间		
		.code
dispx		proc					;16进制数显示子程序,入口参数:EAX=
		push ebx
		push ecx
		push edx
		mov ecx,8
		xor ebx,ebx				;使用ebx相对寻址访问regd,故初始化ebx=0
again:		rol eax,4					;高4位循环移位进入低4位,作为子程序htoasc的入口参数
		push eax					;子程序htoasc使用al返回结果,所以需要压栈保存eax		
		call htoasc				;调用子程序htoasc
		mov regd+[ebx],al				;保存转换后的ASCII码
		pop eax					;恢复保存的数据
		inc ebx
		loop again
		mov eax,offset regd
		call dispmsg				;显示
		pop edx
		pop ecx
		pop ebx
		ret
dispx		endp

		.data					;子程序htoasc使用的数据
ASCII		byte '0123456789ABCDEF'
		.code
htoasc		proc					;将al的低4位表达的一位16进制数转换为ASCII码 
		and eax,0fh				;取al低四位		
		mov al,ASCII+[eax]				;换码
		ret
htoasc		endp


		.code
cmpname		proc					;比对字符串是否一致,ebx、edx接受两字符串首地址,返回edx
		push eax
		push ecx
		xor ecx,ecx
Loopx:		mov al,[ebx+ecx]
		mov ah,[edx+ecx]
		cmp al,ah					;比较相应两字符
		jnz different					;不等则跳转结束
		inc ecx					;偏移地址+1
		cmp al,0					;比对结束
		jz done
		jmp Loopx

done:		cmp ah,0					;判断另一字符串是否结束
		jz same					;两字符串相同
		jnz different				;两字符串不同
same:		pop ecx
		pop eax
		mov edx,1
		ret
different:		pop ecx
		pop eax
		mov edx,0
		ret
cmpname		endp

		.data
fun_name		byte 'Function name:',0
fun_addr		byte 'Function address',0
space		byte '		',0
new_line		byte 10,0
		.code
print		proc					;参数变量为eax、ebx
		push ebx
		push eax
		push eax
		mov eax,offset fun_name
		call dispmsg
		pop eax
		mov eax,eax
		call dispmsg
		mov eax,offset space
		call dispmsg
		mov eax,offset fun_addr
		call dispmsg
		mov eax,ebx
		call dispx

		pop eax
		pop ebx
		jmp forloop
		ret
print		endp

		end start

运行结果展示

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210103001014465.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0ODA2MzA1,size_16,color_FFFFF在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那由塔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值