龙马谷

 找回密码
 立即注册

QQ登录

只需一步,快速开始

龙马谷VIP会员办理客服QQ:82926983(如果临时会话没有收到回复,请先加QQ好友再发。)
1 [已完结] GG修改器新手入门与实战教程 31课 2 [已完结] GG修改器美化修改教程 6课 3 [已完结] GG修改器Lua脚本新手入门教程 12课
4 [已完结] 触动精灵脚本新手入门必学教程 22课 5 [已完结] 手游自动化脚本入门实战教程 9课 6 [已完结] C++射击游戏方框骨骼透视与自瞄教程 27课
7 [已完结] C++零基础UE4逆向开发FPS透视自瞄教程 29课 8 [已完结] C++零基础大漠模拟器手游自动化辅助教程 22课 9 [已完结] C++零基础开发DXF内存脚本辅助教程 32课
以下是天马阁VIP教程,本站与天马阁合作,赞助VIP可以获得天马阁对应VIP会员,名额有限! 点击进入天马阁论坛
1 [已完结] x64CE与x64dbg入门基础教程 7课 2 [已完结] x64汇编语言基础教程 16课 3 [已完结] x64辅助入门基础教程 9课
4 [已完结] C++x64内存辅助实战技术教程 149课 5 [已完结] C++x64内存检测与过检测技术教程 10课 6 [已完结] C+x64二叉树分析遍历与LUA自动登陆教程 19课
7 [已完结] C++BT功能原理与x64实战教程 29课 8 [已完结] C+FPS框透视与自瞄x64实现原理及防护思路
查看: 4116|回复: 0

C++ Win32/X64 通用Shellcode注入csrss进程

[复制链接]

31

主题

3

回帖

43

积分

编程入门

Rank: 1

龙马币
93

这是做的一些研究,觉得没什么用处,人生不应该把精力放在这些小打小闹的垃圾玩意身上;先讲一下文章的主题这样做的目的,这样做免去了用汇编代码限制,纯C++编写的东西移植性高.

注入csrss进程要点:只能用导入表之存在ntdll的dll进行注入,否则会失败.其他要点基本上没什么了,csrss进程pid使用CsrGetProcessId函数获取,免去了遍历进程的痛苦.

