Broihon

Untitled

Sep 11th, 2016
295
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "Injection.h"
  2.  
  3. #pragma comment (lib, "Psapi.lib")
  4.  
  5. #ifdef ReCa
  6. #undef ReCa
  7. #endif
  8. #define ReCa reinterpret_cast
  9.  
  10. #ifdef UNICODE
  11. #undef Module32First
  12. #undef Module32Next
  13. #undef MODULEENTRY32
  14. #endif
  15.  
  16. typedef HINSTANCE(__stdcall * f_LoadLibrary)(const char*);
  17. typedef uintptr_t(__stdcall * f_GetProcAddress)(HINSTANCE, const char*);
  18. typedef BOOL(__stdcall * f_DLL_ENTRY_POINT)(void*, DWORD, void*);
  19.  
  20. struct LDR_LOAD_DLL_DATA
  21. {
  22.     f_LdrLoadDll pLdrLoadDll;
  23.     HANDLE Out;
  24.     UNICODE_STRING pModuleFileName;
  25.     BYTE Data[MAX_PATH * 2];
  26. };
  27.  
  28. bool Inject(const char * szDllFile, HANDLE hProc, bool HijackThread);
  29. bool ManualMap(const char * szDllFile, HANDLE hProc, bool HijackThread);
  30. bool LdrLoadDllStub(const char * szDllFile, HANDLE hProc, bool HijackThread);
  31. bool Cloaking(const char * szDllFile, HANDLE hProc, DWORD Flags);
  32.  
  33. UINT __forceinline _StrlenA(const char * szString);
  34. void __forceinline _ZeroMemory(BYTE * pMem, UINT Size);
  35. void __stdcall ImportTlsExecute(BYTE * pBase);
  36. void __stdcall LdrLoadDllShell(LDR_LOAD_DLL_DATA * pData);
  37.  
  38. bool FileExistsA(const char * szFile);
  39. HANDLE StartRoutine(HANDLE hTargetProc, void * pRoutine, void * pArg, bool Hijack = false, bool Fastcall = true);
  40. PEB * GetPEB(HANDLE hProc);
  41.  
  42. bool InjectDLL(const char * szDllFile, HANDLE hProc, INJECTION_MODE im, bool HijackThread, DWORD Postinjection)
  43. {
  44.     bool Ret = false;
  45.     switch (im)
  46.     {
  47.         case IM_LoadLibrary:
  48.             Ret = Inject(szDllFile, hProc, HijackThread);
  49.             break;
  50.  
  51.         case IM_LdrLoadDll:
  52.             Ret = LdrLoadDllStub(szDllFile, hProc, HijackThread);
  53.             break;
  54.  
  55.         case IM_ManualMap:
  56.             return ManualMap(szDllFile, hProc, HijackThread);
  57.     }
  58.  
  59.     if (Ret)
  60.         return Cloaking(szDllFile, hProc, Postinjection);
  61.    
  62.     return false;
  63. }
  64.  
  65. bool Inject(const char * szDllFile, HANDLE hProc, bool HijackThread)
  66. {
  67.     if (!szDllFile || !hProc || !FileExistsA(szDllFile))
  68.         return false;
  69.  
  70.     auto Len = lstrlenA(szDllFile);
  71.  
  72.     void * pArg = VirtualAllocEx(hProc, nullptr, Len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  73.     if (!pArg)
  74.         return false;
  75.  
  76.     if (!WriteProcessMemory(hProc, pArg, szDllFile, Len, nullptr))
  77.     {
  78.         VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
  79.         return false;
  80.     }
  81.  
  82.     DWORD dwExitCode = 0;
  83.     HANDLE hThread = StartRoutine(hProc, LoadLibraryA, pArg, HijackThread, false);
  84.     if (!hThread)
  85.     {
  86.         VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
  87.         return false;
  88.     }
  89.     else if (!HijackThread)
  90.     {
  91.         WaitForSingleObject(hThread, INFINITE);
  92.         GetExitCodeThread(hThread, &dwExitCode);
  93.         CloseHandle(hThread);
  94.     }
  95.     else
  96.         dwExitCode = 1;
  97.  
  98.     VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
  99.  
  100.     return (dwExitCode != 0);
  101. }
  102.  
  103. bool ManualMap(const char * szDllFile, HANDLE hProc, bool HijackThread)
  104. {
  105.     if (!szDllFile || !hProc || !FileExistsA(szDllFile))
  106.         return false;
  107.  
  108.     BYTE * pSrcData;
  109.     IMAGE_NT_HEADERS *      pOldNtHeader;
  110.     IMAGE_OPTIONAL_HEADER * pOldOptHeader;
  111.     IMAGE_FILE_HEADER *     pOldFileHeader;
  112.     BYTE * pLocalBase;
  113.     BYTE * pTargetBase;
  114.  
  115.     std::ifstream File(szDllFile, std::ios::binary | std::ios::ate);
  116.  
  117.     auto FileSize = File.tellg();
  118.     if (FileSize <= 0x1000)
  119.     {
  120.         File.close();
  121.         return false;
  122.     }
  123.  
  124.     pSrcData = new BYTE[static_cast<UINT_PTR>(FileSize)];
  125.  
  126.     if (!pSrcData)
  127.     {
  128.         File.close();
  129.         return false;
  130.     }
  131.  
  132.     File.seekg(0, std::ios::beg);
  133.     File.read(ReCa<char*>(pSrcData), FileSize);
  134.     File.close();
  135.  
  136.     if (ReCa<IMAGE_DOS_HEADER*>(pSrcData)->e_magic != 0x5A4D)
  137.     {
  138.         delete[] pSrcData;
  139.         return false;
  140.     }
  141.  
  142.     pOldNtHeader = ReCa<IMAGE_NT_HEADERS*>(pSrcData + ReCa<IMAGE_DOS_HEADER*>(pSrcData)->e_lfanew);
  143.     pOldOptHeader = &pOldNtHeader->OptionalHeader;
  144.     pOldFileHeader = &pOldNtHeader->FileHeader;
  145.  
  146.     #ifdef _WIN64
  147.     if (pOldFileHeader->Machine != IMAGE_FILE_MACHINE_AMD64)
  148.     {
  149.         delete[] pSrcData;
  150.         return false;
  151.     }
  152.     #else
  153.     if (pOldFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
  154.     {
  155.         delete[] pSrcData;
  156.         return false;
  157.     }
  158.     #endif
  159.  
  160.     pTargetBase = ReCa<BYTE*>(VirtualAllocEx(hProc, ReCa<void*>(pOldOptHeader->ImageBase), pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
  161.     if (!pTargetBase)
  162.         pTargetBase = ReCa<BYTE*>(VirtualAllocEx(hProc, nullptr, pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
  163.  
  164.     if (!pTargetBase)
  165.     {
  166.         delete[] pSrcData;
  167.         return false;
  168.     }
  169.  
  170.     pLocalBase = ReCa<BYTE*>(VirtualAlloc(nullptr, pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
  171.  
  172.     if (!pLocalBase)
  173.     {
  174.         delete[] pSrcData;
  175.         VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);
  176.         return false;
  177.     }
  178.  
  179.     memset(pLocalBase, 0, pOldOptHeader->SizeOfImage);
  180.     memcpy(pLocalBase, pSrcData, 0x1000);
  181.    
  182.     auto * pSectionHeader = IMAGE_FIRST_SECTION(pOldNtHeader);
  183.     for (UINT i = 0; i < pOldFileHeader->NumberOfSections; ++i, ++pSectionHeader)
  184.         if (pSectionHeader->SizeOfRawData)
  185.             memcpy(pLocalBase + pSectionHeader->VirtualAddress, pSrcData + pSectionHeader->PointerToRawData, pSectionHeader->SizeOfRawData);
  186.  
  187.     delete[] pSrcData;
  188.  
  189.     BYTE * LocationDelta = pTargetBase - pOldOptHeader->ImageBase;
  190.     if (LocationDelta)
  191.     {
  192.         if (!pOldOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)
  193.         {
  194.             VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);
  195.             VirtualFree(pLocalBase, 0, MEM_RELEASE);
  196.             return false;
  197.         }
  198.  
  199.         auto * pRelocData = ReCa<IMAGE_BASE_RELOCATION*>(pLocalBase + pOldOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
  200.         while (pRelocData->VirtualAddress)
  201.         {
  202.             WORD * pRelativeInfo = ReCa<WORD*>(pRelocData + 1);
  203.             for (UINT i = 0; i < ((pRelocData->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2); ++i, ++pRelativeInfo)
  204.             {
  205.                 #ifndef _WIN64
  206.                 if ((*pRelativeInfo >> 0x0C) == IMAGE_REL_BASED_HIGHLOW)
  207.                 {
  208.                     DWORD * pPatch = ReCa<DWORD*>(pLocalBase + pRelocData->VirtualAddress + ((*pRelativeInfo) & 0xFFF));
  209.                     *pPatch += ReCa<DWORD>(LocationDelta);
  210.                 }
  211.                 #else
  212.                 if ((*pRelativeInfo >> 0x0C) == IMAGE_REL_BASED_DIR64)
  213.                 {
  214.                     UINT_PTR * pPatch = ReCa<UINT_PTR*>(pLocalBase + pRelocData->VirtualAddress + ((*pRelativeInfo) & 0xFFF));
  215.                     *pPatch += ReCa<UINT_PTR>(LocationDelta);
  216.                 }
  217.                 #endif
  218.             }
  219.             pRelocData = ReCa<IMAGE_BASE_RELOCATION*>(ReCa<BYTE*>(pRelocData) + pRelocData->SizeOfBlock);
  220.         }
  221.     }
  222.  
  223.     *ReCa<f_LoadLibrary*>(pLocalBase) = LoadLibraryA;
  224.     *ReCa<f_GetProcAddress*>(pLocalBase + 8) = ReCa<f_GetProcAddress>(GetProcAddress);
  225.  
  226.     BOOL Ret = WriteProcessMemory(hProc, pTargetBase, pLocalBase, pOldOptHeader->SizeOfImage, nullptr);
  227.     VirtualFree(pLocalBase, 0, MEM_RELEASE);
  228.     if (!Ret)
  229.         return false;
  230.  
  231.     ULONG_PTR FuncSize = 0x800;
  232.     void * pFunc = VirtualAllocEx(hProc, nullptr, FuncSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  233.     if (!pFunc)
  234.         return false;
  235.  
  236.     if (!WriteProcessMemory(hProc, pFunc, ImportTlsExecute, FuncSize, nullptr))
  237.     {
  238.         VirtualFreeEx(hProc, pFunc, 0, MEM_RELEASE);
  239.         return false;
  240.     }
  241.  
  242.     HANDLE hThread = StartRoutine(hProc, pFunc, pTargetBase, HijackThread, false);
  243.  
  244.     if (!hThread)
  245.     {
  246.         VirtualFreeEx(hProc, pFunc, 0, MEM_RELEASE);
  247.         VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);
  248.         return false;
  249.     }
  250.     else if (!HijackThread)
  251.     {
  252.         WaitForSingleObject(hThread, INFINITE);
  253.         CloseHandle(hThread);
  254.     }
  255.  
  256.     VirtualFreeEx(hProc, pFunc, 0, MEM_RELEASE);
  257.  
  258.     return true;
  259. }
  260.  
  261. bool LdrLoadDllStub(const char * szDllFile, HANDLE hProc, bool HijackThread)
  262. {
  263.     if (!szDllFile || !hProc || !FileExistsA(szDllFile))
  264.         return false;
  265.  
  266.     LDR_LOAD_DLL_DATA data{ 0 };
  267.     data.pModuleFileName.szBuffer = ReCa<wchar_t*>(data.Data);
  268.     data.pModuleFileName.MaxLength = MAX_PATH * 2;
  269.  
  270.     size_t len = _StrlenA(szDllFile);
  271.     mbstowcs_s(&len, data.pModuleFileName.szBuffer, len + 1, szDllFile, len);
  272.     data.pModuleFileName.Length = (WORD)(len * 2) - 2;
  273.  
  274.     HINSTANCE hNTDLL = GetModuleHandleA("ntdll.dll");
  275.     if (!hNTDLL)
  276.         return false;
  277.  
  278.     FARPROC pFunc = GetProcAddress(hNTDLL, "LdrLoadDll");
  279.     if (!pFunc)
  280.         return false;
  281.  
  282.     data.pLdrLoadDll = ReCa<f_LdrLoadDll>(pFunc);
  283.  
  284.     BYTE * pArg = ReCa<BYTE*>(VirtualAllocEx(hProc, nullptr, sizeof(LDR_LOAD_DLL_DATA) + 0x200, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
  285.     if (!pArg)
  286.         return false;
  287.  
  288.     if (!WriteProcessMemory(hProc, pArg, &data, sizeof(LDR_LOAD_DLL_DATA), nullptr))
  289.     {
  290.         VirtualFreeEx(hProc, pArg, MEM_RELEASE, 0);
  291.         return false;
  292.     }
  293.  
  294.     if (!WriteProcessMemory(hProc,pArg + sizeof(LDR_LOAD_DLL_DATA), LdrLoadDllShell, 0x100, nullptr))
  295.     {
  296.         VirtualFreeEx(hProc, pArg, MEM_RELEASE, 0);
  297.         return false;
  298.     }
  299.  
  300.     HANDLE hThread = StartRoutine(hProc, pArg + sizeof(LDR_LOAD_DLL_DATA), pArg, HijackThread, false);
  301.     if (!hThread)
  302.     {
  303.         VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
  304.         return false;
  305.     }
  306.     else if (!HijackThread)
  307.     {
  308.         WaitForSingleObject(hThread, INFINITE);
  309.         CloseHandle(hThread);
  310.     }
  311.  
  312.     VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
  313.  
  314.     return true;
  315. }
  316.  
  317. bool Cloaking(const char * szDllFile, HANDLE hProc, DWORD Flags)
  318. {
  319.     if (!Flags)
  320.         return true;
  321.  
  322.     if (Flags > INJ_FLAGS_ALL)
  323.         return false;
  324.  
  325.     HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetProcessId(hProc));
  326.     if (!hSnap)
  327.         return false;
  328.  
  329.     MODULEENTRY32 ME32{ 0 };
  330.     ME32.dwSize = sizeof(MODULEENTRY32);
  331.  
  332.     HINSTANCE hMod = 0;
  333.  
  334.     BOOL Ret = Module32First(hSnap, &ME32);
  335.     while (Ret)
  336.     {
  337.         char Buffer[MAX_PATH]{ 0 };
  338.         GetModuleFileNameExA(hProc, ReCa<HINSTANCE>(ME32.modBaseAddr), Buffer, MAX_PATH);
  339.         if (Buffer[3] == szDllFile[3] && !lstrcmpA(szDllFile, Buffer))
  340.         {
  341.             hMod = ME32.hModule;
  342.             break;
  343.         }
  344.         Ret = Module32Next(hSnap, &ME32);
  345.     }
  346.     CloseHandle(hSnap);
  347.  
  348.     if (!Ret || !hMod)
  349.         return false;
  350.  
  351.     if (Flags & INJ_FAKE_HEADER)
  352.     {
  353.         void * pK32 = ReCa<void*>(GetModuleHandleA("kernel32.dll"));
  354.         DWORD dwOld = 0;
  355.         VirtualProtectEx(hProc, hMod, 0x1000, PAGE_EXECUTE_READWRITE, &dwOld);
  356.         WriteProcessMemory(hProc, hMod, pK32, 0x1000, nullptr);
  357.         VirtualProtectEx(hProc, hMod, 0x1000, dwOld, &dwOld);
  358.     }
  359.     else if (Flags & INJ_ERASE_HEADER)
  360.     {
  361.         BYTE Buffer[0x1000];
  362.         memset(Buffer, 0, 0x1000);
  363.         DWORD dwOld = 0;
  364.         VirtualProtectEx(hProc, hMod, 0x1000, PAGE_EXECUTE_READWRITE, &dwOld);
  365.         WriteProcessMemory(hProc, hMod, Buffer, 0x1000, nullptr);
  366.     }
  367.  
  368.     if (Flags & INJ_UNLINK_FROM_PEB)
  369.     {
  370.         PEB * ppeb;
  371.         PEB peb;
  372.         PEB_LDR_DATA ldrdata;
  373.         LDR_DATA_TABLE_ENTRY * pCurrent;
  374.         LDR_DATA_TABLE_ENTRY current;
  375.         LIST_ENTRY flink;
  376.         LIST_ENTRY blink;
  377.  
  378.         ppeb = GetPEB(hProc);
  379.         ReadProcessMemory(hProc, ppeb, &peb, sizeof(PEB), nullptr);
  380.         ReadProcessMemory(hProc, peb.pLdrData, &ldrdata, sizeof(PEB_LDR_DATA), nullptr);
  381.  
  382.         pCurrent = ReCa<LDR_DATA_TABLE_ENTRY*>(ldrdata.InLoadOrderModuleListHead.Flink);
  383.  
  384.         do
  385.         {
  386.             ReadProcessMemory(hProc, pCurrent, &current, sizeof(LDR_DATA_TABLE_ENTRY), nullptr);
  387.  
  388.             if (current.DllBase == hMod)
  389.             {
  390.                 ReadProcessMemory(hProc, current.InLoadOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
  391.                 ReadProcessMemory(hProc, current.InLoadOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
  392.                 flink.Blink = current.InLoadOrder.Blink;
  393.                 blink.Flink = current.InLoadOrder.Flink;
  394.                 WriteProcessMemory(hProc, current.InLoadOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
  395.                 WriteProcessMemory(hProc, current.InLoadOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
  396.  
  397.                 ReadProcessMemory(hProc, current.InMemoryOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
  398.                 ReadProcessMemory(hProc, current.InMemoryOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
  399.                 flink.Blink = current.InMemoryOrder.Blink;
  400.                 blink.Flink = current.InMemoryOrder.Flink;
  401.                 WriteProcessMemory(hProc, current.InMemoryOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
  402.                 WriteProcessMemory(hProc, current.InMemoryOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
  403.  
  404.                 ReadProcessMemory(hProc, current.InInitOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
  405.                 ReadProcessMemory(hProc, current.InInitOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
  406.                 flink.Blink = current.InInitOrder.Blink;
  407.                 blink.Flink = current.InInitOrder.Flink;
  408.                 WriteProcessMemory(hProc, current.InInitOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
  409.                 WriteProcessMemory(hProc, current.InInitOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
  410.  
  411.                 BYTE Buffer[MAX_PATH * 2]{0};
  412.                 WriteProcessMemory(hProc, current.BaseDllName.szBuffer, Buffer, current.BaseDllName.MaxLength, nullptr);
  413.                 WriteProcessMemory(hProc, current.FullDllName.szBuffer, Buffer, current.FullDllName.MaxLength, nullptr);
  414.                 WriteProcessMemory(hProc, pCurrent, Buffer, sizeof(LDR_DATA_TABLE_ENTRY), nullptr);
  415.  
  416.                 return true;
  417.             }
  418.             pCurrent = ReCa<LDR_DATA_TABLE_ENTRY*>(current.InLoadOrder.Flink);
  419.         }
  420.         while (current.InLoadOrder.Flink != ldrdata.InLoadOrderModuleListHead.Flink);
  421.     }
  422.  
  423.     return false;
  424. }
  425. #include <iostream>
  426. UINT __forceinline _StrlenA(const char * szString)
  427. {
  428.     UINT Ret = 0;
  429.     while (*szString)
  430.     {
  431.         ++Ret;
  432.         ++szString;
  433.     }
  434.     return Ret;
  435. }
  436.  
  437. void __forceinline _ZeroMemory(BYTE * pMem, UINT Size)
  438. {
  439.     for (BYTE * i = pMem; i < pMem + Size; ++i)
  440.         *i = 0x00;
  441. }
  442.  
  443. void __stdcall ImportTlsExecute(BYTE * pBase)
  444. {
  445.     auto * pOp = &ReCa<IMAGE_NT_HEADERS*>(pBase + ReCa<IMAGE_DOS_HEADER*>(pBase)->e_lfanew)->OptionalHeader;
  446.     auto _LoadLibraryA = *ReCa<f_LoadLibrary*>(pBase);
  447.     auto _GetProcAddress = *ReCa<f_GetProcAddress*>(pBase + 8);
  448.     auto _DllMain = ReCa<f_DLL_ENTRY_POINT>(pBase + pOp->AddressOfEntryPoint);
  449.  
  450.     if (pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
  451.     {
  452.         auto * pImportDescr = ReCa<IMAGE_IMPORT_DESCRIPTOR*>(pBase + pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  453.         while (pImportDescr->Name)
  454.         {
  455.             HINSTANCE hDll = _LoadLibraryA(ReCa<const char*>(pBase + pImportDescr->Name));
  456.             ULONG_PTR * pThunkRef = ReCa<ULONG_PTR*>(pBase + pImportDescr->OriginalFirstThunk);
  457.             ULONG_PTR * pFuncRef = ReCa<ULONG_PTR*>(pBase + pImportDescr->FirstThunk);
  458.  
  459.             _ZeroMemory(pBase + pImportDescr->Name, _StrlenA(ReCa<char*>(pBase + pImportDescr->Name)));
  460.  
  461.             if (!pImportDescr->OriginalFirstThunk)
  462.                 pThunkRef = pFuncRef;
  463.  
  464.             for (; *pThunkRef; ++pThunkRef, ++pFuncRef)
  465.             {
  466.                 if (IMAGE_SNAP_BY_ORDINAL(*pThunkRef))
  467.                 {
  468.                     *pFuncRef = _GetProcAddress(hDll, ReCa<const char*>(*pThunkRef & 0xFFFF));
  469.                     _ZeroMemory(ReCa<BYTE*>(*pThunkRef & 0xFFFF), _StrlenA(ReCa<char*>(*pThunkRef & 0xFFFF)));
  470.                 }
  471.                 else
  472.                 {
  473.                     auto * pImport = ReCa<IMAGE_IMPORT_BY_NAME*>(pBase + (*pThunkRef));
  474.                     *pFuncRef = _GetProcAddress(hDll, ReCa<const char*>(&pImport->Name));
  475.                     _ZeroMemory(ReCa<BYTE*>(&pImport->Name), _StrlenA(ReCa<char*>(&pImport->Name)));
  476.                 }
  477.             }
  478.             ++pImportDescr;
  479.         }
  480.     }
  481.  
  482.     if (pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size)
  483.     {
  484.         auto * pTLS = ReCa<IMAGE_TLS_DIRECTORY*>(pBase + pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
  485.         auto * pCallback = ReCa<PIMAGE_TLS_CALLBACK*>(pTLS->AddressOfCallBacks);
  486.         for (; pCallback && *pCallback; ++pCallback)
  487.             (*pCallback)(pBase, DLL_PROCESS_ATTACH, nullptr);
  488.     }
  489.  
  490.     for (UINT i = 0; i <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR; ++i)
  491.     {
  492.         if (i == IMAGE_DIRECTORY_ENTRY_IAT)
  493.             continue;
  494.  
  495.         DWORD Size = pOp->DataDirectory[i].Size;
  496.         if (Size)
  497.             _ZeroMemory(pBase + pOp->DataDirectory[i].VirtualAddress, Size);
  498.     }
  499.  
  500.     _DllMain(pBase, DLL_PROCESS_ATTACH, nullptr);
  501.  
  502.     for (UINT i = 0; i != 0x1000; i += sizeof(ULONG64))
  503.         *ReCa<ULONG64*>(pBase + i) = 0;
  504. }
  505.  
  506. void __stdcall LdrLoadDllShell(LDR_LOAD_DLL_DATA * pData)
  507. {
  508.     if (!pData)
  509.         return;
  510.     pData->pModuleFileName.szBuffer = ReCa<wchar_t*>(pData->Data);
  511.     pData->pLdrLoadDll(nullptr, 0, &pData->pModuleFileName, &pData->Out);
  512. }
  513.  
  514. bool FileExistsA(const char * szFile)
  515. {
  516.     return (GetFileAttributesA(szFile) != INVALID_FILE_ATTRIBUTES);
  517. }
  518.  
  519. HANDLE StartRoutine(HANDLE hTargetProc, void * pRoutine, void * pArg, bool Hijack, bool Fastcall)
  520. {
  521.     if (!hTargetProc || !pRoutine)
  522.         return nullptr;
  523.    
  524.     if (!Hijack)
  525.     {
  526.         HINSTANCE hNtDll = GetModuleHandleA("ntdll.dll");
  527.         auto pNtCreateThreadEx = ReCa<f_NtCreateThreadEx>(GetProcAddress(hNtDll, "NtCreateThreadEx"));
  528.         if (!pNtCreateThreadEx)
  529.             return CreateRemoteThreadEx(hTargetProc, nullptr, 0, ReCa<LPTHREAD_START_ROUTINE>(pRoutine), pArg, 0, nullptr, nullptr);
  530.        
  531.         HANDLE hRet = nullptr;
  532.         pNtCreateThreadEx(&hRet, THREAD_ALL_ACCESS, nullptr, hTargetProc, pRoutine, pArg, 0, 0, 0, 0, nullptr);
  533.         return hRet;
  534.     }
  535.  
  536.     DWORD dwProcId = GetProcessId(hTargetProc);
  537.     if (!dwProcId)
  538.         return nullptr;
  539.  
  540.     HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
  541.     if (!hSnap)
  542.         return nullptr;
  543.  
  544.     THREADENTRY32 TE32 = { 0 };
  545.     TE32.dwSize = sizeof(THREADENTRY32);
  546.  
  547.     BOOL Ret = Thread32First(hSnap, &TE32);
  548.     while (Ret)
  549.     {
  550.         if (TE32.th32OwnerProcessID == dwProcId && TE32.th32ThreadID != GetCurrentThreadId())
  551.             break;
  552.         Ret = Thread32Next(hSnap, &TE32);
  553.     }
  554.     CloseHandle(hSnap);
  555.  
  556.     if (!Ret)
  557.         return nullptr;
  558.  
  559.     HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, TE32.th32ThreadID);
  560.     if (!hThread)
  561.         return nullptr;
  562.  
  563.     if (SuspendThread(hThread) == (DWORD)-1)
  564.     {
  565.         CloseHandle(hThread);
  566.         return nullptr;
  567.     }
  568.  
  569.     CONTEXT OldContext;
  570.     OldContext.ContextFlags = CONTEXT_CONTROL;
  571.     if (!GetThreadContext(hThread, &OldContext))
  572.     {
  573.         ResumeThread(hThread);
  574.         CloseHandle(hThread);
  575.         return nullptr;
  576.     }
  577.  
  578.     void * pCodecave = VirtualAllocEx(hTargetProc, nullptr, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  579.     if (!pCodecave)
  580.     {
  581.         ResumeThread(hThread);
  582.         CloseHandle(hThread);
  583.         return nullptr;
  584.     }
  585.  
  586.     #ifdef _WIN64
  587.  
  588.     Fastcall = true;
  589.  
  590.     BYTE Shellcode[] =
  591.     {
  592.         0x48, 0x83, 0xEC, 0x08,                                                     //sub rsp,08                    (+0x00)
  593.  
  594.         0xC7, 0x04, 0x24, 0xEF, 0xBE, 0xAD, 0xDE,                                   //mov [rsp],RipLowPart          (+0x04) (+0x07)
  595.         0xC7, 0x44, 0x24, 0x04, 0xEF, 0xBE, 0xAD, 0xDE,                             //mov [rsp+04],RipHighPart      (+0x0B) (+0x0F)
  596.  
  597.         0x50, 0x51, 0x52, 0x53, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53,     //push r(acdb)x r(8-11)         (+0x13)
  598.  
  599.         0x48, 0xBB, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,                 //mov rbx,pFunc                 (+0x1F) (+0x21)
  600.         0x48, 0xB9, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,                 //mov rcx,pArg                  (+0x29) (+0x2B)
  601.  
  602.         0x48, 0x83, 0xEC, 0x20,                                                     //sub rsp,32                    (+0x33)
  603.         0xFF, 0xD3,                                                                 //call rbx                      (+0x37)
  604.         0x48, 0x83, 0xC4, 0x20,                                                     //add rsp,32                    (+0x39)
  605.  
  606.         0x41, 0x5B, 0x41, 0x5A, 0x41, 0x59, 0x41, 0x58, 0x5B, 0x5A, 0x59, 0x58,     //pop r(11-8) r(bdca)x          (+0x3D)
  607.  
  608.         0xC6, 0x05, 0xB0, 0xFF, 0xFF, 0xFF, 0x00,                                   //mov byte ptr[$-0x49],0        (+0x49)
  609.  
  610.         0xC3                                                                        //ret                           (+0x50)
  611.     }; // SIZE = 0x51
  612.    
  613.     DWORD dwLoRIP = (DWORD)(OldContext.Rip & 0xFFFFFFFF);
  614.     DWORD dwHiRIP = (DWORD)((OldContext.Rip >> 0x20) & 0xFFFFFFFF);
  615.  
  616.     *ReCa<DWORD*>(Shellcode + 0x07) = dwLoRIP;
  617.     *ReCa<DWORD*>(Shellcode + 0x0F) = dwHiRIP;
  618.     *ReCa<void**>(Shellcode + 0x21) = pRoutine;
  619.     *ReCa<void**>(Shellcode + 0x2B) = pArg;
  620.  
  621.     OldContext.Rip = ReCa<DWORD64>(pCodecave);
  622.  
  623.     #else
  624.    
  625.     BYTE Shellcode[] =
  626.     {
  627.         0x60,                                       //pushad                        (+0x00)
  628.         0xE8, 0x00, 0x00, 0x00, 0x00,               //call pCodecave+6              (+0x01)
  629.        
  630.         0x58,                                       //pop eax                       (+0x06)
  631.  
  632.         0xB9, 0xEF, 0xBE, 0xAD, 0xDE,               //mov ecx,pArg                  (+0x07) (+0x08)
  633.         0xB8, 0xEF, 0xBE, 0xAD, 0xDE,               //mov eax,pFunc                 (+0x0C) (+0x0D)
  634.         0x90,                                       //__fastcall(default): nop      (+0x11)
  635.                                                     //__stdcall(assumed):  push ecx
  636.         0xFF, 0xD0,                                 //call eax                      (+0x12)
  637.        
  638.         0x61,                                       //popad                         (+0x14)
  639.  
  640.         0x68, 0xEF, 0xBE, 0xAD, 0xDE,               //push Eip                      (+0x15) (+0x16)
  641.  
  642.         0xC6, 0x05, 0xEF, 0xBE, 0xAD, 0xDE, 0x00,   //mov byte ptr[pCodecave],0     (+0x1A) (+0x1C)
  643.  
  644.         0xC3,                                       //ret                           (+0x21)
  645.     }; // SIZE = 0x22
  646.     if (!Fastcall)
  647.         Shellcode[0x11] = 0x51;
  648.  
  649.     *ReCa<void**>(Shellcode + 0x08) = pArg;
  650.     *ReCa<void**>(Shellcode + 0x0D) = pRoutine;
  651.     *ReCa<DWORD*>(Shellcode + 0x16) = OldContext.Eip;
  652.     *ReCa<void**>(Shellcode + 0x1C) = pCodecave;
  653.    
  654.     OldContext.Eip = ReCa<DWORD>(pCodecave);
  655.  
  656.     #endif
  657.  
  658.     if (!WriteProcessMemory(hTargetProc, pCodecave, Shellcode, sizeof(Shellcode), nullptr))
  659.     {
  660.         VirtualFreeEx(hTargetProc, pCodecave, MEM_RELEASE, 0);
  661.         ResumeThread(hThread);
  662.         CloseHandle(hThread);
  663.         return nullptr;
  664.     }
  665.  
  666.     if (!SetThreadContext(hThread, &OldContext))
  667.     {
  668.         VirtualFreeEx(hTargetProc, pCodecave, MEM_RELEASE, 0);
  669.         ResumeThread(hThread);
  670.         CloseHandle(hThread);
  671.         return nullptr;
  672.     }
  673.  
  674.     if (ResumeThread(hThread) == (DWORD)-1)
  675.     {
  676.         VirtualFreeEx(hTargetProc, pCodecave, MEM_RELEASE, 0);
  677.         CloseHandle(hThread);
  678.         return nullptr;
  679.     }
  680.  
  681.     BYTE CheckByte = 1;
  682.     while (CheckByte)
  683.         ReadProcessMemory(hTargetProc, pCodecave, &CheckByte, 1, nullptr);
  684.        
  685.     CloseHandle(hThread);
  686.     VirtualFreeEx(hTargetProc, pCodecave, MEM_RELEASE, 0); 
  687.    
  688.     return (HANDLE)1;
  689. }
  690.  
  691. PEB * GetPEB(HANDLE hProc)
  692. {
  693.     f_NtQueryInformationProcess pNtQueryInformationProcess =
  694.         reinterpret_cast<f_NtQueryInformationProcess>(
  695.             GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess"));
  696.  
  697.     if (!pNtQueryInformationProcess)
  698.         return nullptr;
  699.  
  700.     PROCESS_BASIC_INFORMATION PBI{ 0 };
  701.     ULONG SizeOut = 0;
  702.     if (pNtQueryInformationProcess(hProc, PROCESSINFOCLASS::ProcessBasicInformation, &PBI, sizeof(PBI), &SizeOut))
  703.         return nullptr;
  704.  
  705.     return PBI.pPEB;
  706. }
Add Comment
Please, Sign In to add comment