首页
社区
课程
招聘
[求助]关于catch22上自杀代码在GCC下的编译问题.
发表于: 2006-2-1 13:36 6150

[求助]关于catch22上自杀代码在GCC下的编译问题.

2006-2-1 13:36
6150

在http://www.catch22.net/tuts/selfdel.asp上看到的代码。实际编译中在vc6下使用release模式编译通过。编译出来的文件也可自删除。Debug模式下编译通过。运行生成的文件出错。无法自删除。
在使用mingw32中GCC编译时候。编译通过。但是运行无法自删除。

想请教下如果想用gcc编译。要怎么做哦?

ps:代码中的
#pragma pack(push, 1)

#define CODESIZE 0x200
        。
        。
        。
#pragma pack(pop)

#ifdef _DEBUG
#define FUNC_ADDR(func) (PVOID)(*(DWORD *)((BYTE *)func + 1) + (DWORD)((BYTE *)func + 5))
#else
#define FUNC_ADDR(func) func
#endif
这几句不是很懂。希望大大们帮忙解释下。谢谢了先。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 161
活跃值: (231)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
#pragma pack(push, 1)

这里有详细的解释:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_predir_pack.asp

#define CODESIZE 0x200
定义复制到远程线程中代码长度

#define FUNC_ADDR(func) (PVOID)(*(DWORD *)((BYTE *)func + 1) + (DWORD)((BYTE *)func + 5))
这个宏表示得到近CALL或者近跳转地址,它们指令长度都是5字节,例如:
DEBUG版生成如下形式代码,
.text:004110D7 sub_4110D7      proc near               ; CODE XREF: sub_411280+90p
.text:004110D7                                         ; sub_411280+110p ...
.text:004110D7                 jmp     sub_411880
.text:004110D7 sub_4110D7      endp

FUNC_ADDR(sub_4110D7)宏后就得到sub_411880这个地址
2006-2-1 16:13
0
雪    币: 161
活跃值: (231)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
用MINGW不能自动删除是因为编译器对于函数地址解释与VC不同的原因:

出错代码如下:
local.fnWaitForSingleObject	= (FARPROC)WaitForSingleObject;
local.fnCloseHandle		= (FARPROC)CloseHandle;
local.fnDeleteFile		= (FARPROC)DeleteFile;
local.fnSleep		= (FARPROC)Sleep;
local.fnExitProcess		= (FARPROC)ExitProcess;
local.fnRemoveDirectory	= (FARPROC)RemoveDirectory;
local.fnGetLastError		= (FARPROC)GetLastError;


WaitForSingleObject得到的并不是函数地址,而是间接调用地址,对应的反汇编代码如下:
  401160:	c7 85 90 fb ff ff c0 	movl   $0x4013c0,0xfffffb90(%ebp)

004013c0 <_WaitForSingleObject@8>:
  4013c0:	ff 25 d8 40 40 00    	jmp    *0x4040d8
  4013c6:	90                   	nop    
  4013c7:	90                   	nop    

当在远程代码是调用local.fnWaitForSingleObject等函数的时候,也就是调用$0x4013C0这个地址,而这个地址在远程代码所在进程中不是WaitForSingleObject函数的调用。
当用VC编译的时候,编译器传入的是WaitForSingleObject直接地址,这个直接地址在整个NT操作系统所有的进程空间中的地址都是一样的,不用考虑DLL重定位后的地址不同这个问题。
所以正确的VC和GCC编译器通用代码应该是传递WaitForSingleObject等函数的直接地址,如下:
HINSTANCE hKernel;
hKernel = LoadLibrary("kernel32.dll");
local.fnWaitForSingleObject	= GetProcAddress( hKernel, "WaitForSingleObject");
// 其它的函数...
FreeLibrary(hKernel);


附修改后的代码及DEV-CPP工程文件:
上传的附件:
2006-2-5 13:10
0
游客
登录 | 注册 方可回帖
返回
//