【转】别人写的pe代码

// PEOperate.cpp: implementation of the PEOperate class.
//
//////////////////////////////////////////////////////////////////////

#include "PEOperate.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include "windows.h"
#include "stdio.h"
#include "string.h"

#define MESSAGEBOXADDR    0x77D507EA
#define SHELLCODELENGTH 0x12

BYTE shellCode[]={
        0x6A,00,0x6A,00,0x6A,00,0x6A,00,
        0xE8,00,00,00,00,
        0xE9,00,00,00,00
};

//加载PE文件到内存中
LPVOID ReadPEFile(LPSTR lpszFile)
{
    FILE *pFile = NULL;
    DWORD fileSize = 0;
    LPVOID pFileBuffer = NULL;
    
    //打开文件
    pFile = fopen(lpszFile,"rb");
    
    if(!pFile)
    {
        printf("无法打开文件EXE文件");
        return NULL;
    }
    
    fseek(pFile,0,SEEK_END);
    fileSize = ftell(pFile);
    fseek(pFile,0,SEEK_SET);
    
    //分配缓冲区
    pFileBuffer = malloc(fileSize);
    if(!pFileBuffer)
    {
        printf("分配空间失败!\n");
        fclose(pFile);
        return NULL;
    }
    
    //文件读取
    
    size_t n = fread(pFileBuffer,fileSize,1,pFile);
    
    if(!n)
    {
        printf("读取数据失败\n");
        free(pFileBuffer);
        fclose(pFile);
        return NULL;
    }
    
    //关闭文件
    fclose(pFile);
    return pFileBuffer;
    
}

//内存直接写入到文件
void WirteToFile(LPVOID pFileBuffer,size_t fileSize,LPSTR lpszFile)
{
    FILE *pFile = NULL;    
    //打开文件
    pFile = fopen(lpszFile,"wb");
    
    if(!pFile)
    {
        printf("无法打开文件EXE文件");
        return;
    }
    
    size_t writeSize = fwrite(pFileBuffer,fileSize,1,pFile);
    printf("WirteSize:%d\n",writeSize);
    
    //关闭文件
    fclose(pFile);
    return;
    
}


//打印所有的PE头信息
VOID PrintNTHeaders(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }
    
    //MZ标志
    if(*((PWORD)pFileBuffer)!=IMAGE_DOS_SIGNATURE)
    {
        printf("不是有效的MZ标志\n");
        free(pFileBuffer);
        return;
    }
    
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    
    //打印DOS头
    printf("------------DOS头------------\n");
    printf("MZ标志: %x\n",pDosHeader->e_magic);
    printf("PE偏移: %x\n",pDosHeader->e_lfanew);

    //判断是否是有效的PE 
    if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew))!=IMAGE_NT_SIGNATURE)
    {
        printf("不是有效的PE标志\n");
        free(pFileBuffer);
        return;
    }

    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);

    //打印NT头
    printf("------------NT头------------\n");
    printf("Signature: %x\n",pNTHeader->Signature);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    printf("------------标准PE头--------\n");
    printf("Machine: %x\n",pPEHeader->Machine);
    printf("节的数量: %x\n",pPEHeader->NumberOfSections);
    printf("SizeOfOptionHeaders: %x\n",pPEHeader->SizeOfOptionalHeader);

    //可选择PE头
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    printf("------------OPTION_PE头--------\n");
    printf("Machine: %x \n",pOptionHeader->Magic);
    printf("OEP: %x \n",pOptionHeader->AddressOfEntryPoint);
    printf("ImageBase: %x \n",pOptionHeader->ImageBase);
    printf("SectionAlignment: %x \n",pOptionHeader->SectionAlignment);
    printf("FileAlignment: %x \n",pOptionHeader->FileAlignment);
    printf("SizeOfImage: %x \n",pOptionHeader->SizeOfImage);
    printf("SizeOfHeaders: %x \n",pOptionHeader->SizeOfHeaders);
    
    
    //节表的信息(分别打印)
    //确定节表的个数:
    int Section_Number = pPEHeader->NumberOfSections;
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

    for(int i=0;i<Section_Number;i++)
    {
        printf("------------节表信息:%d--------\n",i+1);
        printf("Name: %s \n",pSectionHeader->Name);
        printf("VirualSize : %x\n",pSectionHeader->Misc);
        printf("VirualAddress: %x\n",pSectionHeader->VirtualAddress);
        printf("SizeOfRawData: %x \n",pSectionHeader->SizeOfRawData);
        printf("PointerToRowData: %x \n",pSectionHeader->PointerToRawData);
        
        //下一个节表
        pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);

    }
    //释放内存
    free(pFileBuffer);
}


//将PE的FileBuffer拷贝到ImageBuffer
LPVOID CopyFileBufferToImageBuffer(LPVOID pFileBuffer)
{
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return NULL;
    }

    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    
    DWORD ImageSize = pOptionHeader->SizeOfImage;
    
    //LPVOID pImageBuffer=NULL;
    //分配缓冲区
    LPVOID pImageBuffer=NULL;
    pImageBuffer = malloc(ImageSize);

    if(!pImageBuffer)
    {
        printf("pImageBuffer分配空间失败!\n");
        return NULL;
    }
    //printf("%x \n",ImageSize);

    memset(pImageBuffer,0,ImageSize);

    //分段拷贝数据到ImageBuffer中
    //1 拷贝头
    DWORD HeaderSize = pOptionHeader->SizeOfHeaders;
    //DWORD Head_i = 0;
    //copy header
    memcpy(pImageBuffer,pFileBuffer,HeaderSize);
    
    //2 拷贝节 pSectionHeader
    //数量,位置
    int Section_Number = pPEHeader->NumberOfSections;
    //分节进行写入

    LPVOID pFileBuffer_sec = pFileBuffer;
    LPVOID pImageBuffer_sec = pImageBuffer;

    //printf("pFileBuffer_sec: %x \n",pFileBuffer_sec);
    //printf("pImageBuffer_sec: %x \n",pImageBuffer_sec);

    for(int i=0;i<Section_Number;i++)
    {
        DWORD FileSizeOfRawData = pSectionHeader->SizeOfRawData;
        DWORD FilePointerToRawData = pSectionHeader->PointerToRawData;
        DWORD MemVirtualAddress = pSectionHeader->VirtualAddress;
        pFileBuffer_sec=(LPVOID)((DWORD)pFileBuffer+FilePointerToRawData);
        pImageBuffer_sec=(LPVOID)((DWORD)pImageBuffer+MemVirtualAddress);
    
        //printf("pFileBuffer_sec: %x \n",pFileBuffer_sec);
        //printf("pImageBuffer_sec: %x \n",pImageBuffer_sec);

        memcpy(pImageBuffer_sec,pFileBuffer_sec,FileSizeOfRawData);
        //下一个节表
        pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);
    }
    
    //写出
    //WirteToFile(pImageBuffer,ImageSize,"c://image.exe");

    return pImageBuffer;
}

