#include <windows.h> #include <stdio.h>
struct TypeOffset { WORD Offset : 12; WORD Type : 4; };
DWORD FileSize = 0; DWORD FileBase = 0;
PIMAGE_DOS_HEADER DosHeader = nullptr; PIMAGE_NT_HEADERS NtHeader = nullptr; PIMAGE_FILE_HEADER FileHead = nullptr;
DWORD RVAtoFOA(DWORD rva) { auto SectionTables = IMAGE_FIRST_SECTION(NtHeader); WORD Count = NtHeader->FileHeader.NumberOfSections;
for (int i = 0; i < Count; ++i) { DWORD Section_Start = SectionTables[i].VirtualAddress; DWORD Section_Ends = SectionTables[i].VirtualAddress + SectionTables[i].SizeOfRawData; if (rva >= Section_Start && rva < Section_Ends) { return rva - SectionTables[i].VirtualAddress + SectionTables[i].PointerToRawData; } } return -1; }
bool OpenPeFile(LPCSTR FileName) { HANDLE Handle = CreateFileA(FileName, GENERIC_READ, NULL,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (Handle == INVALID_HANDLE_VALUE) return false;
FileSize = GetFileSize(Handle, NULL);
DWORD OperSize = 0; FileBase = (DWORD)new BYTE[FileSize]; ReadFile(Handle, (LPVOID)FileBase, FileSize, &OperSize, NULL);
DosHeader = (PIMAGE_DOS_HEADER)FileBase; if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE) return false;
NtHeader = (PIMAGE_NT_HEADERS)(FileBase + DosHeader->e_lfanew); if (NtHeader->Signature != IMAGE_NT_SIGNATURE) return false;
if (NtHeader->OptionalHeader.Magic != 0x010B) return false; CloseHandle(Handle); return true; }
void RepairFixReloc(char new_file[]) { DWORD base = NtHeader->OptionalHeader.ImageBase; DWORD RelocRVA = NtHeader->OptionalHeader.DataDirectory[5].VirtualAddress; auto Reloc = (PIMAGE_BASE_RELOCATION)(FileBase + RVAtoFOA(RelocRVA));
while (Reloc->SizeOfBlock != 0) { printf("[↓] 分页基址: 0x%08X \n\n", Reloc->VirtualAddress); auto Offset = (TypeOffset*)(Reloc + 1);
DWORD Size = (Reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2;
for (DWORD i = 0; i < Size; ++i) { DWORD Type = Offset[i].Type; DWORD pianyi = Offset[i].Offset; DWORD rva = pianyi + Reloc->VirtualAddress; DWORD foa = RVAtoFOA(rva); DWORD fa = foa + FileBase; DWORD addr = *(DWORD*)fa; DWORD new_addr = addr - base + 0x1500000;
if (Offset[i].Type == 3) *(DWORD*)fa = new_addr;
printf("\t [->] 重定位RVA: 0x%08X | 重定位FOA: 0x%08X | 重定位地址: 0x%08X | 修正地址: 0x%08X \n", rva, foa, addr, new_addr); } Reloc = (PIMAGE_BASE_RELOCATION)((DWORD)Reloc + Reloc->SizeOfBlock); } NtHeader->OptionalHeader.ImageBase = 0x1500000;
HANDLE new_handle = CreateFileA(new_file, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (new_handle == INVALID_HANDLE_VALUE) return;
DWORD OperSize = 0; BOOL ret = WriteFile(new_handle, (LPVOID)FileBase, FileSize, &OperSize, NULL); if (ret == TRUE) { printf("\n\n"); CloseHandle(new_handle);
printf("[*] 修复 %s 文件 \t 写入基址: %08X \t 总长度: %d \t 写入长度: %d \n", new_file, FileBase, FileSize, OperSize); } }
void Banner() { printf(" ____ _ _ _ ____ _ \n"); printf("| __ ) _ _(_) | __| | | _ \\ ___| | ___ ___ \n"); printf("| _ \\| | | | | |/ _` | | |_) / _ \\ |/ _ \\ / __|\n"); printf("| |_) | |_| | | | (_| | | _ < __/ | (_) | (__ \n"); printf("|____/ \\__,_|_|_|\\__,_| |_| \\_\\___|_|\\___/ \\___|\n"); printf(" \n"); printf("Reloc 重定位表快速修复工具 \t By: LyShark \n"); printf("Usage: BuildFix [原文件位置] [修复后文件位置] \n\n\n"); }
int main(int argc, char* argv[]) { Banner(); if (argc == 3) { bool flag = OpenPeFile(argv[1]); if (true == flag) { RepairFixReloc(argv[2]); } } return 0; }
|