标题:找错。。。重谢
只看楼主
GNUREN
Rank: 1
等 级:新手上路
帖 子:92
专家分:0
注 册:2007-10-3
 问题点数:0 回复次数:19 
找错。。。重谢

这里有个asm

;msgbx.asm文件
;
.386p
.model flat,stdcall
option casemap:none

include windows.inc
include user32.inc
includelib user32.lib

.code

start:
push MB_ICONINFORMATION or MB_OK
call Func1
db "Test",0
Func1:
call Func2
db "Hello",0
Func2:
push NULL
call MessageBoxA
; ret
end start
编译的obj文件得到如下图




//Pe.h:定义CPe类
//
#ifndef _PE_H_INCLUDED
#define _PE_H_INCLUDED

#include<io.h>
#include<fcntl.h>
#include<sys\stat.h>

typedef struct PE_HEADER_MAP
{
DWORD signature;
IMAGE_FILE_HEADER _head;
IMAGE_OPTIONAL_HEADER opt_head;
IMAGE_SECTION_HEADER section_header[6];
}peHeader;

class CPe
{
public:
CPe();
virtual ~CPe();

public:
void CalcAddress(const void* base);
void ModifyPe(CString strFileName,CString strMsg);
void WriteFile(CString strFileName,CString strMsg);

BOOL WriteNewEntry(int ret,long offset,DWORD dwAddress);
BOOL WriteMessageBox(int ret,long offset,CString strCap,CString strTxt);

CString StrOfDWord(DWORD dwAddress);

public:
DWORD dwSpace;
DWORD dwEntryAddress;
DWORD dwEntryWrite;
DWORD dwProgRAV;
DWORD dwOldEntryAddress;
DWORD dwNewEntryAddress;
DWORD dwCodeOffset;
DWORD dwPeAddress;
DWORD dwFlagAddress;
DWORD dwVirtSize;
DWORD dwPhysAddress;
DWORD dwPhysSize;
DWORD dwMessageBoxAadaddress;
};

#endif


// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#if !defined(AFX_STDAFX_H__F2145562_A49A_4B7D_87C2_5E1926A0F215__INCLUDED_)
#define AFX_STDAFX_H__F2145562_A49A_4B7D_87C2_5E1926A0F215__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT


//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__F2145562_A49A_4B7D_87C2_5E1926A0F215__INCLUDED_)

//Pe.cpp:实现CPe类
//

#include "stdafx.h"
#include "pe.h"

CPe::CPe()
{}

CPe::~CPe()
{}


void CPe::ModifyPe(CString strFileName,CString strMsg)
{
CString strErrMsg;

HANDLE hFile,hMapping;
void* basepointer;

//打开要修改的文件
if((hFile=CreateFile(strFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0))==INVALID_HANDLE_VALUE)
{
AfxMessageBox("Can not open file!");
return;
}

//创建一个映射文件
if(!(hMapping=CreateFileMapping(hFile,0,PAGE_READONLY|SEC_COMMIT,0,0,0)))
{
AfxMessageBox("View failed!");
CloseHandle(hFile);
return;
}

//把文件头映象存入basepointer
if(!(basepointer=MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0)))
{
AfxMessageBox("View failed!");
CloseHandle(hMapping);
CloseHandle(hFile);
return;
}

CloseHandle(hMapping);
CloseHandle(hFile);

CalcAddress(basepointer); //得到相关地址
UnmapViewOfFile(basepointer);

if(dwSpace<50)
{
AfxMessageBox("NO room to write the data!");
}
else
{
WriteFile(strFileName,strMsg); //写文件
}

if((hFile=CreateFile(strFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0))==INVALID_HANDLE_VALUE)
{
AfxMessageBox("Could not open file!");
return;
}

CloseHandle(hFile);
}