LPVOID CopyImageBuffertoNewBuffer(LPVOID pImageBuffer)
{
    

    return NULL;
}

BOOL MemeryTOFile(LPVOID pMemBuffer,LPSTR lpszFile)
{
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pMemBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pMemBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    

    //将内存中的文件转入到File中
    FILE *pFile = NULL;    
    //打开文件
    pFile = fopen(lpszFile,"a+b");
    
    if(!pFile)
    {
        printf("无法打开文件EXE文件");
        return FALSE;
    }
    
    //写header
    DWORD SIZE_HEADER =  pOptionHeader->SizeOfHeaders;
    fwrite(pMemBuffer,SIZE_HEADER,1,pFile);

    //写节表
    int Section_Number = pPEHeader->NumberOfSections;

    LPVOID pImageBuffer_sec = pMemBuffer;
    
    printf("pImageBuffer_SEC : %x \n",pImageBuffer_sec);
    for(int i=0;i<Section_Number;i++)
    {
        DWORD FileSizeOfRawData = pSectionHeader->SizeOfRawData;
        DWORD FilePointerToRawData = pSectionHeader->PointerToRawData;
        DWORD MemVirtualAddress = pSectionHeader->VirtualAddress;

        pImageBuffer_sec=(LPVOID)((DWORD)pMemBuffer+MemVirtualAddress);
        printf("pImageBuffer_SEC : %x \n",pImageBuffer_sec);

        fwrite(pImageBuffer_sec,FileSizeOfRawData,1,pFile);

        pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);    
    }

    
    
    //关闭文件
    fclose(pFile);
    
    return TRUE;
}

DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
{
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return NULL;
    }

    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

    DWORD ImageSize = pOptionHeader->SizeOfImage;
    int Section_Number = pPEHeader->NumberOfSections;
    int i=0;
    for(i=0;i<Section_Number;i++)
    {
        //printf("VirualSize : %x\n",pSectionHeader->Misc);
        //printf("VirualAddress: %x\n",pSectionHeader->VirtualAddress);
        
        DWORD dumpVirualSize = pSectionHeader->Misc.VirtualSize;
        DWORD dumpVirualAddress = pSectionHeader->VirtualAddress;

        if(dwRva>=dumpVirualAddress && dwRva <=dumpVirualAddress+dumpVirualSize)
        {
            //printf("地址在第:%d 节 %s \n",i+1,pSectionHeader->Name);
            break;
        }
        //下一个节表
        pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);
    }
    
    //确定是第i+1节
    //确定偏移距离
    DWORD fileOff = pSectionHeader->PointerToRawData + (dwRva-pSectionHeader->VirtualAddress);

    return fileOff;
}

DWORD FileOffsetToRVA(LPVOID pFileBuffer,DWORD dwFoa)
{
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return NULL;
    }

    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

    DWORD ImageSize = pOptionHeader->SizeOfImage;
    int Section_Number = pPEHeader->NumberOfSections;
    int i=0;
    for(i=0;i<Section_Number;i++)
    {
        DWORD dumpPointerToRawData = pSectionHeader->PointerToRawData;
        DWORD dumpSizeOfRaw = pSectionHeader->SizeOfRawData;

        if(dwFoa>=dumpPointerToRawData && dwFoa <=dumpPointerToRawData+dumpSizeOfRaw)
        {
            //printf("地址在第:%d 节 %s \n",i+1,pSectionHeader->Name);
            break;
        }
        //下一个节表
        pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);
    }
    
    //确定是第i+1节
    //确定偏移距离
    DWORD RVA = pSectionHeader->VirtualAddress + (dwFoa-pSectionHeader->PointerToRawData);
    return RVA;

}

void TestAddCodeInCodeSec(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }
    
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    
    LPVOID pImageBuffer = CopyFileBufferToImageBuffer(pFileBuffer);

    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    

    //确定添加代码的位置
    //1判断能否添加
    if((pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize)<=SHELLCODELENGTH){
        printf("空余字节大小不够添加shellCode\n");
        free(pFileBuffer);
        return;
    }

    //size_t file_size = pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize;
    //printf("%x \n",file_size);

    //2代码加的位置
    printf("pImageBuffer: %x\n",pImageBuffer);
    DWORD shellLocation =  pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize;
    //确定位置
    LPVOID pShellLoc = (LPVOID)((DWORD)pImageBuffer + shellLocation);
    printf("pShellLoc: %x\n",pShellLoc);
    
    //拷贝初始化代码到内存
    memcpy(pShellLoc,shellCode,SHELLCODELENGTH);
    
    //修改E8地址
    DWORD  pE8Content = MESSAGEBOXADDR - (((DWORD)pShellLoc+13 )- ((DWORD)pImageBuffer)+ pOptionHeader->ImageBase);
    *(PDWORD)((DWORD)pShellLoc+9)=pE8Content;

    //修改E9地址
    DWORD pE9Content = (pOptionHeader->AddressOfEntryPoint+pOptionHeader->ImageBase) - (((DWORD)pShellLoc+0x12 )- ((DWORD)pImageBuffer)+ pOptionHeader->ImageBase);
    *(PDWORD)((DWORD)pShellLoc+14)=pE9Content;

    //修改OEP
    pOptionHeader->AddressOfEntryPoint = (DWORD)pShellLoc-(DWORD)pImageBuffer;

    //更改完的ImageBuffer,写出到File中
    MemeryTOFile(pImageBuffer,"C://testShell.exe");

    //释放
    free(pFileBuffer);
    free(pImageBuffer);
    return;
}

