Files
CowInjecter/CowInject/main.cpp
2021-01-01 13:54:35 +08:00

240 lines
8.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "head.h"
#include "main.h"
struct moudle_info
{
uintptr_t bsae;
uintptr_t size;
};
bool get_moudle_base(PEPROCESS process, moudle_info* kernel32, moudle_info* ntdll, moudle_info* kernelbase) {
PPEB peb = PsGetProcessPeb(process);
bool result = false;
if (peb == NULL)
return result;
DebugPrintA("process peb: %p \n", peb);
//PEB + 0x18 = PEB.Ldr
auto peb_ldr = *(PDWORD64)((PUCHAR)peb + 0x18);
//Pebldr + 0x10 = InLoadOrderModuleList
PLIST_ENTRY module_list_head = (PLIST_ENTRY)((PUCHAR)peb_ldr + 0x10);
PLIST_ENTRY moudle = module_list_head->Flink;
/*
win7: kernel32.dll
win10: KERNEL32.DLL
*/
wchar_t moudle_list[][15] = {
{L"kernel32.dll"},
{L"ntdll.dll"},
{L"kernelbase.dll"},
};
while (module_list_head != moudle)
{
PLDR_DATA_TABLE_ENTRY info = (PLDR_DATA_TABLE_ENTRY)moudle;
UNICODE_STRING str_moudle_name;
for (size_t i = 0; i < sizeof(moudle_list); i++)
{
RtlInitUnicodeString(&str_moudle_name, moudle_list[i]);
if (BlackBoneSafeSearchString(&info->BaseDllName, &str_moudle_name, true) != -1)
{
DebugPrintA("MoudleBase %p Size %p Name %wZ\n", info->DllBase, info->SizeOfImages, info->BaseDllName);
if (i == 0) {
kernel32->bsae = (uintptr_t)info->DllBase;
kernel32->size = (uintptr_t)info->SizeOfImages;
}
if (i == 1) {
ntdll->bsae = (uintptr_t)info->DllBase;
ntdll->size = (uintptr_t)info->SizeOfImages;
}
if (i == 2) {
kernelbase->bsae = (uintptr_t)info->DllBase;
kernelbase->size = (uintptr_t)info->SizeOfImages;
}
break;
}
}
if (kernel32->bsae && ntdll->bsae && kernelbase->bsae)
break;
moudle = moudle->Flink;
}
result = kernel32->bsae != NULL && ntdll->bsae != NULL && kernelbase->bsae != NULL;
DebugPrintA("kernel32->bsae %p sizeof:%p ntdll->bsae %p kernelbase->bsae %p result: %d \n", kernel32->bsae, kernel32->size, ntdll->bsae, kernelbase->bsae, result);
return result;
}
uintptr_t get_free_speace(uintptr_t base, size_t size, size_t need_size) {
size_t return_length;
for (uintptr_t address = (uintptr_t)base; address <= (uintptr_t)base + size; address += sizeof(uintptr_t)) {
__try
{
ProbeForRead((void*)address, need_size, 0x1);
if (*(uintptr_t*)address == 0x00 || *(uintptr_t*)address == 0x90)
{
MEMORY_BASIC_INFORMATION memory_information = { 0 };
NTSTATUS status = ZwQueryVirtualMemory(NtCurrentProcess(), (PVOID)address, (MEMORY_INFORMATION_CLASS)0, &memory_information, need_size, &return_length);
if (NT_SUCCESS(status)) {
if ((memory_information.Protect == PAGE_EXECUTE || memory_information.Protect == PAGE_EXECUTE_READ || memory_information.Protect == PAGE_EXECUTE_READWRITE || memory_information.Protect == PAGE_EXECUTE_WRITECOPY) == false) {
continue;
}
}
DebugPrintA("address : %p \n", address);
uintptr_t count = 0;
bool is_good = true;
uintptr_t max_count = 0;
for (; count < need_size && is_good; count += sizeof(uintptr_t))
{
max_count++;
auto check_ptr = (uintptr_t*)((PUCHAR)address + count);
if (*check_ptr != 0x0 && *check_ptr != 0x90)
{
is_good = false;
break;
}
}
if (is_good) {
DebugPrintA("location Cow virtual address : %p \n", address);
return address;
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
continue;
}
}
return NULL;
}
VOID DriverUnload(PDRIVER_OBJECT driver)
{
DebugPrintA("[DebugMessage] Unload Driver");
}
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
DebugPrintA("init Driver \n");
/*
<09><>ʼ<EFBFBD><CABC>shellcode
*/
//uintptr_t size_of_shellcode = CALCSIZE(HkCreateFileW, ShellCodeEnd);
uintptr_t size_of_shellcode = sizeof(HookCode);
DebugPrintA("shell code size: %p \n", size_of_shellcode);
/*
get a x64 process
*/
for (uintptr_t i = 8; i < 100000000; i = i + 4)
{
PEPROCESS _eprocess = NULL;
NTSTATUS nt_status = PsLookupProcessByProcessId((HANDLE)i, &_eprocess);
if (NT_SUCCESS(nt_status) && _eprocess != NULL)
{
ObDereferenceObject(_eprocess);
bool is_x64_process = PsGetProcessWow64Process(_eprocess) == NULL;
if (is_x64_process) {
KAPC_STATE apc;
KeStackAttachProcess(_eprocess, &apc);
moudle_info kernel32 = {0};
moudle_info ntdll = { 0 };
moudle_info kernelbase = { 0 };
/*
is x64 process, get kernel32.dll and kernelbase.dll and ntdll.dll base
*/
if (get_moudle_base(_eprocess, &kernel32, &ntdll, &kernelbase)) {
uintptr_t kernel32_loadlibrary = GetProcAddressR(kernel32.bsae, "LoadLibraryW", TRUE);
uintptr_t ntdll_wcsstr = GetProcAddressR(ntdll.bsae, "wcsstr", TRUE);
uintptr_t kernelbase_GetModuleFileNameW = GetProcAddressR(kernelbase.bsae, "GetModuleFileNameW", TRUE);
uintptr_t kernelbase_CreateFileW = GetProcAddressR(kernelbase.bsae, "CreateFileW", TRUE);
if (kernel32_loadlibrary && ntdll_wcsstr && kernelbase_GetModuleFileNameW && kernelbase_CreateFileW) {
uintptr_t hook_function = get_free_speace(kernel32.bsae, kernel32.size, size_of_shellcode + sizeof(void*) + sizeof(CreateFileWT));
if (hook_function) {
/*
Copy shellcode to freespeace
*/
_memcpy((PVOID)hook_function, (PVOID)HookCode, size_of_shellcode);
/*
hook
*/
BYTE _mov_rax[] = {
0x48, 0xB8 // mov rax, [xxx]
};
BYTE _jmp_rax[] = {
0xFF, 0xE0, // jmp rax
};
BYTE shell_code_jmp_back[] = {
0xCC, 0xCC, //mov rax
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //void*
0xCC, 0xCC, //jmp rax
};
uintptr_t function_offset = kernelbase_CreateFileW;
//backup
_memcpy(shell_code_jmp_back, (void*)function_offset, sizeof(shell_code_jmp_back));
/*
hook_function -> origin_code
*/
function_offset = hook_function + size_of_shellcode;
uintptr_t jmp_back = function_offset;
_memcpy((void*)function_offset, shell_code_jmp_back, sizeof(shell_code_jmp_back));
function_offset += sizeof(shell_code_jmp_back);
/*
origin_code -> jmp CreateFileW
*/
uintptr_t jmp_offset = kernelbase_CreateFileW + sizeof(_mov_rax) + sizeof(_jmp_rax) + sizeof(void*);
_memcpy((void*)function_offset, _mov_rax, sizeof(_mov_rax));
function_offset += sizeof(_mov_rax);
_memcpy((void*)function_offset, &jmp_offset, sizeof(void*));
function_offset += sizeof(void*);
_memcpy((void*)function_offset, _jmp_rax, sizeof(_jmp_rax));
/*
location shellcode function
*/
for (int i = 0; i < size_of_shellcode; i++)
{
auto write_ptr = (uintptr_t*)((PUCHAR)hook_function + i);
if (*write_ptr == 0x1234567812345678)
{
_memcpy((void*)write_ptr, (void*)&jmp_back, sizeof(uintptr_t));
DebugPrintA("[jmp_back]Fix KernelBase.CreateFileW %p \n", jmp_back);
}
if (*write_ptr == 0x1234567891ABCDEF)
{
_memcpy((void*)write_ptr, (void*)&ntdll_wcsstr, sizeof(uintptr_t));
DebugPrintA("Fix Ntdll.wcsstr %p \n", ntdll_wcsstr);
}
if (*write_ptr == 0x1337567891ABCDEF)
{
_memcpy((void*)write_ptr, (void*)&kernelbase_GetModuleFileNameW, sizeof(uintptr_t));
DebugPrintA("Fix KernelBase.GetModuleFileNameW %p \n", kernelbase_GetModuleFileNameW);
}
if (*write_ptr == 0x1234567891AB1337)
{
_memcpy((void*)write_ptr, (void*)&kernel32_loadlibrary, sizeof(uintptr_t));
DebugPrintA("Fix kernel32.loadlibrary %p \n", kernel32_loadlibrary);
}
}
/*
CreateFileW -> hook_function
*/
function_offset = kernelbase_CreateFileW;
_memcpy((void*)function_offset, _mov_rax, sizeof(_mov_rax));
function_offset += sizeof(_mov_rax);
_memcpy((void*)function_offset, &hook_function, sizeof(void*));
function_offset += sizeof(void*);
_memcpy((void*)function_offset, _jmp_rax, sizeof(_jmp_rax));
DebugPrintA("success hooked at: %p \n", hook_function);
} else {
DebugPrintA("can not get free speace for shellcode \n");
}
}
else {
DebugPrintA("can not get export function\n");
}
}
KeUnstackDetachProcess(&apc);
break;
}
}
}
driver->DriverUnload = DriverUnload;
return STATUS_UNSUCCESSFUL;
}