zoukankan      html  css  js  c++  java
  • PE各种操作

    #include<stdio.h>
    #include<stdlib.h>
    #include<Windows.h>
    #pragma warning(disable:4996)
    
    #define FILEPATH_IN "D:\IPMSG2007.exe"
    #define FILEPATH_OUT "D:\Dll2.dll"
    #define FILEPATH "D:\Dll3.dll"
    #define SHELLCODELENGTH 12
    #define MESSAGEBOXADDR 0x76A885D0
    #define INFILEPATH "D:\IPMSG2007.exe"
    
    BYTE shellCode[] = {
        0x6A, 00, 0x6A, 00, 0x6A, 00, 0x6A, 00,
        0xE8, 00, 00, 00, 00,
        0xE9, 00, 00, 00, 00
    };
    //函数声明                                
    //**************************************************************************                                
    //ReadPEFile:将文件读取到缓冲区                                
    //参数说明:                                
    //lpszFile 文件路径                                
    //pFileBuffer 缓冲区指针                                
    //返回值说明:                                
    //读取失败返回0  否则返回实际读取的大小                                
    //**************************************************************************                                
    DWORD ReadPEFile(IN LPSTR lpszFile, OUT LPVOID* pFileBuffer);
    //**************************************************************************                                
    //CopyFileBufferToImageBuffer:将文件从FileBuffer复制到ImageBuffer                                
    //参数说明:                                
    //pFileBuffer  FileBuffer指针                                
    //pImageBuffer ImageBuffer指针                                
    //返回值说明:                                
    //读取失败返回0  否则返回复制的大小                                
    //**************************************************************************                                
    DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer);
    //**************************************************************************                                
    //CopyImageBufferToNewBuffer:将ImageBuffer中的数据复制到新的缓冲区                                
    //参数说明:                                
    //pImageBuffer ImageBuffer指针                                
    //pNewBuffer NewBuffer指针                                
    //返回值说明:                                
    //读取失败返回0  否则返回复制的大小                                
    //**************************************************************************                                
    DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer,OUT LPVOID* pNewBuffer);
    //**************************************************************************                                
    //MemeryTOFile:将内存中的数据复制到文件                                
    //参数说明:                                
    //pMemBuffer 内存中数据的指针                                
    //size 要复制的大小                                
    //lpszFile 要存储的文件路径                                
    //返回值说明:                                
    //读取失败返回0  否则返回复制的大小                                
    //**************************************************************************                                
    BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile);
    //**************************************************************************                                
    //RvaToFileOffset:将内存偏移转换为文件偏移                                
    //参数说明:                                
    //pFileBuffer FileBuffer指针                                
    //dwRva RVA的值                                
    //返回值说明:                                
    //返回转换后的FOA的值  如果失败返回0                                
    //**************************************************************************                                
    DWORD RvaToFileOffset(IN LPVOID pFileBuffer, IN DWORD dwRva);
    
    
    DWORD ReadPEFile(IN LPSTR lpszFile, OUT LPVOID* pFileBuffer)
    {
        FILE* fp = fopen(lpszFile, "rb");
        DWORD fileSize = 0;
        if (!fp)
        {
            printf("无法打开exe文件!");
            return 0;
        }
        fseek(fp, 0, SEEK_END);
        fileSize = ftell(fp);
        fseek(fp, 0, SEEK_SET);
    
        *pFileBuffer = malloc(fileSize);
        if (!(*pFileBuffer))
        {
            printf("分配空间失败!");
            fclose(fp);
            return 0;
        }
    
        size_t n = fread(*pFileBuffer, fileSize, 1, fp);
        if (!n)
        {
            printf("读取数据失败!");
            free(*pFileBuffer);
            fclose(fp);
            return 0;
        }
        fclose(fp);
        return n;
    }
    
    DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer)
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    
        if ((*(PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
        {
            printf("不是有效的MZ标志!");
            free(pFileBuffer);
            return 0;
        }
    
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
        {
            printf("不是有效的PE标志!");
            free(pFileBuffer);
            return 0;
        }
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
        pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
    
        *pImageBuffer = malloc(pOptionalHeader->SizeOfImage);
        if (!(*pImageBuffer))
        {
            printf("分配内存失败!");
            return 0;
        }
        memset(*pImageBuffer, 0, pOptionalHeader->SizeOfImage);
        memcpy(*pImageBuffer, pFileBuffer, pOptionalHeader->SizeOfHeaders);
        //printf("%c%c", *((char *)*pImageBuffer), *((char*)*pImageBuffer + 1));
        for (int i = 0; i < pFileHeader->NumberOfSections;i++)
        {
            memcpy((char *) *pImageBuffer + pSectionHeader->VirtualAddress,(char *) pFileBuffer + pSectionHeader->PointerToRawData,
                pSectionHeader->SizeOfRawData);
            pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER);
        }
        return pOptionalHeader->SizeOfImage;
    }
    
    DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer, OUT LPVOID* pNewBuffer)
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL, flag = NULL;
        
        if ((*(PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE)
        {
            printf("不是有效的MZ标志!");
            free(pImageBuffer);
            return 0;
        }
    
        pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
        if (*((PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
        {
            printf("不是有效的PE标志!");
            free(pImageBuffer);
            return 0;
        }
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
        pSectionHeader = flag = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
    
    
        int num = 0;
        for (int i = 0; i < pFileHeader->NumberOfSections; i++)
        {
            num += pSectionHeader->SizeOfRawData;
            pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER);
        }
        pSectionHeader = flag;
        num += pOptionalHeader->SizeOfHeaders;
        *pNewBuffer = malloc(num);
        memset(*pNewBuffer, 0, num);
        memcpy(*pNewBuffer, pImageBuffer, pOptionalHeader->SizeOfHeaders);
    
        for (int j = 0; j < pFileHeader->NumberOfSections; j++)
        {
            memcpy((char*)*pNewBuffer + pSectionHeader->PointerToRawData, (char*)pImageBuffer + pSectionHeader->VirtualAddress,
                pSectionHeader->SizeOfRawData);
            pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER);
        }
        //printf("%c %c %d
    ", *((char*)*pNewBuffer), *((char*)*pNewBuffer + 1), __LINE__);
        return num;
    }
    BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile)
    {
        FILE* fp;
        fp = fopen(lpszFile, "wb");
        if (!fp)
        {
            printf("打开文件失败!");
            return FALSE;
        }
    
        fwrite(pMemBuffer, size, 1, fp);
        fclose(fp);
        return TRUE;
    }
    
    VOID TestAddCodeInCodeSec()
    {
        LPVOID pFileBuffer = NULL;
        LPVOID pImageBuffer = NULL;
        LPVOID pNewBuffer = NULL;
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;
        PBYTE codeBegin = NULL;
        BOOL isOk = FALSE;
        DWORD size = 0;
    
        ReadPEFile(FILEPATH_IN, &pFileBuffer);
        if (!pFileBuffer)
        {
            printf("文件-->缓冲区失败!");
            return;
        }
        CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
        if (!pImageBuffer)
        {
            printf("FileBuffer-->ImageBuffer失败!");
            free(pFileBuffer);
            return;
        }
        pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(((DWORD)pDosHeader + pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER);
        pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + 0XE0);
        if (pSectionHeader->SizeOfRawData - pSectionHeader->Misc.VirtualSize < SHELLCODELENGTH)
        {
            printf("代码空闲区不够!");
            free(pFileBuffer);
            free(pImageBuffer);
    
        }
        codeBegin = (PBYTE)((DWORD)pImageBuffer + pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize);
        memcpy(codeBegin, shellCode, SHELLCODELENGTH);
        //修改E8 X
        DWORD callAddr = MESSAGEBOXADDR - (pOptionalHeader->ImageBase + (((DWORD)codeBegin + 0xD) - (DWORD)pImageBuffer));
        *(PDWORD)(codeBegin + 9) = callAddr;
        //修改E9 X
        DWORD jmpAddr = (pOptionalHeader->ImageBase + pOptionalHeader->AddressOfEntryPoint)
            - (pOptionalHeader->ImageBase + ((DWORD)codeBegin + SHELLCODELENGTH - (DWORD)pImageBuffer));
        *(PWORD)(codeBegin + 0xE) = jmpAddr;
    
        pOptionalHeader->AddressOfEntryPoint = (DWORD)codeBegin - (DWORD)pImageBuffer;
        size = CopyImageBufferToNewBuffer(pImageBuffer, &pNewBuffer);
        if (size == 0 || !pNewBuffer)
        {
            printf("ImageBuffer-->NewBuffer失败!");
            free(pFileBuffer);
            free(pImageBuffer);
            return;
        }
    
        isOk = MemeryTOFile(pNewBuffer, size, FILEPATH_OUT);
        if (isOk)
        {
            printf("存盘成功!");
    
        }
    }
    
    //添加节和节表
    DWORD AddSectionToFileBuffer()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;
        LPVOID pFileBuffer = NULL;
        DWORD addr = 0;
    
        ReadPEFile(FILEPATH_IN, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionalHeader + 1);
        if (pOptionalHeader->SizeOfHeaders - (pDosHeader->e_lfanew + 4 + 20 + pFileHeader->SizeOfOptionalHeader
            + pFileHeader->NumberOfSections * 0x28) < 80)
        {
            printf("节表后空间不足!");
            free(pFileBuffer);
            return;
        }
        PIMAGE_SECTION_HEADER pNewSectionHeader = pSectionHeader + (pFileHeader->NumberOfSections - 1);
        int sum = pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData + 0x1000;
        addr = pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData;
        LPVOID pNewBuffer = malloc(sum);
        memset((char *)pNewBuffer + pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData, 0x20, 0x1000);
        pFileHeader->NumberOfSections += 1;
        pOptionalHeader->SizeOfImage += 0x1000;
        PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + 4;
        memcpy(pLastSectionHeader, pSectionHeader, 0x28);
        strcpy(pLastSectionHeader->Name, ".tttt");
        pLastSectionHeader->Misc.VirtualSize = 0x1000;
        int size = (pNewSectionHeader->Misc.VirtualSize > pNewSectionHeader->SizeOfRawData) ? pNewSectionHeader->Misc.VirtualSize : pNewSectionHeader->SizeOfRawData;
        pLastSectionHeader->VirtualAddress = pNewSectionHeader->VirtualAddress + size;
        pLastSectionHeader->SizeOfRawData = 0x1000;
        pLastSectionHeader->PointerToRawData = pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData;
        //printf("%x
    ", pLastSectionHeader->PointerToRawData);
        memcpy(pNewBuffer, pFileBuffer, sum);
        
    
        free(pFileBuffer);
        if (MemeryTOFile(pNewBuffer, sum, FILEPATH_OUT))
        {
            printf("存盘成功!");
        }
        free(pNewBuffer);
        return addr;
    }
    
    
    //扩大最后一个节
    VOID ExpandLastSection()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;
        LPVOID pFileBuffer = NULL;
        LPVOID pNewBuffer = NULL;
    
        ReadPEFile(FILEPATH_IN, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionalHeader + 1);
        PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + pFileHeader->NumberOfSections - 1;
    
        pNewBuffer = malloc(pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData + 0x1000);
        memset((char*)pNewBuffer + pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData, 0x20, 0x1000);
        pOptionalHeader->SizeOfImage += 0x1000;
        pLastSectionHeader->Misc.VirtualSize = pLastSectionHeader->SizeOfRawData = pLastSectionHeader->SizeOfRawData + 0x1000;
        memcpy(pNewBuffer, pFileBuffer, pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData);
    
        if (MemeryTOFile(pNewBuffer, pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData + 0x1000
            , FILEPATH_OUT))
        {
            printf("存盘成功!");
        }
        free(pFileBuffer);
        free(pNewBuffer);
    }
    
    //合并所有节
    VOID MergeAllSection()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL, pNextSectionHeader = NULL;
        LPVOID pFileBuffer = NULL, pImageBuffer = NULL, pNewBuffer = NULL;
        ReadPEFile(FILEPATH_IN, &pFileBuffer);
        CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
    
        free(pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        pNextSectionHeader = pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionalHeader + 1);
    
        pSectionHeader->Misc.VirtualSize = pSectionHeader->SizeOfRawData = pOptionalHeader->SizeOfImage -
            pSectionHeader->VirtualAddress;
        for (int i = 0; i < pFileHeader->NumberOfSections; i++)
        {
            pSectionHeader->Characteristics = pSectionHeader->Characteristics | pNextSectionHeader->Characteristics;
            pNextSectionHeader += 1;
        }
        pFileHeader->NumberOfSections = 1;
        CopyImageBufferToNewBuffer(pImageBuffer, &pNewBuffer);
        if (MemeryTOFile(pNewBuffer, pOptionalHeader->SizeOfImage, FILEPATH_OUT))
        {
            printf("存盘成功!");
        }
        free(pImageBuffer);
        free(pNewBuffer);
    }
    
    DWORD RvaToFileOffset(IN LPVOID FileBuffer, IN DWORD Rva)
    {
        PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)FileBuffer;
        PIMAGE_NT_HEADERS pNT = (PIMAGE_NT_HEADERS)((DWORD)FileBuffer + pDOS->e_lfanew);
        PIMAGE_SECTION_HEADER pSECTION = (PIMAGE_SECTION_HEADER)(pNT + 1);
        int i;
        for (i = 0; i < pNT->FileHeader.NumberOfSections; i++, pSECTION++) {
            if (Rva >= pSECTION->VirtualAddress && Rva < pSECTION->VirtualAddress + pSECTION->SizeOfRawData) {
                return (Rva - pSECTION->VirtualAddress + pSECTION->PointerToRawData);
                break;
            }
        }
    
        return 0;
    }
    
    VOID PrintfExportImform()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;
        PIMAGE_EXPORT_DIRECTORY pExport = NULL;
        LPVOID pFileBuffer = NULL;
        DWORD pExportFileOffset = NULL;
    
        ReadPEFile(FILEPATH_IN, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        
        pExportFileOffset = pOptionalHeader->DataDirectory[0].VirtualAddress;
        pExportFileOffset = RvaToFileOffset(pFileBuffer, pExportFileOffset);
        pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + pExportFileOffset);
        //printf("%d", pExport->NumberOfFunctions);
        //函数地址
        DWORD FileOffOfFunctions = RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions);
        LPVOID pFunctionInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfFunctions);
        for (int i = 0; i < pExport->NumberOfFunctions; i++)
        {
            printf("%x
    ", *((PDWORD)pFunctionInFile));
            pFunctionInFile = (LPVOID)((DWORD)pFunctionInFile + 4);
        }
    
        //函数名称
        //AddressOfNames在文件中的偏移
        DWORD FileOffOfNames = RvaToFileOffset(pFileBuffer, pExport->AddressOfNames);
        //printf("%x", FileOffOfNames);
        //AddressOfNames在文件中的地址
        LPVOID pNamesInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfNames);
        //printf("%x", pNamesInFile);
        //AddressOfNames数组项在文件中的偏移
        DWORD OffsetOfNames;      
        LPVOID pNameInFile = NULL;
        //OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile)));
        for (int j = 0; j < pExport->NumberOfNames; j++)
        {
            OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile)));
            pNameInFile = (LPVOID)((DWORD)pFileBuffer + OffsetOfNames);
            printf("%s
    ", pNameInFile);
            pNamesInFile = (LPVOID)((DWORD)pNamesInFile + 4);
        }
        //函数序号
        DWORD OrdOffsetInFile = RvaToFileOffset(pFileBuffer, pExport->AddressOfNameOrdinals);
        LPVOID pOrdinalsInFile = (LPVOID)((DWORD)pFileBuffer + OrdOffsetInFile);
        for (int k = 0; k < pExport->NumberOfNames; k++)
        {
            printf("%d
    ", *((PWORD)pOrdinalsInFile));
            pOrdinalsInFile = (LPVOID)((DWORD)pOrdinalsInFile + 2);
        }
    } 
    
    VOID GetFunctionAddrByName(LPVOID pFileBuffer, char* funcName)
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;
        PIMAGE_EXPORT_DIRECTORY pExport = NULL;
        DWORD pExportFileOffset = NULL;
    
        //ReadPEFile(FILEPATH_IN, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
    
        pExportFileOffset = pOptionalHeader->DataDirectory[0].VirtualAddress;
        pExportFileOffset = RvaToFileOffset(pFileBuffer, pExportFileOffset);
        pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + pExportFileOffset);
        //printf("%d", pExport->NumberOfFunctions);
        
        //函数名称
        //AddressOfNames在文件中的偏移
        DWORD FileOffOfNames = RvaToFileOffset(pFileBuffer, pExport->AddressOfNames);
        //printf("%x", FileOffOfNames);
        //AddressOfNames在文件中的地址
        LPVOID pNamesInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfNames);
        //printf("%x", pNamesInFile);
        //AddressOfNames数组项在文件中的偏移
        DWORD OffsetOfNames;
        LPVOID pNameInFile = NULL;
        //OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile)));
        int j;
        for (j = 0; j < pExport->NumberOfNames; j++)
        {
            OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile)));
            pNameInFile = (LPVOID)((DWORD)pFileBuffer + OffsetOfNames);
            if( !strcmp(funcName, (char *)pNameInFile))
                break;
            pNamesInFile = (LPVOID)((DWORD)pNamesInFile + 4);
        }
        //函数序号
        DWORD OrdOffsetInFile = RvaToFileOffset(pFileBuffer, pExport->AddressOfNameOrdinals);
        LPVOID pOrdinalsInFile = (LPVOID)((DWORD)pFileBuffer + OrdOffsetInFile);
        pOrdinalsInFile = (LPVOID)((DWORD)pOrdinalsInFile + 2 * j);
        int flag = *((PWORD)pOrdinalsInFile);
        
    
    
        //函数地址
        DWORD FileOffOfFunctions = RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions);
        LPVOID pFunctionInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfFunctions);
        pFunctionInFile = (LPVOID)((DWORD)pFunctionInFile + 4 * flag);
            printf("%x
    ", *((PDWORD)pFunctionInFile));
        
    
    }
    
    VOID GetFunctionAddrByOrdinals(LPVOID pFileBuffer, int num)
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;
        PIMAGE_EXPORT_DIRECTORY pExport = NULL;
        DWORD pExportFileOffset = NULL;
    
        //ReadPEFile(FILEPATH_IN, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
    
        pExportFileOffset = pOptionalHeader->DataDirectory[0].VirtualAddress;
        pExportFileOffset = RvaToFileOffset(pFileBuffer, pExportFileOffset);
        pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + pExportFileOffset);
        //printf("%d", pExport->NumberOfFunctions);
    
        DWORD FileOffOfFunctions = RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions);
        LPVOID pFunctionInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfFunctions);
        pFunctionInFile = (LPVOID)((DWORD)pFunctionInFile + 4 * (num - pExport->Base));
        printf("%x
    ", *((PDWORD)pFunctionInFile));
    }
    
    //打印重定位表
    VOID PrintRelocation()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        LPVOID pFileBuffer = NULL;
        PIMAGE_BASE_RELOCATION pRelocation = NULL;
        DWORD offset = 0;
        ReadPEFile(FILEPATH_IN, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
    
        offset = RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress);
        pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + offset);
        int num = 0;
        int i = 0;
        LPVOID pDetails = NULL;
        while (1)
        {
            if (pRelocation->VirtualAddress == 0 && pRelocation->SizeOfBlock == 0)
                break;
            num = (pRelocation->SizeOfBlock - 8) / 2;
            printf("VirtualAddress:%x
    ", pRelocation->VirtualAddress);
            printf("SizeOfBlock:%d
    ", pRelocation->SizeOfBlock);
            printf("修改项:
    ");
            pDetails = (LPVOID)((DWORD)pRelocation + 8);
            for (i = 0; i < num; i++)
            {
                printf("%x
    ", *((PWORD)pDetails));
                pDetails = (LPVOID)((DWORD)pDetails + 2);
            
            }
            pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation + pRelocation->SizeOfBlock);
        }
    
    
    }
    
    DWORD FileFoaToRva(LPVOID pFileBuffer, DWORD foa)
    {
        PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(pNTHeader + 1);
        for (int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++, pSectionHeader++)
        {
            if (foa > pSectionHeader->PointerToRawData && foa <= pSectionHeader->PointerToRawData + pSectionHeader->SizeOfRawData)
                return (foa - pSectionHeader->PointerToRawData + pSectionHeader->VirtualAddress);
        }
    
        return 0;
    
    }
    VOID MoveExport()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_EXPORT_DIRECTORY pExport = NULL;
        LPVOID pFileBuffer = NULL;
        LPVOID pAddrOfFunc = NULL;
        LPVOID pAddrOfNames = NULL;
        LPVOID pAddrOfOri = NULL;
        LPVOID pCurrent = NULL;
        LPVOID pFunc = NULL;
        LPVOID pNames = NULL;
        LPVOID pOrdinals = NULL;
        LPVOID pNamesInFile = NULL;
        LPVOID pAddrName = NULL;
        int sum = 0;
        DWORD addr = AddSectionToFileBuffer();
        sum = addr + 0x1000;
        ReadPEFile(FILEPATH_OUT, &pFileBuffer);
    
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        
        DWORD Foa = RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[0].VirtualAddress);
        pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa);
    
        pAddrOfFunc = (LPVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions));
        pAddrOfNames = (LPVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExport->AddressOfNames));
        pAddrOfOri = (LPVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExport->AddressOfNameOrdinals));
        
        pFunc = pCurrent = (LPVOID)((DWORD)pFileBuffer + addr);
        memcpy(pCurrent, pAddrOfFunc, 4 * pExport->NumberOfFunctions);
    
        pOrdinals = pCurrent = (LPVOID)((DWORD)pCurrent + 4 * pExport->NumberOfFunctions);
        memcpy(pCurrent, pAddrOfOri, 2 * pExport->NumberOfNames);
    
        pNames = pAddrName = pCurrent = (LPVOID)((DWORD)pCurrent + 2 * pExport->NumberOfNames);
        memcpy(pCurrent, pAddrOfNames, 4 * pExport->NumberOfNames);
        
        pCurrent = (LPVOID)((DWORD)pCurrent + 4 * pExport->NumberOfNames);
        for (int i = 0; i < pExport->NumberOfNames; i++)
        {
            Foa = RvaToFileOffset(pFileBuffer,(DWORD) (*((PDWORD)pAddrOfNames)));
            pNamesInFile = (LPVOID)((DWORD)pFileBuffer + Foa);
            strcpy((char*)pCurrent, (char*)pNamesInFile);
            *((PDWORD)pAddrName) = FileFoaToRva(pFileBuffer,(DWORD)pCurrent - (DWORD)pFileBuffer);
            pCurrent = (LPVOID)((DWORD)pCurrent + strlen((char*)pNamesInFile) + 1);
            pAddrName = (LPVOID)((DWORD)pAddrName + 4);
            pAddrOfNames = (LPVOID)((DWORD)pAddrOfNames + 4);
        }
        memcpy(pCurrent, pExport, 0x28);
        pExport = (PIMAGE_EXPORT_DIRECTORY)pCurrent;
        pExport->AddressOfFunctions = FileFoaToRva(pFileBuffer, (DWORD)pFunc - (DWORD)pFileBuffer);
        pExport->AddressOfNames = FileFoaToRva(pFileBuffer, (DWORD)pNames - (DWORD)pFileBuffer);
        pExport->AddressOfNameOrdinals = FileFoaToRva(pFileBuffer, (DWORD)pOrdinals - (DWORD)pFileBuffer);
        pOptionalHeader->DataDirectory[0].VirtualAddress = FileFoaToRva(pFileBuffer,(DWORD)pCurrent - (DWORD)pFileBuffer);
        MemeryTOFile(pFileBuffer, sum, FILEPATH);
    }
    
    DWORD MoveRelo()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_BASE_RELOCATION pRelocation = NULL;
        LPVOID pFileBuffer = NULL;
        LPVOID pNewBuffer = NULL;
        LPVOID pNewRe = NULL;
        int sum = 0;
        DWORD addr = AddSectionToFileBuffer();
        sum = addr + 0x1000;
        ReadPEFile(FILEPATH_OUT, &pFileBuffer);
                 
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress));
        pNewRe = pNewBuffer = (LPVOID)((DWORD)pFileBuffer + addr);
        
        while (1)
        {
            if (pRelocation->SizeOfBlock == 0 && pRelocation->VirtualAddress == 0)
            {
                memcpy(pNewBuffer, pRelocation, 8);
                break;
            }
            memcpy(pNewBuffer, pRelocation, pRelocation->SizeOfBlock);
            pNewBuffer = (LPVOID)((DWORD)pNewBuffer + pRelocation->SizeOfBlock);
            pRelocation = (LPVOID)((DWORD)pRelocation + pRelocation->SizeOfBlock);
        }
        pOptionalHeader->DataDirectory[5].VirtualAddress = FileFoaToRva(pFileBuffer, (DWORD)pNewRe - (DWORD)pFileBuffer);
    
        MemeryTOFile(pFileBuffer, sum, FILEPATH);
        return addr;
    }
    
    VOID FixRelocation()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_BASE_RELOCATION pRelocation = NULL;
        LPVOID pFileBuffer = NULL;
        LPVOID pr = NULL;
        LPVOID offset = NULL;
        int addr = MoveRelo();
        int sum = 0, howMany = 0;
        sum = addr + 0x1000;
        //printf("%x
    ", addr);
        ReadPEFile(FILEPATH, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        //printf("%x
    ", RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress));
        pr = pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress));
    
        pOptionalHeader->ImageBase += 0x1000;
        int i = 0;
        while (1)
        {
            if (pRelocation->VirtualAddress == 0 && pRelocation->SizeOfBlock == 0)
                break;
            howMany = (pRelocation->SizeOfBlock - 8) / 2;
            for (i = 0; i < howMany; i++)
            {
                pr = (LPVOID)((DWORD)pRelocation + 8);
                if (*((PWORD)pr) >> 12 == 3)
                {
                    offset = (LPVOID)(RvaToFileOffset(pFileBuffer, (pRelocation->VirtualAddress + 
                        (*((PWORD)pr) & 0xfff))) + (DWORD)pFileBuffer);
                    *((PDWORD)offset) += 0x1000;
                }
                pr = (LPVOID)((DWORD)pr + 2);
            }
            pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation + pRelocation->SizeOfBlock);
        }
        MemeryTOFile(pFileBuffer, sum, FILEPATH);
    
    }
    
    VOID PrintImportTable()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        LPVOID pFileBuffer = NULL;
        PIMAGE_IMPORT_DESCRIPTOR pImport = NULL;
        PIMAGE_IMPORT_BY_NAME pName = NULL;
        DWORD addrOfOri = 0;
        int i = 0;
    
        ReadPEFile(FILEPATH_IN, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + 
            RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[1].VirtualAddress));
        addrOfOri = (DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pImport->OriginalFirstThunk);
        while (1)
        {
            if (pImport->OriginalFirstThunk == 0)
                break;
            printf("****************%s****************
    ", (char *)((DWORD)pFileBuffer + 
                RvaToFileOffset(pFileBuffer, pImport->Name)));
            addrOfOri = (DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pImport->OriginalFirstThunk);
            while (1)
            {
                if ((DWORD)(*(PDWORD)addrOfOri == 0))
                {
                    break;
                }
                if ((DWORD)(*(PDWORD)addrOfOri) >> 31 == 1)
                    printf("序号:%d
    ", (DWORD)(*(PDWORD)addrOfOri) & 0x7fffffff);
                else
                {
                    pName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pFileBuffer + 
                        RvaToFileOffset(pFileBuffer, (DWORD)(*(PDWORD)addrOfOri)));
                    i = 0;
                    while (pName->Name[i] != 0)
                    {
                        
                        printf("%c", pName->Name[i]);
                        i++;
                    }
                    printf("
    ");
                }
                addrOfOri += 4;
            }
            pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImport + 20);
        }
        free(pFileBuffer);
    }
    
    VOID printBoundImportTable()
    {//RVATOFOA需要考虑rva在sizeofheaders里的情况
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_BOUND_IMPORT_DESCRIPTOR pBdImport = NULL, pImport = NULL;
        PIMAGE_BOUND_FORWARDER_REF pRef = NULL;
        LPVOID pFileBuffer = NULL;
    
        ReadPEFile(FILEPATH_IN, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        if (pOptionalHeader->DataDirectory[11].VirtualAddress == 0)
        {
            printf("没有绑定导入表
    ");
            return;
        }
        pBdImport = pImport =  (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + 
            RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[11].VirtualAddress));
        int i = 0;
        while (1)
        {
            
            if (pBdImport->OffsetModuleName == 0 && pBdImport->NumberOfModuleForwarderRefs == 0 && pBdImport->TimeDateStamp == 0)
                break;
            printf("***************OffsetMoudleName:%s*****************
    ", (char*)((DWORD)pImport + pBdImport->OffsetModuleName));
            printf("TimeDateStamp:%d
    ", pBdImport->TimeDateStamp);
            printf("NumberOfModuleForWarderRefs:%d
    ", pBdImport->NumberOfModuleForwarderRefs);
            pRef = (PIMAGE_BOUND_FORWARDER_REF)((DWORD)pBdImport + 8);
            for (i = 0; i < pBdImport->NumberOfModuleForwarderRefs; i++)
            {
                printf("***************OffsetMoudleName:%s*****************
    ", (char*)((DWORD)pImport + pRef->OffsetModuleName));
                printf("TimeDateStamp:%d
    ", pRef->TimeDateStamp);
                pRef += 1;
            }
            pBdImport += pBdImport->NumberOfModuleForwarderRefs + 1;
    
        }
    }
    
    PrintResourceTable()
    {
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
        PIMAGE_RESOURCE_DIRECTORY pRes = NULL;
        PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry = NULL;
        PIMAGE_DATA_DIRECTORY pDataDir = NULL;
        LPVOID pFileBuffer = NULL;
    
        ReadPEFile(FILEPATH_IN, &pFileBuffer);
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
        pRes = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer,pOptionalHeader->DataDirectory[2].VirtualAddress));
        size_t num1 = pRes->NumberOfNamedEntries + pRes->NumberOfIdEntries;
        pEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pRes + sizeof(IMAGE_RESOURCE_DIRECTORY));
        for (size_t i = 0; i < num1; i++)
        {
            if (!pEntry[i].NameIsString)
            {
                printf("资源类型ID: %d 
    ", pEntry[i].Id);
                if (pEntry[i].Id == 3)
                {
                    PIMAGE_RESOURCE_DIRECTORY pRes2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pRes + pEntry[i].OffsetToDirectory);
                    PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes2 + 1);
                    size_t num2 = pRes2->NumberOfIdEntries + pRes2->NumberOfNamedEntries;
                    for (size_t i = 0; i < num2; i++)
                    {
                        if(!pEntry1[i].NameIsString)
                        {
                            printf("资源编号ID: %d", pEntry1[1].Id);
                        }
                        else
                        {
                            PIMAGE_RESOURCE_DIR_STRING_U pStr1 = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pRes + pEntry1[i].NameOffset);
                            WCHAR str1[MAX_PATH] = { 0 };
                            memcpy_s(str1, MAX_PATH, pStr1, pStr1->Length * sizeof(WCHAR));
                            printf("%资源名称: %ls", str1);
                        }
                        PIMAGE_RESOURCE_DIRECTORY pRes3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pRes + pEntry1[i].OffsetToDirectory);
                        PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes3 + 1);
                        size_t num3 = pRes3->NumberOfIdEntries + pRes3->NumberOfNamedEntries;
                        for (size_t i = 0; i < num3; i++)
                        {
                            PIMAGE_RESOURCE_DATA_ENTRY pData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pRes + pEntry2[i].OffsetToData);
                            printf("rva: %x  size: %x 
    ", pData->OffsetToData, pData->Size);
                        }
                        printf("
    
    ");
                    }
                }
            }
            else {
                PIMAGE_RESOURCE_DIR_STRING_U pStr = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pRes + pEntry[i].NameOffset);
                WCHAR str[MAX_PATH] = { 0 };
                memcpy_s(str, MAX_PATH, pStr, pStr->Length * sizeof(WCHAR));
                printf("%资源名称: %ls", str);
            }
        }
    
    }
    
    VOID PrintfResourceTable() {
        //定义一个名称数组
        static char* szResName[0x11] =
    
        { 0, "鼠标指针", "位图", "图标", "菜单", "对话框", "字符串列表",
    
        "字体目录", "字体", "快捷键", "非格式化资源", "消息列表",
        "鼠标指针组", "zz", "图标组", "xx", "版本信息"
        };
    
    
        //读取文件
        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNtHeader = NULL;
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
        PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;
        PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = NULL;
    
        printf("打印的文件是:%s!
    ", INFILEPATH);
        //定义文件缓冲区
        LPVOID pFileBuffer = NULL;
        ReadPEFile(INFILEPATH, &pFileBuffer);
    
        if (pFileBuffer != 0) {
            printf("文件打开成功!
    ");
        }
        else
        {
            printf("文件打开失败!
    ");
            free(pFileBuffer);
            return;
        }
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
        pFileHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNtHeader) + 4);
        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
        pDataDirectory = (PIMAGE_DATA_DIRECTORY)(((DWORD)pOptionalHeader) + 96);
    
        pDataDirectory += 2;
    
        PIMAGE_RESOURCE_DIRECTORY  pResourceDirectory = NULL;
    
        DWORD RESRVA = pDataDirectory->VirtualAddress;
        DWORD RESFOA = 0;
        RESFOA = RvaToFileOffset(pFileBuffer, RESRVA);
        
        //定位资源目录
        pResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + RESFOA);
    
        //printf("NumberOfNameEntries:%d,NumberOfIdEntries:%d
    ", pResourceDirectory->NumberOfNamedEntries, pResourceDirectory->NumberOfIdEntries);
    
        //获取RESOURCEENTRY 的个数
    
        size_t NumEntry = pResourceDirectory->NumberOfIdEntries + pResourceDirectory->NumberOfNamedEntries;
    
        //资源目录表的宽度
    
        size_t dwResourceData = sizeof(PIMAGE_RESOURCE_DIRECTORY);
    
        //定位资源目录节点
    
        PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResourceDirectory + 16);
    
        //获取第一层
        for (size_t i = 0; i < NumEntry; i++)
        {
            if (!pResEntry[i].NameIsString) {//0
                if (pResEntry[i].Id < 0x11)
                    //如果id大于0x11就是自己写的ID资源
                {
                    printf("资源类型ID:%p %s
    ", pResEntry[i].Id, szResName[pResEntry[i].Id]);
                }
                else {
                    char  type[20];
                    sprintf_s(type, "%d", pResEntry[i].Id);
                    printf("资源类型ID:%p %s
    ", pResEntry[i].Id, type);
                }
            }
            else {//1那么这个第一个联合体的最高位为1,也就是说NameIsString为1,如果资源是未知的,这种资源属于字符串作为资源标识, Name就不会起作用了,NameOffset会指向IMAGE_RESOUCE_DIR_STRING_U的位置
    
                //先获取偏移
                PIMAGE_RESOURCE_DIR_STRING_U pStringRes = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceDirectory + pResEntry[i].NameOffset);
                //定义一个用来接收自定义字符串的宽数组然后直接复制
                WCHAR szStr[MAX_PATH] = { 0 };
                memcpy_s(szStr, MAX_PATH, pStringRes->NameString, pStringRes->Length * sizeof(WCHAR));
    
                printf("资源名称:%ls 
    ", szStr);
            }
    
            //第二层
            if (pResEntry[i].DataIsDirectory) {
                printf("第二层目录偏移是:%p
    ", pResEntry[i].OffsetToDirectory);
                //定义二层目录的目录头 以及entry
                PIMAGE_RESOURCE_DIRECTORY pResDirectory2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceDirectory + pResEntry[i].OffsetToDirectory);
    
                PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResDirectory2 + 1);
                //获得ENtry个数
                size_t NumEntry2 = pResDirectory2->NumberOfIdEntries + pResDirectory2->NumberOfNamedEntries;
    
                for (DWORD i = 0; i < NumEntry2; i++)
                {
                    if (!pResEntry2[i].NameIsString)
                    {
                        printf("->资源标识ID:%d
    ", pResEntry2[i].Id);
                    }
                    else
                    {
                        // 显示资源字符串
                        // NameOffset为相对资源的文件偏移
                        // 字符串偏移为 资源基地址+NameOffset
                        PIMAGE_RESOURCE_DIR_STRING_U pstcString = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceDirectory + pResEntry2[i].NameOffset);
                        WCHAR szStr[MAX_PATH] = { 0 };
                        memcpy(szStr,
                            pstcString->NameString,
                            pstcString->Length * sizeof(WCHAR)
                        );
                        printf("->资源字符串:%ls
    ", szStr);
                    }
                }
                //第三层
                PIMAGE_RESOURCE_DIRECTORY pResourceDirectory3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceDirectory + pResEntry2[i].OffsetToDirectory);
                printf("第三层目录:%d
    ", pResourceDirectory3->NumberOfIdEntries);
                PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResourceDirectory3 + 1);
                if (!pResEntry3[i].DataIsDirectory)
                {
                    // 取数据偏移,显示数据
                    PIMAGE_RESOURCE_DATA_ENTRY pResData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pResourceDirectory + pResEntry3->OffsetToData);
                    printf("->->->数据RVA:%x	数据大小:%x
    ", pResData->OffsetToData, pResData->Size);
                    //printf("->->->数据大小:%x
    ", pResData->Size);
                    //printf("->->->数据RVA:%x
    ", pResData->OffsetToData);
                }
    
            }
            printf("
    
    
    ");
        }
    }
    void main()
    {
        PVOID p2 = NULL;    //pFileBuffer
        PVOID p3 = NULL;    //pImageBuffer
        PVOID p4 = NULL;    //pNewBuffer
        FILE* fp;
        int sum;
        ReadPEFile(FILEPATH_IN, &p2);
        //CopyFileBufferToImageBuffer(p2, &p3);
        //free(p2);
        /*sum = CopyImageBufferToNewBuffer(p3, &p4);
        free(p3);*/
    
        
        
        //TestAddCodeInCodeSec();
        //AddSectionToFileBuffer();
        //ExpandLastSection(); 
        //MergeAllSection();
        //PrintfExportImform();
        //GetFunctionAddrByName(p2, "sub1");
        //GetFunctionAddrByOrdinals(p2, 2);
        //PrintRelocation();
        //MoveExport();
        //MoveRelo();
        //FixRelocation();
        //PrintImportTable();
        //printBoundImportTable();
    //    LPVOID pFileBuffer = NULL;
        //ReadPEFile(FILEPATH_IN, &pFileBuffer);
        //PrintBoundImport(pFileBuffer);
        PrintResourceTable();
    }
  • 相关阅读:
    Select与Epoll的区别
    C++ 多态详解及常见面试题
    Linux进程状态详解及状态转换
    C++ 设计模式之单例模式
    DS 图解归并排序
    TCP三次握手,四次挥手详解及常见面试题
    Linux 进程间通信(管道、共享内存、消息队列、信号量)
    # maven
    # select sort 选择排序
    # gitlab与git私钥公钥
  • 原文地址:https://www.cnblogs.com/Lu3ky-Athena/p/13673849.html
Copyright © 2011-2022 走看看