!!很高的手才可以进的,一个从内存中加载并启动一个exe的问题?
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <tlhelp32.h>
//#include <psapi.h>
struct PE_Header
{
unsigned long signature;
unsigned short machine;
unsigned short numSections;
unsigned long timeDateStamp;
unsigned long pointerToSymbolTable;
unsigned long numOfSymbols;
unsigned short sizeOfOptionHeader;
unsigned short characteristics;
};
struct PE_ExtHeader
{
unsigned short magic;
unsigned char majorLinkerVersion;
unsigned char minorLinkerVersion;
unsigned long sizeOfCode;
unsigned long sizeOfInitializedData;
unsigned long sizeOfUninitializedData;
unsigned long addressOfEntryPoint;
unsigned long baseOfCode;
unsigned long baseOfData;
unsigned long imageBase;
unsigned long sectionAlignment;
unsigned long fileAlignment;
unsigned short majorOSVersion;
unsigned short minorOSVersion;
unsigned short majorImageVersion;
unsigned short minorImageVersion;
unsigned short majorSubsystemVersion;
unsigned short minorSubsystemVersion;
unsigned long reserved1;
unsigned long sizeOfImage;
unsigned long sizeOfHeaders;
unsigned long checksum;
unsigned short subsystem;
unsigned short DLLCharacteristics;
unsigned long sizeOfStackReserve;
unsigned long sizeOfStackCommit;
unsigned long sizeOfHeapReserve;
unsigned long sizeOfHeapCommit;
unsigned long loaderFlags;
unsigned long numberOfRVAAndSizes;
unsigned long exportTableAddress;
unsigned long exportTableSize;
unsigned long importTableAddress;
unsigned long importTableSize;
unsigned long resourceTableAddress;
unsigned long resourceTableSize;
unsigned long exceptionTableAddress;
unsigned long exceptionTableSize;
unsigned long certFilePointer;
unsigned long certTableSize;
unsigned long relocationTableAddress;
unsigned long relocationTableSize;
unsigned long debugDataAddress;
unsigned long debugDataSize;
unsigned long archDataAddress;
unsigned long archDataSize;
unsigned long globalPtrAddress;
unsigned long globalPtrSize;
unsigned long TLSTableAddress;
unsigned long TLSTableSize;
unsigned long loadConfigTableAddress;
unsigned long loadConfigTableSize;
unsigned long boundImportTableAddress;
unsigned long boundImportTableSize;
unsigned long importAddressTableAddress;
unsigned long importAddressTableSize;
unsigned long delayImportDescAddress;
unsigned long delayImportDescSize;
unsigned long COMHeaderAddress;
unsigned long COMHeaderSize;
unsigned long reserved2;
unsigned long reserved3;
};
struct SectionHeader
{
unsigned char sectionName[8];
unsigned long virtualSize;
unsigned long virtualAddress;
unsigned long sizeOfRawData;
unsigned long pointerToRawData;
unsigned long pointerToRelocations;
unsigned long pointerToLineNumbers;
unsigned short numberOfRelocations;
unsigned short numberOfLineNumbers;
unsigned long characteristics;
};
struct MZHeader
{
unsigned short signature;
unsigned short partPag;
unsigned short pageCnt;
unsigned short reloCnt;
unsigned short hdrSize;
unsigned short minMem;
unsigned short maxMem;
unsigned short reloSS;
unsigned short exeSP;
unsigned short chksum;
unsigned short exeIP;
unsigned short reloCS;
unsigned short tablOff;
unsigned short overlay;
unsigned char reserved[32];
unsigned long offsetToPE;
};
struct ImportDirEntry
{
DWORD importLookupTable;
DWORD timeDateStamp;
DWORD fowarderChain;
DWORD nameRVA;
DWORD importAddressTable;
};
/
WINBASEAPI
LPVOID
WINAPI
VirtualAllocEx(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);
[解决办法]
咕~~()b
我就是来接分的。。。
[解决办法]
struct MZHeader mzH;
struct PE_Header peH;
struct PE_ExtHeader peXH;
struct SectionHeader *secHdr;
//从文件取得Exe信息(MZ,PE,PEEXT,Sections)
if(readPEInfo(fp, &mzH, &peH, &peXH, &secHdr))
{
//按exe头的信息计算所需空间
int imageSize = calcTotalImageSize(&mzH, &peH, &peXH, secHdr);
//printf("Image Size = %X\n", imageSize);
LPVOID ptrLoc = VirtualAlloc(NULL, imageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);//分配空间
if(ptrLoc)
{
//printf("Memory allocated at %X\n", ptrLoc);
loadPE(fp, &mzH, &peH, &peXH, secHdr, ptrLoc);//装载exe文件数据到分配空间
doFork(&mzH, &peH, &peXH, secHdr, ptrLoc, imageSize);//模拟目标Exe运行环境跑Exe代码
[解决办法]
各个函数基本都注释了,需要的知识点比较多,尤其是PE格式是一定要熟悉的,没什么好说的,lz还是要自己加强学习。
- C/C++ code
BOOL readPEInfo(FILE *fp, struct MZHeader *outMZ, struct PE_Header *outPE, struct PE_ExtHeader *outpeXH, struct SectionHeader **outSecHdr){ //获取要执行的exe文件的长度 fseek(fp, 0, SEEK_END); long fileSize = ftell(fp); fseek(fp, 0, SEEK_SET); //判断长度是否小于PE文件中DOS Stub的大小,如果小于,则说明不是合法的PE格式文件 if(fileSize < sizeof(struct MZHeader)) { printf("File size too small\n"); return FALSE; } //读取DOS Stub到mzH // read MZ Header struct MZHeader mzH; fread(&mzH, sizeof(struct MZHeader), 1, fp); //判断DOS Stub的标志是否是"MZ",如果不是则说明不是合法的PE格式文件 if(mzH.signature != 0x5a4d) // MZ { printf("File does not have MZ header\n"); return FALSE; } //printf("Offset to PE Header = %X\n", mzH.offsetToPE); //检查文件的大小是否小于PE文件头中指明的大小。如果小于,则说明不是合法的PE格式文件 //通常这两个值应该相等,但是实际上fileSize大于后面的和是有可能的,呵呵。 if((unsigned long)fileSize < mzH.offsetToPE + sizeof(struct PE_Header)) { printf("File size too small\n"); return FALSE; } //接下来是读取PE头,PE头的起始位置在DOS Stub中会指明,通常不是和Dos Stub连在一块的, //所以这里需要先SEEK一下文件指针的位置,然后读取 // read PE Header fseek(fp, mzH.offsetToPE, SEEK_SET); struct PE_Header peH; fread(&peH, sizeof(struct PE_Header), 1, fp); //printf("Size of option header = %d\n", peH.sizeOfOptionHeader); //printf("Number of sections = %d\n", peH.numSections); //又是一个判断,检查文件中的可选头的大小和实际大小一致 if(peH.sizeOfOptionHeader != sizeof(struct PE_ExtHeader)) { printf("Unexpected option header size.\n"); return FALSE; } //接着读取PE的可选头 // read PE Ext Header //struct PE_ExtHeader peXH; struct PE_ExtHeader peXH; fread(&peXH, sizeof(struct PE_ExtHeader), 1, fp); //printf("Import table address = %X\n", peXH.importTableAddress); //printf("Import table size = %X\n", peXH.importTableSize); //printf("Import address table address = %X\n", peXH.importAddressTableAddress); //printf("Import address table size = %X\n", peXH.importAddressTableSize); // read the sections //SectionHeader *secHdr = new SectionHeader[peH.numSections]; // VC++ //根据PE头中指明的section个数来分配内存,记录所有的section数据 struct SectionHeader *secHdr = (struct SectionHeader*)malloc(sizeof(struct SectionHeader) * peH.numSections); fread(secHdr, sizeof(struct SectionHeader) * peH.numSections, 1, fp); *outMZ = mzH; *outPE = peH; *outpeXH = peXH; *outSecHdr = secHdr; return TRUE;}
[解决办法]