日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PE读写

發布時間:2025/5/22 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PE读写 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

// 仿PE文件.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <malloc.h>

?

/*將文件從硬盤讀取到緩沖區中
參數1 :文件路徑 參數2:接受讀取數據的緩沖區的地址的指針【指針的指針】
讀取成功返回文件的長度 讀取失敗則返回0
*/
//int ReadFileToBuffer(IN LPSTR FilePath,OUT LPVOID* PFileBuffer);

?

//接下來將EXE從文件緩沖區拷貝到內存鏡像緩沖區中
//DWORD CopyFileBufferToImageBuffer(IN LPSTR FileBuffer,OUT LPVOID* PImageBuffer);

int main(int argc, char* argv[])

{
char* FilePath1="E:/notepad++.exe"; //讀入的文件路勁

DWORD FileLength=0;

FILE* InputStream=NULL;

void* pFileBuffer=NULL;

InputStream=fopen(FilePath1,"rb");//打開文件流

?

if(FilePath1=NULL){
printf("文件為空\n");
return 0;
}


int nseek=fseek(InputStream,0,SEEK_END);//將文件流指針指向文件末尾
if(nseek!=0){
printf("設置文件位置指針失敗\n");
fclose(InputStream);
return 0;
}

FileLength=ftell(InputStream);
printf("the lentgth of the exe is %d Byte\n",FileLength);

//重新設置文件位置指針指向文件首
fseek(InputStream,0,SEEK_SET);
pFileBuffer=(void*)malloc(FileLength);
if(pFileBuffer==NULL){
printf("文件緩沖區申請失敗\n");
fclose(InputStream);
return 0;
}

memset(pFileBuffer,0,FileLength);

int n=fread(pFileBuffer,FileLength,1,InputStream);

if(n==0){
printf("文件讀取失敗\n");
free(pFileBuffer);
fclose(InputStream);
return 0;
}



//接下來將EXE從文件緩沖區拷貝到內存鏡像緩沖區中

?

PIMAGE_DOS_HEADER pDosHeader=NULL;
PIMAGE_NT_HEADERS pNTHeaders=NULL;
PIMAGE_FILE_HEADER pPEHeader=NULL;
PIMAGE_OPTIONAL_HEADER pOptionalHeader=NULL;
PIMAGE_SECTION_HEADER pSectionHeader=NULL;

//判斷文件緩沖區是否有效
if(pFileBuffer==NULL){
printf("文件緩沖區指針無效\n");
return 0;
}

//判斷該文件是否是PE文件
if(*((PWORD)pFileBuffer)!=IMAGE_DOS_SIGNATURE){
printf("不是有效的DOS文件\n");
return 0;
}
pDosHeader=(PIMAGE_DOS_HEADER)(pFileBuffer);
if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew))!=IMAGE_NT_SIGNATURE){ //這里注意:FileBuffer是一個指針,也就是一個地址,所以轉型為DWROD與pDosHeader->e_lfanew相加
printf("該文件不是有效的PE文件");
return 0;
}

printf("DOS的開始地址是:%x\n",pDosHeader);
//NT頭指針
pNTHeaders=(PIMAGE_NT_HEADERS)((DWORD)pDosHeader+pDosHeader->e_lfanew);
printf("NT的開始地址是:%x\n",pNTHeaders);
//PE頭指針等于NT頭指針加四
pPEHeader=(PIMAGE_FILE_HEADER)(((DWORD)pFileBuffer+pDosHeader->e_lfanew)+4);
printf("PE的開始地址是:%x\n",pPEHeader);

//血的教訓,一個指針加上一個整數,加上的實際的大小是該指針表示的數據類型【去掉一個*】乘以整數
pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);//指針在加數時務必將其轉化為整形
printf("optional的開始地址是:%x\n",pOptionalHeader);

pSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pPEHeader->SizeOfOptionalHeader);
printf("section表的開始地址是:%x\n",pSectionHeader);

//根據SIZE_OF_IMAGE來分配內存緩沖區的大小,雖然每一個應用程序在理論上都擁有獨立的4GB虛擬內存,但是還是根據SIZE FOF IMAGE來分配內存大小
LPVOID pImageBuffer=NULL;
pImageBuffer=malloc(pOptionalHeader->SizeOfImage);
printf("%x\n",pOptionalHeader->SizeOfImage);
if(pImageBuffer==NULL){
printf("分配內存鏡像文件失敗\n");
}

