www.pudn.com > PEInject.rar > ChildView.cpp
// ChildView.cpp : CChildView 类的实现
//
#include "stdafx.h"
#include "PEInject.h"
#include "ChildView.h"
#include ".\childview.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CChildView
CChildView::CChildView()
{
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_COMMAND(ID_FILEOPEN, OnFileopen)
ON_COMMAND(ID_MYPLAYER, OnMyplayer)
ON_COMMAND(ID_SWFPLAYER, OnSwfplayer)
END_MESSAGE_MAP()
// CChildView 消息处理程序
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), reinterpret_cast(COLOR_WINDOW+1), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // 用于绘制的设备上下文
// TODO: 在此处添加消息处理程序代码
// 不要为绘制消息而调用 CWnd::OnPaint()
}
void CChildView::OnFileopen()
{
// TODO: 在此添加命令处理程序代码
CString str,str1;
CFileDialog fdlg(TRUE, 0, 0, OFN_NOCHANGEDIR, "*.exe|*.EXE||");
fdlg.DoModal();
str.Empty();
str = fdlg.GetFileExt();
str.MakeUpper();
str1.Empty();
str1 = fdlg.GetPathName();
if (!str1.IsEmpty() && strcmp(str.GetBuffer(), "EXE") ==0)
{
CInputPassWord dlg(this);
dlg.DoModal();
memset(m_PassWord, 0, 12);
memcpy(m_PassWord, dlg.m_PassWord.GetBuffer(), 10);
ListPEFile(str1);
}
}
void CChildView::ListPEFile(CString FileName)
{
IMAGE_DOS_HEADER dosHeader;
IMAGE_NT_HEADERS NtHeader;
IMAGE_SECTION_HEADER MySHeader;
DWORD MySHeadOffset = 0;
IMAGE_SECTION_HEADER LastSHeader;
DWORD LastHeadOffset = 0;
unsigned char *buff = NULL;
DWORD RunModeSZ = 0;
CFile fExe(FileName, CFile::modeReadWrite |CFile::typeBinary);
CFile fR("data.bin", CFile::modeReadWrite |CFile::modeReadWrite|CFile::typeBinary);
RunModeSZ = fR.Seek(0, CFile::end);
fExe.Read(&dosHeader, sizeof(IMAGE_DOS_HEADER));
fExe.Seek(dosHeader.e_lfanew, CFile::begin );
fExe.Read(&NtHeader, sizeof(IMAGE_NT_HEADERS));
DWORD nSections = NtHeader.FileHeader.NumberOfSections;
MySHeadOffset += 4;
MySHeadOffset += sizeof(IMAGE_FILE_HEADER);
MySHeadOffset += sizeof(IMAGE_OPTIONAL_HEADER);
MySHeadOffset += nSections * sizeof(IMAGE_SECTION_HEADER);
if (MySHeadOffset > NtHeader.OptionalHeader.SizeOfHeaders)
{
::AfxMessageBox("文件空间不够!存储不下新节头!", 0, 0);
}
//新节表在文件中的偏移地址
MySHeadOffset += dosHeader.e_lfanew;
//新节表的上一节表在文件中的偏移地址
LastHeadOffset = MySHeadOffset - sizeof(IMAGE_SECTION_HEADER);
//读取新节表的上一节表的数据
fExe.Seek(LastHeadOffset, CFile::begin);
fExe.Read(&LastSHeader, sizeof(IMAGE_SECTION_HEADER));
memset(&MySHeader, 0, sizeof(IMAGE_SECTION_HEADER));
//新节名称
strcpy((char*)MySHeader.Name, ".GZL");
//新节的实际大小(末对齐)Virtual理解为:事实上的,Actual
MySHeader.Misc.VirtualSize = RunModeSZ;
/********************************************************
* MySHeader.VirtualAddress是
* 新节被装载到内存中后的偏移地址,
* 这是一个RVA地址。这个地址是按照内存页对齐的,
* 它的数值总是SectionAlignment的值的整数倍。
* MySHeader.VirtualAddress = NtHeader.OptionalHeader.SizeOfImage;
**********************************************************/
//上一节装载到内存中按照内存页对齐的大小
DWORD LastSectionVirtualSZ = ((LastSHeader.Misc.VirtualSize
/ NtHeader.OptionalHeader.SectionAlignment) + 1)
* NtHeader.OptionalHeader.SectionAlignment;
//新节装载到内存中的偏移地址:上一节装载到内存中的偏移地址 + 上一节装载到内存中按照内存页对齐的大小
MySHeader.VirtualAddress = LastSHeader.VirtualAddress + LastSectionVirtualSZ;
//计算新节在文件中对齐后大小
DWORD sz = MySHeader.Misc.VirtualSize / NtHeader.OptionalHeader.FileAlignment;
sz += 1;
sz *= NtHeader.OptionalHeader.FileAlignment;
MySHeader.SizeOfRawData = sz;
//每个节表的 PointerToRawData 等于它的上一节的 SizeOfRawData + PointerToRawData
//MySHeader.PointerToRawData即新节在文件中的偏移地址
//等于上一节在文件中的偏移地址(PointerToRawData) + 上一节在文件中的大小(SizeOfRawData)
MySHeader.PointerToRawData = LastSHeader.PointerToRawData
+ LastSHeader.SizeOfRawData;
MySHeader.PointerToRelocations = 0;
MySHeader.PointerToLinenumbers = 0;
MySHeader.NumberOfRelocations = 0;
MySHeader.NumberOfLinenumbers = 0;
MySHeader.Characteristics = 0x0E0000020; //可读可写可执行
//写入新“节表”
fExe.Seek(MySHeadOffset, CFile::begin);
fExe.Write(&MySHeader, sizeof(IMAGE_SECTION_HEADER));
//读取新节的数据
buff = new unsigned char[MySHeader.SizeOfRawData];
memset(buff, 0, MySHeader.SizeOfRawData);
fR.Seek(0, CFile::begin);
fR.Read(buff, RunModeSZ);
fR.Close();
//记录下原来ImageBase,AddressOfEntryPoint
//按执行模块中存储原来ImageBase,AddressOfEntryPoint的地址
//要求按顺序在最后两个DWORD
DWORD* p = (DWORD*)(buff + RunModeSZ - 8);
*p = NtHeader.OptionalHeader.ImageBase;
p++;
*p = NtHeader.OptionalHeader.AddressOfEntryPoint;
p = (DWORD*)(buff + RunModeSZ - 20);
strcpy((char *)p, m_PassWord);
//在文件中写入新节的数据
fExe.Seek(MySHeader.PointerToRawData, CFile::begin);
fExe.Write(buff, MySHeader.SizeOfRawData);
delete []buff;
/************************************************************
* 改写IMAGE_NT_HEADERS,使新节可以首先执行:
* (需要改写 SizeOfImage , AddressOfEntryPoint
* ,NumberOfSections)
* SizeOfImage :内存中整个PE映像大小,对齐到SectionAlignment
*************************************************************/
NtHeader.FileHeader.NumberOfSections += 1;
sz = MySHeader.Misc.VirtualSize / NtHeader.OptionalHeader.SectionAlignment;
sz += 1;
sz *= NtHeader.OptionalHeader.SectionAlignment;
NtHeader.OptionalHeader.SizeOfImage += sz;
NtHeader.OptionalHeader.AddressOfEntryPoint = MySHeader.VirtualAddress;
fExe.Seek(dosHeader.e_lfanew, CFile::begin);
fExe.Write(&NtHeader, sizeof (IMAGE_NT_HEADERS));
fExe.Close();
::AfxMessageBox("成功写入新节!", 0, 0);
}
void CChildView::OnMyplayer()
{
// TODO: 在此添加命令处理程序代码
int Len = 0;
char buff[1024] = "";
DWORD SWFFlg = 0;
DWORD SWFlen = 0;
CFile fR("tt.exe", CFile::modeRead |CFile::typeBinary);
CFile fW("MyPlayer.exe", CFile::modeCreate|CFile::modeReadWrite |CFile::typeBinary);
Len = fR.GetLength();
fR.Seek(Len - 8, CFile::begin);
//读取SWF文件标识
fR.Read(&SWFFlg, sizeof(DWORD));
//读取SWF文件大小减去8的值
fR.Read(&SWFlen, sizeof(DWORD));
//文件总长度减去SWF文件长度,即为播器长度。
Len = Len - (SWFlen + 8);
fR.Seek(0, CFile::begin);
int n = Len / 1024;
for (int i = 0; i