void TestAddSecToFile(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }
    
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;

    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    pSectionHeader_ADD = pSectionHeader;
    

    //1 判断能否添加节
    DWORD Header_size = pDosHeader->e_lfanew + 4 + 20 + pPEHeader->SizeOfOptionalHeader + pPEHeader->NumberOfSections*40;
    if(pOptionHeader->SizeOfHeaders-Header_size<80)
    {
        printf("没有可用空间填充节表\n");
        free(pFileBuffer);
        return;
    }
    
    printf("空间:%d\n",pOptionHeader->SizeOfHeaders-Header_size);
    
    

    //添加一个节
    //确定参数
    PIMAGE_SECTION_HEADER pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);
    pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader_ADD+(pPEHeader->NumberOfSections)*40);
    //="NewSec";
    strcpy((char*)pSectionHeader_ADD->Name,"NewSec");
    pSectionHeader_ADD->Misc.VirtualSize = 0x1000;
    pSectionHeader_ADD->VirtualAddress = pOptionHeader->SizeOfImage;
    pSectionHeader_ADD->SizeOfRawData = 0x1000;
    pSectionHeader_ADD->PointerToRawData = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData;
    pSectionHeader_ADD->Characteristics = pSectionHeader->Characteristics;

    //填充0
    LPVOID pSectionEND = (LPVOID)((DWORD)pSectionHeader_ADD+40);
    memset(pSectionEND,0,IMAGE_SIZEOF_SECTION_HEADER);
    

    printf("pFileBuffer: %x\n",pFileBuffer);
    printf("pSectionHeader: %x\n",pSectionHeader);
    printf("pSectionHeader_LAST: %x\n",pSectionHeader_LAST);
    printf("pSectionHeader_ADD: %x\n",pSectionHeader_ADD);
    printf("pSectionEND: %x\n",pSectionEND);
    
    //修改PE头信息
    pPEHeader->NumberOfSections = pPEHeader->NumberOfSections +1;
    pOptionHeader->SizeOfImage  = pOptionHeader->SizeOfImage+0x1000;

    //写入到文件
    FILE *pOutFile = NULL;    
    //打开文件
    pOutFile = fopen("C://addSec.exe","a+b");
    
    if(!pOutFile)
    {
        printf("无法打开文件EXE文件");
        return;
    }
    //写出第一部分
    printf("length: %x \n ",pSectionHeader_ADD->PointerToRawData+pSectionHeader_ADD->SizeOfRawData);

    size_t writeSize = fwrite(pFileBuffer,pSectionHeader_ADD->PointerToRawData,1,pOutFile);
    printf("WirteSize:%d\n",writeSize);
    //写出第二部分
    LPVOID pNewBuffer=(LPVOID)malloc(0x1000);
    if(pNewBuffer==NULL)
    {
        printf("pNewBuffer分配空间失败\n");
        return;
    }
    memset(pNewBuffer,0,0x1000);
    writeSize = fwrite(pNewBuffer,0x1000,1,pOutFile);
    
    //关闭文件
    fclose(pOutFile);
    


    free(pFileBuffer);
    free(pNewBuffer);

}

void TestAddLastSectionToFile(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }
    
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader_LAST = NULL;

    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);
    int fileLength = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData;

    //更改ImageSize
    pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage+0x1000;
    
    //更改最后一个节的SizeOfRawData 以及 VirtualSize
    pSectionHeader_LAST->SizeOfRawData =     pSectionHeader_LAST->SizeOfRawData+0x1000;
    pSectionHeader_LAST->Misc.VirtualSize = pSectionHeader_LAST->Misc.VirtualSize+0x1000;
    
    //写出文件
    
    //写入到文件
    FILE *pOutFile = NULL;    
    //打开文件
    pOutFile = fopen("C://addSecLength.exe","a+b");
    
    if(!pOutFile)
    {
        printf("无法打开文件EXE文件");
        return;
    }
    //写出第一部分
    printf("length: %x \n ",fileLength);

    size_t writeSize = fwrite(pFileBuffer,fileLength,1,pOutFile);
    printf("WirteSize:%d\n",writeSize);
    //写出第二部分
    LPVOID pNewBuffer=(LPVOID)malloc(0x1000);
    if(pNewBuffer==NULL)
    {
        printf("pNewBuffer分配空间失败\n");
        return;
    }
    memset(pNewBuffer,0,0x1000);
    writeSize = fwrite(pNewBuffer,0x1000,1,pOutFile);
    
    //关闭文件
    fclose(pOutFile);
    free(pFileBuffer);
    free(pNewBuffer);

}

DWORD Align(int size,int filesize)
{
    if(size<=filesize)
    {
        return filesize;
    }else
    {
        int n=0;
        if(size%filesize == 0)
        {
            n = size/filesize;
        }else{
            n = size/filesize;
            n=n+1;
        }

        return filesize*n;
        
    }
}


void TestChangeOneSec(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }
    
    LPVOID pImageBuffer =NULL;
    pImageBuffer = CopyFileBufferToImageBuffer(pFileBuffer);


    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader_LAST = NULL;

    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);

    //合并节的操作
    DWORD LastSize = (pSectionHeader_LAST->SizeOfRawData > pSectionHeader_LAST->Misc.VirtualSize)?pSectionHeader_LAST->SizeOfRawData:pSectionHeader_LAST->Misc.VirtualSize;

    pSectionHeader->Misc.VirtualSize = pSectionHeader_LAST->VirtualAddress + LastSize - pSectionHeader->VirtualAddress;
    pSectionHeader->SizeOfRawData = pSectionHeader_LAST->VirtualAddress + LastSize - pSectionHeader->VirtualAddress;
    pSectionHeader->PointerToRawData = pSectionHeader->VirtualAddress;

    //设置属性值
    //pSectionHeader->Characteristics
    DWORD MyCharacteristics = pSectionHeader->Characteristics;
    for(int k=0;k<pPEHeader->NumberOfSections;k++)
    {
        PIMAGE_SECTION_HEADER pSectionHeader_NEXT;
        pSectionHeader_NEXT= (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+k*40);
        MyCharacteristics = MyCharacteristics |(pSectionHeader_NEXT->Characteristics);
    }

    printf("MyCharacteristics: %x \n",MyCharacteristics);
    pSectionHeader->Characteristics = MyCharacteristics;
        
    pPEHeader->NumberOfSections = 0x1;

    DWORD ImageSize  = pOptionHeader->SizeOfImage;

    //直接写出到文件
    WirteToFile(pImageBuffer,ImageSize,"C://hebing.exe");

}

