2000下可执行文件修改自身
pjf(jfpan20000@sina.com)
总有人问起这个老问题,其实在2年前在bbs上贴过的有关windows
内核句柄的帖子就详细写了改写正运行程序的方法,原理一样。为了减
少邮箱信件,所以再整理一下放到一个google一下就可发现的地方:)
另创一个程序改自己当然不是这里说的。NT系统中程序修改自身,
只需做下面几步:
1、先只读打开程序(自然也可以是其他程序)自身,获取一句柄。
2、从EPROCESS开始,访问句柄表的数据结构,找出该句柄掩码。
3、修改掩码,此刻已可通过该句柄对正在运行的可执行文件进行
修改了。
4、做需要的文件操作。
关于句柄表的简单描述,请搜寻以前的贴过的有关的帖子,不再赘诉。
下面是一简单的示例程序:
#include<windows.h>
#include<stdio.h>
#include"rwpm.h"
void ModifyProt2000(HANDLE h)
{
USHORT pointer1, pointer2, pointer3;
ULONG addr;
ULONG index = (ULONG)h;
addr = GetData((PVOID)0xffdff124);
addr = GetData((PVOID)(addr+0x22c));
addr = GetData((PVOID)(addr+0x128));
pointer3 = (USHORT)(index&0x000003FF);
pointer2 = (USHORT)((index&0x0003FC00)>>10);
pointer1 = (USHORT)((index&0x03FC0000)>>18);
addr = GetData((PVOID)(addr+8));
addr = GetData((PVOID)(addr+pointer1*4));
addr = GetData((PVOID)(addr+pointer2*4));
//以上是步骤2,下面是步骤3
SetData((PVOID)(addr+(pointer3/2+1)*4), 0xffffffff);
}
int main()
{
HANDLE h;
char buf[MAX_PATH];
DWORD ret;
GetModuleFileName( NULL, buf, MAX_PATH );
h = CreateFile( buf, 0, FILE_SHARE_READ, 0, OPEN_EXISTING, \
FILE_ATTRIBUTE_NORMAL, 0 );
if ( h == INVALID_HANDLE_VALUE )
return 0;
if ( !InitLib() )
{
printf( "init failed\n" );
return 0;
}
ModifyProt2000( h );
WriteFile( h, "AAAAAA", 6, &ret, 0 );
CloseHandle( h );
ExitLib();
return 0;
}
在windows2000下执行后可以看到文件开始变为“AAAAAA”。
其中用到的InitLib/GetData等函数在那个进程隐藏代码中已给出,不重复贴了。
至于在XP等系统上的代码,这里就不给出了,要修改的部分是句柄掩码的
定位(句柄表结构有变化)、InitLib中页目录的定位。有了思路自己hack是比
较简单的。
好短,确实简单了点。
ULONG GetData(PVOID addr)
{
ULONG phys=(ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory,(PVOID)addr);
PULONG tmp=(PULONG)MapViewOfFile(g_hMPM, 4, 0, phys & 0xfffff000, 0x1000);
if (tmp==0)
return 0;
ULONG ret=tmp[(phys & 0xFFF)>>2];
UnmapViewOfFile(tmp);
return ret;
}
BOOL SetData(PVOID addr,ULONG data)
{
ULONG phys=(ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory,(PVOID)addr);
PULONG tmp=(PULONG)MapViewOfFile(g_hMPM, FILE_MAP_WRITE, 0, phys & 0xfffff000, 0x1000);
if (tmp==0)
return FALSE;
tmp[(phys & 0xFFF)>>2]=data;
UnmapViewOfFile(tmp);
return TRUE;
}