通过修改PE结构来实现注入代码加深了解WINDOWS机制
#include "stdafx.h"
#include "AnalyticalPe.h"
#define filePath "F:\\test11111.exe"
#define ToFilePath "C:\\shuchu1.exe"
#defineMessageBoxAddress 0x759BFD3F
/*******************************************************************************
名称:ZrFile
功能:注入EXE
参数:filePath需要注入的EXE路径
时间:9/24/2015 范乐乐
版本:1.0
注意:
*******************************************************************************/
VOID ZrFile(IN LPSTR pfilePath){
////定义一个buffer保存返回的PE磁盘格式
//LPVOID pFileBuffer = NULL;
//LPVOID pImageBuffer = NULL;
//LPVOID pNewFileBuffer = NULL;
////定义一个文件大小的变量
//DWORD fileSize = 0;
////读取PE磁盘格式
//fileSize = ReadPeFile(pfilePath,&pFileBuffer);
//if(fileSize == 0){
// printf("读取PE失败");
// free(pFileBuffer);
// getchar();
// return;
//}
//fileSize = ZrImageToFile(pFileBuffer,&pImageBuffer);
//if(!fileSize){
// printf("文件结构转内存结构失败");
// free(pImageBuffer);
// getchar();
// return;
//}
//定义一个buffer保存返回的PE磁盘格式
LPVOID pFileBuffer = NULL;
LPVOID pImageBuffer = NULL;
LPVOID pNewFileBuffer = NULL;
//定义一个文件大小的变量
DWORD fileSize = 0;
//读取PE磁盘格式
fileSize = ReadPeFile(filePath,&pFileBuffer);
if(fileSize == 0){
printf("读取PE失败");
free(pFileBuffer);
getchar();
return;
}
fileSize = FileToImage(pFileBuffer,&pImageBuffer);
if(!fileSize){
printf("文件结构转内存结构失败");
free(pImageBuffer);
getchar();
return;
}
fileSize = ZrImageToFile(pImageBuffer,&pNewFileBuffer);
if(!fileSize){
printf("文件结构转内存结构失败");
free(pNewFileBuffer);
getchar();
return;
}
if(SaveFile(ToFilePath,pNewFileBuffer,fileSize)){
printf("存盘成功!");
}
//SaveFile("C:\\0000.exe",pImageBuffer,fileSize);
}
/*******************************************************************************
名称:ZrImage (作废)
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD ZrImage(IN LPVOID pFileBuffer,OUT LPVOID* pImageBuffer);
/*******************************************************************************
名称:ZrImageToFile
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD ZrImageToFile(IN LPVOID pImageBuffer,OUT LPVOID* pFileBuffer){
//定义一系列变量
PIMAGE_DOS_HEADER pDosHeader = NULL; //DOS头
PIMAGE_NT_HEADERS32 pNtHeader = NULL; //NT头
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; //扩展头
PIMAGE_FILE_HEADER pFileHeader = NULL; //标准头
PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表头
//判断取出来的磁盘PE格式格式是否正确 (DOS)
if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE){
printf("DOS格式错误");
free(pImageBuffer);
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
printf("pDosHeader->e_magic:%x\n",pDosHeader->e_magic);
printf("pDosHeader->e_lfanew:%x\n",pDosHeader->e_lfanew);
pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
if(pNtHeader->Signature != IMAGE_NT_SIGNATURE){
printf("PE格式错误");
}
printf("pNtHeader->Signature:%x\n",pNtHeader->Signature);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader+4);
printf("pFileHeader->NumberOfSections:%x\n",pFileHeader->NumberOfSections);
printf("pFileHeader->SizeOfOptionalHeader:%x\n",pFileHeader->SizeOfOptionalHeader);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader+IMAGE_SIZEOF_FILE_HEADER);
DWORD fileSize = pOptionalHeader->SizeOfImage;
printf("pOptionalHeader->ImageBase:%x\n",pOptionalHeader->ImageBase);
printf("pOptionalHeader->SizeOfImage:%x\n",pOptionalHeader->SizeOfImage);
printf("pOptionalHeader->SizeOfHeaders:%x\n",pOptionalHeader->SizeOfHeaders);
//***********************************修改pe**********************************************************
//开始赋值节
DWORD MyTextJie = 0;
DWORD SectionTwo = 0;
for (int i =0; i < pFileHeader->NumberOfSections;i++)
{
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);
if(i == 1){
MyTextJie = pSectionHeader->Misc.VirtualSize;
SectionTwo = pSectionHeader->VirtualAddress;
}
}
printf("------------->%x,--------------------->%x,-------------->%x",MyTextJie,SectionTwo,(DWORD)pImageBuffer);
void * thisCode = (void*)((DWORD)pImageBuffer+SectionTwo+MyTextJie);
BYTEmyByte = {0x6A,0x00,0x6A,0x00,0x6A,0x00,0x6A,0x00,0xE8,0x00,0x00,0x00,0x00,0xE9,0x00,0x00,0x00,0x00};
memcpy(thisCode,myByte,18);
//修正E8
DWORD E8Address = MessageBoxAddress - ((pOptionalHeader->ImageBase + (DWORD)thisCode+0xD) - (DWORD)pImageBuffer);
*(PDWORD)((DWORD)thisCode + 0x9) = E8Address;
//修正E9
DWORD E9Address = (pOptionalHeader->ImageBase + pOptionalHeader->AddressOfEntryPoint ) - ((pOptionalHeader->ImageBase + (DWORD)thisCode+0x12) - (DWORD)pImageBuffer);
*(PDWORD)((DWORD)thisCode + 0xE) = E9Address;
//修正EOP
pOptionalHeader->AddressOfEntryPoint =(DWORD)thisCode-(DWORD)pImageBuffer;
//***********************************创建Image存储结构***************************************************
LPVOIDpFileBuffer_Buffer = malloc(pOptionalHeader->SizeOfImage); //开辟了一个空间用来保存在内存中结构
memset(pFileBuffer_Buffer,0,pOptionalHeader->SizeOfImage);
//因为NT头是不会有任何变化的,所以可以直接拷贝过去
memcpy(pFileBuffer_Buffer,pImageBuffer,pOptionalHeader->SizeOfHeaders); //这里的pimage_buffer已经有了头部
//开始赋值节
for (int i =0; i < pFileHeader->NumberOfSections;i++)
{
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);
memcpy((void*)((DWORD)pFileBuffer_Buffer+pSectionHeader->PointerToRawData),(void*)((DWORD)pImageBuffer+pSectionHeader->VirtualAddress),pSectionHeader->SizeOfRawData);
}
*pFileBuffer = pFileBuffer_Buffer;
free(pImageBuffer);
pDosHeader = NULL; //DOS头
pNtHeader = NULL; //NT头
pOptionalHeader = NULL; //扩展头
pFileHeader = NULL; //标准头
pSectionHeader = NULL;//节表头
return fileSize;
}
int _tmain(int argc, _TCHAR* argv[])
{
//TestZh();
//定义注入程序
ZrFile(filePath);
getchar();
return 0;
}
/*******************************************************************************
名称:TestZh
功能:测试转换
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
*******************************************************************************/
VOID TestZh(){
//定义一个buffer保存返回的PE磁盘格式
LPVOID pFileBuffer = NULL;
LPVOID pImageBuffer = NULL;
LPVOID pNewFileBuffer = NULL;
//定义一个文件大小的变量
DWORD fileSize = 0;
//读取PE磁盘格式
fileSize = ReadPeFile(filePath,&pFileBuffer);
if(fileSize == 0){
printf("读取PE失败");
free(pFileBuffer);
getchar();
return;
}
fileSize = FileToImage(pFileBuffer,&pImageBuffer);
if(!fileSize){
printf("文件结构转内存结构失败");
free(pImageBuffer);
getchar();
return;
}
fileSize = ImageToFile(pImageBuffer,&pNewFileBuffer);
if(!fileSize){
printf("文件结构转内存结构失败");
free(pNewFileBuffer);
getchar();
return;
}
if(SaveFile(ToFilePath,pNewFileBuffer,fileSize)){
printf("存盘成功!");
}
}
/*******************************************************************************
名称:ReadPeFile
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD ReadPeFile(IN LPSTRpFilePath,OUT LPVOID* pFileBuffer ){
//1.创建一个File指针
FILE * pFile = NULL;
//2.创建一个变量保存文件的大小
DWORD fileSize = 0;
//3.创建一个Buffer保存文件内容
LPVOIDmyFileBuffer = NULL;
errno_t errNum = 0;
errNum = fopen_s(&pFile,pFilePath,"rb");
if(errNum != 0){
printf("打开文件失败了!");
return 0;
}
fseek(pFile,0,SEEK_END);
fileSize = ftell(pFile);
fseek(pFile,0,SEEK_SET);
myFileBuffer = malloc(fileSize);
size_t n =fread(myFileBuffer,fileSize,1,pFile);
if(!n){
printf("加载缓冲区失败");
//关闭file
fclose(pFile);
//释放开辟的内存
free(myFileBuffer);
return 0;
}
*pFileBuffer = myFileBuffer;
//关闭file
fclose(pFile);
return fileSize;
}
/*******************************************************************************
名称:FileToImage
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD FileToImage(IN LPVOID pFileBuffer,OUT LPVOID* pImageBuffer){
//定义一系列变量
PIMAGE_DOS_HEADER pDosHeader = NULL; //DOS头
PIMAGE_NT_HEADERS32 pNtHeader = NULL; //NT头
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; //扩展头
PIMAGE_FILE_HEADER pFileHeader = NULL; //标准头
PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表头
//判断取出来的磁盘PE格式格式是否正确 (DOS)
if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){
printf("DOS格式错误");
free(pFileBuffer);
free(pImageBuffer);
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
printf("pDosHeader->e_magic:%x\n",pDosHeader->e_magic);
printf("pDosHeader->e_lfanew:%x\n",pDosHeader->e_lfanew);
pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
if(pNtHeader->Signature != IMAGE_NT_SIGNATURE){
printf("PE格式错误");
free(pFileBuffer);
free(pImageBuffer);
return 0;
}
printf("pNtHeader->Signature:%x\n",pNtHeader->Signature);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader+4);
printf("pFileHeader->NumberOfSections:%x\n",pFileHeader->NumberOfSections);
printf("pFileHeader->SizeOfOptionalHeader:%x\n",pFileHeader->SizeOfOptionalHeader);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader+IMAGE_SIZEOF_FILE_HEADER);
printf("pOptionalHeader->ImageBase:%x\n",pOptionalHeader->ImageBase);
printf("pOptionalHeader->SizeOfImage:%x\n",pOptionalHeader->SizeOfImage);
printf("pOptionalHeader->SizeOfHeaders:%x\n",pOptionalHeader->SizeOfHeaders);
DWORD fileSize = pOptionalHeader->SizeOfImage;
for (int i =0; i < pFileHeader->NumberOfSections;i++)
{
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);
BYTE * name = (BYTE)(pSectionHeader->Name);
printf("pSectionHeader->Name:%s\n",name);
printf("pSectionHeader->VirtualAddress:%x\n",pSectionHeader->VirtualAddress);
printf("pSectionHeader->PointerToRawData:%x\n",pSectionHeader->PointerToRawData);
}
//***********************************创建Image存储结构***************************************************
LPVOIDpImage_Buffer = malloc(pOptionalHeader->SizeOfImage); //开辟了一个空间用来保存在内存中结构
memset(pImage_Buffer,0,pOptionalHeader->SizeOfImage);
fileSize = pOptionalHeader->SizeOfImage;
//因为NT头是不会有任何变化的,所以可以直接拷贝过去
memcpy(pImage_Buffer,pFileBuffer,pOptionalHeader->SizeOfHeaders); //这里的pimage_buffer已经有了头部
//开始赋值节
for (int i =0; i < pFileHeader->NumberOfSections;i++)
{
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);
memcpy((void*)((DWORD)pImage_Buffer+pSectionHeader->VirtualAddress),(void*)((DWORD)pFileBuffer+pSectionHeader->PointerToRawData),pSectionHeader->SizeOfRawData);
}
*pImageBuffer = pImage_Buffer;
free(pFileBuffer);
pDosHeader = NULL; //DOS头
pNtHeader = NULL; //NT头
pOptionalHeader = NULL; //扩展头
pFileHeader = NULL; //标准头
pSectionHeader = NULL;//节表头
return fileSize;
}
/*******************************************************************************
名称:ImageToFile
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD ImageToFile(IN LPVOID pImageBuffer,OUT LPVOID* pFileBuffer){
//定义一系列变量
PIMAGE_DOS_HEADER pDosHeader = NULL; //DOS头
PIMAGE_NT_HEADERS32 pNtHeader = NULL; //NT头
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; //扩展头
PIMAGE_FILE_HEADER pFileHeader = NULL; //标准头
PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表头
//判断取出来的磁盘PE格式格式是否正确 (DOS)
if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE){
printf("DOS格式错误");
free(pImageBuffer);
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
printf("pDosHeader->e_magic:%x\n",pDosHeader->e_magic);
printf("pDosHeader->e_lfanew:%x\n",pDosHeader->e_lfanew);
pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
if(pNtHeader->Signature != IMAGE_NT_SIGNATURE){
printf("PE格式错误");
}
printf("pNtHeader->Signature:%x\n",pNtHeader->Signature);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader+4);
printf("pFileHeader->NumberOfSections:%x\n",pFileHeader->NumberOfSections);
printf("pFileHeader->SizeOfOptionalHeader:%x\n",pFileHeader->SizeOfOptionalHeader);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader+IMAGE_SIZEOF_FILE_HEADER);
DWORD fileSize = pOptionalHeader->SizeOfImage;
printf("pOptionalHeader->ImageBase:%x\n",pOptionalHeader->ImageBase);
printf("pOptionalHeader->SizeOfImage:%x\n",pOptionalHeader->SizeOfImage);
printf("pOptionalHeader->SizeOfHeaders:%x\n",pOptionalHeader->SizeOfHeaders);
//***********************************创建Image存储结构***************************************************
LPVOIDpFileBuffer_Buffer = malloc(pOptionalHeader->SizeOfImage); //开辟了一个空间用来保存在内存中结构
memset(pFileBuffer_Buffer,0,pOptionalHeader->SizeOfImage);
//因为NT头是不会有任何变化的,所以可以直接拷贝过去
memcpy(pFileBuffer_Buffer,pImageBuffer,pOptionalHeader->SizeOfHeaders); //这里的pimage_buffer已经有了头部
//开始赋值节
for (int i =0; i < pFileHeader->NumberOfSections;i++)
{
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);
memcpy((void*)((DWORD)pFileBuffer_Buffer+pSectionHeader->PointerToRawData),(void*)((DWORD)pImageBuffer+pSectionHeader->VirtualAddress),pSectionHeader->SizeOfRawData);
}
*pFileBuffer = pFileBuffer_Buffer;
free(pImageBuffer);
pDosHeader = NULL; //DOS头
pNtHeader = NULL; //NT头
pOptionalHeader = NULL; //扩展头
pFileHeader = NULL; //标准头
pSectionHeader = NULL;//节表头
return fileSize;
}
/*******************************************************************************
名称:SaveFile
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:保存成功true 保存失败false
*******************************************************************************/
BOOL SaveFile(IN LPSTR pfilePath,IN LPVOID pFileBuffer,IN DWORD fileSize){
//获取文件指针
FILE *pFile = NULL;
errno_t et = 0;
et = fopen_s(&pFile,pfilePath,"wb+");
if(pFile == NULL){
printf("打开失败");
return 0;
}
fwrite(pFileBuffer,fileSize,1,pFile);
fflush(pFile);
fclose(pFile);
free(pFileBuffer);
return 1;
}
#include "stdafx.h"
PLVOID ReadPEFile (LPSTRpath ){
{
FILE *pFile =NULL ;
DWORD fileSize = 0 ;
LPVOID pFileBuffer = NULL;
/* 1 打开文件 */
if(!(pFile = fopen(path,"rb")))
{
printf("can not open file %s \n",path);
return NULL;
}
/* 2.获取文件大小 */
fseek(pFile,0,SEEK_END);
fileSize =ftell(pFile);
fseek(pFile,0,SEEK_SET);
//rewind(fp);
/* 3 分配缓冲区 */
pFileBuffer = malloc(fileSize);
if (!pFileBuffer)
{
printf("buffer devided error!\n");
fclose(pFile);
return NULL;
}
/* 4 将文件拷贝到buffer中 */
size_t n = fread(pFileBuffer,fileSize,1,pFile);
if(!n){
printf("read file error !\n");
free(pFileBuffer);
fclose(pFile);
return NULL;
}
fclose(pFile);
return pFilBuffer;
}
/*
VOID PrintNTHeaders()
{
LPVOID pFileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTION_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pFileBuffer = ReadPEFile(FILEPATH);
if(!pFileBuffer){
printf("read file error! \n")
return ;
}
//判断是否有效的mz
if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("invalid mz \n");
free(pFileBuffer);
return ;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
// printf
printf("*****************************************\n");
printf(" mz: %X\n",pDOSHeader->e_magic);
printf(" pe offset: %X\n",pDOSHeader->e_lfanew);
if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("invalid pe signature \n");
free(pFileBuffer);
return;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
//printf nt
printf("*****************************************\n");
printf("nt : %x\n ",pNTHeader->Signature);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
printf("*****************************************\n");
printf("pe: %x \n",pPEHeader->Machine);
printf("section: %x \n",pPEHeader->NumberOfSections);
printf("size of optionalHeader: %x \n",pPEHeader->SizeOfOptionalHeader);
// optionalheader
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
printf("*****************************************\n");
printf("option_pe: %X \n",pOptionHeader->Magic);
free(pFileBuffer);
*/
}
int main(int argc, char* argv[])
{
char * string;
string= ReadPEFile("c:/c.exe");
printf("%d\n",string);
// PrintNTHeaders();
return 0;
}
我编译不过,你能看下为什么吗?出错在第一句呀
页:
[1]