Guest User

Untitled

a guest
Aug 24th, 2017
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.72 KB | None | 0 0
  1. /* This code copies the target process in our own address space, performs relocation and executes new thread with a new function */
  2.  
  3. #include <Windows.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6.  
  7. typedef BOOL(WINAPI* DllMain_t)(
  8.     HINSTANCE hinstDLL,
  9.     DWORD fdwReason,
  10.     LPVOID lpReserved);
  11.  
  12. void loadDLL(const char *dllName)
  13. {
  14.  
  15.     HANDLE hFile, hMapping;
  16.     void *uiBaseAddress;
  17.  
  18.     hFile = CreateFileA((LPCSTR)dllName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  19.  
  20.     if (hFile == INVALID_HANDLE_VALUE)
  21.     {
  22.         puts("Unable to open file\n");
  23.         exit(1);
  24.     }
  25.  
  26.     hMapping = CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0);
  27.  
  28.     if (hMapping == INVALID_HANDLE_VALUE)
  29.     {
  30.         puts("Unable to map file\n");
  31.         CloseHandle(hFile);
  32.         exit(1);
  33.     }
  34.  
  35.     uiBaseAddress = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
  36.  
  37.     if (!uiBaseAddress)
  38.     {
  39.         puts("Unable mapping view of file to memory\n");
  40.         UnmapViewOfFile(hMapping);
  41.         CloseHandle(hFile);
  42.         exit(1);
  43.     }
  44.  
  45.     UINT_PTR pViewBase = (UINT_PTR)uiBaseAddress; // Mapping address
  46.     IMAGE_NT_HEADERS *pNtHeader = (IMAGE_NT_HEADERS*)(pViewBase + ((IMAGE_DOS_HEADER*)pViewBase)->e_lfanew);
  47.  
  48.  
  49.     /* Get location of NT headers */
  50.     //IMAGE_NT_HEADERS *pNtHeader = (IMAGE_NT_HEADERS*)((PIMAGE_DOS_HEADER)pViewBase)->e_lfanew + (LONG)pViewBase;
  51.  
  52.     /* Allocate a memory block of pNtHeader.OptionalHeader.SizeOfImage bytes at position pNtHeader.OptionalHeader.ImageBase */
  53.     void *pLibraryBase = VirtualAlloc((void *)pNtHeader->OptionalHeader.ImageBase, pNtHeader->OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  54.  
  55.     if (!pLibraryBase)
  56.     {
  57.         puts("Unable to allocate memory for library in process\n");
  58.         exit(1);
  59.     }
  60.  
  61.     PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((unsigned long)pNtHeader + sizeof(IMAGE_NT_HEADERS));
  62.  
  63.     for (unsigned int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++)
  64.     {
  65.         /* Section start in memory */
  66.         void *pSectionMemoryAddress = (void *)(pSectionHeader[i].VirtualAddress + (unsigned long)pLibraryBase);
  67.  
  68.         /* Section start in file */
  69.         void *pSectionFileAddress = (void *)(pSectionHeader[i].PointerToRawData + (unsigned long)pViewBase);
  70.  
  71.         unsigned long ulSectionSize = pSectionHeader[i].SizeOfRawData;
  72.  
  73.         if (!ulSectionSize)
  74.         {
  75.             if (pSectionHeader[i].Characteristics & IMAGE_SCN_CNT_CODE)
  76.                 ulSectionSize = pNtHeader->OptionalHeader.SizeOfCode;
  77.  
  78.             else if (pSectionHeader[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
  79.                 ulSectionSize = pNtHeader->OptionalHeader.SizeOfInitializedData;
  80.  
  81.             else if (pSectionHeader[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
  82.                 ulSectionSize = pNtHeader->OptionalHeader.SizeOfUninitializedData;
  83.         }
  84.  
  85.         if (VirtualAlloc(pSectionMemoryAddress, ulSectionSize, MEM_COMMIT, PAGE_READWRITE) != pSectionMemoryAddress)
  86.         {
  87.             puts("Error in commit memory\n");
  88.             exit(1);
  89.         }
  90.  
  91.         if (ulSectionSize > 0)
  92.         {
  93.             /* Copy sections from disk to memory */
  94.             memcpy(pSectionMemoryAddress, pSectionFileAddress, ulSectionSize);
  95.         }
  96.     }
  97.  
  98.     /* Resolve imports and setup IAT */
  99.     PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (unsigned long)pLibraryBase);
  100.  
  101.     for (unsigned int i = 0; i < pImportDescriptor[i].FirstThunk; i++)
  102.     {
  103.         PIMAGE_THUNK_DATA pOFT = (PIMAGE_THUNK_DATA)(pImportDescriptor[i].OriginalFirstThunk + (unsigned long)pLibraryBase);
  104.         PIMAGE_THUNK_DATA pIAT = (PIMAGE_THUNK_DATA)(pImportDescriptor[i].FirstThunk + (unsigned long)pLibraryBase);
  105.  
  106.         HMODULE hImportLib = LoadLibraryA((LPCSTR)((unsigned long)pLibraryBase + pImportDescriptor[i].Name));
  107.         if (!hImportLib)
  108.         {
  109.             puts("Unable to find dependency library\n");
  110.             exit(1);
  111.         }
  112.  
  113.         for (unsigned int x = 0; x < pOFT[x].u1.Function; x++)
  114.         {
  115.             unsigned long ulImportNameOrdinal = 0;
  116.  
  117.             if (pOFT[x].u1.Function & (1 >> 31))
  118.             {
  119.                 ulImportNameOrdinal = pIAT[x].u1.Function & ~(1 >> 31);
  120.             }
  121.             else
  122.             {
  123.                 /* Address of the function called from the DLL */
  124.                 PIMAGE_IMPORT_BY_NAME pImport = PIMAGE_IMPORT_BY_NAME((unsigned long)pLibraryBase + pOFT[x].u1.Function);
  125.                 ulImportNameOrdinal = (unsigned long)pImport->Name;
  126.             }
  127.  
  128.             /* Patch the IAT with the address of the function */
  129.             if (!(pIAT[x].u1.Function = (unsigned long)(GetProcAddress(hImportLib, (const char *)ulImportNameOrdinal))))
  130.             {
  131.                 puts("Error finding import\n");
  132.                 exit(1);
  133.             }
  134.         }
  135.     }
  136.  
  137.     /* Do relocation as described in Relocation directory */
  138.     DWORD_PTR difference = (DWORD)pLibraryBase - pNtHeader->OptionalHeader.ImageBase;
  139.     if (difference != 0)
  140.     {
  141.         IMAGE_BASE_RELOCATION *relo_start = (IMAGE_BASE_RELOCATION*)((DWORD)pLibraryBase + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
  142.         IMAGE_BASE_RELOCATION *relo_end = (IMAGE_BASE_RELOCATION*)((DWORD)relo_start + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size - sizeof(IMAGE_BASE_RELOCATION));
  143.  
  144.         for (; relo_start < relo_end; relo_start = (IMAGE_BASE_RELOCATION*)((DWORD)relo_start + relo_start->SizeOfBlock))
  145.         {
  146.             /* To determine the number of relocation in this block, substract the size of an
  147.             IMAGE_BASE_RELOCATION (8 bytes) from the value of this field, and then divide
  148.             by 2 (size of WORD).
  149.             */
  150.             WORD *reloc_item = (WORD*)(relo_start + 1);
  151.             DWORD num_items = (relo_start->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
  152.  
  153.             for (DWORD i = 0; i < num_items; ++i, ++reloc_item)
  154.             {
  155.                 switch (*reloc_item >> 12)
  156.                 {
  157.                 case IMAGE_REL_BASED_ABSOLUTE:
  158.                     break;
  159.                 case IMAGE_REL_BASED_HIGHLOW:
  160.                     *(DWORD_PTR*)((DWORD)pLibraryBase + relo_start->VirtualAddress + (*reloc_item & 0xFFF)) += difference;
  161.                 }
  162.             }
  163.         }
  164.     }
  165.  
  166.  
  167.     /* Relocation have been done. Now apply proper page permissions */
  168.     //  for (unsigned int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++)
  169.     //  {
  170.     //      void *pMemorySectionAddress = (void*)(pSectionHeader->VirtualAddress + (unsigned long)pLibraryBase);
  171.     //      setSectionPermission(pMemorySectionAddress, pSectionHeader[i].Misc.VirtualSize, pSectionHeader[i].Characteristics);
  172.     //  }
  173.  
  174.     DllMain_t entry = (DllMain_t)((DWORD)pLibraryBase + pNtHeader->OptionalHeader.AddressOfEntryPoint);
  175.     entry((HINSTANCE)pLibraryBase, DLL_PROCESS_ATTACH, 0);
  176.  
  177.     UnmapViewOfFile(hMapping);
  178.     CloseHandle(hFile);
  179. }
  180.  
  181. DWORD WINAPI ThreadProc(PVOID p)
  182. {
  183.     MessageBox(NULL, "FUNCTION INJECTED", "HI", MB_ICONINFORMATION);
  184.     char *dll = "C:\\Users\\root_sec\\Documents\\Visual Studio 2015\\Projects\\ManualMapping\\Debug\\TestFinal.dll";
  185.     loadDLL(dll);
  186.     return 0;
  187. }
  188.  
  189. int main(int argc, char **argv)
  190. {
  191.     if (argc != 2)
  192.     {
  193.         printf("[!] Not enough arguments\n");
  194.         return -1;
  195.     }
  196.  
  197.     ULONG i, *p;
  198.     WORD *relocItems;
  199.     PIMAGE_DOS_HEADER pDosh;
  200.     PIMAGE_NT_HEADERS pNth;
  201.     PIMAGE_BASE_RELOCATION pBase;
  202.  
  203.     printf("[*] Opening the target process ...\n");
  204.  
  205.     HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, atoi(argv[1]));
  206.     if (hProcess == INVALID_HANDLE_VALUE)
  207.     {
  208.         puts("[!] Unable to open process");
  209.         return -1;
  210.     }
  211.  
  212.     HANDLE imageBase = GetModuleHandle(NULL);
  213.     printf("[*] Image Base in current process: 0x%x\n", (unsigned int)imageBase);
  214.  
  215.     pDosh = (PIMAGE_DOS_HEADER)imageBase;
  216.     pNth = (PIMAGE_NT_HEADERS)((PUCHAR)imageBase + pDosh->e_lfanew);
  217.  
  218.     printf("[*] Allocating memory in target process ...\n");
  219.  
  220.     void *mem = VirtualAllocEx(hProcess, NULL, pNth->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  221.  
  222.     if (!mem)
  223.     {
  224.         printf("[!] Unable to allocate memory. Error (%u)\n", GetLastError());
  225.         CloseHandle(hProcess);
  226.         return -1;
  227.     }
  228.  
  229.     printf("[*] Memory allocated at 0x%x\n", (unsigned int)mem);
  230.  
  231.     void *Buffer = VirtualAlloc(NULL, pNth->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
  232.     memcpy(Buffer, imageBase, pNth->OptionalHeader.SizeOfImage);
  233.  
  234.     printf("[*] Performing relocation ...\n");
  235.  
  236.     pBase = (PIMAGE_BASE_RELOCATION)((PUCHAR)Buffer + pNth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
  237.     ULONG difference = (ULONG)mem - (ULONG)imageBase;
  238.  
  239.     while (pBase->VirtualAddress)
  240.     {
  241.         if (pBase->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION))
  242.         {
  243.             ULONG numItems = (pBase->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
  244.             relocItems = (WORD *)(pBase + 1);
  245.  
  246.             for (i = 0; i<numItems; i++)
  247.             {
  248.                 if (relocItems[i])
  249.                 {
  250.                     p = (PULONG)((PUCHAR)Buffer + pBase->VirtualAddress + (relocItems[i] & 0xFFF));
  251.                     *p += difference;
  252.                 }
  253.             }
  254.         }
  255.  
  256.         pBase = (PIMAGE_BASE_RELOCATION)((PUCHAR)pBase + pBase->SizeOfBlock);
  257.     }
  258.  
  259.  
  260.     printf("[*] Writing relocated image into target process ...\n");
  261.     if (!WriteProcessMemory(hProcess, mem, Buffer, pNth->OptionalHeader.SizeOfImage, NULL))
  262.     {
  263.         printf("[!] Unable to write to process memory. Error (%u)\n", GetLastError());
  264.         VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); // size of memory should be 0 when using MEM_RELEASE
  265.         CloseHandle(hProcess);
  266.         return -1;
  267.     }
  268.  
  269.     VirtualFree(Buffer, 0, MEM_RELEASE);
  270.  
  271.     printf("[*] Executing thread in remote process at : 0x%08x\n", (difference + (PUCHAR)loadDLL));
  272.  
  273.     char *dll = "C:\\Users\\root_sec\\Documents\\Visual Studio 2015\\Projects\\ManualMapping\\Debug\\TestFinal.dll";
  274.     HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, ((LPTHREAD_START_ROUTINE)(difference + (PUCHAR)loadDLL)), dll, 0, NULL);
  275.  
  276.     if (hThread == INVALID_HANDLE_VALUE)
  277.     {
  278.         printf("[!] Could not create a remote thread.\n");
  279.         VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE);
  280.         CloseHandle(hProcess);
  281.         return -1;
  282.     }
  283.  
  284.     printf("[*] Waiting for thread to terminate ...\n");
  285.     WaitForSingleObject(hThread, INFINITE);
  286.  
  287.     printf("[*] Thread terminated. Freeing resources ...\n");
  288.     VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE);
  289.     CloseHandle(hProcess);
  290.  
  291.     return 0;
  292. }
Add Comment
Please, Sign In to add comment