【问题标题】:Finding the base address after creating suspended process创建挂起进程后查找基地址
【发布时间】:2019-05-25 00:13:09
【问题描述】:

我正在尝试学习如何进行流程空心化/替换(为了学习)。我创建了一个处于挂起状态的 32 位进程,之后我需要该进程的基地址,以便稍后从内存中取消映射并替换为其他内容。

根据我的研究,我可以从流程的 PEB 中获得它,其中包括该地址。同样据我了解,PEB 始终位于 ebx 寄存器中,入口点位于 eax 寄存器中。

但是,当我获得主线程的上下文(保存寄存器的内容)时,它全为零,这对我来说毫无意义,但它不会失败。

第二个问题。当我读取进程内存时,我得到 error 299 (12B),据我了解,这是在尝试从 32 位读取 64 位内存时发生的(但请记住,我正在运行 32 位进程)。

#include <Windows.h>
#include <tchar.h>
#include <stdio.h>

void end_program(LPPROCESS_INFORMATION pinfo, LPSTARTUPINFO stinfo)
{
    TerminateProcess(pinfo->hProcess, 1);
    CloseHandle(pinfo->hProcess);
    CloseHandle(pinfo->hThread);
    CloseHandle(stinfo->hStdError);
    CloseHandle(stinfo->hStdInput);
    CloseHandle(stinfo->hStdOutput);
    system("pause");
}

void main()
{
    // Create process suspended
    PROCESS_INFORMATION process_info;
    STARTUPINFO start_info;
    ZeroMemory(&process_info, sizeof(process_info));
    ZeroMemory(&start_info, sizeof(start_info));
    TCHAR path[100] = TEXT("C:\\Windows\\SysWOW64\\svchost.exe");
    if (!CreateProcess(NULL, path, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &start_info, &process_info))
    {
        printf("Failed creating process: error 0x%p", GetLastError());
        return;
    }
    printf("PID: %i Handle: 0x%p\r\n", process_info.dwProcessId, process_info.hProcess);

    // Get context of thread
    CONTEXT context;
    ZeroMemory(&context, sizeof(context));
    if (!GetThreadContext(process_info.hThread, &context))
    {
        printf("Failed getting context: error 0x%p\r\n", GetLastError());
        end_program(&process_info, &start_info);
        return;
    }
    printf("Context recieved!\r\n");

    // Get base address
    PVOID base_address;
    ZeroMemory(&base_address, sizeof(base_address));
    if (!ReadProcessMemory(process_info.hProcess, (BYTE)(context.Ebx + 8), &base_address, sizeof(PVOID), NULL))
    {
        printf("Error reading file: error 0x%p\r\n", GetLastError());
        end_program(&process_info, &start_info);
        return;
    }

    // Bugs that haven't been uncovered yet goes here




    // End of program
    end_program(&process_info, &start_info);
}

注1:研究称偏移量为8字节的PEB为基地址。

注意 2:尝试对所有进程进行快照但同样的错误,也尝试了 enumprocessmodules,出现同样的错误。

注 3:我在网上找到的所有内容都是为了找到正在运行的进程的基地址,我尝试并成功了,但是由于没有加载任何模块但尚未挂起(因为它出现在任务管理器中,因为没有进程的名称,不过可能是错的),它对我不起作用。

注 4:我对 C 编码也很陌生,如果有什么奇怪的地方,请见谅。

我们将很乐意为您提供任何帮助。如果您有其他方法来获取基本地址,我很想听听。 抱歉,如果代码有点乱,或者我不清楚。我会尽力解释...

忘了补充:我的系统是Windows 10 64bit

编辑:修复了问题。需要做 context.ContextFlags=CONTEXT_INTEGER。 这让我可以阅读。 readprocess 内存也失败了,因为我给了它错误的读取地址(基本上是 0+8=8),我认为这是一个 64 位进程

【问题讨论】:

    标签: c winapi memory createprocess base-address


    【解决方案1】:

    您永远不会设置 context.ContextFlags,您必须在调用 GetThreadContext() 之前将其设置为 CONTEXT_INTEGER。

    这是一个示例代码:

    #if defined(_WIN64)
        WOW64_CONTEXT context;
        memset(&context, 0, sizeof(WOW64_CONTEXT));
        context.ContextFlags = CONTEXT_INTEGER;
        Wow64GetThreadContext(pi.hThread, &context);
    #else   
        CONTEXT context;
        memset(&context, 0, sizeof(CONTEXT));
        context.ContextFlags = CONTEXT_INTEGER;
        GetThreadContext(pi.hThread, &context);
    #endif
    

    取自 hasherezade 出色的 runpe 实现

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      相关资源
      最近更新 更多