首页
社区
课程
招聘
大家帮忙看个错误
发表于: 2004-5-10 18:10 8448

大家帮忙看个错误

2004-5-10 18:10
8448
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <time.h>
#include <SYS\STAT.H>
unsigned char writeline[18]={
0x6a,0x40,0x6a,0x0,0x6a,0x0,0x6a,0x0,0xe8,0x01,0x0,0x0,0x0,0xe9,0x0,0x0,0x0,0x0
};

DWORD space;
DWORD entryaddress;
DWORD entrywrite;
DWORD progRAV;
DWORD oldentryaddress;
DWORD newentryaddress;
DWORD codeoffset;
DWORD peaddress;
DWORD flagaddress;
DWORD flags;

DWORD virtsize;
DWORD physaddress;
DWORD physsize;
DWORD MessageBoxAadaddress;

int main(int argc,char * * argv)
{
HANDLE hFile, hMapping;
void *basepointer;
FILETIME * Createtime;
FILETIME * Accesstime;
FILETIME * Writetime;
Createtime = new FILETIME;
Accesstime = new FILETIME;
Writetime = new FILETIME;

if ((hFile = CreateFile(argv[1], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) == INVALID_HANDLE_VALUE)//打开要修改的文件
{
puts("(could not open)");
return EXIT_FAILURE;
}
if(!GetFileTime(hFile,Createtime,Accesstime,Writetime))
{
printf("\nerror getfiletime: %d\n",GetLastError());
}
//得到要修改文件的创建、修改等时间
if (!(hMapping = CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0)))
{
puts("(mapping failed)");
CloseHandle(hFile);
return EXIT_FAILURE;
}
if (!(basepointer = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0)))
{
puts("(view failed)");
CloseHandle(hMapping);
CloseHandle(hFile);
return EXIT_FAILURE;
}
//把文件头映象存入baseointer
CloseHandle(hMapping);
CloseHandle(hFile);
map_exe(basepointer);//得到相关地址
UnmapViewOfFile(basepointer);
printaddress();
printf("\n\n");
if(space<50)
{
printf("\n空隙太小,数据不能写入.\n");
}
else
{
writefile();//写文件
}

if ((hFile = CreateFile(argv[1], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) == INVALID_HANDLE_VALUE)
{
puts("(could not open)");
return EXIT_FAILURE;
}

if(!SetFileTime(hFile,Createtime,Accesstime,Writetime))
{
printf("error settime : %d\n",GetLastError());
}
//恢复修改后文件的建立时间等
delete Createtime;
delete Accesstime;
delete Writetime;
CloseHandle(hFile);
return 0;
}

