VC中程序自修改实现

本文介绍了在VC中利用SMC(Self-Modifying Code)技术修改代码段中的函数内容,通过预编译指令使代码段具备可读写属性。在运行时,程序将RepalceMentProc的机器码替换CalledProc,从而改变函数行为。通过示例展示了如何在程序执行过程中动态修改自身代码,以实现解密和加密目的。
摘要由CSDN通过智能技术生成

地址:http://hi.baidu.com/combojiang/blog/item/b58750137ac144d6f6039e3c%2Ehtml
说明:如果需要正常演示出程序中的结果,请使用原作者要求的IDE和编译版。本文只演示了程序自修改的实现过程,由于不同的编译器生成PE文件的偏移不一样,请原作者的要求来演示。
当然这篇文章与实际应用还是有很大的距离的,RepalceMentProc的长度不能比CalledProc(); 长的太多,虽然在中间补了EndCalledProc,但也不能太长。可不可把修改的代码放到堆上,然后将CalledProc的地址改过去。有时间测试一下,嘻嘻。by lonkil
===========================================================
理论:
所谓SMC(Self Modifying Code)技术,就是一种将可执行文件中的代码或数据进行加密,防止别人使用逆向工程工具对程序进行静态分析的方法,只有程序运行时才对代码和数据进行解密,从而正常运行程序和访问数据。本篇通过一个简单的实例来介绍这个技术。需要的运行环境vc6,程序编译为release版 。由于本篇我们要在程序执行过程中,修改代码段中的一个函数内容,而默认情况下,我们编译生成的程序代码段是可读可执行属性。所以我们需要使用一个预编译指令。
#pragma comment(linker, “/SECTION:.text,ERW”)
是告诉链接程序最终在生成代码时修改这个名为”.text” 的代码段,段属性为”ERW”,分别表示可执行、可读和可写。当然你也可以不使用预编译指令#pragma comment,直接在编译选项中添加”/SECTION:.text,ERW”选项也可以达到相同的目的。


include "windows.h"
#pragma comment(linker, "/SECTION:.text,ERW")
int lnth1;
char szDlgTitle[] = "SMC example";
char Phony[] = "This is lst call of proc";
char Replc[] = "This is 2nd call of proc";
char ttl1[] = "Original Code";
char ttl2[] = "ReplaceMent Code";
void CalledProc();
void EndCalledProc();
void RepalceMentProc();
void EndRepalceMentProc();
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
CalledProc();
int lnth1 = (char *)EndRepalceMentProc - (char *)RepalceMentProc;
memcpy((char *)CalledProc,(char *)RepalceMentProc,lnth1);

CalledProc();
return 0;
}

void CalledProc()
{
MessageBox(0,Phony,ttl1,MB_OK);

}
void EndCalledProc()
{
}

void RepalceMentProc()
{
MessageBox(0,Replc,ttl2,MB_OK|MB_ICONEXCLAMATION);
}

void EndRepalceMentProc()
{

 

 

分析:
本例中,我们先执行了CalledProc函数,显示出一个MESSAGEBOX. 然后,我们用RepalceMentProc函数的内容,在运行过程中修改CalledProc函数,在C语言中,函数名代表函数的首地址,为了计算函数体的长度,我们在函数后面定义了一个空函数,通过下面这样的公式,来大致的计算函数体的长度。主要原因是函数之间还有空隙。
int lnth1 = (char *)EndRepalceMentProc – (char *)RepalceMentProc;
由于代码段属性是可写的,因此,我们在这里通过下面的代码
memcpy((char *)CalledProc,(char *)RepalceMentProc,lnth1);
使用RepalceMentProc函数体中的机器码替换了CalledProc函数中原有的机器码。
这样再次调用CalledProc的时候,实际就执行的是RepalceMentProc函数的代码了。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhengtingt108/archive/2009/09/15/4555332.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值