看流星社区

 找回密码
 注册账号
查看: 2821|回复: 0

学习笔记之将EXE程序的参数保存在EXE文件本身

[复制链接]

该用户从未签到

发表于 2012-10-17 20:56:32 | 显示全部楼层 |阅读模式
1.先假设一种情况:EXE文件A运行时需要EXE文件B的路径作为参数.
在EXE文件A用了一个字串char PathB[256]存贮有文件B的路径.然而因为某种原因EXE文件B的位置并不是固定在某一特定目录下.这时就需要改变EXE文件A中的字串PathB的值

实现原理及方法:
我们可以用文件操作fread()或fwrite()等函数读取或修改EXE文件A中的PathB的值,读取和修改很好实现.关键问题如何找到字串PathB在EXE文件A中的位置?方法是在串PathB前面放置一个特征串.
我们可以在EXE文件A中创建一个全局串PathStr[]在该串的前50个字节(或更大范围)中放置一个'特征串'比如:"Attention! I am a characteristic character string."
最好将这个特征串范围设大一点.这样不容易出错.这样一旦EXE文件A编译连接后这个全局串PathStr[]在EXE文件中就会有一个固定的位置.在打开文件进行查找的时候首先找到特征串.只要这个特征串范围足够大.一般都不会出错.只要找到这个特征串后.紧接在它后面的256个字节(如果参数很复杂.此处范围还可以扩大)就是我们要找的参数(这里即是EXE文件B的路径).只要找到了这个位置后.就可以把新的参数(即文件B的新路径写到这里.)这样就完成了文件A中参数的修改.当EXE文件A再次运行时.它就会根据新的参数来运行程序.

2.要更改文件A中的内容.前提条件是EXE文件A不处于运行状态.
所以到文件A中去修改参数的任务可以交由另外的进程来完成.当然也可以由EXE文件A自身的进程来完成.
由另外一个进程来完成这种方式很容易实现.然而要将这项任务交由EXE文件A自身来完成也并非不可能.
这就需要EXE文件A具备自杀功能.(关于自杀程序以后慢慢讲解)当程序A需要修改自身参数的时候就将自已拷贝到一临时目录.再调用CreateProcess函数创建一个新的进程.暂时叫做进程M(当然新进程M的启动是有条件的.先前的进程A需用参数来告诉新进程M该干什么事情.)当新进程M运行以后等待先前的进程A退出.这时进程M就可以对原EXE文件A进行修改了.当新进程修改保存完毕后.再由新进程M调用 CreateProcess函数恢复原EXE文件进程A.这时进程A就会用新参数.而进程M就可以退出了.进程M的临时文件也就没有用处.可以删除了.(其实这并非是真正的自杀程序)

这里简要说一下自杀程序.自杀程序仍然原进程运行后拷贝自已到临时目录.用CreateFile函数将此文件加上FILE_FLAG_DELETE_ON_CLOSE标志.(该标志指明此文件是临时文件.当此文件创建的进程结束后系统将会删除该文件.注:是系统帮我们进行的删除操作.严格的讲也并非是真正的自杀)然原进程再调用CreateProcess函数创建一个新线程.新进程启动后等原进程结束后.将原进程的文件删除.然后再结束自已.因为该新进程的文件被设置了FILE_FLAG_DELETE_ON_CLOSE标志.当该进程结束后操作系统就会将该文件从系统中删除.这样就达到了自杀的目的.看起来也像是程序自己删除了自己.

3.再说说第一种方法.用另外的进程来修改文件A中的内容.此种方法非常的简单.
下面附上我的原码:
首先是进程A(此处进程A的功能就是读取自己的参数显示出来)
//=======================进程A===========================
//定义特征串的长度.
#define csize 50  //strlen("Attention! I am a characteristic character string.");
#define bsize 256  //参数所占字节数
//定义全局字串并初始化.注意居特征串后面的就是具体的参数(文件B的路径)
char PathStr[csize+bsize]="Attention! I am a characteristic character string.c:\\windows\\b.exe";