看下我们的注入器(这是Win32/x64通用的).
代码:
  1. #include "main.h"
  2. #include "base/component_name.h"

  3. namespace bootldr{
  4.   static HANDLE WINAPI ShellcodeBegin(PTHREAD_DATA parameter){
  5.     if (parameter->fnRtlInitUnicodeString != nullptr&&parameter->fnLdrLoadDll != nullptr){
  6.       UNICODE_STRING UnicodeString;
  7.       parameter->fnRtlInitUnicodeString(&UnicodeString, parameter->dllpath);
  8.       HANDLE module_handle = nullptr;
  9.       return (HANDLE)parameter->fnLdrLoadDll(nullptr, nullptr, &UnicodeString, &module_handle);
  10.     }
  11.     else{
  12.       return (HANDLE)-3;
  13.     }
  14.   }
  15.   static DWORD WINAPI ShellcodeEnd(){
  16.     return 0;
  17.   }
  18.   static bool SetProcessPrivilege(DWORD SE_DEBUG_PRIVILEGE = 0x14){
  19.     BOOLEAN bl;
  20.     RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &bl);
  21.     return bl;
  22.   }
  23.   static bool ProcessInternalExecute(PTHREAD_DATA parameter,DWORD process_id){
  24.     HANDLE hProcess = nullptr;
  25.     CLIENT_ID cid = { (HANDLE)process_id, nullptr };
  26.     OBJECT_ATTRIBUTES oa;
  27.     InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL);
  28.     if (!NT_SUCCESS(NtOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &oa, &cid))){
  29.       return false;
  30.     }
  31.     PVOID data = VirtualAllocEx(hProcess, NULL, 0x2000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
  32.     PVOID code = VirtualAllocEx(hProcess, NULL, 0x2000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  33.     if (!data || !code){
  34.       NtClose(hProcess);
  35.       return false;
  36.     }
  37.     NtWriteVirtualMemory(hProcess, data, parameter, sizeof(THREAD_DATA), NULL);
  38.     NtWriteVirtualMemory(hProcess, code, (PVOID)ShellcodeBegin, (ULONG)((LPBYTE)ShellcodeEnd - (LPBYTE)ShellcodeBegin), NULL);
  39.     HANDLE hThread = nullptr;
  40.     if (!NT_SUCCESS(RtlCreateUserThread(hProcess, NULL, FALSE, 0, 0, 0, code, data, &hThread, NULL))){
  41.       NtClose(hProcess);
  42.       return false;
  43.     }
  44.     NtWaitForSingleObject(hThread, FALSE, NULL);
  45.     DWORD exit_code = -1;
  46.     GetExitCodeThread(hThread, &exit_code);
  47.     NtClose(hThread);
  48.     VirtualFreeEx(hProcess, data, 0, MEM_RELEASE);
  49.     VirtualFreeEx(hProcess, code, 0, MEM_RELEASE);
  50.     NtClose(hProcess);
  51.     return (exit_code==0);
  52.   }
  53.   std::wstring GetAbsolutePath(const std::wstring& name){
  54.     wchar_t fileName[MAX_PATH] = {0};
  55.     GetModuleFileNameW(NULL, fileName, MAX_PATH);
  56.     PathRemoveFileSpec(fileName);
  57.     return std::wstring(fileName).append(name);
  58.   }
  59.   void SetShellcodeLdrModulePath(PTHREAD_DATA parameter,const std::wstring& srcfile){
  60.     wcscpy_s(parameter->dllpath, srcfile.c_str());
  61.   }
  62. }

  63. int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nShowCmd){
  64.   THREAD_DATA parameter = {0};
  65.   parameter.fnRtlInitUnicodeString = (pRtlInitUnicodeString)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlInitUnicodeString");
  66.   parameter.fnLdrLoadDll = (pLdrLoadDll)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "LdrLoadDll");
  67.   parameter.fnGetTempPathW = (pGetTempPathW)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetTempPathW");
  68.   parameter.fnGetSystemDirectoryW = (pGetSystemDirectoryW)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetSystemDirectoryW");
  69.   parameter.fnGetVolumeInformationW = (pGetVolumeInformationW)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetVolumeInformationW");
  70.   bootldr::SetProcessPrivilege();
  71.   bootldr::SetShellcodeLdrModulePath(&parameter, bootldr::GetAbsolutePath(base::kBootldrName));
  72.   bootldr::ProcessInternalExecute(&parameter, GetCurrentProcessId()/*CsrGetProcessId()*/);
  73.     return 0;
  74. }
复制代码


这里再看一下我们的shellcode式的加载器,该动态库加载一个第三方dll,没有导入任何函数,全部函数通过动态获取(如果你不知道怎么动态获取,请先去研究PEB链表).