memset(pImageBuffer,0,pOptionalHeader->SizeOfImage);

//開始從文件緩沖區拷貝到鏡像緩沖區中 1:第一步:將所有的頭拷貝到鏡像緩沖區中 DosHeader+NTHeader+SectionHeader
memcpy(pImageBuffer,pFileBuffer,pOptionalHeader->SizeOfHeaders);


//第二步:循環將區塊拷貝到IMAGBUFFER中
PIMAGE_SECTION_HEADER pTempSectionHeader=pSectionHeader;

for(int i=0;i<pPEHeader->NumberOfSections;i++,pTempSectionHeader++){
memcpy((void*)((DWORD)pImageBuffer+pTempSectionHeader->VirtualAddress),(void*)((DWORD)pDosHeader+pTempSectionHeader->PointerToRawData),pTempSectionHeader->SizeOfRawData);
}



PIMAGE_DOS_HEADER pImageDosHeader=NULL;
PIMAGE_NT_HEADERS pImageNTHeaders=NULL;
PIMAGE_FILE_HEADER pImagePEHeader=NULL;
PIMAGE_OPTIONAL_HEADER pImageOptionalHeader=NULL;
PIMAGE_SECTION_HEADER pImageSectionHeader=NULL;

pImageDosHeader=(PIMAGE_DOS_HEADER)pImageBuffer;
printf("IMAGE中DOS頭的首地址是:%x\n",pImageDosHeader);

pImageNTHeaders=(PIMAGE_NT_HEADERS)((DWORD)pImageDosHeader+pImageDosHeader->e_lfanew);
printf("IMAGE中NT頭的首地址是:%x\n",pImageNTHeaders);

pImagePEHeader=(PIMAGE_FILE_HEADER)((DWORD)pImageNTHeaders+4);
printf("IMAGE中PE頭的首地址是:%x\n",pImagePEHeader);

pImageOptionalHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pImagePEHeader+IMAGE_SIZEOF_FILE_HEADER);
printf("IMAGE中OPTIONAL頭的首地址是:%x\n",pImageOptionalHeader);

pImageSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader+pImagePEHeader->SizeOfOptionalHeader);

//重新申請一塊文件緩沖區,將鏡像中的可執行程序還原到文件緩沖區中
LPVOID pNewFileBuffer=NULL;
pNewFileBuffer=malloc(FileLength);
if(pNewFileBuffer==NULL){
printf("重新申請文件緩沖區失敗\n");
return 0;
}

memset(pNewFileBuffer,0,FileLength);
//第一步:將第一部分拷貝到新的文件緩沖區中DOSHEADER+NTHEADER+SECTIONHEADER
memcpy(pNewFileBuffer,pImageDosHeader,pImageOptionalHeader->SizeOfHeaders);

//第二步:循環將各個區塊拷貝到新的文件緩沖區中
//用一個臨時指針來完成pImageSectionHeader指針的自增變化

PIMAGE_SECTION_HEADER pTempImageSectionHeader=NULL;
pTempImageSectionHeader=pImageSectionHeader;

for(i=0;i<pImagePEHeader->NumberOfSections;i++,pTempImageSectionHeader++){
memcpy((void*)((DWORD)pNewFileBuffer+pTempImageSectionHeader->PointerToRawData),(void*)((DWORD)pImageDosHeader+pTempImageSectionHeader->VirtualAddress),pTempImageSectionHeader->SizeOfRawData);
}

//將還原后的文件緩沖區寫到一個文件中,并測試是有可以運行

char* FilePath2="E:/zhuhao3.exe"; //文件輸出路徑
FILE* OutputStream=NULL;
OutputStream=fopen(FilePath2,"w+");

fwrite(pFileBuffer,FileLength,1,OutputStream);

char* pchar;
char arry[]="zhuhao";
pchar=arry;
int a=3;


return 0;
}

?

轉載于:https://www.cnblogs.com/zhuh102/p/6130624.html

總結

以上是生活随笔為你收集整理的PE读写的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。