...
for(int i=0;i<=256;i++)
{
    char PathB[256];
    PathB[i]=PathStr[i+csize];
}
MessageBox(0,PathB,"文件B的路径",MB_OK);
...

然后是进程C(进程C负责用新的参数值去修改进程A中原来的参数值)
//=======================进程C============================
#define csize 50
#define bsize 256
//定义并初始化特征字串.在后将根据它在文件A中进行查找
char Tstr[csize+1]="Attention! I am a characteristic character string.";
...
//获取参数在文件中的开始位置
    char *NewPathB="mer.\sdfw/sdsd.exe"; //这是文件B的新路径.程序将把它写到文件A中去
    FILE*fp=NULL;
    DWORD start=0;//保存参数在文件中的开始位置
    if (fp=fopen("a.exe","rb+"))//打开文件A可读可写
    {
        char ch;
        int i=0;
        while(fread(&ch,1,1,fp)==1)//一个字节一个字节读取方法有点笨拙
        {   
            char TTstr[csize];
            if(ch==Tstr[i])
            {               
                TTstr[i]=ch;
                i++;
                if(i>=csize)//判断特征串是否比较完
                {
                    //
                    //下面是修改程序
                    i=0;
                    TTstr[csize]=0;
                    //cout<<TTstr<<endl;
                    start=ftell(fp);//获取参数在文件中的开始位置.
                    break;
                }
            }
            else
            {
                i=0;//不相等.将i设为0.将从特征串的开始位置从表毕较
            }
        }
        fclose(fp);
    }
...
//把新的参数写入文件A中
    if (fp=fopen("a.exe","rb+"))//打开文件A可读可写
    {
        fseek(fp,start,SEEK_SET);//移动文件指针到参数的开始位置
        int i=0;
        while(fwrite(&NewPathB[i],1,1,fp)==1)
        {
            //cout<<NewPathB[i];
            i++;                       
            if(i>=(int)strlen(NewPathB) && i<bsize)//新参数写入完毕后面的空位补0
            {
                //cout<<endl;
                char ch;
                ch=0;
                while(fwrite(&ch,1,1,fp)==1)
                {
                    i++;                              
                    if(i>=bsize)//超出参数范围 bsize=256
                        break;
                }
                break;
            }
           
        }
        fclose(fp);
    }

...

可以将进程C做为进程A中的资源.当进程A需要修改参数的时候把进程C释放出来.然后像自杀程序一样用参数启动进程C来完成对进程A的修改

4.可以将此方法用到病毒技术中去.感染文件.
联系<<学习笔记之卸载远程目标进程中的DLL模块>>一文中最后一个问题.
病毒通过扫描发现某进程的DLL文件满足感染条件后.就把此DLL文件拷贝到一个特定的目录.然后把我们的病毒DLL复制到该进程目录下替换原DLL文件(修改病毒DLL文件名和原DLL文件名一致).
说明.该病毒DLL就会在该进程启动时被进程载入.该病毒DLL会根据里面存贮的参数载入正常DLL文件.并同时启动病毒代码.当病毒代码启动后.该病毒DLL会自我卸载.
这里就会有一个问题.该病毒DLL是如何载入正常DLL的.
这里的情况刚好和上面学习的内容是一样的.该病毒DLL不可能每感染一个文件都手动从新编写.它里面大部分内容是一样的.只是它载入的那个DLL文件的路径发生了变化.所以我们可以用上面的方法.在DLL里面用一个全局串来保存正常DLL文件路径.当然前面需要有一个特征串.以便于查找修改.每感染一个文件.我们只需要修改该DLL中的一个串就可以了.
附:哪些进程的DLL满足感染条件.
.首先该DLL在进程启动就会被进程载入
.该进程启动后并没有马上调用该DLL文件里面的内容.
我们就可以用病毒DLL去替换这样的满足感染条件的DLL.由于病毒DLL载入后马上载入了正常的DLL.病毒卸载了自己.进程在以后调用该DLL中的内容并不会出错.这种方式启动病毒也很隐蔽.不易被发现.
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-27 18:21

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表