代码:
  1. namespace Function{
  2.   HANDLE GetKernel32Handle(){
  3.     HANDLE hKernel32 = INVALID_HANDLE_VALUE;
  4. #ifdef _WIN64
  5.     PPEB lpPeb = (PPEB)__readgsqword(0x60);
  6. #else
  7.     PPEB lpPeb = (PPEB)__readfsdword(0x30);
  8. #endif
  9.     PLIST_ENTRY pListHead = &lpPeb->Ldr->InMemoryOrderModuleList;
  10.     PLIST_ENTRY pListEntry = pListHead->Flink;
  11.     WCHAR strDllName[MAX_PATH];
  12.     WCHAR strKernel32[] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', L'\0' };

  13.     while (pListEntry != pListHead){
  14.       PLDR_DATA_TABLE_ENTRY pModEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
  15.       if (pModEntry->FullDllName.Length){
  16.         DWORD dwLen = pModEntry->FullDllName.Length;
  17.         __MEMCPY__(strDllName, pModEntry->FullDllName.Buffer, dwLen);
  18.         strDllName[dwLen / sizeof(WCHAR)] = L'\0';
  19.         if (__STRSTRIW__(strDllName, strKernel32)){
  20.           hKernel32 = pModEntry->DllBase;
  21.           break;
  22.         }
  23.       }
  24.       pListEntry = pListEntry->Flink;
  25.     }
  26.     return hKernel32;
  27.   }

  28.   BOOL Initialize(){
  29.     HANDLE hKernel32 = GetKernel32Handle();
  30.     if (hKernel32 == INVALID_HANDLE_VALUE){
  31.       return FALSE;
  32.     }
  33.     LPBYTE lpBaseAddr = (LPBYTE)hKernel32;
  34.     PIMAGE_DOS_HEADER lpDosHdr = (PIMAGE_DOS_HEADER)lpBaseAddr;
  35.     PIMAGE_NT_HEADERS pNtHdrs = (PIMAGE_NT_HEADERS)(lpBaseAddr + lpDosHdr->e_lfanew);
  36.     PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(lpBaseAddr + pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

  37.     LPDWORD pNameArray = (LPDWORD)(lpBaseAddr + pExportDir->AddressOfNames);
  38.     LPDWORD pAddrArray = (LPDWORD)(lpBaseAddr + pExportDir->AddressOfFunctions);
  39.     LPWORD pOrdArray = (LPWORD)(lpBaseAddr + pExportDir->AddressOfNameOrdinals);
  40.     CHAR strLoadLibraryA[] = { 'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'W', 0x0 };
  41.     CHAR strGetProcAddress[] = { 'G', 'e', 't', 'P', 'r', 'o', 'c', 'A', 'd', 'd', 'r', 'e', 's', 's', 0x0 };

  42.     for (UINT i = 0; i < pExportDir->NumberOfNames; i++){
  43.       LPSTR pFuncName = (LPSTR)(lpBaseAddr + pNameArray[i]);
  44.       if (!__STRCMPI__(pFuncName, strGetProcAddress)){
  45.         GetProcAddressAPI = (FARPROC(WINAPI*)(HMODULE, LPCSTR))(lpBaseAddr + pAddrArray[pOrdArray[i]]);
  46.       }
  47.       else if (!__STRCMPI__(pFuncName, strLoadLibraryA)){
  48.         LoadLibraryWAPI = (HMODULE(WINAPI*)(LPCWSTR))(lpBaseAddr + pAddrArray[pOrdArray[i]]);
  49.       }
  50.       if (GetProcAddressAPI != nullptr && LoadLibraryWAPI != nullptr){
  51.         return TRUE;
  52.       }
  53.     }
  54.     return FALSE;
  55.   }


  56.   FARPROC GetAddress(const char* function_name){
  57. #ifdef OS_WIN_64
  58.     PPEB lpPeb = (PPEB)__readgsqword(0x60);
  59. #else
  60.     PPEB lpPeb = (PPEB)__readfsdword(0x30);
  61. #endif
  62.     PLIST_ENTRY pListHead = &lpPeb->Ldr->InMemoryOrderModuleList;
  63.     PLIST_ENTRY pListEntry = pListHead->Flink;
  64.     while (pListEntry != pListHead){
  65.       PLDR_DATA_TABLE_ENTRY pModEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
  66.       if (pModEntry->FullDllName.Length){
  67.         FARPROC address = GetProcAddressAPI(LoadLibraryWAPI(pModEntry->FullDllName.Buffer), function_name);
  68.         if (address){
  69.           return address;
  70.         }
  71.       }
  72.       pListEntry = pListEntry->Flink;
  73.     }
  74.     return nullptr;
  75.   }


  76.   bool ImportDll(){
  77.     using OLE_INITIALIZE = HRESULT(WINAPI*)(LPVOID);
  78.     wchar_t dll_ole32[] = { L'O', L'l', L'e', L'3', L'2', L'.', L'd', L'l', L'l', 0 };
  79.     char dll_ole32_api[] = { 'O', 'l', 'e', 'I', 'n', 'i', 't', 'i', 'a', 'l', 'i', 'z', 'e', 0 };
  80.     OLE_INITIALIZE ole_initialize = reinterpret_cast<OLE_INITIALIZE>(GetProcAddressAPI(LoadLibraryWAPI(dll_ole32), dll_ole32_api));
  81.     using INIT_COMMON_CONTROLS_EX = void (WINAPI*)(const void*);
  82.     wchar_t dll_comctl32[] = { L'C', L'o', L'm', L'c', L't', L'l', L'3', L'2', L'.', L'd', L'l', L'l', 0 };
  83.     char dll_comctl32_api[] = { 'I', 'n', 'i', 't', 'C', 'o', 'm', 'm', 'o', 'n', 'C', 'o', 'n', 't', 'r', 'o', 'l', 's', 'E', 'x', 0 };
  84.     INIT_COMMON_CONTROLS_EX init_common_controls_ex = reinterpret_cast<INIT_COMMON_CONTROLS_EX>(GetProcAddressAPI(LoadLibraryWAPI(dll_comctl32), dll_comctl32_api));
  85.     if (ole_initialize == nullptr || init_common_controls_ex == nullptr){
  86.       return false;
  87.     }
  88.     init_common_controls_ex(nullptr);
  89.     return (ole_initialize(nullptr) == S_OK);
  90.   }


  91.   HMODULE LoadPluginEngine(HMODULE hModule, const wchar_t* name){
  92.     DWORD(WINAPI* GetModuleFileNameWAPI)(HMODULE, LPWSTR, DWORD);
  93.     GetModuleFileNameWAPI = (DWORD(WINAPI*)(HMODULE, LPWSTR, DWORD))Function::GetAddress("GetModuleFileNameW");
  94.     HRESULT(STDAPICALLTYPE* PathRemoveFileSpecWPI)(LPWSTR);
  95.     PathRemoveFileSpecWPI = (HRESULT(STDAPICALLTYPE*)(LPWSTR))Function::GetAddress("PathRemoveFileSpecW");
  96.     if (GetModuleFileNameWAPI!=nullptr&&PathRemoveFileSpecWPI != nullptr){
  97.       wchar_t fileName[MAX_PATH];
  98.       GetModuleFileNameWAPI(hModule, fileName, MAX_PATH);
  99.       PathRemoveFileSpecWPI(fileName);
  100.       __STRCATW__(fileName, (LPWSTR)name);
  101.       return LoadLibraryWAPI(fileName);
  102.     }
  103.     return nullptr;
  104.   }
  105. }


  106. BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){
  107.   static HMODULE ldr = nullptr;
  108.   if(ul_reason_for_call==DLL_PROCESS_ATTACH){
  109.     Function::Initialize();
  110.     Function::ImportDll();
  111.     if (DisableThreadLibraryCallsAPI == nullptr){
  112.       DisableThreadLibraryCallsAPI = (BOOL(WINAPI*)(HMODULE))Function::GetAddress("DisableThreadLibraryCalls");
  113.       DisableThreadLibraryCallsAPI(hModule);
  114.     }
  115.     if (RtlAdjustPrivilege==nullptr){
  116.       BOOLEAN enabled_privilege = 0;
  117.       const DWORD SE_DEBUG_PRIVILEGE = 0x14;
  118.       RtlAdjustPrivilege = (ULONG(NTAPI*)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN))Function::GetAddress("RtlAdjustPrivilege");
  119.       RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &enabled_privilege);
  120.     }
  121.     ldr = Function::LoadPluginEngine(hModule, base::kPluginLdrName);
  122.     return (ldr != nullptr);
  123.   }
  124.   if (ul_reason_for_call == DLL_PROCESS_DETACH){
  125.     if (FreeLibraryAPI == nullptr){
  126.       FreeLibraryAPI = (BOOL(WINAPI*)(HMODULE))Function::GetAddress("FreeLibrary");
  127.       return (FreeLibraryAPI(ldr));
  128.     }
  129.   }
  130.   return FALSE;
  131. }
复制代码

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

龙马谷| C/C++辅助教程| 安卓逆向安全| 论坛导航| 免责申明|Archiver|
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表龙马谷立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2018-2021 All Right Reserved.
在线客服
快速回复 返回顶部 返回列表