日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PE工具函数(新)

發(fā)布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PE工具函数(新) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

說明

一些常見的PE操作。。

2021年3月7日

#ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif // !_CRT_SECURE_NO_WARNINGS#include "PE.h" #include <stdio.h> #include <WINDOWS.H> #include <STRING.h> #include <MALLOC.H> #include "DebugTool.h" #include "Win32API.h"// 讀取文件到內(nèi)存中,返回讀取的字節(jié)數(shù);讀取失敗返回0 DWORD FileToMemory(LPCSTR lpszFile, LPVOID *pFileBuffer) {// 打開文件,權(quán)限是讀共享HANDLE hFile = pCreateFileA(lpszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (INVALID_HANDLE_VALUE == hFile){PrintDebugInfo("打開文件失敗\n");return 0;}// 判斷文件大小LARGE_INTEGER nFileSize = { 0 };pGetFileSizeEx(hFile, &nFileSize);if (nFileSize.QuadPart >= 0xFFFFFFFFull){PrintDebugInfo("源文件過大,無法處理(%lld)\n", nFileSize.QuadPart);pCloseHandle(hFile);return 0;}pSetFilePointer(hFile, 0, NULL, FILE_BEGIN);//PrintDebugInfo("文件大小:%d 字節(jié)\n", nFileSize.LowPart);LPVOID pFile = pVirtualAlloc(NULL, nFileSize.LowPart, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);if (pFile == NULL){PrintDebugInfo("申請內(nèi)存失敗\n");pCloseHandle(hFile);return 0;}memset(pFile, 0, nFileSize.LowPart);// 讀文件DWORD dwRead = 0;BOOL bRet = FALSE;bRet = pReadFile(hFile, pFile, nFileSize.LowPart, &dwRead, NULL);if (bRet == FALSE){PrintDebugInfo("讀取文件錯誤:%d\n", GetLastError());pVirtualFree(pFile, 0, MEM_RELEASE);pCloseHandle(hFile);return 0;}if (dwRead != nFileSize.LowPart){PrintDebugInfo("期望讀取:%d,實際讀取:%d\n", nFileSize.LowPart, dwRead);pVirtualFree(pFile, 0, MEM_RELEASE);pCloseHandle(hFile);return 0;}pCloseHandle(hFile);*pFileBuffer = pFile;return nFileSize.LowPart; }// 驗證是否是合法的32位PE文件 BOOL Is32PEFile(LPVOID pFileBuffer, DWORD dwSize) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE){PrintDebugInfo("不是有效的MZ標志 %x != %x", pDosHeader->e_magic, IMAGE_DOS_SIGNATURE);return FALSE;}if (pNtHeader->Signature != IMAGE_NT_SIGNATURE){PrintDebugInfo("不是有效的PE標記");return FALSE;}if (pNtHeader->FileHeader.Machine != IMAGE_FILE_MACHINE_I386){PrintDebugInfo("不是32位PE程序");return FALSE;}return TRUE; }// 將 FileBuffer 拉伸成 ImageBuffer 并寫入到新的緩沖區(qū) // 返回 ImageBuffer 的大小;失敗返回0 DWORD FileBufferToImageBuffer(LPVOID pFileBuffer, LPVOID *pImageBuffer, DWORD flProtect) {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)((DWORD)pNtHeader +sizeof(pNtHeader->Signature) +sizeof(pNtHeader->FileHeader) +pNtHeader->FileHeader.SizeOfOptionalHeader);*pImageBuffer = pVirtualAlloc(NULL, pNtHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, flProtect);if (*pImageBuffer == NULL){PrintDebugInfo("分配內(nèi)存失敗\n");return 0;}memset(*pImageBuffer, 0, pNtHeader->OptionalHeader.SizeOfImage);// 復(fù)制所有頭(DOS頭,PE頭,可選PE頭)和節(jié)表memcpy(*pImageBuffer, pFileBuffer, pNtHeader->OptionalHeader.SizeOfHeaders);// 遍歷節(jié)表,復(fù)制所有節(jié) for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++){memcpy((PBYTE)(*pImageBuffer) + pSectionHeader[i].VirtualAddress,(PBYTE)pFileBuffer + pSectionHeader[i].PointerToRawData,pSectionHeader[i].SizeOfRawData);}return pNtHeader->OptionalHeader.SizeOfImage; }// 將 ImageBuffer 變成文件對齊的 FileBuffer 寫入新的緩沖區(qū) // 返回復(fù)制的大小,失敗返回0 DWORD ImageBufferToFileBuffer(LPVOID pImageBuffer, LPVOID *pFileBuffer) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader +sizeof(pNtHeader->Signature) +sizeof(pNtHeader->FileHeader) +pNtHeader->FileHeader.SizeOfOptionalHeader);// 最后一個節(jié)表PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + pNtHeader->FileHeader.NumberOfSections - 1;// 計算要復(fù)制的字節(jié)// 這一步有BUG,當最后一個節(jié)后面還有數(shù)據(jù)時,這些數(shù)據(jù)會丟失DWORD dwFileBufferSize = pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData;*pFileBuffer = pVirtualAlloc(NULL, dwFileBufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);if (*pFileBuffer == NULL){PrintDebugInfo("分配內(nèi)存失敗\n");return 0;}memset(*pFileBuffer, 0, dwFileBufferSize);// 復(fù)制所有頭(DOS頭,PE頭,可選PE頭)和節(jié)表memcpy(*pFileBuffer, pImageBuffer, pNtHeader->OptionalHeader.SizeOfHeaders);// 遍歷節(jié)表,復(fù)制所有節(jié) for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++){memcpy((PBYTE)(*pFileBuffer) + pSectionHeader[i].PointerToRawData,(PBYTE)pImageBuffer + pSectionHeader[i].VirtualAddress,pSectionHeader[i].SizeOfRawData);}return dwFileBufferSize; }// 內(nèi)存數(shù)據(jù)寫入文件 BOOL MemoryToFile(LPVOID pMemBuffer, DWORD dwSize, LPCSTR lpszFile) {// 打開文件,權(quán)限是獨占寫HANDLE hFile = pCreateFileA(lpszFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (INVALID_HANDLE_VALUE == hFile){PrintDebugInfo("打開文件失敗\n");return FALSE;}BOOL bRet = FALSE;DWORD dwWritten = 0;bRet = pWriteFile(hFile, pMemBuffer, dwSize, &dwWritten, NULL);if (!bRet){PrintDebugInfo("寫文件錯誤:%d\n", GetLastError());pCloseHandle(hFile);return FALSE;}pCloseHandle(hFile);return TRUE; }// 計算對齊的函數(shù),如偏移為900,對齊為1000h,返回1000h DWORD Align(DWORD dwOffset, DWORD dwAlign) {// 如果偏移小于對齊,向上取整if (dwOffset <= dwAlign) return dwAlign;// 如果偏移大于對齊且不能除盡,向上取整if (dwOffset % dwAlign){return (dwOffset / dwAlign + 1) * dwAlign;}// 如果能除盡,直接返回offsetreturn dwOffset; }// RVA 轉(zhuǎn) FOA DWORD RvaToFoa(LPVOID pFileBuffer, DWORD dwRva) {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)((DWORD)pNtHeader +sizeof(pNtHeader->Signature) +sizeof(pNtHeader->FileHeader) +pNtHeader->FileHeader.SizeOfOptionalHeader);if (dwRva < pNtHeader->OptionalHeader.SizeOfHeaders){return dwRva;}// 遍歷節(jié)表,確定偏移屬于哪一個節(jié) for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++){if (dwRva >= pSectionHeader[i].VirtualAddress && \dwRva < pSectionHeader[i].VirtualAddress + pSectionHeader[i].Misc.VirtualSize){int offset = dwRva - pSectionHeader[i].VirtualAddress;return pSectionHeader[i].PointerToRawData + offset;}}PrintDebugInfo("找不到RVA %x 對應(yīng)的 FOA,轉(zhuǎn)換失敗\n", dwRva);return 0; }// FOA 轉(zhuǎn) RVA DWORD FoaToRva(LPVOID pFileBuffer, DWORD dwFoa) {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)((DWORD)pNtHeader +sizeof(pNtHeader->Signature) +sizeof(pNtHeader->FileHeader) +pNtHeader->FileHeader.SizeOfOptionalHeader);if (dwFoa < pNtHeader->OptionalHeader.SizeOfHeaders){return dwFoa;}// 遍歷節(jié)表,確定偏移屬于哪一個節(jié) for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++){if (dwFoa >= pSectionHeader[i].PointerToRawData && \dwFoa < pSectionHeader[i].PointerToRawData + pSectionHeader[i].SizeOfRawData){int offset = dwFoa - pSectionHeader[i].PointerToRawData;return pSectionHeader[i].VirtualAddress + offset;}}PrintDebugInfo("找不到FOA %x 對應(yīng)的 RVA,轉(zhuǎn)換失敗\n", dwFoa);return 0; }// 修改 ImageBase 并修復(fù)重定位表 BOOL SetNewImageBase(LPVOID pImageBuffer, DWORD dwNewImageBase) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader +sizeof(pNtHeader->Signature) +sizeof(pNtHeader->FileHeader) +pNtHeader->FileHeader.SizeOfOptionalHeader);PIMAGE_BASE_RELOCATION pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)pImageBuffer + \pNtHeader->OptionalHeader.DataDirectory[5].VirtualAddress);if (pRelocationTable == pImageBuffer){PrintDebugInfo("重定位表不存在\n");return FALSE;}// 重定位表的 VirtualAddress + 低12位偏移 = RVA// RVA + ImageBase 這個內(nèi)存里存儲了一個“指針”// 要修改的是這個“指針”的值,要讓這個“指針”加上兩個ImageBase的差值while (pRelocationTable->VirtualAddress != NULL && pRelocationTable->SizeOfBlock != NULL){size_t n = (pRelocationTable->SizeOfBlock - 8) / 2; // 可能需要修改的地址數(shù)量(高4位==0011才要修改)PWORD pOffset = (PWORD)((DWORD)pRelocationTable + 8); // 2字節(jié)偏移的數(shù)組for (size_t i = 0; i < n; i++){__try{// 高4位等于0011才需要重定位//if ((pOffset[i] & 0xF000) == 0x3000)if ((pOffset[i] & 0x3000) == 0x3000){// 計算需要重定位的數(shù)據(jù)的RVA地址DWORD dwRva = pRelocationTable->VirtualAddress + (pOffset[i] & 0x0FFF);// 計算在鏡像中的地址PDWORD pData = (PDWORD)((DWORD)pImageBuffer + dwRva);// 重定位,即修正寫死的地址 *pData = *pData - pNtHeader->OptionalHeader.ImageBase + dwNewImageBase;}}__except (EXCEPTION_EXECUTE_HANDLER){continue;}}pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocationTable + pRelocationTable->SizeOfBlock);}// 修改 ImageBasepNtHeader->OptionalHeader.ImageBase = dwNewImageBase;return TRUE; }// 傳入一個imagebuffer,修復(fù)它的IAT表 void RepairIAT(LPVOID pImageBuffer) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader +sizeof(pNtHeader->Signature) +sizeof(pNtHeader->FileHeader) +pNtHeader->FileHeader.SizeOfOptionalHeader);PIMAGE_IMPORT_DESCRIPTOR pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImageBuffer + \pNtHeader->OptionalHeader.DataDirectory[1].VirtualAddress);// 嚴格來說應(yīng)該是 sizeof(IMAGE_IMPORT_DESCRIPTOR) 個字節(jié)為0表示結(jié)束while (pImportTable->OriginalFirstThunk || pImportTable->FirstThunk)//while (memcmp(&EndFlag, pImportTable, sizeof(EndFlag)) != 0){HMODULE hModule = LoadLibraryA((LPCSTR)(pImportTable->Name + (DWORD)pImageBuffer));if (NULL == hModule){PrintDebugInfo("獲取模塊句柄失敗,模塊名: %s\n", (LPCSTR)(pImportTable->Name + (DWORD)pImageBuffer));continue;}// 修復(fù)IAT表PIMAGE_THUNK_DATA32 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pImageBuffer + pImportTable->FirstThunk);while (*((PDWORD)pThunkData) != 0){// IMAGE_THUNK_DATA32 是一個4字節(jié)數(shù)據(jù)// 如果最高位是1,那么除去最高位就是導(dǎo)出序號// 如果最高位是0,那么這個值是RVA 指向 IMAGE_IMPORT_BY_NAMEif ((*((PDWORD)pThunkData) & 0x80000000) == 0x80000000){DWORD dwProcAddress = (DWORD)GetFunctionByName(hModule, MAKEINTRESOURCE((*((PDWORD)pThunkData) & 0x7FFFFFFF)));*((PDWORD)pThunkData) = dwProcAddress;}else{PIMAGE_IMPORT_BY_NAME pIBN = (PIMAGE_IMPORT_BY_NAME)(*((PDWORD)pThunkData) + (DWORD)pImageBuffer);DWORD dwProcAddress = (DWORD)GetFunctionByName(hModule, (LPCSTR)pIBN->Name);*((PDWORD)pThunkData) = dwProcAddress;}pThunkData++;}pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportTable + sizeof(IMAGE_IMPORT_DESCRIPTOR));} }// 寫入加密數(shù)據(jù)到資源節(jié) // 返回新文件的大小,失敗返回0 VOID WriteEncryptedDataToResourceSection(LPCSTR szFileName,LPVOID pData,DWORD nData ) {NaiveEncrypt(pData, nData, szEncKey, sizeof(szEncKey));Rc4Encrypt(pData, nData, szEncKey, sizeof(szEncKey));HANDLE hFile = BeginUpdateResourceA(szFileName, TRUE);UpdateResourceA(hFile,RT_RCDATA,MAKEINTRESOURCEA(SRCPE),GetSystemDefaultLangID(),pData,nData);EndUpdateResourceA(hFile, FALSE); }// ----------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------- // 加密相關(guān)的函數(shù) // ----------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------void Rc4Encrypt(void *pData, size_t byteDataLen, const void *pKey, const size_t byteKeyLen) {unsigned char s[256] = { 0 }; //S-boxrc4_init(s, (unsigned char *)pKey, byteKeyLen); //初始化密鑰rc4_crypt(s, (unsigned char *)pData, byteDataLen);//解密 }void Rc4Decrypt(void *pData, size_t byteDataLen, const void *pKey, const size_t byteKeyLen) {unsigned char s[256] = { 0 }; //S-boxrc4_init(s, (unsigned char *)pKey, byteKeyLen); //已經(jīng)完成了初始化rc4_crypt(s, (unsigned char *)pData, byteDataLen);//加密 }void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函數(shù) {int i = 0, j = 0;unsigned char k[256] = { 0 };unsigned char tmp = 0;for (i = 0; i < 256; i++) {s[i] = i;k[i] = key[i % Len];}for (i = 0; i < 256; i++) {j = (j + s[i] + k[i]) % 256;tmp = s[i];s[i] = s[j]; //交換s[i]和s[j]s[j] = tmp;} }void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密 {int i = 0, j = 0, t = 0;unsigned long k = 0;unsigned char tmp;for (k = 0; k < Len; k++) {i = (i + 1) % 256;j = (j + s[i]) % 256;tmp = s[i];s[i] = s[j]; //交換s[x]和s[y]s[j] = tmp;t = (s[i] + s[j]) % 256;Data[k] ^= s[t];} }// 字節(jié)循環(huán)右移 unsigned char RorByte(unsigned char bData, size_t shift) {unsigned char temp = bData >> (8 - shift);bData = bData << shift;bData |= temp;return bData; }// 加密函數(shù):先與密鑰異或,然后取反,然后右移3位 void NaiveEncrypt(void *pData, size_t byteDataLen, const void *pKey, const size_t byteKeyLen) {size_t uDataIndex = 0, uKeyIndex = 0;for (; uDataIndex < byteDataLen; uDataIndex++){((char *)pData)[uDataIndex] = ((char *)pData)[uDataIndex] ^ ((char *)pKey)[uKeyIndex];((char *)pData)[uDataIndex] = ~((char *)pData)[uDataIndex];RorByte(((unsigned char *)pData)[uDataIndex], 3);uKeyIndex++;if (uKeyIndex == byteKeyLen) uKeyIndex = 0;} }// 解密函數(shù):先右移5位,再取反,在與密鑰異或 void NaiveDecrypt(void *pData, size_t byteDataLen, const void *pKey, const size_t byteKeyLen) {size_t uDataIndex = 0, uKeyIndex = 0;for (; uDataIndex < byteDataLen; uDataIndex++){RorByte(((unsigned char *)pData)[uDataIndex], 5);((char *)pData)[uDataIndex] = ~((char *)pData)[uDataIndex];((char *)pData)[uDataIndex] = ((char *)pData)[uDataIndex] ^ ((char *)pKey)[uKeyIndex];uKeyIndex++;if (uKeyIndex == byteKeyLen) uKeyIndex = 0;} }