void map_exe(const void *base)
{
IMAGE_DOS_HEADER * dos_head;
dos_head =(IMAGE_DOS_HEADER *)base;
#include <pshpack1.h>
typedef struct PE_HEADER_MAP
{
DWORD signature;
IMAGE_FILE_HEADER _head;
IMAGE_OPTIONAL_HEADER opt_head;
IMAGE_SECTION_HEADER section_header[];
} peHeader;
#include <poppack.h>

if (dos_head->e_magic != IMAGE_DOS_SIGNATURE)
{
puts("unknown type of file");
return;
}

peHeader * header;
header = (peHeader *)((char *)dos_head + dos_head->e_lfanew);//得到PE文件头
if (IsBadReadPtr(header, sizeof(*header)))
{
puts("(no PE header, probably DOS executable)");
return;
}

DWORD mods;
char tmpstr[4]={0};
DWORD tmpaddress;
DWORD tmpaddress1;

if(strstr((const char *)header->section_header[0].Name,".text")!=NULL)
{
virtsize=header->section_header[0].Misc.VirtualSize;
//此段的真实长度
physaddress=header->section_header[0].PointerToRawData;
//此段的物理偏移
physsize=header->section_header[0].SizeOfRawData;
//此段的物理长度
peaddress=dos_head->e_lfanew;
//得到PE文件头的开始偏移

peHeader peH;
tmpaddress=(unsigned long )&peH;
//得到结构的偏移
tmpaddress1=(unsigned long )&(peH.section_header[0].Characteristics);
//得到变量的偏移
flagaddress=tmpaddress1-tmpaddress+2;
//得到属性的相对偏移
flags=0x8000;
//一般情况下,“.text”段是不可读写的,如果我们要把数据写入这个段需要改变其属性,实际上这个程序并没有把数据写入“.text”段,所以并不需要更改,但如果你实现复杂的功能,肯定需要数据,肯定需要更改这个值,

space=physsize-virtsize;
//得到代码段的可用空间,用以判断可不可以写入我们的代码
//用此段的物理长度减去此段的真实长度就可以得到
progRAV=header->opt_head.ImageBase;
//得到程序的装载地址,一般为400000
codeoffset=header->opt_head.BaseOfCode-physaddress;
//得到代码偏移,用代码段起始RVA减去此段的物理偏移
//应为程序的入口计算公式是一个相对的偏移地址,计算公式为:
//代码的写入地址+codeoffset

entrywrite=header->section_header[0].PointerToRawData+header->section_header[0].Misc.VirtualSize;
//代码写入的物理偏移
mods=entrywrite%16;
//对齐边界
if(mods!=0)
{
entrywrite+=(16-mods);
}
oldentryaddress=header->opt_head.AddressOfEntryPoint;
//保存旧的程序入口地址
newentryaddress=entrywrite+codeoffset;
//计算新的程序入口地址
return;
}

void printaddress()
{
HINSTANCE gLibMsg=NULL;
DWORD funaddress;
gLibMsg=LoadLibrary("user32.dll");
funaddress=(DWORD)GetProcAddress(gLibMsg,"MessageBoxA");
MessageBoxAadaddress=funaddress;
gLibAMsg=LoadLibrary("kernel32.dll");
//得到MessageBox在内存中的地址,以便我们使用
}

void writefile()
{
int ret;
long retf;
DWORD address;
int tmp;
unsigned char waddress[4]={0};

ret=_open(filename,_O_RDWR | _O_CREAT | _O_BINARY,_S_IREAD | _S_IWRITE);
if(!ret)
{
printf("error open\n");
return;
}

retf=_lseek(ret,(long)peaddress+40,SEEK_SET);
//程序的入口地址在PE文件头开始的40处
if(retf==-1)
{
printf("error seek\n");
return;
}
address=newentryaddress;
tmp=address>>24;
waddress[3]=tmp;
tmp=address<<8;
tmp=tmp>>24;
waddress[2]=tmp;
tmp=address<<16;
tmp=tmp>>24;
waddress[1]=tmp;
tmp=address<<24;
tmp=tmp>>24;
waddress[0]=tmp;
retf=_write(ret,waddress,4);
//把新的入口地址写入文件
if(retf==-1)
{
printf("error write: %d\n",GetLastError());
return;
}

retf=_lseek(ret,(long)entrywrite,SEEK_SET);
if(retf==-1)
{
printf("error seek\n");
return;
}
retf=_write(ret,writeline,18);
if(retf==-1)
{
printf("error write: %d\n",GetLastError());
return;
}
//把writeline写入我们计算出的空间

retf=_lseek(ret,(long)entrywrite+9,SEEK_SET);
//更改MessageBox函数地址,它的二进制代码在writeline[10]处
if(retf==-1)
{
printf("error seek\n");
return;
}

address=MessageBoxAadaddress-(progRAV+newentryaddress+9+4);
//重新计算MessageBox函数的地址,MessageBox函数的原地址减去程序的装载地址加上新的入口地址加9(它的二进制代码相对偏移)加上4(地址长度)
tmp=address>>24;
waddress[3]=tmp;
tmp=address<<8;
tmp=tmp>>24;
waddress[2]=tmp;
tmp=address<<16;
tmp=tmp>>24;
waddress[1]=tmp;
tmp=address<<24;
tmp=tmp>>24;
waddress[0]=tmp;
retf=_write(ret,waddress,4);
//写入重新计算的MessageBox地址
if(retf==-1)
{
printf("error write: %d\n",GetLastError());
return;
}

retf=_lseek(ret,(long)entrywrite+14,SEEK_SET);
//更改返回地址,用jpm返回原程序入口地址,其它的二进制代码在writeline[15]处
if(retf==-1)
{
printf("error seek\n");
return;
}

address=0-(newentryaddress-oldentryaddress+4+15);
//返回地址计算的方法是新的入口地址减去老的入口地址加4(地址长度)加15(二进制代码相对偏移)后取反
tmp=address>>24;
waddress[3]=tmp;
tmp=address<<8;
tmp=tmp>>24;
waddress[2]=tmp;
tmp=address<<16;
tmp=tmp>>24;
waddress[1]=tmp;
tmp=address<<24;
tmp=tmp>>24;
waddress[0]=tmp;
retf=_write(ret,waddress,4);
//写入返回地址
if(retf==-1)
{
printf("error write: %d\n",GetLastError());
return;
}

_close(ret);
printf("\nall done...\n");
return;
}

我在VC6.0里面运行的时候出现以下错误:
e:\pe\writepe.cpp(65) : error C2065: 'map_exe' : undeclared identifier
e:\pe\writepe.cpp(67) : error C2065: 'printaddress' : undeclared identifier
e:\pe\writepe.cpp(75) : error C2065: 'writefile' : undeclared identifier
e:\pe\writepe.cpp(97) : error C2373: 'map_exe' : redefinition; different type modifiers
e:\pe\writepe.cpp(106) : warning C4200: nonstandard extension used : zero-sized array in struct/union
e:\pe\writepe.cpp(176) : error C2373: 'printaddress' : redefinition; different type modifiers
e:\pe\writepe.cpp(176) : error C2601: 'printaddress' : local function definitions are illegal
e:\pe\writepe.cpp(187) : error C2373: 'writefile' : redefinition; different type modifiers
e:\pe\writepe.cpp(187) : error C2601: 'writefile' : local function definitions are illegal
e:\pe\writepe.cpp(304) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

writePE.obj - 9 error(s), 1 warning(s)
不知道有谁知道这是什么问题哦?哪为老大帮个忙哦!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 6
支持
分享
最新回复 (6)
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
2

map_exe,printaddress,writefile等等这些函数的作个声明放在文件的开头部份
2004-5-10 19:20
0
雪    币: 235
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我放在前面后出现了下面的错误哦:
E:\pe\writePE.cpp(37) : warning C4200: nonstandard extension used : zero-sized array in struct/union
E:\pe\writePE.cpp(107) : error C2601: 'printaddress' : local function definitions are illegal
E:\pe\writePE.cpp(118) : error C2601: 'writefile' : local function definitions are illegal
E:\pe\writePE.cpp(237) : error C2601: 'main' : local function definitions are illegal
E:\pe\writePE.cpp(304) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

writePE.obj - 4 error(s), 1 warning(s)

不知道该怎么弄哦
2004-5-10 19:34
0
雪    币: 235
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我修改了一下,调试是没问题了,但是构件EXE的时候有错误哦:
Linking...
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
Debug/3232.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

3232.exe - 2 error(s), 0 warning(s)

该怎么办哦
2004-5-10 19:51
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
5
把你的main改为WinMain
2004-5-10 20:40
0
雪    币: 235
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我该过哦,该了后会出现下面的错误的:
Compiling...
writePE.cpp
E:\pe\writePE.cpp(38) : warning C4200: nonstandard extension used : zero-sized array in struct/union
E:\pe\writePE.cpp(239) : warning C4007: 'WinMain' : must be '__stdcall'
E:\pe\writePE.cpp(239) : error C2731: 'WinMain' : function cannot be overloaded
        E:\pe\writePE.cpp(238) : see declaration of 'WinMain'
Error executing cl.exe.

writePE.obj - 1 error(s), 2 warning(s)
2004-5-10 21:25
0
雪    币: 235
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
问题解决了哦,多谢xIkUg的帮忙哦,谢谢哦
2004-5-10 21:33
0
游客
登录 | 注册 方可回帖
返回
//