//IMAGE_DATA_DIRECTORY
void printDirectoryData(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }

    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_DATA_DIRECTORY DataDirectory=NULL;
    
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

    //定位Directory_Data;
    DataDirectory = pOptionHeader->DataDirectory;
    
    //IMAGE_DIRECTORY_ENTRY_EXPORT
    printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
    
    printf("IMAGE_DIRECTORY_ENTRY_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size);

    printf("IMAGE_DIRECTORY_ENTRY_RESOURCE: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);

    printf("IMAGE_DIRECTORY_ENTRY_EXCEPTION: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size);

    printf("IMAGE_DIRECTORY_ENTRY_SECURITY: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size);
    
    printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

    printf("IMAGE_DIRECTORY_ENTRY_DEBUG: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size);

    printf("IMAGE_DIRECTORY_ENTRY_ARCHITECTURE: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].Size);

    printf("IMAGE_DIRECTORY_ENTRY_GLOBALPTR: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].Size);

    printf("IMAGE_DIRECTORY_ENTRY_TLS: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size);

    printf("IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size);

    printf("IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size);

    printf("IMAGE_DIRECTORY_ENTRY_IAT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size);

    printf("IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size);

    printf("IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size);
    

}

void TestExportDirectory(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }

    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_DATA_DIRECTORY DataDirectory=NULL;
    
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

    //定位Directory_Data;
    DataDirectory = pOptionHeader->DataDirectory;
    
    //导出表

    printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

    //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
    DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
    //printf("%x \n",FoA);

    DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
    FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address);

    /*
    typedef struct _IMAGE_EXPORT_DIRECTORY {
        DWORD   Characteristics;
        DWORD   TimeDateStamp;
        WORD    MajorVersion;
        WORD    MinorVersion;
        DWORD   Name;                    //指向该导出表文件名字符串
        DWORD   Base;                    //导出函数起始序号
        DWORD   NumberOfFunctions;        //所有导出函数的个数
        DWORD   NumberOfNames;            //以函数名字导出的函数个数    
        DWORD   AddressOfFunctions;     // 导出函数地址表 RVA
        DWORD   AddressOfNames;         // 导出函数名称表 RVA
        DWORD   AddressOfNameOrdinals;  // 导出函数序号表 RVA
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
    */
    
    //定位导出表的位置

    PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL;
    pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA);

    printf("Characteristics: %x\n",pExDirectory->Characteristics);
    printf("TimeDateStamp: %x\n",pExDirectory->TimeDateStamp);
    printf("MajorVersion: %x\n",pExDirectory->MajorVersion);
    printf("MinorVersion: %x\n",pExDirectory->MinorVersion);
    printf("Name: %x\n",pExDirectory->Name);
    printf("Base: %x\n",pExDirectory->Base);
    printf("NumberOfFunctions: %x\n",pExDirectory->NumberOfFunctions);
    printf("NumberOfNames: %x\n",pExDirectory->NumberOfNames);
    printf("AddressOfFunctions: %x\n",pExDirectory->AddressOfFunctions);
    printf("AddressOfNames: %x\n",pExDirectory->AddressOfNames);
    printf("AddressOfNameOrdinals: %x\n",pExDirectory->AddressOfNameOrdinals);
    
    printf("------------------------\n");
    //输出函数地址表信息
    //AddressOfFunctions
    DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions;
    DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions);
    DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions;
    
    PDWORD pExAddressOfFunctions = NULL;
    pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA);

    //输出每个函数地址表信息
    DWORD k =0;
    for(k=0;k<ExNumberOfFunctions;k++)
    {
        printf("%d : %x \n",k,*pExAddressOfFunctions);
        pExAddressOfFunctions++;
    }
    printf("------------------------\n");
    //函数名称表
    DWORD ExAddressOfNames = pExDirectory->AddressOfNames;
    DWORD ExAddressOfNamesFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNames);
    DWORD ExNumberOfNames = pExDirectory->NumberOfNames;
    
    PDWORD pExAddressOfNames = NULL;
    pExAddressOfNames = (PDWORD)((DWORD)pFileBuffer + ExAddressOfNamesFoA);

    for(k=0;k<ExNumberOfNames;k++)
    {
        printf("%d : %x   \n",k,*pExAddressOfNames);
        //函数名的地址转换为FoA ,输出函数名
        PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames);
        //输出函数名
        printf("%s \n",(char*)((DWORD)pFileBuffer + (DWORD)NameAddress));
        pExAddressOfNames++;
    }
    
    //函数序号表
    printf("------------------------\n");
    DWORD ExAddressOfNameOrdinals = pExDirectory->AddressOfNameOrdinals;
    DWORD ExAddressOfNameOrdinalsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNameOrdinals);
    ExNumberOfNames = pExDirectory->NumberOfNames;
    
    PWORD pExAddressOfNameOrdinals = NULL;
    pExAddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + ExAddressOfNameOrdinalsFoA);


    for(k=0;k<ExNumberOfNames;k++)
    {
        printf("%d : %x   \n",k,*pExAddressOfNameOrdinals);
        pExAddressOfNameOrdinals++;
    }
}

DWORD GetFunctionAddrByName(LPVOID pFileBuffer,LPSTR FunctionName)
{
    //LPVOID pFileBuffer = NULL;
    //pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return 0;
    }

    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_DATA_DIRECTORY DataDirectory=NULL;
    
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

    //定位Directory_Data;
    DataDirectory = pOptionHeader->DataDirectory;
    
    //导出表

    printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

    //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
    DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
    //printf("%x \n",FoA);

    DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
    FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address);

    //定位导出表的位置

    PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL;
    pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA);
    
    printf("------------------------\n");
    

    //输出每个函数地址表信息
    WORD k =0;
    
    //函数名称表
    DWORD ExAddressOfNames = pExDirectory->AddressOfNames;
    DWORD ExAddressOfNamesFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNames);
    DWORD ExNumberOfNames = pExDirectory->NumberOfNames;
    
    PDWORD pExAddressOfNames = NULL;
    pExAddressOfNames = (PDWORD)((DWORD)pFileBuffer + ExAddressOfNamesFoA);

    for(k=0;k<ExNumberOfNames;k++)
    {
        //printf("%d : %x   \n",k,*pExAddressOfNames);
        //函数名的地址转换为FoA ,输出函数名
        PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames);
        //输出函数名
        //printf("%s \n",(char*)((DWORD)pFileBuffer + (DWORD)NameAddress));
        char* s_name = (char*)((DWORD)pFileBuffer + (DWORD)NameAddress);
        WORD num = strcmp(FunctionName,s_name);
        if(num==0)
        {
            break;
        }
        pExAddressOfNames++;
    }

    
    //函数的位置k
    WORD Location_Fun = k;
    printf("Function: %s\n",FunctionName);
    printf("Location_Fun: %d \n",Location_Fun); 
    
    //return 0;
    //函数序号表
    
    DWORD ExAddressOfNameOrdinals = pExDirectory->AddressOfNameOrdinals;
    DWORD ExAddressOfNameOrdinalsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNameOrdinals);
    ExNumberOfNames = pExDirectory->NumberOfNames;
    PWORD pExAddressOfNameOrdinals = NULL;
    pExAddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + ExAddressOfNameOrdinalsFoA);

    //函数表的序号
    WORD NUM_FUN = pExAddressOfNameOrdinals[Location_Fun];
    
    printf("NUM_FUN: %d \n",NUM_FUN); 
    
    //return 0;
    
    //输出函数地址表信息
    //AddressOfFunctions
    DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions;
    DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions);
    DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions;
    
    PDWORD pExAddressOfFunctions = NULL;
    pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA);
    
    //确定函数的地址

    DWORD Fun_Addr = pExAddressOfFunctions[NUM_FUN];
    return Fun_Addr;
}

