Я создаю драйвер режима ядра для управления памятью в моих собственных процессах и других. Пока это было хорошо, я вручную сопоставил его с процессом, над которым работал, и использовал экспортированные функции для выполнения своих функций из пользовательского режима. Я экспортирую особую функцию для управления памятью чтения и записи, которая запускает отдельные неэкспортированные функции, чтобы выполнить эту работу за меня.
Функция, которую я использую для этого - недокументированная функция внутри ntoskrnl.exe с именем MmCopyVirtualMemory, которая вызывает ошибку компоновщика всякий раз, когда я пытаюсь ее использовать. Это приводит к тому, что я не могу скомпилировать драйвер.
Я пытался использовать какой-то источник из https://github.com/Zer0Mem0ry проектов KernelReadWriteMemory и KernelBhop, но ни один из них не устранил мою проблему.
Я также пытался отключить большинство, если не все, сообщений об ошибках, связанных с компоновщиком, и ошибок времени выполнения. Оба ничего не сделали, чтобы решить проблему.
/* The Linker Error: unresolved external symbol "long __cdecl MmCopyVirtualMemory(struct _KPROCESS *,void *,struct _KPROCESS *,void *,unsigned __int64,char,unsigned __int64 *)" (?MmCopyVirtualMemory@@YAJPEAU_KPROCESS@@PEAX01_KDPEA_K@Z) referenced in function "int __cdecl readmem(struct _KPROCESS *,void *,void *,unsigned __int64)" (?readmem@@YAHPEAU_KPROCESS@@PEAX1_K@Z) */
// Undocumented Definitions
NTSTATUS NTAPI MmCopyVirtualMemory
(
PEPROCESS SourceProcess,
PVOID SourceAddress,
PEPROCESS TargetProcess,
PVOID TargetAddress,
SIZE_T BufferSize,
KPROCESSOR_MODE PreviousMode,
PSIZE_T ReturnSize
);
NTKERNELAPI
NTSTATUS
PsLookupProcessByProcessId(
IN HANDLE ProcessId,
OUT PEPROCESS *Process
);
// Memory Functions
int readmem(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size)
{
PSIZE_T Bytes = 0;
if (Process != nullptr && NT_SUCCESS(MmCopyVirtualMemory(Process, SourceAddress, current_process, TargetAddress, Size, KernelMode, Bytes))) {
return 1; // memory successful
}
else {
return 0; // request failure
}
}
int writemem(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size)
{
PSIZE_T Bytes = 0;
if (Process != nullptr && NT_SUCCESS(MmCopyVirtualMemory(current_process, SourceAddress, Process, TargetAddress, Size, KernelMode, Bytes))) {
return 1; // memory successful
}
else {
return 0; // request failure
}
}
// Memory Export
extern "C" __declspec(dllexport) PMEMORY_REQUEST memory_handler(int code, PMEMORY_REQUEST request) {
int requestcode = -1;
PEPROCESS memory_process;
if (request->read != nullptr) {
requestcode = 1;
}
else if (request->write != nullptr) {
requestcode = 2;
}
if (requestcode != code) {
request->read = nullptr;
request->write = nullptr;
return request; // bad request
}
if (code == 1) { // read
PsLookupProcessByProcessId(reinterpret_cast<HANDLE>(request->read->ProcessId), &memory_process);
request->response = readmem(memory_process, reinterpret_cast<PVOID>(request->read->Address), &request->read->Response, request->read->Size);
DbgPrintEx(0, 0, "read value: %d", request->read->Response);
}
else if (code == 2) { // write
PsLookupProcessByProcessId(reinterpret_cast<HANDLE>(request->write->ProcessId), &memory_process);
request->response = writemem(memory_process, &request->write->Value, reinterpret_cast<PVOID>(request->write->Address), request->write->Size);
DbgPrintEx(0, 0, "write value: %d", request->write->Value);
}
return request;
}