編譯環(huán)境:32位 多字節(jié)字符集
PE.hpp

#ifndef PE_HPP_ #define PE_HPP_/******************************************************************************** 時間:2020年7月14日 作者:hambaga 說明:重新整理的PE工具函數(shù),僅適用于32位程序 ********************************************************************************/#ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif // !_CRT_SECURE_NO_WARNINGS#include <stdio.h> #include <WINDOWS.H> #include <STRING.h> #include <MALLOC.H>DWORD FileToMemory(LPCSTR lpszFile, LPVOID *pFileBuffer); BOOL MemoryToFile(LPVOID pMemBuffer, DWORD dwSize, LPCSTR lpszFile); BOOL Is32PEFile(LPVOID pFileBuffer, DWORD dwSize); DWORD FileBufferToImageBuffer(LPVOID pFileBuffer, LPVOID *pImageBuffer); DWORD ImageBufferToFileBuffer(LPVOID pImageBuffer, LPVOID *pFileBuffer); DWORD Align(DWORD dwOffset, DWORD dwAlign); DWORD RvaToFoa(LPVOID pFileBuffer, DWORD dwRva); DWORD FoaToRva(LPVOID pFileBuffer, DWORD dwFoa); DWORD MoveNTHeaderAndSectionHeadersToDosStub(LPVOID pFileBuffer); VOID SetNewImageBase(LPVOID pFileBuffer, DWORD dwNewImageBase); DWORD WriteEncryptedDataToNewSection(LPVOID pFileBuffer, DWORD dwFileBufferSize, LPVOID *pNewFileBuffer, LPVOID pData, DWORD dwDataSize); DWORD ReadEncryptedDataFromLastSection(LPVOID pFileBuffer, DWORD dwFileBufferSize, LPVOID *pData);struct PEINFO {PIMAGE_DOS_HEADER pDosHeader;PIMAGE_NT_HEADERS pNTHeader;PIMAGE_FILE_HEADER pPEHeader;PIMAGE_OPTIONAL_HEADER32 pOptionHeader;PIMAGE_SECTION_HEADER pSectionHeader; };VOID InitPEInfo(LPVOID pPEBuffer, PEINFO *pPEInfo) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pPEBuffer;PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);pPEInfo->pDosHeader = pDosHeader;pPEInfo->pNTHeader = pNTHeader;pPEInfo->pPEHeader = pPEHeader;pPEInfo->pOptionHeader = pOptionHeader;pPEInfo->pSectionHeader = pSectionHeader; }// 讀取文件到內(nèi)存中,返回讀取的字節(jié)數(shù);讀取失敗返回0 DWORD FileToMemory(LPCSTR lpszFile, LPVOID *pFileBuffer) {FILE *pFile = NULL;DWORD dwFileSize = 0;pFile = fopen(lpszFile, "rb");if (pFile == NULL){printf("打開文件失敗\n");return 0;}fseek(pFile, 0, SEEK_END);dwFileSize = ftell(pFile);fseek(pFile, 0, SEEK_SET);*pFileBuffer = malloc(dwFileSize);if (*pFileBuffer == NULL){printf("分配內(nèi)存失敗\n");fclose(pFile);return 0;}DWORD dwRead = fread(*pFileBuffer, 1, dwFileSize, pFile);fclose(pFile);if (dwRead != dwFileSize){free(*pFileBuffer);return 0;}return dwRead; }// 驗證是否是合法的32位PE文件 BOOL Is32PEFile(LPVOID pFileBuffer, DWORD dwSize) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);if (*((PWORD)pDosHeader) != IMAGE_DOS_SIGNATURE){printf("不是有效的MZ標志\n");return FALSE;}if (pNTHeader->Signature != IMAGE_NT_SIGNATURE){printf("不是有效的PE標記\n");return FALSE;}return TRUE; }// 將 FileBuffer 拉伸成 ImageBuffer 并寫入到新的緩沖區(qū) // 返回 ImageBuffer 的大小;失敗返回0 DWORD FileBufferToImageBuffer(LPVOID pFileBuffer, LPVOID *pImageBuffer) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);*pImageBuffer = malloc(pOptionHeader->SizeOfImage);if (*pImageBuffer == NULL){printf("分配內(nèi)存失敗\n");return 0;}memset(*pImageBuffer, 0, pOptionHeader->SizeOfImage);// 復(fù)制DOS頭+PE頭+可選PE頭+節(jié)表+文件對齊memcpy(*pImageBuffer, pFileBuffer, pOptionHeader->SizeOfHeaders);// 遍歷節(jié)表,復(fù)制所有節(jié) for (int i = 0; i < pPEHeader->NumberOfSections; i++){memcpy((LPVOID)((DWORD)(*pImageBuffer) + pSectionHeader[i].VirtualAddress), \(LPVOID)((DWORD)pFileBuffer + pSectionHeader[i].PointerToRawData), \pSectionHeader[i].SizeOfRawData);}return pOptionHeader->SizeOfImage; }// 將 ImageBuffer 變成文件對齊的 FileBuffer 寫入新的緩沖區(qū) // 返回復(fù)制的大小,失敗返回0 DWORD ImageBufferToFileBuffer(LPVOID pImageBuffer, LPVOID *pFileBuffer) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);// 最后一個節(jié)表PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + pPEHeader->NumberOfSections - 1;// 計算要復(fù)制的字節(jié)// 這一步有BUG,當最后一個節(jié)后面還有數(shù)據(jù)時(多見于控制臺程序),丟失數(shù)據(jù)DWORD dwFileBufferSize = pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData;*pFileBuffer = malloc(dwFileBufferSize);if (*pFileBuffer == NULL){printf("分配內(nèi)存失敗\n");return 0;}memset(*pFileBuffer, 0, dwFileBufferSize);// 復(fù)制DOS頭+PE頭+可選PE頭+節(jié)表+文件對齊memcpy(*pFileBuffer, pImageBuffer, pOptionHeader->SizeOfHeaders);// 遍歷節(jié)表,復(fù)制文件對齊后的節(jié) for (int i = 0; i < pPEHeader->NumberOfSections; i++){memcpy((LPVOID)((DWORD)(*pFileBuffer) + pSectionHeader[i].PointerToRawData), \(LPVOID)((DWORD)pImageBuffer + pSectionHeader[i].VirtualAddress), \pSectionHeader[i].SizeOfRawData);}return dwFileBufferSize; }// 內(nèi)存數(shù)據(jù)寫入文件 BOOL MemoryToFile(LPVOID pMemBuffer, DWORD dwSize, LPCSTR lpszFile) {FILE *fp = NULL;fp = fopen(lpszFile, "wb+");if (fp == NULL){printf("打開文件失敗\n");return FALSE;}DWORD dwWritten = fwrite(pMemBuffer, 1, dwSize, fp);if (dwWritten != dwSize){printf("寫入了 %d 字節(jié),不等于 %d\n", dwWritten, dwSize);fclose(fp);return FALSE;}fclose(fp);return TRUE; }// 計算對齊的函數(shù),如偏移為900,對齊為1000h,返回1000h DWORD Align(DWORD dwOffset, DWORD dwAlign) {// 如果偏移小于對齊,向上取整if (dwOffset <= dwAlign) return dwAlign;// 如果偏移大于對齊且不能除盡,向上取整if (dwOffset % dwAlign){return (dwOffset / dwAlign + 1) * dwAlign;}// 如果能除盡,直接返回offsetreturn dwOffset; }// RVA 轉(zhuǎn) FOA DWORD RvaToFoa(LPVOID pFileBuffer, DWORD dwRva) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)(pDosHeader->e_lfanew + (DWORD)pFileBuffer + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);// RVA在文件頭中或者文件對齊==內(nèi)存對齊時,RVA==FOA 錯!第一句是對的,第二句是錯的if (dwRva < pOptionHeader->SizeOfHeaders){return dwRva;}// 遍歷節(jié)表,確定偏移屬于哪一個節(jié) for (int i = 0; i < pPEHeader->NumberOfSections; i++){if (dwRva >= pSectionHeader[i].VirtualAddress && \dwRva < pSectionHeader[i].VirtualAddress + pSectionHeader[i].Misc.VirtualSize){int offset = dwRva - pSectionHeader[i].VirtualAddress;return pSectionHeader[i].PointerToRawData + offset;}}printf("找不到RVA %x 對應(yīng)的 FOA,轉(zhuǎn)換失敗\n", dwRva);return 0; }// FOA 轉(zhuǎn) RVA DWORD FoaToRva(LPVOID pFileBuffer, DWORD dwFoa) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)(pDosHeader->e_lfanew + (DWORD)pFileBuffer + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);// RVA在文件頭中或者文件對齊==內(nèi)存對齊時,RVA==FOA 錯!第一句是對的,第二句是錯的if (dwFoa < pOptionHeader->SizeOfHeaders){return dwFoa;}// 遍歷節(jié)表,確定偏移屬于哪一個節(jié) for (int i = 0; i < pPEHeader->NumberOfSections; i++){if (dwFoa >= pSectionHeader[i].PointerToRawData && \dwFoa < pSectionHeader[i].PointerToRawData + pSectionHeader[i].SizeOfRawData){int offset = dwFoa - pSectionHeader[i].PointerToRawData;return pSectionHeader[i].VirtualAddress + offset;}}printf("找不到FOA %x 對應(yīng)的 RVA,轉(zhuǎn)換失敗\n", dwFoa);return 0; }// 移動NT頭和節(jié)表到DOS STUB,該函數(shù)在新增節(jié)時節(jié)表空間不足的情況下調(diào)用;返回地址減小值 DWORD MoveNTHeaderAndSectionHeadersToDosStub(LPVOID pFileBuffer) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);LPVOID pDst = (LPVOID)((DWORD)pDosHeader + sizeof(IMAGE_DOS_HEADER)); // NT頭插入點DWORD dwRet = (DWORD)pNTHeader - (DWORD)pDst; // 返回地址減小的值DWORD dwSize = 4 + sizeof(IMAGE_FILE_HEADER) + pPEHeader->SizeOfOptionalHeader + \sizeof(IMAGE_SECTION_HEADER) * pPEHeader->NumberOfSections; // 移動的字節(jié)數(shù)LPVOID pSrc = malloc(dwSize);if (pSrc == NULL){printf("分配內(nèi)存失敗\n");return 0;}memcpy(pSrc, (LPVOID)pNTHeader, dwSize); // 保存要復(fù)制的數(shù)據(jù)memset((LPVOID)pNTHeader, 0, dwSize); // 清空原數(shù)據(jù)memcpy(pDst, pSrc, dwSize); // 移動數(shù)據(jù)free(pSrc);pDosHeader->e_lfanew = sizeof(IMAGE_DOS_HEADER); // 更新 e_lfanewreturn dwRet; }// 修改 ImageBase 并修復(fù)重定位表 VOID SetNewImageBase(LPVOID pFileBuffer, DWORD dwNewImageBase) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)(pDosHeader->e_lfanew + (DWORD)pDosHeader + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);PIMAGE_BASE_RELOCATION pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + \RvaToFoa(pFileBuffer, pOptionHeader->DataDirectory[5].VirtualAddress));DWORD dwImageBaseDelta = dwNewImageBase - pOptionHeader->ImageBase; // 新舊ImageBase 的差值 // 重定位表的 VirtualAddress + 低12位偏移 = RVA// RVA + ImageBase 這個內(nèi)存里存儲了一個“指針”// 要修改的是這個“指針”的值,要讓這個“指針”加上兩個ImageBase的差值while (pRelocationTable->VirtualAddress || pRelocationTable->SizeOfBlock){size_t n = (pRelocationTable->SizeOfBlock - 8) / 2; // 可能需要修改的地址數(shù)量(高4位==0011才要修改)PWORD pOffset = (PWORD)((DWORD)pRelocationTable + 8); // 2字節(jié)偏移的數(shù)組for (size_t i = 0; i < n; i++){// 高4位等于0011才需要重定位if ((pOffset[i] & 0xF000) == 0x3000){// 計算需要重定位的數(shù)據(jù)的RVA地址DWORD dwRva = pRelocationTable->VirtualAddress + (pOffset[i] & 0x0FFF);// 計算在文件中的偏移DWORD dwFoa = RvaToFoa(pFileBuffer, dwRva);// 計算在文件中的地址PDWORD pData = (PDWORD)((DWORD)pFileBuffer + dwFoa);// 重定位,即修正寫死的地址 *pData += dwImageBaseDelta;}}pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocationTable + pRelocationTable->SizeOfBlock);}// 修改 ImageBasepOptionHeader->ImageBase = dwNewImageBase; }// 將數(shù)據(jù)添加到新增節(jié)中 // 返回新緩沖區(qū)的大小,失敗返回0 // 這個數(shù)據(jù)節(jié)前N個字節(jié)是一串十進制字符串,表示數(shù)據(jù)大小,以NULL結(jié)束 DWORD WriteEncryptedDataToNewSection(LPVOID pFileBuffer, DWORD dwFileBufferSize, LPVOID *pNewFileBuffer, LPVOID pData, DWORD dwDataSize) {// 復(fù)制一份 pFileBuffer,不要修改原來的數(shù)據(jù)LPVOID pFileBuffer3 = malloc(dwFileBufferSize);memcpy(pFileBuffer3, pFileBuffer, dwFileBufferSize);pFileBuffer = pFileBuffer3;pFileBuffer3 = NULL;PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);PWORD pNumberOfSections = &(pPEHeader->NumberOfSections); // 節(jié)的數(shù)量PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + *pNumberOfSections - 1; // 最后一個節(jié)表PIMAGE_SECTION_HEADER pNewSectionHeader = pSectionHeader + *pNumberOfSections; // 新節(jié)表插入點DWORD newFileBufferSize = 0; // 新文件的大小// 判斷最后一個節(jié)表后面是否有空閑的80字節(jié)if (80 > (DWORD)pFileBuffer + pOptionHeader->SizeOfHeaders - (DWORD)pNewSectionHeader){printf("沒有足夠的80字節(jié)插入新節(jié)表\n");free(pFileBuffer);return 0;}// 判斷空閑的80字節(jié)是否全為0,如果不是,則把整個NT頭往上挪覆蓋dos stub以空出空間插入節(jié)表for (int i = 0; i < 80; i++){if (((PBYTE)pNewSectionHeader)[i] != 0){DWORD dwRet = MoveNTHeaderAndSectionHeadersToDosStub(pFileBuffer);printf("節(jié)表空間不足,NT頭和節(jié)表向低地址移動了 %d 字節(jié)\n", dwRet);if (dwRet < 80){printf("移動后仍沒有足夠的80字節(jié)空間插入新節(jié)表\n");free(pFileBuffer);return 0;}// 更新指針pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);pNumberOfSections = &(pPEHeader->NumberOfSections); // 節(jié)的數(shù)量pLastSectionHeader = pSectionHeader + *pNumberOfSections - 1; // 最后一個節(jié)表pNewSectionHeader = pSectionHeader + *pNumberOfSections; // 新節(jié)表插入點break;}}// 創(chuàng)建數(shù)據(jù)大小標記char sSizeFlag[100] = { 0 };sprintf(sSizeFlag, "%d", dwDataSize);DWORD dwFlagLen = strlen(sSizeFlag) + 1; // 拷貝長度包括NULL// 定義一個 IMAGE_SECTION_HEADER 結(jié)構(gòu),計算里面的屬性IMAGE_SECTION_HEADER newSectionHeader;memcpy(newSectionHeader.Name, ".encsrc", 8);newSectionHeader.Misc.VirtualSize = Align(dwDataSize + dwFlagLen, pOptionHeader->SectionAlignment);newSectionHeader.VirtualAddress = pLastSectionHeader->VirtualAddress + \Align(pLastSectionHeader->Misc.VirtualSize, pOptionHeader->SectionAlignment);newSectionHeader.SizeOfRawData = Align(dwDataSize + dwFlagLen, pOptionHeader->FileAlignment);newSectionHeader.PointerToRawData = pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData;newSectionHeader.PointerToRelocations = 0;newSectionHeader.PointerToLinenumbers = 0;newSectionHeader.NumberOfRelocations = 0;newSectionHeader.NumberOfLinenumbers = 0;newSectionHeader.Characteristics = 0xC0000040;// pNewFileBuffer 分配內(nèi)存,把 pFileBuffer 復(fù)制過去,后面的修改都在 pNewFileBuffer 進行 *pNewFileBuffer = malloc(dwFileBufferSize + newSectionHeader.SizeOfRawData);memcpy(*pNewFileBuffer, pFileBuffer, dwFileBufferSize);memset((LPVOID)((DWORD)*pNewFileBuffer + dwFileBufferSize), 0, newSectionHeader.SizeOfRawData); // 新增節(jié)數(shù)據(jù)清0// 更新指針,指向新內(nèi)存 pDosHeader = (PIMAGE_DOS_HEADER)*pNewFileBuffer;pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);pNumberOfSections = &(pPEHeader->NumberOfSections);pLastSectionHeader = pSectionHeader + *pNumberOfSections - 1;pNewSectionHeader = pSectionHeader + *pNumberOfSections;// 節(jié)的數(shù)量+1,SizeOfImage是內(nèi)存中拉伸后的大小*pNumberOfSections += 1;pOptionHeader->SizeOfImage += Align(newSectionHeader.Misc.VirtualSize, pOptionHeader->SectionAlignment);// 拷貝 newSectionHeadermemcpy(pNewSectionHeader, &newSectionHeader, sizeof(newSectionHeader));// 拷貝數(shù)據(jù)到新增節(jié)LPVOID pNewSec = (LPVOID)((DWORD)*pNewFileBuffer + (DWORD)(pSectionHeader[*pNumberOfSections - 1].PointerToRawData));memcpy(pNewSec, sSizeFlag, dwFlagLen);memcpy((LPVOID)((PBYTE)pNewSec + dwFlagLen), pData, dwDataSize);//printf("插入成功\n");free(pFileBuffer);return dwFileBufferSize + newSectionHeader.SizeOfRawData; }// 從最后一個節(jié)里讀取數(shù)據(jù),返回數(shù)據(jù)大小 // 最后一個節(jié)名字必須是.encsrc,開頭N個字節(jié)必須是十進制數(shù)字符串,NULL結(jié)尾,表示后面的數(shù)據(jù)字節(jié)數(shù) // pNewFileBuffer 輸出數(shù)據(jù)內(nèi)容,不包含開頭大小標記 // 數(shù)據(jù)通過 pData 返回,與pFileBuffer 共享一塊內(nèi)存 DWORD ReadEncryptedDataFromLastSection(LPVOID pFileBuffer, DWORD dwFileBufferSize, LPVOID *pData) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);PWORD pNumberOfSections = &(pPEHeader->NumberOfSections); // 節(jié)的數(shù)量PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + *pNumberOfSections - 1; // 最后一個節(jié)表if (memcmp(".encsrc", pLastSectionHeader->Name, 8) != 0){printf("不是有效的加密程序\n");int i = 0;for (; i < 8; i++){printf("%c", pLastSectionHeader->Name[i]);}puts("");return 0;}LPVOID pLastSection = (LPVOID)(pLastSectionHeader->PointerToRawData + (PBYTE)pFileBuffer);DWORD dwDataSize = -1;sscanf((char *)pLastSection, "%d", &dwDataSize);*pData = (PBYTE)pLastSection + strlen((char *)pLastSection) + 1;return dwDataSize; }#endif

總結(jié)

以上是生活随笔為你收集整理的PE工具函数(新)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。