DWORD GetFunctionAddrByOrdinals(LPVOID pFileBuffer,WORD FunctionOrdinals)
{
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return 0;
    }

    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_DATA_DIRECTORY DataDirectory=NULL;
    
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

    //定位Directory_Data;
    DataDirectory = pOptionHeader->DataDirectory;
    
    //导出表
    printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

    //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
    DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
    //printf("%x \n",FoA);

    DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
    FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address);

    //定位导出表的位置
    PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL;
    pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA);

    //直接定位函数的位置
    DWORD Function_Index = FunctionOrdinals-pExDirectory->Base; 
    
    //输出函数地址表信息
    //AddressOfFunctions
    DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions;
    DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions);
    DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions;
    
    PDWORD pExAddressOfFunctions = NULL;
    pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA);
    
    //确定函数的地址

    DWORD Fun_Addr = pExAddressOfFunctions[Function_Index];
    return Fun_Addr;

    //return 0;
}

void printDirectoryRelocTable(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }

    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_DATA_DIRECTORY DataDirectory=NULL;
    
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

    //定位Directory_Data;
    DataDirectory = pOptionHeader->DataDirectory;
    
    //重定位表

    printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

    //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
    DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
    
    DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
    DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
    FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address);
    

    //定位到第一个重定位块
    PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA);
    
    //输出所有的标信息
    while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock)
    {
        DWORD RelocVirtualAddress = pRelocData->VirtualAddress;
        DWORD RelocSize = pRelocData->SizeOfBlock;

        printf("VirtualSize: %x ,Size: %x , Number: %x  \n",RelocVirtualAddress,RelocSize,(RelocSize-8)/2);
        
        int k = (RelocSize-8)/2;
        PWORD pMyRelocAddress = NULL;
        pMyRelocAddress = (PWORD)((DWORD)pRelocData+8);
        
        for(int i=0;i<k;i++)
        {
            printf("第%x个 : 标志 : %x 偏移 : %x\n",i+1,pMyRelocAddress[i]&0xF000,RelocVirtualAddress+(pMyRelocAddress[i]&0x0FFF));
        }
        pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize);
    }

}

void TestMoveExportDirectory(LPSTR lpszFile)
{
    /*
    1 在DLL中新增一个节, 并返回新增的FOA
    2 复制AddressOfFunctions  长度:4*NumberOfFunctions
    3 复制AddressOfNameOrdinals  长度:NumberOfNames*2
    4 复制AddressOfNames  长度:NumberOfNames*4
    5 复制所有的函数名
        长度不确定,复制时直接修复AddressOfNames
    6 复制IMAGE_EXPORT_DIRECTORY结构
    7 修复IMAGE_EXPORT_DIRECTORY结构中的
        AddressOfFunctions
        AddressOfNameOrdinals
        AddressOfNames
    8 修复目录中项的值,指向新的IMAGE_EXPORT_DIRECTORY
    */

}

