1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
|
#include "inject.h" #include "C:\D\test\CC++\cc++lib\driver\def.h" #include "C:\D\test\CC++\cc++lib\driver\ntldr.h" #include "EnumModule.h"
VOID TestInjectAPC();
ULONG_PTR GetKernelModuleBase(PUCHAR moduleName, PULONG pModuleSize) { RTL_PROCESS_MODULES SysModules = { 0 }; PRTL_PROCESS_MODULES pModules = &SysModules; ULONG SystemInformationLength = 0; NTSTATUS status = ZwQuerySystemInformation(SystemModuleInformation, pModules, sizeof(RTL_PROCESS_MODULES), &SystemInformationLength); if (status == STATUS_INFO_LENGTH_MISMATCH) { pModules = ExAllocatePool(NonPagedPool, SystemInformationLength + sizeof(RTL_PROCESS_MODULES)); RtlZeroMemory(pModules, SystemInformationLength + sizeof(RTL_PROCESS_MODULES)); status = ZwQuerySystemInformation(SystemModuleInformation, pModules, SystemInformationLength + sizeof(RTL_PROCESS_MODULES), &SystemInformationLength); if (!NT_SUCCESS(status)) { ExFreePool(pModules); return 0; } } if (!strcmp("ntoskrnl.exe", moduleName) || !strcmp("ntkrnlpa.exe.exe", moduleName)) { *pModuleSize = pModules->Modules[0].ImageSize; ULONG_PTR ret = pModules->Modules[0].ImageBase; if (SystemInformationLength) { ExFreePool(pModules); } return ret; } for (ULONG i = 0; i < pModules->NumberOfModules; i++) { if (strstr(pModules->Modules[i].FullPathName, moduleName)) { *pModuleSize = pModules->Modules[i].ImageSize; ULONG_PTR ret = pModules->Modules[i].ImageBase; if (SystemInformationLength) { ExFreePool(pModules); } return ret; } } if (SystemInformationLength) { ExFreePool(pModules); } return 0; } static CHAR g_injectshellcode[] = { 0x48,0x31,0xC9, 0x48,0x31,0xD2, 0x49,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x49,0xB9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x48,0x83,0xEC,0x48, 0xff,0xd0, 0x48,0x83,0xC4,0x48,0xC3,0x90 }; PVOID CreateInjectCode(PVOID r3addr, PWCHAR dllpath) { UNICODE_STRING str = { 0 }; PVOID retaddr = NULL; RtlInitUnicodeString(&str, dllpath); PVOID ldrloaddll = GetExportFuncAddr(GetProcessModuleBase(IoGetCurrentProcess(), L"ntdll.dll"), "LdrLoadDll"); if (!ldrloaddll)return NULL; __try { RtlCopyMemory(r3addr, &str, sizeof(USHORT) * 2); *(PULONG64)((ULONG64)r3addr + sizeof(USHORT) * 2 + 4) = (PULONG64)r3addr + 20; RtlCopyMemory((PVOID)((PULONG64)r3addr + 20), str.Buffer, str.Length); *(PULONG64)(g_injectshellcode + 8) = r3addr; *(PULONG64)(g_injectshellcode + 18) = (ULONG64)r3addr + 400; *(PULONG64)(g_injectshellcode + 28) = (ULONG64)ldrloaddll; retaddr = (PVOID)((ULONG64)r3addr + 420); RtlCopyMemory(retaddr, g_injectshellcode, sizeof(g_injectshellcode)); } __except (1) { retaddr = NULL; } return retaddr; }
PVOID SearchHexcode(PCHAR search_hex, ULONG hex_size, PVOID strataddr, ULONG search_long) { if (!MmIsAddressValid(strataddr)) return NULL; PCHAR cmpaddr = (PCHAR)strataddr; for (size_t i = 0; i < search_long; i++) { ULONG equal = 0; for (size_t u = 0; u < hex_size; u++) { if (MmIsAddressValid((PCHAR)(cmpaddr + u)) && *(PCHAR)(cmpaddr + u) == search_hex[u]) equal++; else break; } if (equal == hex_size) return cmpaddr++; } return NULL; } PVOID FindKernelSystemRoutine(PCHAR shellcode, SIZE_T size) { ULONG modsize = 0; PVOID modbase = GetKernelModuleBase("ntoskrnl.exe", &modsize); if (!modbase || !modsize) return; return SearchHexcode(shellcode, size, modbase, modsize); } NTSTATUS DllInjectRemote(HANDLE pid, PWCHAR dllpath) { CHAR hex[] = { 0x40,0x55,0x53,0x56,0x57,0x41,0x54,0x41,0x55,0x41,0x56,0x41,0x57,0x48,0x81,0xEC,0x38, 0x03,0x00,0x00,0x48,0x8d,0x6c,0x24,0x70,0x48,0x8b,0x05,0xC0,0x0C,0x56,0x00 }; PEPROCESS pr = NULL; PVOID pe = NULL; UNICODE_STRING str = { 0 }; KAPC_STATE kapc = { 0 }; PVOID newaddr = NULL; SIZE_T mem_length = 0x1000; PVOID shelladdr = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; HANDLE hthread = NULL; LARGE_INTEGER timeout = { .QuadPart = -10 * 1000 * 1000 * 10 }; FN_NtCreateThreadEx NtCreateThreadEx = NULL;
if (!NT_SUCCESS(PsLookupProcessByProcessId(pid, &pe))) return STATUS_UNSUCCESSFUL; ObDereferenceObject(pe); NtCreateThreadEx = FindKernelSystemRoutine(hex, sizeof(hex)); if (!MmIsAddressValid(NtCreateThreadEx)) return STATUS_UNSUCCESSFUL; KeStackAttachProcess(pe, &kapc); status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &newaddr, 0, &mem_length, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(status)) { KeUnstackDetachProcess(&kapc); return STATUS_UNSUCCESSFUL; } shelladdr = CreateInjectCode(newaddr, dllpath); if (!shelladdr) goto end; status = NtCreateThreadEx(&hthread, THREAD_ALL_ACCESS, NULL, ZwCurrentProcess(), shelladdr, NULL, 0, 0, 0x10000, 0x100000, NULL); if (NT_SUCCESS(status)) { ZwWaitForSingleObject(hthread, FALSE, &timeout); ZwClose(hthread); } end: ZwFreeVirtualMemory(ZwCurrentProcess(), &newaddr, &mem_length, MEM_RELEASE); KeUnstackDetachProcess(&kapc); return status;
}
VOID InjectApc_KernelRoutine( PRKAPC Apc, PKNORMAL_ROUTINE* NormalRoutine, PVOID* NormalContext, PVOID* SystemArgument1, PVOID* SystemArgument2) { ExFreePool(Apc); } PVOID g_inject_shellcode = NULL;
VOID InjectApc_PreApc(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2) { PVOID newaddr = NULL; size_t length = 0X1000; NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING dllpath = { 0 }; if (!g_inject_shellcode) { status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &newaddr, 0, &length, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(status))return; g_inject_shellcode = CreateInjectCode(newaddr, (PWCHAR)NormalContext); if (!g_inject_shellcode) { ZwFreeVirtualMemory(ZwCurrentProcess(), &newaddr, &length, MEM_RELEASE); return; } } PRKAPC kapc = (PRKAPC)ExAllocatePool(NonPagedPool, sizeof(KAPC)); KeInitializeApc(kapc, PsGetCurrentThread(), OriginalApcEnvironment, InjectApc_KernelRoutine, NULL, (PKNORMAL_ROUTINE)g_inject_shellcode, UserMode, NULL); KeInsertQueueApc(kapc, NULL, NULL, IO_NO_INCREMENT); } NTSTATUS DLLInjectApc(HANDLE pid, PWCHAR dllpath) { g_inject_shellcode = NULL; for (size_t i = 4; i < 0x10000; i += 4) { PETHREAD pethread = NULL; if (NT_SUCCESS(PsLookupThreadByThreadId((HANDLE)i, &pethread))) { if (PsGetThreadProcessId(pethread) == pid) { PRKAPC kapc = (PRKAPC)ExAllocatePool(NonPagedPool, sizeof(KAPC)); KeInitializeApc(kapc, pethread, OriginalApcEnvironment, InjectApc_KernelRoutine, NULL, InjectApc_PreApc, KernelMode, (PVOID)dllpath); KeInsertQueueApc(kapc, NULL, NULL, IO_NO_INCREMENT); } ObDereferenceObject(pethread); } }
}
VOID UnTestInjectAPC() { } VOID TestInjectAPC() { char pname[] = "Taskmgr.exe"; HANDLE pid = 0; pid = GetProcessIdByName(pname); DLLInjectApc(pid, L"C:\\Users\\lyx\\Desktop\\Dll1.dll"); }
|