void CPe::CalcAddress(const void* base)
{
IMAGE_DOS_HEADER* dos_head=(IMAGE_DOS_HEADER*)base;

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

peHeader* header;

//得到PE头文件
header=(peHeader*)((char*)dos_head+dos_head->e_lfanew);

if(IsBadReadPtr(header,sizeof(*header)))
{
AfxMessageBox("No PE header,probably DOS executable!");
return;
}

DWORD mods;
char tmpstr[4]={0};
if(strstr((const char*)header->section_header[0].Name,".text")!=NULL)
{
//此段为真实长度
dwVirtSize=header->section_header[0].Misc.VirtualSize;

//此段的物理偏移
dwPhysAddress=header->section_header[0].PointerToRawData;

//此段的物理长度
dwPhysSize=header->section_header[0].SizeOfRawData;

//得到PE文件头的开始偏移
dwPeAddress=dos_head->e_lfanew;

//得到代码段的可用空间,用以判断可不可以写入我们的代码
//用此段的物理长度减去此段的真实长度就可以的得到
dwSpace=dwPhysSize-dwVirtSize;

//得到程序的装载地址,一般为0x400000
dwProgRAV=header->opt_head.ImageBase;

//得到代码偏移,用代码段起始RVA减去此段的物理偏移
//应为程序的入口计算公式是一个相对偏移地址,计算公式为
//代码的写入地址+dwCodeOffset
dwCodeOffset=header->opt_head.BaseOfCode-dwPhysAddress;

//代码写入的物理偏移
dwEntryWrite=header->section_header[0].PointerToRawData+header->section_header[0].Misc.VirtualSize;

//对齐边界
mods=dwEntryWrite%16;

if(mods!=0)
{
dwEntryWrite+=(16-mods);
}

//保留旧的程序入口地址
dwNewEntryAddress=header->opt_head.AddressOfEntryPoint;

//计算新的程序的入口地址
dwNewEntryAddress=dwEntryWrite+dwCodeOffset;
return;
}
}


CString CPe::StrOfDWord(DWORD dwAddress)
{
unsigned char waddress[4]={0};

waddress[3]=(char)(dwAddress>>24)&0xFF;
waddress[2]=(char)(dwAddress>>16)&0xFF;
waddress[1]=(char)(dwAddress>>8)&0xFF;
waddress[0]=(char)(dwAddress)&0xFF;

return waddress;
}


BOOL CPe::WriteNewEntry(int ret,long offset,DWORD dwAddress)
{
CString strErrMsg;
long retf;
unsigned char waddress[4]={0};

retf=_lseek(ret,offset,SEEK_SET);
if(retf==-1)
{
AfxMessageBox("Error Seek!");
return FALSE;
}

memcpy(waddress,StrOfDWord(dwAddress),4);
retf=_write(ret,waddress,4);

if(retf==-1)
{
strErrMsg.Format("Error write:%d",GetLastError());
AfxMessageBox(strErrMsg);
return FALSE;
}

return TRUE;
}


BOOL CPe::WriteMessageBox(int ret,long offset,CString strCap,CString strTxt)
{
CString strAddress1,strAddress2;
unsigned char waddress[4]={0};
DWORD dwAddress;

//获取MessageBox在内存中地址
HINSTANCE gLibMsg=LoadLibrary("user32.dll");
dwMessageBoxAadaddress=(DWORD)GetProcAddress(gLibMsg,"MessageBoxA");

//计算校验位
int nLenCap1=strCap.GetLength()+1; //加上字符串后面的结束位
int nLenTxt1=strTxt.GetLength()+1; //加上字符串后面的结束位
int nTotLen=nLenCap1+nLenTxt1+24;

//重新计算MessageBox函数的地址
dwAddress=dwMessageBoxAadaddress-(dwProgRAV+dwNewEntryAddress+nTotLen-5);
strAddress1=StrOfDWord(dwAddress);

//计算返回地址
dwAddress=0-(dwNewEntryAddress-dwOldEntryAddress+nTotLen);
strAddress2=StrOfDWord(dwAddress);

//对话框头代码(固定)
unsigned char cHeader[2]={0x6a,0x40};

//标题定义
unsigned char cDesCap[5]={0xe8,nLenCap1,0x00,0x00,0x00};

//内容定义
unsigned char cDesTxt[5]={0xe8,nLenTxt1,0x00,0x00,0x00};

//对话框后部分代码
unsigned char cFix[12]={0x6a,0x00,0xe8,0x00,0x00,0x00,0x00,0xe9,0x00,0x00,0x00,0x00};

//修改对话框后部分代码段
for(int i=0;i<4;i++)
cFix[3+i]=strAddress1.GetAt(i);

for(i=0;i<4;i++)
cFix[8+i]=strAddress2.GetAt(i);

char* cMessageBox=new char[nTotLen];
char* cMsg;

//生成对话框命令字符串
memcpy((cMsg = cMessageBox),(char*)cHeader,2);
memcpy((cMsg += 2),cDesCap,5);
memcpy((cMsg += 5),strCap,nLenCap1);
memcpy((cMsg += nLenCap1),cDesTxt,5);
memcpy((cMsg += 5),strTxt,nLenTxt1);
memcpy((cMsg += nLenTxt1),cFix,12);

//向应用程序写入对话框代码
CString strErrMsg;
long retf;
retf=_lseek(ret,(long)dwEntryWrite,SEEK_SET);
if(retf==-1)
{
delete[] cMessageBox;
AfxMessageBox("Error seek!");
return FALSE;
}

retf=_write(ret,cMessageBox,nTotLen);
if(retf==-1)
{
delete[] cMessageBox;
strErrMsg.Format("Error write:%d",GetLastError());
AfxMessageBox(strErrMsg);
return FALSE;
}

delete[] cMessageBox;
return TRUE;
}


