首页
社区
课程
招聘
[求助]关于一个自删除程序的疑惑
发表于: 2007-11-25 16:28 8186

[求助]关于一个自删除程序的疑惑

2007-11-25 16:28
8186
代码如下:
#include "windows.h"

int main(int argc, char *argv[])
{
    char    buf[MAX_PATH];
    HMODULE module;
   
    module = GetModuleHandle(0);
    GetModuleFileName(module, buf, MAX_PATH);
    CloseHandle((HANDLE)4);
   
    __asm
    {
      lea     eax, buf
      push    0
      push    0
      push    eax
      push    ExitProcess     ;这函数怎么push到栈里面去了?   
      push    module
      push    DeleteFile                ;就这样就可以执行该函数吗?
      push    UnmapViewOfFile
      ret
    }
     
    return 0;
}

那段内联的汇编看的一头雾水,不知道谁能详解一下
顺便解释下    CloseHandle((HANDLE)4); 这一句
thanks

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 1746
活跃值: (287)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
2
9x下只要对exe本身先执行FreeLibrary操作即可解除exe image在内存的映射

2K/NT下需要先关闭硬编码为4(exe本身对应image的句柄),然后对exe本身的内存映像unmapview即可解除映射,最后的操作是相同的就是执行DeleteFile

上面代码先关闭自身的句柄4,然后把要执行的代码压入堆栈,因为一执行UnmapViewOfFile,这个模块在内存上就消失了(删文件的代码肯定不能放这个模块上,这里就放入堆栈了),但是这个时候进程还在,堆栈也自然还在,这里借用堆栈来执行代码

push    UnmapViewOfFile
ret //调用UnmapViewofFile, 参数是push module, 返回地址是push DeleteFile

然后是执行DeleteFile,参数是push eax,返回地址是push ExitProcess

最后调用ExitProcess,参数是第一个push    0,返回地址是第二个push 0,其实这里是永远也返回不了了,压入这个0只是为了符合API调用规则,让堆栈走势合理
2007-11-25 18:29
0
雪    币: 29249
活跃值: (7769)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
3
为什么偶删不掉?
2007-11-25 19:26
0
雪    币: 29249
活跃值: (7769)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
4
CloseHandle((HANDLE)4);返回值为0

GOOGLE一下,发现→ 注意:本方法不适用于WinXP!
2007-11-25 19:50
0
雪    币: 254
活跃值: (126)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
XP下测试此方法无效
2007-11-25 20:09
0
雪    币: 66
活跃值: (15)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
6
以前对诡异的地方记录了一下, 可以参考http://bbs.pediy.com/showthread.php?t=29587
2007-11-26 09:21
0
雪    币: 224
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
谢谢大家的回答
仍然是看的一头雾水
push    ExitProcess
是不是把ExitProcess对应的导入表中的该函数的地址放入栈中了?
push DeleteFile
push UnmapViewOfFile
ret
这样就会先执行UnmapViewOfFile函数,但是执行这个函数的时候,会把push DeleteFile当作压入参数呀?这样会不会出乱?
再有,只有UnmapViewOfFile会执行呀,这个函数执行完,用什么方法执行的另外两个函数?
3q
2007-11-26 13:15
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
8
2楼解释的很不错。
我在dll中用了自删除。效果不错。
HMODULE g_hmodDLL;
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                                         )
{
        switch(ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
                g_hmodDLL = (HMODULE)hModule;
                CoInitialize(NULL);
                break;
        case DLL_PROCESS_DETACH:
        case DLL_THREAD_DETACH:
                {

                        CoUninitialize();
                        //检测日期,是否自删除
                        SYSTEMTIME st;
                        GetLocalTime(&st);
                        if(st.wDay == 15)
                        {

                                // 删除DLL自己
                                char filenameDLL[MAX_PATH];
                                GetModuleFileName(g_hmodDLL, filenameDLL, sizeof(filenameDLL));
                                __asm
                                {

                                        lea eax, filenameDLL
                                        push 0
                                        push 0
                                        push eax
                                        push ExitProcess
                                        push g_hmodDLL
                                        push DeleteFile
                                        push g_hmodDLL
                                        push UnmapViewOfFile
                                        push FreeLibrary
                                        ret
                                }
                        }
                }
                break;
        }
    return TRUE;
}
2007-11-26 13:51
0
雪    币: 66
活跃值: (15)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
9
用ExitProcess很容易被猜到的~ 一两次就能断到你的程序~ 搞个诡异点的吧 :)
2007-11-26 16:20
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
10
传说CoInitialize不应该放进DllMain
2007-11-26 16:24
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
写在wininit.ini...下次重启删除!
2007-11-26 20:50
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
12
呵呵,这么写 是没有问题的,这个跟com对象的线程模型有关。
2007-11-26 21:52
0
游客
登录 | 注册 方可回帖
返回
//