-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathkdmapper.cpp
154 lines (118 loc) · 5.36 KB
/
kdmapper.cpp
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
#include "kdmapper.hpp"
#include "xhackorx.hpp"
uint64_t kdmapper::MapDriver(HANDLE iqvw64e_device_handle, std::vector<uint8_t> raw_image)
{
const PIMAGE_NT_HEADERS64 nt_headers = portable_executable::GetNtHeaders(raw_image.data());
if (!nt_headers)
{
std::cout << XorString(" [!] Invalid format of PE image") << std::endl;
std::cout << XorString(" [!] Error spoof !\n") << std::endl;
Sleep(2000);
return 0;
}
if (nt_headers->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)
{
std::cout << XorString(" [!] Image is not 64 bit") << std::endl;
std::cout << XorString(" [!] Error spoof !\n") << std::endl;
Sleep(2000);
return 0;
}
const uint32_t image_size = nt_headers->OptionalHeader.SizeOfImage;
void* local_image_base = VirtualAlloc(nullptr, image_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
uint64_t kernel_image_base = intel_driver::AllocatePool(iqvw64e_device_handle, nt::NonPagedPool, image_size);
do
{
if (!kernel_image_base)
{
std::cout << XorString(" [!] Failed to allocate remote image in kernel") << std::endl;
std::cout << XorString(" [!] Error spoof !\n") << std::endl;
Sleep(2000);
break;
}
std::cout << XorString(" [+] Image base has been allocated at 0x") << reinterpret_cast<void*>(kernel_image_base) << std::endl;
// Copy image headers
memcpy(local_image_base, raw_image.data(), nt_headers->OptionalHeader.SizeOfHeaders);
// Copy image sections
const PIMAGE_SECTION_HEADER current_image_section = IMAGE_FIRST_SECTION(nt_headers);
for (auto i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i)
{
auto local_section = reinterpret_cast<void*>(reinterpret_cast<uint64_t>(local_image_base) + current_image_section[i].VirtualAddress);
memcpy(local_section, reinterpret_cast<void*>(reinterpret_cast<uint64_t>(raw_image.data()) + current_image_section[i].PointerToRawData), current_image_section[i].SizeOfRawData);
}
// Resolve relocs and imports
RelocateImageByDelta(portable_executable::GetRelocs(local_image_base), kernel_image_base - nt_headers->OptionalHeader.ImageBase);
if (!ResolveImports(iqvw64e_device_handle, portable_executable::GetImports(local_image_base)))
{
std::cout << XorString(" [!] Failed to resolve imports") << std::endl;
std::cout << XorString(" [!] Error spoof !\n") << std::endl;
Sleep(2000);
break;
}
// Write fixed image to kernel
if (!intel_driver::WriteMemory(iqvw64e_device_handle, kernel_image_base, local_image_base, image_size))
{
std::cout << XorString(" [!] Failed to write local image to remote image") << std::endl;
std::cout << XorString(" [!] Error spoof !\n") << std::endl;
Sleep(2000);
break;
}
VirtualFree(local_image_base, 0, MEM_RELEASE);
// Call driver entry point
const uint64_t address_of_entry_point = kernel_image_base + nt_headers->OptionalHeader.AddressOfEntryPoint;
std::cout << XorString(" [<] Calling DriverEntry 0x") << reinterpret_cast<void*>(address_of_entry_point) << std::endl;
NTSTATUS status = 0;
if (!intel_driver::CallKernelFunction(iqvw64e_device_handle, &status, address_of_entry_point))
{
std::cout << XorString(" [!] Failed to call driver entry") << std::endl;
std::cout << XorString(" [!] Error spoof !\n") << std::endl;
Sleep(2000);
break;
}
std::cout << XorString(" [+] DriverEntry returned 0x") << std::hex << std::setw(8) << std::setfill('0') << std::uppercase << status << std::nouppercase << std::dec << std::endl;
// Erase PE headers
intel_driver::SetMemory(iqvw64e_device_handle, kernel_image_base, 0, nt_headers->OptionalHeader.SizeOfHeaders);
return kernel_image_base;
} while (false);
VirtualFree(local_image_base, 0, MEM_RELEASE);
intel_driver::FreePool(iqvw64e_device_handle, kernel_image_base);
return 0;
}
void kdmapper::RelocateImageByDelta(const portable_executable::vec_relocs& relocs, const uint64_t delta)
{
for (const auto& current_reloc : relocs)
{
for (auto i = 0u; i < current_reloc.count; ++i)
{
const uint16_t type = current_reloc.item[i] >> 12;
const uint16_t offset = current_reloc.item[i] & 0xFFF;
if (type == IMAGE_REL_BASED_DIR64)
* reinterpret_cast<uint64_t*>(current_reloc.address + offset) += delta;
}
}
}
bool kdmapper::ResolveImports(HANDLE iqvw64e_device_handle, const portable_executable::vec_imports& imports)
{
for (const auto& current_import : imports)
{
if (!utils::GetKernelModuleAddress(current_import.module_name))
{
std::cout << XorString(" [!] Dependency ") << current_import.module_name << XorString(" wasn't found") << std::endl;
std::cout << XorString(" [!] Error spoof !\n") << std::endl;
Sleep(2000);
return false;
}
for (auto& current_function_data : current_import.function_datas)
{
const uint64_t function_address = intel_driver::GetKernelModuleExport(iqvw64e_device_handle, utils::GetKernelModuleAddress(current_import.module_name), current_function_data.name);
if (!function_address)
{
std::cout << XorString(" [!] Failed to resolve import ") << current_function_data.name << XorString(" (") << current_import.module_name << XorString(")") << std::endl;
std::cout << XorString(" [!] Error spoof !\n") << std::endl;
Sleep(2000);
return false;
}
*current_function_data.address = function_address;
}
}
return true;
}