void TestMoveRelocDirectory(LPSTR lpszFile)
{
    /*
    1 新增一个节
    2 把重定位的表 移动到那个节中
    3 更改标志位
    */
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }
    
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;
    PIMAGE_DATA_DIRECTORY DataDirectory=NULL;
    
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    pSectionHeader_ADD = pSectionHeader;
    
    //1 判断能否添加节
    DWORD Header_size = pDosHeader->e_lfanew + 4 + 20 + pPEHeader->SizeOfOptionalHeader + pPEHeader->NumberOfSections*40;
    if(pOptionHeader->SizeOfHeaders-Header_size<80)
    {
        printf("没有可用空间填充节表\n");
        free(pFileBuffer);
        return;
    }
    
    printf("空间:%d\n",pOptionHeader->SizeOfHeaders-Header_size);
    

    //添加一个节
    //确定参数
    PIMAGE_SECTION_HEADER pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);
    pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader_ADD+(pPEHeader->NumberOfSections)*40);
    //="NewSec";
    strcpy((char*)pSectionHeader_ADD->Name,"NewSec");
    pSectionHeader_ADD->Misc.VirtualSize = 0x2000;
    pSectionHeader_ADD->VirtualAddress = pOptionHeader->SizeOfImage;
    pSectionHeader_ADD->SizeOfRawData = 0x2000;
    pSectionHeader_ADD->PointerToRawData = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData;
    pSectionHeader_ADD->Characteristics = pSectionHeader->Characteristics;

    //填充0
    LPVOID pSectionEND = (LPVOID)((DWORD)pSectionHeader_ADD+40);
    memset(pSectionEND,0,IMAGE_SIZEOF_SECTION_HEADER);

    
    //修改PE头信息
    pPEHeader->NumberOfSections = pPEHeader->NumberOfSections +1;
    pOptionHeader->SizeOfImage  = pOptionHeader->SizeOfImage+0x2000;

    //写入到文件
    FILE *pOutFile = NULL;    
    //打开文件
    pOutFile = fopen("C://addSec.dll","a+b");
    
    if(!pOutFile)
    {
        printf("无法打开文件EXE文件");
        return;
    }
    //写出第一部分
    printf("length: %x \n ",pSectionHeader_ADD->PointerToRawData+pSectionHeader_ADD->SizeOfRawData);

    size_t writeSize = fwrite(pFileBuffer,pSectionHeader_ADD->PointerToRawData,1,pOutFile);
    printf("WirteSize:%d\n",writeSize);
    //写出第二部分
    LPVOID pNewBuffer=(LPVOID)malloc(0x2000);
    if(pNewBuffer==NULL)
    {
        printf("pNewBuffer分配空间失败\n");
        return;
    }
    memset(pNewBuffer,0,0x2000);
    writeSize = fwrite(pNewBuffer,0x2000,1,pOutFile);
    //关闭文件
    fclose(pOutFile);
    free(pFileBuffer);
    free(pNewBuffer);

    //读入添加好节的文件
    pFileBuffer= ReadPEFile("C://addSec.dll");
    
    //将重定位表的信息,放到最后一个节中
        //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    //最后一个节
    pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);

    //定位Directory_Data;
    DataDirectory = pOptionHeader->DataDirectory;
    
    //重定位表

    printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

    //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
    DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
    
    DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
    DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
    FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address);
    

    //定位到第一个重定位块
    PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA);
    PIMAGE_BASE_RELOCATION pRelocData_Start = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA);

    DWORD sizeOfRelocDirectory = 0;
    //计算重定位表的大小
    while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock)
    {
        DWORD RelocVirtualAddress = pRelocData->VirtualAddress;
        DWORD RelocSize = pRelocData->SizeOfBlock;

        sizeOfRelocDirectory = sizeOfRelocDirectory + RelocSize;

        pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize);
    }

    //起始位置pRelocData
    
    
    //移动
    PDWORD myRelocLoc = (PDWORD)pSectionHeader_ADD->PointerToRawData;
    printf("Reloc: %x , Size: %x \n",pRelocData,sizeOfRelocDirectory);

    //memcpy(myRelocLoc,pRelocData,sizeOfRelocDirectory);
    LPVOID destStart = (LPVOID)((DWORD)pFileBuffer + (DWORD)myRelocLoc);
    printf("pFileBuffer:%x, myRelocLoc: %x \n",pFileBuffer,destStart);
    LPVOID srcStart = (LPVOID)(pRelocData_Start);
    memcpy(destStart,srcStart,sizeOfRelocDirectory);
    
    //修改重定位表的参数
    DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = FileOffsetToRVA(pFileBuffer,pSectionHeader_ADD->PointerToRawData);
    //写出到dll中
    DWORD FileSize = pSectionHeader_ADD->PointerToRawData + pSectionHeader_ADD->SizeOfRawData;
    WirteToFile(pFileBuffer,FileSize,"C://addNewSec.dll");

}

void testUseReloc(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }

    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_DATA_DIRECTORY DataDirectory=NULL;
    PIMAGE_SECTION_HEADER pSectionHeader_LAST = NULL;

    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);
    //定位Directory_Data;
    DataDirectory = pOptionHeader->DataDirectory;
    
    //重定位表

    printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
        DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

    //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
    DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
    
    DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
    DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
    FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address);
    

    //定位到第一个重定位块
    PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA);
    
    //输出所有的标信息
    while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock)
    {
        DWORD RelocVirtualAddress = pRelocData->VirtualAddress;
        DWORD RelocSize = pRelocData->SizeOfBlock;

        printf("VirtualSize: %x ,Size: %x , Number: %x  \n",RelocVirtualAddress,RelocSize,(RelocSize-8)/2);
        
        int k = (RelocSize-8)/2;
        PWORD pMyRelocAddress = NULL;
        pMyRelocAddress = (PWORD)((DWORD)pRelocData+8);
        
        for(int i=0;i<k;i++)
        {
            printf("第%x个 : 标志 : %x 偏移 : %x\n",i+1,pMyRelocAddress[i]&0xF000,RelocVirtualAddress+(pMyRelocAddress[i]&0x0FFF));
            //依次进行修改
            DWORD changeRVA = RelocVirtualAddress+(pMyRelocAddress[i]&0x0FFF);
            DWORD changeFoa = RVAToFileOffset(pFileBuffer,changeRVA);

            printf("changeRVA:%x   changeFoa: %x \n",changeRVA,changeFoa);

            if((pMyRelocAddress[i]&0xF000) == 0x3000)
            {
                //修改数据:
                PDWORD myAddress = (PDWORD)((DWORD)pFileBuffer + changeFoa);
                printf("myAddress: %x\n",*myAddress);
                *myAddress = *myAddress - 0x10000000 + 0x20000000;
                printf("change :myAddress: %x\n",*myAddress);
            }
        }
        pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize);
    }

    //写出dll
    //确定大小
    LPVOID pFileBuffer_Start = pFileBuffer;
    DWORD FileSize = pSectionHeader_LAST->PointerToRawData + pSectionHeader_LAST->SizeOfRawData;    
    WirteToFile(pFileBuffer,FileSize,"C://changeDll.dll");

}



