创建暂停的流程后查找基址

时间:2018-12-26 20:48:43

标签: c winapi memory createprocess base-address

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

从我的研究中,我可以从流程的PEB(包括该地址)中获取它。根据我的理解,PEB始终位于ebx寄存器中,而入口点位于eax寄存器中。

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

第二个问题。当我读取进程内存时,出现错误299(12B),据我理解,当尝试从32bit读取64bit内存时会发生(但请记住,我正在运行32bit进程)。 / p>

#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:我在网上找到的所有内容都是为了查找正在运行的进程的基址,我尝试并成功了该基址,但是由于尚未挂起任何模块,因此该模块未处于挂起状态(如taskmanager所示,因为该进程没有名称,可能是错误的),但它对我不起作用。

注释4:我还是C语言编码的新手,如果有些奇怪,抱歉。

任何帮助都会很高兴得到您的帮助。如果您还有其他获取基本地址的方法,我很想听听。 对不起,如果代码有点混乱,或者我不清楚。我会尽力解释...

忘记添加:我的系统是Windows 10 64bit

编辑:修复了该问题。需要执行context.ContextFlags = CONTEXT_INTEGER。 那让我阅读。读进程内存也失败了,因为我给它错误的地址(基本上是0 + 8 = 8),我认为该地址用于64位进程

1 个答案:

答案 0 :(得分:0)

您从不设置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实现