#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; }
   |