void TestPrintImportDirectory(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }
    
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;
    PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    pDataDirectory = pOptionHeader->DataDirectory;

    //IMAGE_DIRECTORY_ENTRY_IMPORT 
    /*
    #define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
    #define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
    */
    
    //确定导入表
    //pImportDirectory = NULL;
    IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
    
    DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress;
    DWORD ImportFoa = RVAToFileOffset(pFileBuffer,ImportVirtualAddress);

    printf("ImportVirtualAddress: %x \n",ImportVirtualAddress);
    printf("Size: %x \n",pImportDirectory.Size);
    printf("ImportFoa: %x \n",ImportFoa);

    //输出所有的导入表
    //PIMAGE_THUNK_DATA32 pThunkData = NULL;
    //第一个导入表
    PIMAGE_IMPORT_DESCRIPTOR pImportDes = NULL;
    pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + ImportFoa);
    
    while(pImportDes->OriginalFirstThunk != 0x0 && pImportDes->FirstThunk != 0x0 )
    {
        //输出所有的dll
        printf("OriginalFirstThunk: %x\n",pImportDes->OriginalFirstThunk);
        DWORD pNameAddress =  RVAToFileOffset(pFileBuffer,pImportDes->Name);
        PSTR pDllName = (PSTR)((DWORD)pFileBuffer + pNameAddress);
        printf("name: %s \n",pDllName);
        printf("------------------------------------------\n");
        //输出OriginalFirstThunk的信息
        DWORD Thunk_Address = RVAToFileOffset(pFileBuffer,pImportDes->OriginalFirstThunk);
        PIMAGE_THUNK_DATA32 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + Thunk_Address);
        
        //根据pThunkData 的最高为来判断
        DWORD ImportOrdinal = pThunkData->u1.Ordinal;
        while(ImportOrdinal)
        {
            //输出所有所有的信息
            //#define IMAGE_ORDINAL_FLAG32 0x80000000
            if(ImportOrdinal & IMAGE_ORDINAL_FLAG32)
            {
                printf("按序号导入:%x\n",ImportOrdinal&0x0FFF);
            }else
            {
                DWORD ImageNameAddress  = RVAToFileOffset(pFileBuffer,ImportOrdinal);
                PIMAGE_IMPORT_BY_NAME pImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+ImageNameAddress);
                printf("按名字导入:%x - %s \n",pImageName->Hint,pImageName->Name);
            }
            //向下移动
            pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pThunkData + 4);
            ImportOrdinal = pThunkData->u1.Ordinal;
        }

        printf("------------------------------------------\n");
        //printf("FirstThunk:%x \n",pImportDes->FirstThunk);
        DWORD pFirstThunk = (DWORD)pImportDes->FirstThunk;
        printf("FirstThunk:%x \n",pImportDes->FirstThunk);
    
        printf("------------------------------------------\n");
        
        DWORD FirstThunk_Address = RVAToFileOffset(pFileBuffer,pFirstThunk);
        PIMAGE_THUNK_DATA32 pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + FirstThunk_Address);

        DWORD newImportOrdinal = pNewThunkData->u1.Ordinal;
        while(newImportOrdinal)
        {
            //输出所有所有的信息
            //#define IMAGE_ORDINAL_FLAG32 0x80000000
            if(newImportOrdinal & IMAGE_ORDINAL_FLAG32)
            {
                printf("按序号导入:%x\n",newImportOrdinal&0x0FFF);
            }else
            {
                DWORD newImageNameAddress  = RVAToFileOffset(pFileBuffer,newImportOrdinal);
                PIMAGE_IMPORT_BY_NAME pNewImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+newImageNameAddress);
                printf("按名字导入:%x - %s \n",pNewImageName->Hint,pNewImageName->Name);
            }
            //向下移动
            pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pNewThunkData + 4);
            newImportOrdinal = pNewThunkData->u1.Ordinal;
        }

        printf("------------------------------------------\n");
        pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDes + 20);

        //getchar();
    }
}

void TestPrintBindImportDirectory(LPSTR lpszFile)
{
    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }
    
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;
    PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    pDataDirectory = pOptionHeader->DataDirectory;

    //IMAGE_DIRECTORY_ENTRY_IMPORT 
    /*
        #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
        #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers
    */
    
    //确定导入表
    //pImportDirectory = NULL;
    IMAGE_DATA_DIRECTORY pBindImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT];
    
    DWORD BindImportVirtualAddress = pBindImportDirectory.VirtualAddress;
    DWORD BindImportFoa = BindImportVirtualAddress;

    /*
    printf("BindImportVirtualAddress: %x \n",BindImportVirtualAddress);
    printf("Size: %x \n",pBindImportDirectory.Size);
    printf("BindImportFoa: %x \n",BindImportFoa);
    */
    PIMAGE_BOUND_IMPORT_DESCRIPTOR pBindImport = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + BindImportFoa);

    while(pBindImport->TimeDateStamp !=0x0)
    {
        //输出第一个绑定
        DWORD bindTime = pBindImport->TimeDateStamp;
        WORD ModuleName = pBindImport->OffsetModuleName;
        WORD numberModule = pBindImport->NumberOfModuleForwarderRefs;
        
        //输出名字
        PSTR pModuleName = (PSTR)((DWORD)pFileBuffer+(DWORD)BindImportVirtualAddress+ModuleName);
        printf("ModuleName:%s \n",pModuleName);
        printf("--numberModule:%x \n",numberModule);

        for(int i=0;i<numberModule;i++)
        {
            PIMAGE_BOUND_FORWARDER_REF pBoundRef = (PIMAGE_BOUND_FORWARDER_REF)((DWORD)pBindImport+i*8);
            pBindImport =  (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pBindImport+i*8);

            //输出名字
            DWORD refTime = pBoundRef->TimeDateStamp;
            WORD refName = pBoundRef->OffsetModuleName;
            PSTR pRefName = (PSTR)((DWORD)pFileBuffer+(DWORD)BindImportVirtualAddress+refName);    
            printf("        RefName:%s \n",pRefName);
        }

        pBindImport =  (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pBindImport+8);
    }
}