void CPe::WriteFile(CString strFileName,CString strMsg)
{
CString strAddress1,strAddress2;
int ret;
unsigned char waddress[4]={0};

ret=_open(strFileName,_O_RDWR|_O_CREAT|_O_BINARY,_S_IREAD|_S_IWRITE);
if(!ret)
{
AfxMessageBox("Error open!");
return;
}

//把新的入口地址写入文件,程序的入口地址在偏移PE文件头开始第40位
if(!WriteNewEntry(ret,(long)(dwPeAddress+40),dwNewEntryAddress))
{
return;
}

//把对话框代码写入应用程序
if(!WriteMessageBox(ret,(long)dwEntryWrite,"Test","We are the world!"))
return;
_close(ret);
}

//Pefile.cpp:修改PE文件
//

#include "stdafx.h"
#include "pe.h"

int main()
{
CopyFile("C:\\WINDOWS\\system32\\calc.exe","D:\\calc_shell.exe",FALSE);

CPe a;
a.ModifyPe("D:\\calc_shell.exe","We are the World!");
return 0;
}

[此贴子已经被作者于2007-11-17 10:22:09编辑过]

搜索更多相关主题的帖子: include option start 
2007-11-14 21:38
孤魂居士
Rank: 2
来 自:老A(中国地大)
等 级:论坛游民
威 望:4
帖 子:1142
专家分:18
注 册:2007-5-21
得分:0 
....超过我界限````...呼救斑竹``

准备用3年做个高级软件工程师 10年也做不成。准备用10年做成高级软件工程师 3年就成了QQ 群 45771086
欢迎版主...欢迎JAVA爱好者...
一起从深夜 到凌晨...
2007-11-15 00:08
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
得分:0 
还是发到vc版去吧

Fight  to win  or  die...
2007-11-15 01:24
alicefioan37
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2007-9-29
得分:0 

不解

2007-11-15 02:05
PcrazyC
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:5652
专家分:0
注 册:2006-10-20
得分:0 

建的什么工程都不说,怎么看,还是发原程序的好,把程序上传上来,我建个控制台应用程序,出现63个错误


雁无留踪之意,水无取影之心
2007-11-15 10:13
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
得分:0 
回复:(PcrazyC)建的什么工程都不说,怎么看,还是发原...

是个MFC project


Fight  to win  or  die...
2007-11-15 10:28
PcrazyC
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:5652
专家分:0
注 册:2006-10-20
得分:0 
好像不是MFC project,MFC的入口函数应该是WinMain,他这个程序的入口函数是main

雁无留踪之意,水无取影之心
2007-11-15 12:02
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
得分:0 
MFC project工程 的WinMain函数已经被封装了,是看不到这个入口函数的 ^_^

建个基于WIN32的程序,把上面的代码添加进去,编译的时候要设置一下,
project setting-> C\C++ ->code generation ->use runtime library 选择DEbug Multithreaded就OK了

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2007-11-15 12:57
PcrazyC
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:5652
专家分:0
注 册:2006-10-20
得分:0 
MFC工程的WinMain函数是封装了,但跟踪运行几步就可以看到WinMain

他这个程序有MAIN函数,肯定不会是MFC工程了

雁无留踪之意,水无取影之心
2007-11-15 13:12
jonc
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-3-25
得分:0 
看的头都大了??

菜鸟也想高飞
2007-11-15 16:54



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-185995-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.110911 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved