使用retn指令调用API

PS:我也是菜鸟,有什么不对的地方欢迎大牛拍砖。
使用Retn指令调用API的好处就是:在OD中对你用Retn调用的API下断点时,不会显示API调用地址。
这篇文章我就拿HelloWorld举例。

下面是普通调用API的方式

#include <windows.h>  
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//隐藏控制台窗口  
int main(void)  
{  
	MessageBoxA(NULL,/* 窗口句柄 */  
		"Hello World",/* 弹出的信息 */  
		"yeeeee",/* 标题 */  
		MB_OK/* 按钮 */  
		);/* 弹出信息框 */  
	return 0;  
}  


运行后的结果是这样的:

在OD中打开,对MessageBoxA下断点


显示了调用地址对吧,如果对字符串进行加密,但是显示了来自地址,就会非常容易被破解吧。
注意:程序需要将返回地址找对而且要平衡好堆栈哦。
代码写的不是很好,可能会有多余的指令。。。


运行结果

#include <windows.h>
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//隐藏控制台窗口  
int MyRetn()
{
	return 0;//返回到原来的地址
}
int main(void)
{
	LPCSTR szText="Hello World";
	LPCSTR szTitle="yeeeee";
	__asm
	{
		/* 这里需要用OD调试,才能知道参数占用了多少个字节 */
		sub esp,12
		///
		lea eax,szText//内容
		lea ebx,szTitle//标题
		push 0//按钮
		push szTitle//标题
		push szText//内容
		push 0//窗口句柄
		lea edx,MyExit
		push edx
		/* 这一步不是必须的 */
		xor eax,eax
		xor ebx,ebx
		xor ecx,ecx
		xor edx,edx
		xor edi,edi
		xor esi,esi
		/*//*/
		push MessageBoxA
		retn//MessageBoxA
	}
MyExit:
		__asm add esp,12//将sub指令减去的esp寄存器的值加回来。
		MyRetn();
	return 0;//程序在这里退出
}

用OD中打开,对MessageBoxA下断点



PS:这个要用弹出信息框的话,最好写成一个不需要参数的函数,然后逻辑判断之后在调用它。

比如:

#include <stdio.h>
#include <string.h>
#include <windows.h>
LPCSTR szText="HelloWorld";
LPCSTR szTitle="    ";
void Exit()
{
	return;
}
int MyRetn()
{
	MessageBoxA(NULL,"这只是一个例子","请无视我",MB_OK);
	return 0;//返回到原来的地址
}
int Msg()
{
	__asm
	{
		sub esp,12
		///
		lea eax,szText//内容
		lea ebx,szTitle//标题
		push 0//按钮
		push szTitle//标题
		push szText//内容
		push 0//窗口句柄
		lea edx,MyExit
		push edx
		/* 这一步不是必须的 */
		xor eax,eax
		xor ebx,ebx
		xor ecx,ecx
		xor edx,edx
		xor edi,edi
		xor esi,esi
		/*//*/
		push MessageBoxA
		retn//MessageBoxA
	}
MyExit:
		__asm add esp,12//将sub指令减去的esp寄存器的值加回来
		MyRetn();
		return 0;
}
int main(void)
{
	int a;
	DWORD Address=&Msg;//获取Msg函数的地址
	DWORD MExit=&Exit;
	scanf("%d",&a);
	if(a==2308)
	{
		__asm 
		{
			push [ebp+4]//main函数返回地址
			jmp Address
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值