Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Injection.h"
- #pragma comment (lib, "Psapi.lib")
- #ifdef ReCa
- #undef ReCa
- #endif
- #define ReCa reinterpret_cast
- #ifdef UNICODE
- #undef Module32First
- #undef Module32Next
- #undef MODULEENTRY32
- #endif
- typedef HINSTANCE(__stdcall * f_LoadLibrary)(const char*);
- typedef uintptr_t(__stdcall * f_GetProcAddress)(HINSTANCE, const char*);
- typedef BOOL(__stdcall * f_DLL_ENTRY_POINT)(void*, DWORD, void*);
- struct LDR_LOAD_DLL_DATA
- {
- f_LdrLoadDll pLdrLoadDll;
- HANDLE Out;
- UNICODE_STRING pModuleFileName;
- BYTE Data[MAX_PATH * 2];
- };
- bool Inject(const char * szDllFile, HANDLE hProc, bool HijackThread);
- bool ManualMap(const char * szDllFile, HANDLE hProc, bool HijackThread);
- bool LdrLoadDllStub(const char * szDllFile, HANDLE hProc, bool HijackThread);
- bool Cloaking(const char * szDllFile, HANDLE hProc, DWORD Flags);
- UINT __forceinline _StrlenA(const char * szString);
- void __forceinline _ZeroMemory(BYTE * pMem, UINT Size);
- void __stdcall ImportTlsExecute(BYTE * pBase);
- void __stdcall LdrLoadDllShell(LDR_LOAD_DLL_DATA * pData);
- bool FileExistsA(const char * szFile);
- HANDLE StartRoutine(HANDLE hTargetProc, void * pRoutine, void * pArg, bool Hijack = false, bool Fastcall = true);
- PEB * GetPEB(HANDLE hProc);
- bool InjectDLL(const char * szDllFile, HANDLE hProc, INJECTION_MODE im, bool HijackThread, DWORD Postinjection)
- {
- bool Ret = false;
- switch (im)
- {
- case IM_LoadLibrary:
- Ret = Inject(szDllFile, hProc, HijackThread);
- break;
- case IM_LdrLoadDll:
- Ret = LdrLoadDllStub(szDllFile, hProc, HijackThread);
- break;
- case IM_ManualMap:
- return ManualMap(szDllFile, hProc, HijackThread);
- }
- if (Ret)
- return Cloaking(szDllFile, hProc, Postinjection);
- return false;
- }
- bool Inject(const char * szDllFile, HANDLE hProc, bool HijackThread)
- {
- if (!szDllFile || !hProc || !FileExistsA(szDllFile))
- return false;
- auto Len = lstrlenA(szDllFile);
- void * pArg = VirtualAllocEx(hProc, nullptr, Len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- if (!pArg)
- return false;
- if (!WriteProcessMemory(hProc, pArg, szDllFile, Len, nullptr))
- {
- VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
- return false;
- }
- DWORD dwExitCode = 0;
- HANDLE hThread = StartRoutine(hProc, LoadLibraryA, pArg, HijackThread, false);
- if (!hThread)
- {
- VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
- return false;
- }
- else if (!HijackThread)
- {
- WaitForSingleObject(hThread, INFINITE);
- GetExitCodeThread(hThread, &dwExitCode);
- CloseHandle(hThread);
- }
- else
- dwExitCode = 1;
- VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
- return (dwExitCode != 0);
- }
- bool ManualMap(const char * szDllFile, HANDLE hProc, bool HijackThread)
- {
- if (!szDllFile || !hProc || !FileExistsA(szDllFile))
- return false;
- BYTE * pSrcData;
- IMAGE_NT_HEADERS * pOldNtHeader;
- IMAGE_OPTIONAL_HEADER * pOldOptHeader;
- IMAGE_FILE_HEADER * pOldFileHeader;
- BYTE * pLocalBase;
- BYTE * pTargetBase;
- std::ifstream File(szDllFile, std::ios::binary | std::ios::ate);
- auto FileSize = File.tellg();
- if (FileSize <= 0x1000)
- {
- File.close();
- return false;
- }
- pSrcData = new BYTE[static_cast<UINT_PTR>(FileSize)];
- if (!pSrcData)
- {
- File.close();
- return false;
- }
- File.seekg(0, std::ios::beg);
- File.read(ReCa<char*>(pSrcData), FileSize);
- File.close();
- if (ReCa<IMAGE_DOS_HEADER*>(pSrcData)->e_magic != 0x5A4D)
- {
- delete[] pSrcData;
- return false;
- }
- pOldNtHeader = ReCa<IMAGE_NT_HEADERS*>(pSrcData + ReCa<IMAGE_DOS_HEADER*>(pSrcData)->e_lfanew);
- pOldOptHeader = &pOldNtHeader->OptionalHeader;
- pOldFileHeader = &pOldNtHeader->FileHeader;
- #ifdef _WIN64
- if (pOldFileHeader->Machine != IMAGE_FILE_MACHINE_AMD64)
- {
- delete[] pSrcData;
- return false;
- }
- #else
- if (pOldFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
- {
- delete[] pSrcData;
- return false;
- }
- #endif
- pTargetBase = ReCa<BYTE*>(VirtualAllocEx(hProc, ReCa<void*>(pOldOptHeader->ImageBase), pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
- if (!pTargetBase)
- pTargetBase = ReCa<BYTE*>(VirtualAllocEx(hProc, nullptr, pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
- if (!pTargetBase)
- {
- delete[] pSrcData;
- return false;
- }
- pLocalBase = ReCa<BYTE*>(VirtualAlloc(nullptr, pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
- if (!pLocalBase)
- {
- delete[] pSrcData;
- VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);
- return false;
- }
- memset(pLocalBase, 0, pOldOptHeader->SizeOfImage);
- memcpy(pLocalBase, pSrcData, 0x1000);
- auto * pSectionHeader = IMAGE_FIRST_SECTION(pOldNtHeader);
- for (UINT i = 0; i < pOldFileHeader->NumberOfSections; ++i, ++pSectionHeader)
- if (pSectionHeader->SizeOfRawData)
- memcpy(pLocalBase + pSectionHeader->VirtualAddress, pSrcData + pSectionHeader->PointerToRawData, pSectionHeader->SizeOfRawData);
- delete[] pSrcData;
- BYTE * LocationDelta = pTargetBase - pOldOptHeader->ImageBase;
- if (LocationDelta)
- {
- if (!pOldOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)
- {
- VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);
- VirtualFree(pLocalBase, 0, MEM_RELEASE);
- return false;
- }
- auto * pRelocData = ReCa<IMAGE_BASE_RELOCATION*>(pLocalBase + pOldOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
- while (pRelocData->VirtualAddress)
- {
- WORD * pRelativeInfo = ReCa<WORD*>(pRelocData + 1);
- for (UINT i = 0; i < ((pRelocData->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2); ++i, ++pRelativeInfo)
- {
- #ifndef _WIN64
- if ((*pRelativeInfo >> 0x0C) == IMAGE_REL_BASED_HIGHLOW)
- {
- DWORD * pPatch = ReCa<DWORD*>(pLocalBase + pRelocData->VirtualAddress + ((*pRelativeInfo) & 0xFFF));
- *pPatch += ReCa<DWORD>(LocationDelta);
- }
- #else
- if ((*pRelativeInfo >> 0x0C) == IMAGE_REL_BASED_DIR64)
- {
- UINT_PTR * pPatch = ReCa<UINT_PTR*>(pLocalBase + pRelocData->VirtualAddress + ((*pRelativeInfo) & 0xFFF));
- *pPatch += ReCa<UINT_PTR>(LocationDelta);
- }
- #endif
- }
- pRelocData = ReCa<IMAGE_BASE_RELOCATION*>(ReCa<BYTE*>(pRelocData) + pRelocData->SizeOfBlock);
- }
- }
- *ReCa<f_LoadLibrary*>(pLocalBase) = LoadLibraryA;
- *ReCa<f_GetProcAddress*>(pLocalBase + 8) = ReCa<f_GetProcAddress>(GetProcAddress);
- BOOL Ret = WriteProcessMemory(hProc, pTargetBase, pLocalBase, pOldOptHeader->SizeOfImage, nullptr);
- VirtualFree(pLocalBase, 0, MEM_RELEASE);
- if (!Ret)
- return false;
- ULONG_PTR FuncSize = 0x800;
- void * pFunc = VirtualAllocEx(hProc, nullptr, FuncSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- if (!pFunc)
- return false;
- if (!WriteProcessMemory(hProc, pFunc, ImportTlsExecute, FuncSize, nullptr))
- {
- VirtualFreeEx(hProc, pFunc, 0, MEM_RELEASE);
- return false;
- }
- HANDLE hThread = StartRoutine(hProc, pFunc, pTargetBase, HijackThread, false);
- if (!hThread)
- {
- VirtualFreeEx(hProc, pFunc, 0, MEM_RELEASE);
- VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);
- return false;
- }
- else if (!HijackThread)
- {
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- }
- VirtualFreeEx(hProc, pFunc, 0, MEM_RELEASE);
- return true;
- }
- bool LdrLoadDllStub(const char * szDllFile, HANDLE hProc, bool HijackThread)
- {
- if (!szDllFile || !hProc || !FileExistsA(szDllFile))
- return false;
- LDR_LOAD_DLL_DATA data{ 0 };
- data.pModuleFileName.szBuffer = ReCa<wchar_t*>(data.Data);
- data.pModuleFileName.MaxLength = MAX_PATH * 2;
- size_t len = _StrlenA(szDllFile);
- mbstowcs_s(&len, data.pModuleFileName.szBuffer, len + 1, szDllFile, len);
- data.pModuleFileName.Length = (WORD)(len * 2) - 2;
- HINSTANCE hNTDLL = GetModuleHandleA("ntdll.dll");
- if (!hNTDLL)
- return false;
- FARPROC pFunc = GetProcAddress(hNTDLL, "LdrLoadDll");
- if (!pFunc)
- return false;
- data.pLdrLoadDll = ReCa<f_LdrLoadDll>(pFunc);
- BYTE * pArg = ReCa<BYTE*>(VirtualAllocEx(hProc, nullptr, sizeof(LDR_LOAD_DLL_DATA) + 0x200, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
- if (!pArg)
- return false;
- if (!WriteProcessMemory(hProc, pArg, &data, sizeof(LDR_LOAD_DLL_DATA), nullptr))
- {
- VirtualFreeEx(hProc, pArg, MEM_RELEASE, 0);
- return false;
- }
- if (!WriteProcessMemory(hProc,pArg + sizeof(LDR_LOAD_DLL_DATA), LdrLoadDllShell, 0x100, nullptr))
- {
- VirtualFreeEx(hProc, pArg, MEM_RELEASE, 0);
- return false;
- }
- HANDLE hThread = StartRoutine(hProc, pArg + sizeof(LDR_LOAD_DLL_DATA), pArg, HijackThread, false);
- if (!hThread)
- {
- VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
- return false;
- }
- else if (!HijackThread)
- {
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- }
- VirtualFreeEx(hProc, pArg, 0, MEM_RELEASE);
- return true;
- }
- bool Cloaking(const char * szDllFile, HANDLE hProc, DWORD Flags)
- {
- if (!Flags)
- return true;
- if (Flags > INJ_FLAGS_ALL)
- return false;
- HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetProcessId(hProc));
- if (!hSnap)
- return false;
- MODULEENTRY32 ME32{ 0 };
- ME32.dwSize = sizeof(MODULEENTRY32);
- HINSTANCE hMod = 0;
- BOOL Ret = Module32First(hSnap, &ME32);
- while (Ret)
- {
- char Buffer[MAX_PATH]{ 0 };
- GetModuleFileNameExA(hProc, ReCa<HINSTANCE>(ME32.modBaseAddr), Buffer, MAX_PATH);
- if (Buffer[3] == szDllFile[3] && !lstrcmpA(szDllFile, Buffer))
- {
- hMod = ME32.hModule;
- break;
- }
- Ret = Module32Next(hSnap, &ME32);
- }
- CloseHandle(hSnap);
- if (!Ret || !hMod)
- return false;
- if (Flags & INJ_FAKE_HEADER)
- {
- void * pK32 = ReCa<void*>(GetModuleHandleA("kernel32.dll"));
- DWORD dwOld = 0;
- VirtualProtectEx(hProc, hMod, 0x1000, PAGE_EXECUTE_READWRITE, &dwOld);
- WriteProcessMemory(hProc, hMod, pK32, 0x1000, nullptr);
- VirtualProtectEx(hProc, hMod, 0x1000, dwOld, &dwOld);
- }
- else if (Flags & INJ_ERASE_HEADER)
- {
- BYTE Buffer[0x1000];
- memset(Buffer, 0, 0x1000);
- DWORD dwOld = 0;
- VirtualProtectEx(hProc, hMod, 0x1000, PAGE_EXECUTE_READWRITE, &dwOld);
- WriteProcessMemory(hProc, hMod, Buffer, 0x1000, nullptr);
- }
- if (Flags & INJ_UNLINK_FROM_PEB)
- {
- PEB * ppeb;
- PEB peb;
- PEB_LDR_DATA ldrdata;
- LDR_DATA_TABLE_ENTRY * pCurrent;
- LDR_DATA_TABLE_ENTRY current;
- LIST_ENTRY flink;
- LIST_ENTRY blink;
- ppeb = GetPEB(hProc);
- ReadProcessMemory(hProc, ppeb, &peb, sizeof(PEB), nullptr);
- ReadProcessMemory(hProc, peb.pLdrData, &ldrdata, sizeof(PEB_LDR_DATA), nullptr);
- pCurrent = ReCa<LDR_DATA_TABLE_ENTRY*>(ldrdata.InLoadOrderModuleListHead.Flink);
- do
- {
- ReadProcessMemory(hProc, pCurrent, ¤t, sizeof(LDR_DATA_TABLE_ENTRY), nullptr);
- if (current.DllBase == hMod)
- {
- ReadProcessMemory(hProc, current.InLoadOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
- ReadProcessMemory(hProc, current.InLoadOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
- flink.Blink = current.InLoadOrder.Blink;
- blink.Flink = current.InLoadOrder.Flink;
- WriteProcessMemory(hProc, current.InLoadOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
- WriteProcessMemory(hProc, current.InLoadOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
- ReadProcessMemory(hProc, current.InMemoryOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
- ReadProcessMemory(hProc, current.InMemoryOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
- flink.Blink = current.InMemoryOrder.Blink;
- blink.Flink = current.InMemoryOrder.Flink;
- WriteProcessMemory(hProc, current.InMemoryOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
- WriteProcessMemory(hProc, current.InMemoryOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
- ReadProcessMemory(hProc, current.InInitOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
- ReadProcessMemory(hProc, current.InInitOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
- flink.Blink = current.InInitOrder.Blink;
- blink.Flink = current.InInitOrder.Flink;
- WriteProcessMemory(hProc, current.InInitOrder.Flink, &flink, sizeof(LIST_ENTRY), nullptr);
- WriteProcessMemory(hProc, current.InInitOrder.Blink, &blink, sizeof(LIST_ENTRY), nullptr);
- BYTE Buffer[MAX_PATH * 2]{0};
- WriteProcessMemory(hProc, current.BaseDllName.szBuffer, Buffer, current.BaseDllName.MaxLength, nullptr);
- WriteProcessMemory(hProc, current.FullDllName.szBuffer, Buffer, current.FullDllName.MaxLength, nullptr);
- WriteProcessMemory(hProc, pCurrent, Buffer, sizeof(LDR_DATA_TABLE_ENTRY), nullptr);
- return true;
- }
- pCurrent = ReCa<LDR_DATA_TABLE_ENTRY*>(current.InLoadOrder.Flink);
- }
- while (current.InLoadOrder.Flink != ldrdata.InLoadOrderModuleListHead.Flink);
- }
- return false;
- }
- #include <iostream>
- UINT __forceinline _StrlenA(const char * szString)
- {
- UINT Ret = 0;
- while (*szString)
- {
- ++Ret;
- ++szString;
- }
- return Ret;
- }
- void __forceinline _ZeroMemory(BYTE * pMem, UINT Size)
- {
- for (BYTE * i = pMem; i < pMem + Size; ++i)
- *i = 0x00;
- }
- void __stdcall ImportTlsExecute(BYTE * pBase)
- {
- auto * pOp = &ReCa<IMAGE_NT_HEADERS*>(pBase + ReCa<IMAGE_DOS_HEADER*>(pBase)->e_lfanew)->OptionalHeader;
- auto _LoadLibraryA = *ReCa<f_LoadLibrary*>(pBase);
- auto _GetProcAddress = *ReCa<f_GetProcAddress*>(pBase + 8);
- auto _DllMain = ReCa<f_DLL_ENTRY_POINT>(pBase + pOp->AddressOfEntryPoint);
- if (pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
- {
- auto * pImportDescr = ReCa<IMAGE_IMPORT_DESCRIPTOR*>(pBase + pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
- while (pImportDescr->Name)
- {
- HINSTANCE hDll = _LoadLibraryA(ReCa<const char*>(pBase + pImportDescr->Name));
- ULONG_PTR * pThunkRef = ReCa<ULONG_PTR*>(pBase + pImportDescr->OriginalFirstThunk);
- ULONG_PTR * pFuncRef = ReCa<ULONG_PTR*>(pBase + pImportDescr->FirstThunk);
- _ZeroMemory(pBase + pImportDescr->Name, _StrlenA(ReCa<char*>(pBase + pImportDescr->Name)));
- if (!pImportDescr->OriginalFirstThunk)
- pThunkRef = pFuncRef;
- for (; *pThunkRef; ++pThunkRef, ++pFuncRef)
- {
- if (IMAGE_SNAP_BY_ORDINAL(*pThunkRef))
- {
- *pFuncRef = _GetProcAddress(hDll, ReCa<const char*>(*pThunkRef & 0xFFFF));
- _ZeroMemory(ReCa<BYTE*>(*pThunkRef & 0xFFFF), _StrlenA(ReCa<char*>(*pThunkRef & 0xFFFF)));
- }
- else
- {
- auto * pImport = ReCa<IMAGE_IMPORT_BY_NAME*>(pBase + (*pThunkRef));
- *pFuncRef = _GetProcAddress(hDll, ReCa<const char*>(&pImport->Name));
- _ZeroMemory(ReCa<BYTE*>(&pImport->Name), _StrlenA(ReCa<char*>(&pImport->Name)));
- }
- }
- ++pImportDescr;
- }
- }
- if (pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size)
- {
- auto * pTLS = ReCa<IMAGE_TLS_DIRECTORY*>(pBase + pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
- auto * pCallback = ReCa<PIMAGE_TLS_CALLBACK*>(pTLS->AddressOfCallBacks);
- for (; pCallback && *pCallback; ++pCallback)
- (*pCallback)(pBase, DLL_PROCESS_ATTACH, nullptr);
- }
- for (UINT i = 0; i <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR; ++i)
- {
- if (i == IMAGE_DIRECTORY_ENTRY_IAT)
- continue;
- DWORD Size = pOp->DataDirectory[i].Size;
- if (Size)
- _ZeroMemory(pBase + pOp->DataDirectory[i].VirtualAddress, Size);
- }
- _DllMain(pBase, DLL_PROCESS_ATTACH, nullptr);
- for (UINT i = 0; i != 0x1000; i += sizeof(ULONG64))
- *ReCa<ULONG64*>(pBase + i) = 0;
- }
- void __stdcall LdrLoadDllShell(LDR_LOAD_DLL_DATA * pData)
- {
- if (!pData)
- return;
- pData->pModuleFileName.szBuffer = ReCa<wchar_t*>(pData->Data);
- pData->pLdrLoadDll(nullptr, 0, &pData->pModuleFileName, &pData->Out);
- }
- bool FileExistsA(const char * szFile)
- {
- return (GetFileAttributesA(szFile) != INVALID_FILE_ATTRIBUTES);
- }
- HANDLE StartRoutine(HANDLE hTargetProc, void * pRoutine, void * pArg, bool Hijack, bool Fastcall)
- {
- if (!hTargetProc || !pRoutine)
- return nullptr;
- if (!Hijack)
- {
- HINSTANCE hNtDll = GetModuleHandleA("ntdll.dll");
- auto pNtCreateThreadEx = ReCa<f_NtCreateThreadEx>(GetProcAddress(hNtDll, "NtCreateThreadEx"));
- if (!pNtCreateThreadEx)
- return CreateRemoteThreadEx(hTargetProc, nullptr, 0, ReCa<LPTHREAD_START_ROUTINE>(pRoutine), pArg, 0, nullptr, nullptr);
- HANDLE hRet = nullptr;
- pNtCreateThreadEx(&hRet, THREAD_ALL_ACCESS, nullptr, hTargetProc, pRoutine, pArg, 0, 0, 0, 0, nullptr);
- return hRet;
- }
- DWORD dwProcId = GetProcessId(hTargetProc);
- if (!dwProcId)
- return nullptr;
- HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
- if (!hSnap)
- return nullptr;
- THREADENTRY32 TE32 = { 0 };
- TE32.dwSize = sizeof(THREADENTRY32);
- BOOL Ret = Thread32First(hSnap, &TE32);
- while (Ret)
- {
- if (TE32.th32OwnerProcessID == dwProcId && TE32.th32ThreadID != GetCurrentThreadId())
- break;
- Ret = Thread32Next(hSnap, &TE32);
- }
- CloseHandle(hSnap);
- if (!Ret)
- return nullptr;
- HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, TE32.th32ThreadID);
- if (!hThread)
- return nullptr;
- if (SuspendThread(hThread) == (DWORD)-1)
- {
- CloseHandle(hThread);
- return nullptr;
- }
- CONTEXT OldContext;
- OldContext.ContextFlags = CONTEXT_CONTROL;
- if (!GetThreadContext(hThread, &OldContext))
- {
- ResumeThread(hThread);
- CloseHandle(hThread);
- return nullptr;
- }
- void * pCodecave = VirtualAllocEx(hTargetProc, nullptr, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- if (!pCodecave)
- {
- ResumeThread(hThread);
- CloseHandle(hThread);
- return nullptr;
- }
- #ifdef _WIN64
- Fastcall = true;
- BYTE Shellcode[] =
- {
- 0x48, 0x83, 0xEC, 0x08, //sub rsp,08 (+0x00)
- 0xC7, 0x04, 0x24, 0xEF, 0xBE, 0xAD, 0xDE, //mov [rsp],RipLowPart (+0x04) (+0x07)
- 0xC7, 0x44, 0x24, 0x04, 0xEF, 0xBE, 0xAD, 0xDE, //mov [rsp+04],RipHighPart (+0x0B) (+0x0F)
- 0x50, 0x51, 0x52, 0x53, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, //push r(acdb)x r(8-11) (+0x13)
- 0x48, 0xBB, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //mov rbx,pFunc (+0x1F) (+0x21)
- 0x48, 0xB9, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //mov rcx,pArg (+0x29) (+0x2B)
- 0x48, 0x83, 0xEC, 0x20, //sub rsp,32 (+0x33)
- 0xFF, 0xD3, //call rbx (+0x37)
- 0x48, 0x83, 0xC4, 0x20, //add rsp,32 (+0x39)
- 0x41, 0x5B, 0x41, 0x5A, 0x41, 0x59, 0x41, 0x58, 0x5B, 0x5A, 0x59, 0x58, //pop r(11-8) r(bdca)x (+0x3D)
- 0xC6, 0x05, 0xB0, 0xFF, 0xFF, 0xFF, 0x00, //mov byte ptr[$-0x49],0 (+0x49)
- 0xC3 //ret (+0x50)
- }; // SIZE = 0x51
- DWORD dwLoRIP = (DWORD)(OldContext.Rip & 0xFFFFFFFF);
- DWORD dwHiRIP = (DWORD)((OldContext.Rip >> 0x20) & 0xFFFFFFFF);
- *ReCa<DWORD*>(Shellcode + 0x07) = dwLoRIP;
- *ReCa<DWORD*>(Shellcode + 0x0F) = dwHiRIP;
- *ReCa<void**>(Shellcode + 0x21) = pRoutine;
- *ReCa<void**>(Shellcode + 0x2B) = pArg;
- OldContext.Rip = ReCa<DWORD64>(pCodecave);
- #else
- BYTE Shellcode[] =
- {
- 0x60, //pushad (+0x00)
- 0xE8, 0x00, 0x00, 0x00, 0x00, //call pCodecave+6 (+0x01)
- 0x58, //pop eax (+0x06)
- 0xB9, 0xEF, 0xBE, 0xAD, 0xDE, //mov ecx,pArg (+0x07) (+0x08)
- 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, //mov eax,pFunc (+0x0C) (+0x0D)
- 0x90, //__fastcall(default): nop (+0x11)
- //__stdcall(assumed): push ecx
- 0xFF, 0xD0, //call eax (+0x12)
- 0x61, //popad (+0x14)
- 0x68, 0xEF, 0xBE, 0xAD, 0xDE, //push Eip (+0x15) (+0x16)
- 0xC6, 0x05, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, //mov byte ptr[pCodecave],0 (+0x1A) (+0x1C)
- 0xC3, //ret (+0x21)
- }; // SIZE = 0x22
- if (!Fastcall)
- Shellcode[0x11] = 0x51;
- *ReCa<void**>(Shellcode + 0x08) = pArg;
- *ReCa<void**>(Shellcode + 0x0D) = pRoutine;
- *ReCa<DWORD*>(Shellcode + 0x16) = OldContext.Eip;
- *ReCa<void**>(Shellcode + 0x1C) = pCodecave;
- OldContext.Eip = ReCa<DWORD>(pCodecave);
- #endif
- if (!WriteProcessMemory(hTargetProc, pCodecave, Shellcode, sizeof(Shellcode), nullptr))
- {
- VirtualFreeEx(hTargetProc, pCodecave, MEM_RELEASE, 0);
- ResumeThread(hThread);
- CloseHandle(hThread);
- return nullptr;
- }
- if (!SetThreadContext(hThread, &OldContext))
- {
- VirtualFreeEx(hTargetProc, pCodecave, MEM_RELEASE, 0);
- ResumeThread(hThread);
- CloseHandle(hThread);
- return nullptr;
- }
- if (ResumeThread(hThread) == (DWORD)-1)
- {
- VirtualFreeEx(hTargetProc, pCodecave, MEM_RELEASE, 0);
- CloseHandle(hThread);
- return nullptr;
- }
- BYTE CheckByte = 1;
- while (CheckByte)
- ReadProcessMemory(hTargetProc, pCodecave, &CheckByte, 1, nullptr);
- CloseHandle(hThread);
- VirtualFreeEx(hTargetProc, pCodecave, MEM_RELEASE, 0);
- return (HANDLE)1;
- }
- PEB * GetPEB(HANDLE hProc)
- {
- f_NtQueryInformationProcess pNtQueryInformationProcess =
- reinterpret_cast<f_NtQueryInformationProcess>(
- GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess"));
- if (!pNtQueryInformationProcess)
- return nullptr;
- PROCESS_BASIC_INFORMATION PBI{ 0 };
- ULONG SizeOut = 0;
- if (pNtQueryInformationProcess(hProc, PROCESSINFOCLASS::ProcessBasicInformation, &PBI, sizeof(PBI), &SizeOut))
- return nullptr;
- return PBI.pPEB;
- }
Add Comment
Please, Sign In to add comment