LNK2019 | Определенная функция, вызывающая проблемы компоновщика при использовании? - PullRequest
0 голосов
/ 30 апреля 2019

Я создаю драйвер режима ядра для управления памятью в моих собственных процессах и других. Пока это было хорошо, я вручную сопоставил его с процессом, над которым работал, и использовал экспортированные функции для выполнения своих функций из пользовательского режима. Я экспортирую особую функцию для управления памятью чтения и записи, которая запускает отдельные неэкспортированные функции, чтобы выполнить эту работу за меня.

Функция, которую я использую для этого - недокументированная функция внутри 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;
}
...