如何从 Windows 的本机 API 中使用 NtUnmapViewOfSection?

问题描述 投票:0回答:1

我目前正在尝试使用 C 实现某种进程挖空 (RunPE) 技术。 到目前为止我所做的基本上就是找到 PEB 并获取进程的(在挂起模式下)图像基地址。 现在,我明白我必须使用函数

NtUnmapViewOfSection
来“擦除”进程的虚拟内存并用我的替换它。

但是,每当我尝试使用

NtUnmapViewOfSection
时,它都显示为白色,并且不允许我编译... 我包含了
<winternl.h>
并且在 Visual Studio 2019 的链接器选项中,我添加了
ntdll.lib
依赖项。但它仍然不让我使用它,即使它让我使用 Native API 的其他函数,例如 NtQueryInformationProcess(查找 PEB 的地址)。

如果相关的话,这是我到目前为止的代码:

#include <windows.h>
#include <stdio.h>
#include <winternl.h>

int main(int argc, char* argv[])
{

    printf("Creating process\r\n");

    LPSTARTUPINFOA si = (LPSTARTUPINFOA)calloc(1, sizeof(STARTUPINFOA));
    LPPROCESS_INFORMATION pi = (LPPROCESS_INFORMATION)calloc(1, sizeof(PROCESS_INFORMATION));

    if (!CreateProcessA
    (
        "C:\\Windows\\sysWOW64\\calc.exe", // Process uses LoadLibraryA and GetProcAddress. TODO: shellcode with LDR.
        NULL,
        NULL,
        NULL,
        NULL,
        CREATE_SUSPENDED,
        NULL,
        NULL,
        si,
        pi
    ))
    {
        printf("Error with CreateProcessA - %d", GetLastError());
        return 1;
    }

    if (!pi->hProcess)
    {
        printf("Error creating process - %d", GetLastError());
        return 1;
    }

    HANDLE hDestProcess = pi->hProcess;

    PROCESS_BASIC_INFORMATION* pbi = (PROCESS_BASIC_INFORMATION*)calloc(1, sizeof(PROCESS_BASIC_INFORMATION));
    DWORD retLen = 0;

    if (NtQueryInformationProcess(hDestProcess, ProcessBasicInformation, pbi, sizeof(PROCESS_BASIC_INFORMATION), &retLen))
    {
        printf("Error finding peb - %d", GetLastError());
        return 1;
    }

    DWORD pebImageBaseOffset = (DWORD)pbi->PebBaseAddress + 0x8;
    printf("Peb offset: %p\n", pebImageBaseOffset);

    LPVOID destImageBase = 0;
    SIZE_T bytesRead;

    if (!ReadProcessMemory(hDestProcess, (LPCVOID)pebImageBaseOffset, &destImageBase, 0x4, &bytesRead))
    {
        printf("Error getting process's image base - %d", GetLastError());
        return 1;
    }

    printf("Process image base: %p\n", destImageBase);

    if (NtUnmapViewOfSection(pi->hProcess, destImageBase))
    {
        printf("Process view unmapping failed");
    }

    // Read other executable file
    HANDLE sourceFile =
        CreateFileA("C:\\Windows\\sysWOW64\\cmd.exe", GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL);
    DWORD sourceFileSize = GetFileSize(sourceFile, NULL);
    DWORD fileBytesRead = 0;
    LPVOID sourceFileBytes = (LPVOID)malloc(sourceFileSize);
    ReadFile(sourceFile, sourceFileBytes, sourceFileSize, &fileBytesRead, NULL);


    /*DWORD bytesWritten = 0;
    BOOL writeSuccess = WriteProcessMemory(hDestProcess, entryPointAddr, sourceFileBytes, fileBytesRead, &bytesWritten);
    if (!writeSuccess)
    {
        printf("Problem writing to memory - %d", GetLastError());
        return 1;
    }*/

    // Resume the main thread
    ResumeThread(pi->hThread);
    printf("Process main thread resumed");

    // Close handles
    CloseHandle(pi->hProcess);
    CloseHandle(pi->hThread);

    return 0;
}

错误信息: 当我试图包含 wdm.h 或其他人时:

Severity    Code    Description Project File    Line    Suppression State
Error   C1083   Cannot open include file: 'wdm.h': No such file or directory    process_hollowing_other_exe D:\other_projects\process_hollowing\process_hollowing_other_exe\process_hollowing_other_exe\main.c  4

当我尝试使用没有标题的功能时:

Error   LNK2019 unresolved external symbol _NtUnmapViewOfSection referenced in function _main   process_hollowing_other_exe D:\other_projects\process_hollowing\process_hollowing_other_exe\process_hollowing_other_exe\main.obj    1   
c winapi process virtual-memory ntdll
1个回答
0
投票

根据文档:ZwUnmapViewOfSection 函数 (wdm.h)

如果这个函数的调用发生在用户态,你应该使用 将“ZwUnmapViewOfSection”命名为“NtUnmapViewOfSection”。

你应该包括

wdm.h
。项目应该在 WDK 的构建环境中构建。您需要构建一个真正的驱动程序才能使用 NtUnmapViewOfSection。

© www.soinside.com 2019 - 2024. All rights reserved.