zoukankan      html  css  js  c++  java
  • 【转】别人写的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("分配空间失败!
    ");
            fclose(pFile);
            return NULL;
        }
        
        //文件读取
        
        size_t n = fread(pFileBuffer,fileSize,1,pFile);
        
        if(!n)
        {
            printf("读取数据失败
    ");
            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
    ",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("文件读取失败
    ");
            return;
        }
        
        //MZ标志
        if(*((PWORD)pFileBuffer)!=IMAGE_DOS_SIGNATURE)
        {
            printf("不是有效的MZ标志
    ");
            free(pFileBuffer);
            return;
        }
        
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        
        //打印DOS头
        printf("------------DOS头------------
    ");
        printf("MZ标志: %x
    ",pDosHeader->e_magic);
        printf("PE偏移: %x
    ",pDosHeader->e_lfanew);
    
        //判断是否是有效的PE 
        if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew))!=IMAGE_NT_SIGNATURE)
        {
            printf("不是有效的PE标志
    ");
            free(pFileBuffer);
            return;
        }
    
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
    
        //打印NT头
        printf("------------NT头------------
    ");
        printf("Signature: %x
    ",pNTHeader->Signature);
        pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
        printf("------------标准PE头--------
    ");
        printf("Machine: %x
    ",pPEHeader->Machine);
        printf("节的数量: %x
    ",pPEHeader->NumberOfSections);
        printf("SizeOfOptionHeaders: %x
    ",pPEHeader->SizeOfOptionalHeader);
    
        //可选择PE头
        pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
        printf("------------OPTION_PE头--------
    ");
        printf("Machine: %x 
    ",pOptionHeader->Magic);
        printf("OEP: %x 
    ",pOptionHeader->AddressOfEntryPoint);
        printf("ImageBase: %x 
    ",pOptionHeader->ImageBase);
        printf("SectionAlignment: %x 
    ",pOptionHeader->SectionAlignment);
        printf("FileAlignment: %x 
    ",pOptionHeader->FileAlignment);
        printf("SizeOfImage: %x 
    ",pOptionHeader->SizeOfImage);
        printf("SizeOfHeaders: %x 
    ",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--------
    ",i+1);
            printf("Name: %s 
    ",pSectionHeader->Name);
            printf("VirualSize : %x
    ",pSectionHeader->Misc);
            printf("VirualAddress: %x
    ",pSectionHeader->VirtualAddress);
            printf("SizeOfRawData: %x 
    ",pSectionHeader->SizeOfRawData);
            printf("PointerToRowData: %x 
    ",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("文件读取失败
    ");
            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分配空间失败!
    ");
            return NULL;
        }
        //printf("%x 
    ",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 
    ",pFileBuffer_sec);
        //printf("pImageBuffer_sec: %x 
    ",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 
    ",pFileBuffer_sec);
            //printf("pImageBuffer_sec: %x 
    ",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 
    ",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 
    ",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("文件读取失败
    ");
            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
    ",pSectionHeader->Misc);
            //printf("VirualAddress: %x
    ",pSectionHeader->VirtualAddress);
            
            DWORD dumpVirualSize = pSectionHeader->Misc.VirtualSize;
            DWORD dumpVirualAddress = pSectionHeader->VirtualAddress;
    
            if(dwRva>=dumpVirualAddress && dwRva <=dumpVirualAddress+dumpVirualSize)
            {
                //printf("地址在第:%d 节 %s 
    ",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("文件读取失败
    ");
            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 
    ",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("文件读取失败
    ");
            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
    ");
            free(pFileBuffer);
            return;
        }
    
        //size_t file_size = pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize;
        //printf("%x 
    ",file_size);
    
        //2代码加的位置
        printf("pImageBuffer: %x
    ",pImageBuffer);
        DWORD shellLocation =  pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize;
        //确定位置
        LPVOID pShellLoc = (LPVOID)((DWORD)pImageBuffer + shellLocation);
        printf("pShellLoc: %x
    ",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("文件读取失败
    ");
            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("没有可用空间填充节表
    ");
            free(pFileBuffer);
            return;
        }
        
        printf("空间:%d
    ",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
    ",pFileBuffer);
        printf("pSectionHeader: %x
    ",pSectionHeader);
        printf("pSectionHeader_LAST: %x
    ",pSectionHeader_LAST);
        printf("pSectionHeader_ADD: %x
    ",pSectionHeader_ADD);
        printf("pSectionEND: %x
    ",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 
     ",pSectionHeader_ADD->PointerToRawData+pSectionHeader_ADD->SizeOfRawData);
    
        size_t writeSize = fwrite(pFileBuffer,pSectionHeader_ADD->PointerToRawData,1,pOutFile);
        printf("WirteSize:%d
    ",writeSize);
        //写出第二部分
        LPVOID pNewBuffer=(LPVOID)malloc(0x1000);
        if(pNewBuffer==NULL)
        {
            printf("pNewBuffer分配空间失败
    ");
            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("文件读取失败
    ");
            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 
     ",fileLength);
    
        size_t writeSize = fwrite(pFileBuffer,fileLength,1,pOutFile);
        printf("WirteSize:%d
    ",writeSize);
        //写出第二部分
        LPVOID pNewBuffer=(LPVOID)malloc(0x1000);
        if(pNewBuffer==NULL)
        {
            printf("pNewBuffer分配空间失败
    ");
            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("文件读取失败
    ");
            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 
    ",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("文件读取失败
    ");
            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 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
        
        printf("IMAGE_DIRECTORY_ENTRY_IMPORT: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_RESOURCE: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_EXCEPTION: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_SECURITY: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size);
        
        printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_DEBUG: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_ARCHITECTURE: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_GLOBALPTR: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_TLS: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_IAT: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT: Address: %x ,Size: %x 
    ",DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress,
            DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size);
    
        printf("IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: Address: %x ,Size: %x 
    ",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("文件读取失败
    ");
            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 
    ",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 
    ",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
    ",pExDirectory->Characteristics);
        printf("TimeDateStamp: %x
    ",pExDirectory->TimeDateStamp);
        printf("MajorVersion: %x
    ",pExDirectory->MajorVersion);
        printf("MinorVersion: %x
    ",pExDirectory->MinorVersion);
        printf("Name: %x
    ",pExDirectory->Name);
        printf("Base: %x
    ",pExDirectory->Base);
        printf("NumberOfFunctions: %x
    ",pExDirectory->NumberOfFunctions);
        printf("NumberOfNames: %x
    ",pExDirectory->NumberOfNames);
        printf("AddressOfFunctions: %x
    ",pExDirectory->AddressOfFunctions);
        printf("AddressOfNames: %x
    ",pExDirectory->AddressOfNames);
        printf("AddressOfNameOrdinals: %x
    ",pExDirectory->AddressOfNameOrdinals);
        
        printf("------------------------
    ");
        //输出函数地址表信息
        //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 
    ",k,*pExAddressOfFunctions);
            pExAddressOfFunctions++;
        }
        printf("------------------------
    ");
        //函数名称表
        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   
    ",k,*pExAddressOfNames);
            //函数名的地址转换为FoA ,输出函数名
            PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames);
            //输出函数名
            printf("%s 
    ",(char*)((DWORD)pFileBuffer + (DWORD)NameAddress));
            pExAddressOfNames++;
        }
        
        //函数序号表
        printf("------------------------
    ");
        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   
    ",k,*pExAddressOfNameOrdinals);
            pExAddressOfNameOrdinals++;
        }
    }
    
    DWORD GetFunctionAddrByName(LPVOID pFileBuffer,LPSTR FunctionName)
    {
        //LPVOID pFileBuffer = NULL;
        //pFileBuffer= ReadPEFile(lpszFile);
        if(!pFileBuffer)
        {
            printf("文件读取失败
    ");
            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 
    ",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 
    ",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("------------------------
    ");
        
    
        //输出每个函数地址表信息
        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   
    ",k,*pExAddressOfNames);
            //函数名的地址转换为FoA ,输出函数名
            PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames);
            //输出函数名
            //printf("%s 
    ",(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
    ",FunctionName);
        printf("Location_Fun: %d 
    ",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 
    ",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("文件读取失败
    ");
            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 
    ",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 
    ",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("文件读取失败
    ");
            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 
    ",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  
    ",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
    ",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("文件读取失败
    ");
            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("没有可用空间填充节表
    ");
            free(pFileBuffer);
            return;
        }
        
        printf("空间:%d
    ",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 
     ",pSectionHeader_ADD->PointerToRawData+pSectionHeader_ADD->SizeOfRawData);
    
        size_t writeSize = fwrite(pFileBuffer,pSectionHeader_ADD->PointerToRawData,1,pOutFile);
        printf("WirteSize:%d
    ",writeSize);
        //写出第二部分
        LPVOID pNewBuffer=(LPVOID)malloc(0x2000);
        if(pNewBuffer==NULL)
        {
            printf("pNewBuffer分配空间失败
    ");
            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 
    ",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 
    ",pRelocData,sizeOfRelocDirectory);
    
        //memcpy(myRelocLoc,pRelocData,sizeOfRelocDirectory);
        LPVOID destStart = (LPVOID)((DWORD)pFileBuffer + (DWORD)myRelocLoc);
        printf("pFileBuffer:%x, myRelocLoc: %x 
    ",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("文件读取失败
    ");
            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 
    ",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  
    ",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
    ",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 
    ",changeRVA,changeFoa);
    
                if((pMyRelocAddress[i]&0xF000) == 0x3000)
                {
                    //修改数据:
                    PDWORD myAddress = (PDWORD)((DWORD)pFileBuffer + changeFoa);
                    printf("myAddress: %x
    ",*myAddress);
                    *myAddress = *myAddress - 0x10000000 + 0x20000000;
                    printf("change :myAddress: %x
    ",*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("文件读取失败
    ");
            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 
    ",ImportVirtualAddress);
        printf("Size: %x 
    ",pImportDirectory.Size);
        printf("ImportFoa: %x 
    ",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
    ",pImportDes->OriginalFirstThunk);
            DWORD pNameAddress =  RVAToFileOffset(pFileBuffer,pImportDes->Name);
            PSTR pDllName = (PSTR)((DWORD)pFileBuffer + pNameAddress);
            printf("name: %s 
    ",pDllName);
            printf("------------------------------------------
    ");
            //输出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
    ",ImportOrdinal&0x0FFF);
                }else
                {
                    DWORD ImageNameAddress  = RVAToFileOffset(pFileBuffer,ImportOrdinal);
                    PIMAGE_IMPORT_BY_NAME pImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+ImageNameAddress);
                    printf("按名字导入:%x - %s 
    ",pImageName->Hint,pImageName->Name);
                }
                //向下移动
                pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pThunkData + 4);
                ImportOrdinal = pThunkData->u1.Ordinal;
            }
    
            printf("------------------------------------------
    ");
            //printf("FirstThunk:%x 
    ",pImportDes->FirstThunk);
            DWORD pFirstThunk = (DWORD)pImportDes->FirstThunk;
            printf("FirstThunk:%x 
    ",pImportDes->FirstThunk);
        
            printf("------------------------------------------
    ");
            
            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
    ",newImportOrdinal&0x0FFF);
                }else
                {
                    DWORD newImageNameAddress  = RVAToFileOffset(pFileBuffer,newImportOrdinal);
                    PIMAGE_IMPORT_BY_NAME pNewImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+newImageNameAddress);
                    printf("按名字导入:%x - %s 
    ",pNewImageName->Hint,pNewImageName->Name);
                }
                //向下移动
                pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pNewThunkData + 4);
                newImportOrdinal = pNewThunkData->u1.Ordinal;
            }
    
            printf("------------------------------------------
    ");
            pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDes + 20);
    
            //getchar();
        }
    }
    
    void TestPrintBindImportDirectory(LPSTR lpszFile)
    {
        LPVOID pFileBuffer = NULL;
        pFileBuffer= ReadPEFile(lpszFile);
        if(!pFileBuffer)
        {
            printf("文件读取失败
    ");
            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 
    ",BindImportVirtualAddress);
        printf("Size: %x 
    ",pBindImportDirectory.Size);
        printf("BindImportFoa: %x 
    ",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 
    ",pModuleName);
            printf("--numberModule:%x 
    ",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 
    ",pRefName);
            }
    
            pBindImport =  (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pBindImport+8);
        }
    }
    
    void TestPrintResourceICO(LPSTR lpszFile)
    {
    
        LPVOID pFileBuffer = NULL;
        pFileBuffer= ReadPEFile(lpszFile);
        if(!pFileBuffer)
        {
            printf("文件读取失败
    ");
            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 
    ",ResourceVirtualAddress);
        printf("ResourceSize: %x 
    ",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 
    ",pResource->NumberOfNamedEntries);
        printf("NumberOfIdEntries: %x 
    ",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 
    ",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 
    ",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 
    ",i+1,
                NameIsString,ResName,OffsetToData,DataIsDirectory);
        
            //依次解析页码表
            pICOContent = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource +pICOEntry->OffsetToDirectory);
            //页码表解析
            DWORD NumberOfICOContent = pICOContent->NumberOfIdEntries + pICOContent->NumberOfNamedEntries;
            printf("NumberOfICOContent: %d 
    ",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 
    ",pDataIco->VirtualAddress,pDataIco->Size);
            pICOEntry  = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pICOEntry + 8);
        }
    }
  • 相关阅读:
    STL hashtable杂谈
    生成器模式——创建型模式(3)
    JNuit4实战技巧总结
    抽象工厂方法模式——创建型模式(2)
    原型模式——创建型模式(4)
    几个经典同步问题的思考
    工厂方法模式——创建型模型(1)
    HDU 2050 折线分割平面 简单动态规划
    HDU 2084 数塔 简单动态规划
    HDU 2018 母牛的故事 简单动态规划
  • 原文地址:https://www.cnblogs.com/ShiningArmor/p/11693422.html
Copyright © 2011-2022 走看看