首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

!很高的手才可以进的,一个从内存中加载并启动一个exe的有关问题

2012-03-30 
!!很高的手才可以进的,一个从内存中加载并启动一个exe的问题?#include stdio.h#include string.h#incl

!!很高的手才可以进的,一个从内存中加载并启动一个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;} 


[解决办法]

热点排行