void TestPrintResourceICO(LPSTR lpszFile)
{

    LPVOID pFileBuffer = NULL;
    pFileBuffer= ReadPEFile(lpszFile);
    if(!pFileBuffer)
    {
        printf("文件读取失败\n");
        return;
    }
    
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;
    PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
    //Header信息
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
    pDataDirectory = pOptionHeader->DataDirectory;

    //IMAGE_DATA_DIRECTORY pBindImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT];
    IMAGE_DATA_DIRECTORY ResourceDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
    
    DWORD ResourceVirtualAddress = ResourceDirectory.VirtualAddress;
    DWORD ResourceSize = ResourceDirectory.Size;

    printf("ResourceVirtualAddress : %x \n",ResourceVirtualAddress);
    printf("ResourceSize: %x \n",ResourceSize);
    
    /*
        typedef struct _IMAGE_RESOURCE_DIRECTORY {
            DWORD   Characteristics;
            DWORD   TimeDateStamp;
            WORD    MajorVersion;
            WORD    MinorVersion;
            WORD    NumberOfNamedEntries;
            WORD    NumberOfIdEntries;
        //  IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
        } IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;

      //第一个导入表
    PIMAGE_IMPORT_DESCRIPTOR pImportDes = NULL;
    pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + ImportFoa);
    */
    DWORD dwFoa = RVAToFileOffset(pFileBuffer,ResourceVirtualAddress);
    PIMAGE_RESOURCE_DIRECTORY  pResource = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + dwFoa);
    //输出PIMAGE_RESOURCE_DIRECTORY 的信息
    
    printf("NumberOfNamedEntries: %x \n",pResource->NumberOfNamedEntries);
    printf("NumberOfIdEntries: %x \n",pResource->NumberOfIdEntries);

    //第一层类型的解析
    //第一个资源表
    PIMAGE_RESOURCE_DIRECTORY_ENTRY pResdirectoryEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResource + sizeof(IMAGE_RESOURCE_DIRECTORY));
    DWORD NumberOfResType  =  pResource->NumberOfNamedEntries + pResource->NumberOfIdEntries;

    //找到图标资源
    PIMAGE_RESOURCE_DIRECTORY pResICODir=NULL;
    

    for(DWORD i=0;i<NumberOfResType;i++)
    {
        //解析内容:
        DWORD NameIsString = pResdirectoryEntry->NameIsString;
        DWORD ResName = pResdirectoryEntry->Name;
        DWORD OffsetToData = pResdirectoryEntry->OffsetToData;
        DWORD DataIsDirectory = pResdirectoryEntry->DataIsDirectory;
        
        //printf("Info: %d -NameIsString: %d - Name: %x -- OffToDa: %x - IsD - %d \n",i+1,
            //NameIsString,ResName,OffsetToData,DataIsDirectory);

        if(ResName == 0x3)
        {
            //PIMAGE_RESOURCE_DIRECTORY  pResource = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + dwFoa);
            pResICODir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource +pResdirectoryEntry->OffsetToDirectory);
            break;
        }

        pResdirectoryEntry  = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResdirectoryEntry + 8);
    }
    
    


    //IMAGE_RESOURCE_DIR_STRING_U;
    /*
    NameIsString = 1 的时候指向的结构

    typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
        WORD    Length;
        WCHAR   NameString[ 1 ];
    } IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
    
  */
    
    //确定图标的地址,找第二层
    DWORD NumberOffICO = pResICODir->NumberOfIdEntries + pResICODir->NumberOfNamedEntries;
    printf("NumberOffICO : %d \n",NumberOffICO);

    /*
        typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
            union {
                struct {
                    DWORD NameOffset:31;
                    DWORD NameIsString:1;
                };
                DWORD   Name;
                WORD    Id;
            };
            union {
                DWORD   OffsetToData;
                struct {
                    DWORD   OffsetToDirectory:31;
                    DWORD   DataIsDirectory:1;
                };
            };
        } IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
    */

    //第一个图标描述
    PIMAGE_RESOURCE_DIRECTORY_ENTRY pICOEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResICODir + sizeof(IMAGE_RESOURCE_DIRECTORY));
    
    PIMAGE_RESOURCE_DIRECTORY pICOContent = NULL;

    for(DWORD j = 0;j<NumberOffICO;j++)
    {
        //解析内容:
        DWORD NameIsString = pICOEntry->NameIsString;
        DWORD ResName = pICOEntry->Name;
        DWORD OffsetToData = pICOEntry->OffsetToData;
        DWORD DataIsDirectory = pICOEntry->DataIsDirectory;
        
        printf("Info: %d -NameIsString: %d - Name: %x -- OffToDa: %x - IsD - %d \n",i+1,
            NameIsString,ResName,OffsetToData,DataIsDirectory);
    
        //依次解析页码表
        pICOContent = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource +pICOEntry->OffsetToDirectory);
        //页码表解析
        DWORD NumberOfICOContent = pICOContent->NumberOfIdEntries + pICOContent->NumberOfNamedEntries;
        printf("NumberOfICOContent: %d \n",NumberOfICOContent);
        //图标测试只有一个,不循环测试
        //找到关键点:
        PIMAGE_RESOURCE_DIRECTORY_ENTRY pICOGetVS =  (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pICOContent + sizeof(IMAGE_RESOURCE_DIRECTORY));
        //找到图标资源的VistrualAddress 和 Size
        PIMAGE_DATA_DIRECTORY pDataIco = (PIMAGE_DATA_DIRECTORY)((DWORD)pResource + pICOGetVS->OffsetToDirectory);
        //输出每个图标信息
        printf("VirtualAddress: %x, Size: %x \n",pDataIco->VirtualAddress,pDataIco->Size);
        pICOEntry  = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pICOEntry + 8);
    }
}

猜你喜欢

转载自www.cnblogs.com/ShiningArmor/p/11693422.html