Advertisement
HITOA

LoadLibrary 32bit reprograming training

Jan 5th, 2021
1,046
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.28 KB | None | 0 0
  1. #include <iostream>
  2. #include <windows.h>
  3. #include <fstream>
  4. #include <cstdlib>
  5.  
  6. typedef BOOL(WINAPI* PDLL_MAIN)(HMODULE, DWORD, PVOID);
  7.  
  8. typedef struct _PE_FILE {
  9.     PIMAGE_DOS_HEADER dos_header;
  10.     PIMAGE_NT_HEADERS pe_header;
  11.     PIMAGE_SECTION_HEADER section_header;
  12. }PE_FILE, *PPE_FILE;
  13.  
  14. typedef struct _DLL_LOADER {
  15.     PPE_FILE pe_file;
  16.     PVOID image;
  17. }DLL_LOADER;
  18.  
  19. DWORD WINAPI LoadDLL(DLL_LOADER dll_loader) {
  20.     PIMAGE_BASE_RELOCATION base_relocation = (PIMAGE_BASE_RELOCATION)((LPBYTE)dll_loader.image + dll_loader.pe_file->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
  21.     PIMAGE_IMPORT_DESCRIPTOR import_descriptor = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)dll_loader.image + dll_loader.pe_file->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  22.     PIMAGE_NT_HEADERS pe_header = (PIMAGE_NT_HEADERS)((LPBYTE)dll_loader.image + dll_loader.pe_file->dos_header->e_lfanew);
  23.  
  24.     DWORD delta = (DWORD)((LPBYTE)dll_loader.image - dll_loader.pe_file->pe_header->OptionalHeader.ImageBase); //difference
  25.  
  26.     printf("ImageBase adress is %#x\n", dll_loader.pe_file->pe_header->OptionalHeader.ImageBase);
  27.     printf("Delta for relocation is %#x\n", delta);
  28.  
  29.     PDWORD ptr;
  30.     while (base_relocation->VirtualAddress) {
  31.         printf("Base relocation %#x\n", base_relocation->VirtualAddress);
  32.         if (base_relocation->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION)) {
  33.             DWORD count = ((base_relocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD));
  34.             PWORD list = (PWORD)(base_relocation + 1);
  35.  
  36.             for (int i = 0; i < count; i++)
  37.             {
  38.                 if (list[i])
  39.                 {
  40.                     ptr = (PDWORD)((LPBYTE)dll_loader.image + (base_relocation->VirtualAddress + (list[i] & 0xFFF)));
  41.                     *ptr += delta;
  42.                 }
  43.             }
  44.         }
  45.  
  46.         base_relocation = (PIMAGE_BASE_RELOCATION)((LPBYTE)base_relocation + base_relocation->SizeOfBlock);
  47.     }
  48.  
  49.     PIMAGE_THUNK_DATA FirstThunk, OrigFirstThunk;
  50.  
  51.     while (import_descriptor->Characteristics) {
  52.         OrigFirstThunk = (PIMAGE_THUNK_DATA)((LPBYTE)dll_loader.image + import_descriptor->OriginalFirstThunk);
  53.         FirstThunk = (PIMAGE_THUNK_DATA)((LPBYTE)dll_loader.image + import_descriptor->FirstThunk);
  54.  
  55.         HMODULE hModule = LoadLibraryA((LPCSTR)dll_loader.image + import_descriptor->Name);
  56.  
  57.         if (!hModule) {
  58.             return FALSE;
  59.         }
  60.  
  61.         while (OrigFirstThunk->u1.AddressOfData) {
  62.             if (OrigFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) {
  63.                 DWORD func = (DWORD)GetProcAddress(hModule, (LPCSTR)(OrigFirstThunk->u1.Ordinal & 0xFFFF));
  64.  
  65.                 if (!func) {
  66.                     return false;
  67.                 }
  68.  
  69.                 FirstThunk->u1.Function = func;
  70.             }
  71.             else {
  72.                 PIMAGE_IMPORT_BY_NAME import_by_name = (PIMAGE_IMPORT_BY_NAME)((LPBYTE)dll_loader.image + OrigFirstThunk->u1.AddressOfData);
  73.                 DWORD func = (DWORD)GetProcAddress(hModule, (LPCSTR)import_by_name->Name);
  74.  
  75.                 if (!func) {
  76.                     return false;
  77.                 }
  78.  
  79.                 FirstThunk->u1.Function = func;
  80.             }
  81.  
  82.             OrigFirstThunk++;
  83.             FirstThunk++;
  84.         }
  85.  
  86.         import_descriptor++;
  87.     }
  88.  
  89.     if (dll_loader.pe_file->pe_header->OptionalHeader.AddressOfEntryPoint) {
  90.         PDLL_MAIN entry_point = (PDLL_MAIN)((LPBYTE)dll_loader.image + pe_header->OptionalHeader.AddressOfEntryPoint);
  91.         return entry_point((HMODULE)dll_loader.image, DLL_PROCESS_ATTACH, NULL);
  92.     }
  93.  
  94.     return TRUE;
  95. }
  96.  
  97. PE_FILE ParsePE(char* buffer) {
  98.     PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)buffer;
  99.     PIMAGE_NT_HEADERS pe_header = (PIMAGE_NT_HEADERS)(buffer + dos_header->e_lfanew);
  100.     PIMAGE_SECTION_HEADER section_header = (PIMAGE_SECTION_HEADER)(buffer + dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS));
  101.  
  102.     PE_FILE pe_file;
  103.     pe_file.dos_header = dos_header;
  104.     pe_file.pe_header = pe_header;
  105.     pe_file.section_header = section_header;
  106.  
  107.     return pe_file;
  108. }
  109.  
  110. bool IsValidPE(PE_FILE pe_file) {
  111.     if (pe_file.dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
  112.         return false;
  113.     }
  114.     if (pe_file.pe_header->Signature != IMAGE_NT_SIGNATURE) {
  115.         return false;
  116.     }
  117.     if (!(pe_file.pe_header->FileHeader.Characteristics & IMAGE_FILE_DLL)) {
  118.         return false;
  119.     }
  120.     return true;
  121. }
  122.  
  123. int main() {
  124.     std::ifstream file(/*path*/, std::ios::binary);
  125.  
  126.     if (!file.is_open()) {
  127.         return EXIT_FAILURE;
  128.     }
  129.  
  130.     file.seekg(0, file.end);
  131.     int size = file.tellg();
  132.     file.seekg(0, file.beg);
  133.  
  134.     char* buffer = (char*)malloc(sizeof(char) * size);
  135.     file.read(buffer, size);
  136.  
  137.     file.close();
  138.  
  139.     if (!buffer) {
  140.         return EXIT_FAILURE;
  141.     }
  142.  
  143.     PE_FILE pe_file = ParsePE(buffer);
  144.  
  145.     if (!IsValidPE(pe_file)) {
  146.         return EXIT_FAILURE;
  147.     }
  148.  
  149.     PVOID image = VirtualAlloc(NULL,
  150.         pe_file.pe_header->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  151.  
  152.     if (!image) {
  153.         return EXIT_FAILURE;
  154.     }
  155.    
  156.  
  157.     if (!memcpy(image, buffer, pe_file.pe_header->OptionalHeader.SizeOfHeaders)) {
  158.         return EXIT_FAILURE;
  159.     }
  160.  
  161.     for (int i = 0; i < pe_file.pe_header->FileHeader.NumberOfSections; i++) {
  162.         memcpy((LPBYTE)image + pe_file.section_header[i].VirtualAddress,
  163.             (LPBYTE)buffer + pe_file.section_header[i].PointerToRawData,
  164.             pe_file.section_header[i].SizeOfRawData);
  165.     }
  166.  
  167.     printf("Dll write at %#x\n", image);
  168.     printf("EntryPoint at %#x\n", (LPBYTE)image + pe_file.pe_header->OptionalHeader.AddressOfEntryPoint);
  169.  
  170.     DLL_LOADER dll_loader;
  171.     dll_loader.pe_file = &pe_file;
  172.     dll_loader.image = image;
  173.  
  174.     if (!LoadDLL(dll_loader)) {
  175.         return EXIT_FAILURE;
  176.     }
  177.  
  178.     return EXIT_SUCCESS;
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement