C++ 从32位进程获取64位进程内存的入口点

C++ 从32位进程获取64位进程内存的入口点,c++,windows,memory,process,readprocessmemory,C++,Windows,Memory,Process,Readprocessmemory,我想获得我从32位进程编写的64位进程的入口点,与使用EnumProcessModule并获取主模块的内存地址的方法相同。 我的最终目标是在我的64位进程中从内存中读取一个字节,从一个偏移量到它(entry+offset) 但是我的NtWow64ReadVirtualMemory64函数一直失败。 我想这和我的输入内存地址有关 #define PROC_BASIC_INFO 0 #define NT_WOW64_QUERY_INFORMATION_PROCESS_64_NAME

我想获得我从32位进程编写的64位进程的入口点,与使用EnumProcessModule并获取主模块的内存地址的方法相同。 我的最终目标是在我的64位进程中从内存中读取一个字节,从一个偏移量到它(entry+offset)

但是我的NtWow64ReadVirtualMemory64函数一直失败。 我想这和我的输入内存地址有关

    #define PROC_BASIC_INFO 0
    #define NT_WOW64_QUERY_INFORMATION_PROCESS_64_NAME  "NtWow64QueryInformationProcess64"
    #define NT_WOW64_READ_VIRTUAL_MEMORY_64_NAME  "NtWow64ReadVirtualMemory64"

    typedef UINT64 SYM;
    typedef SIZE_T SIZE_T64;

    HWND   WINDOW_HANDLE;
    HANDLE PROC_HANDLE;
    DWORD PROC_ID;
    UINT address;
    UINT64 address64;
    SIZE_T bytesRead;
    SIZE_T64 bytesRead64;

    using namespace std;


    //initialize variables for importing of essential 64 bit reading functions
    //from ntdll
    typedef NTSTATUS(NTAPI *FUNC_NtReadVirtualMemory64)
    ( 
        IN  HANDLE  ProcessHandle,
        IN  PVOID64 BaseAddress,
        OUT PVOID   Buffer,
        IN  ULONGLONG BufferLength,
        OUT PULONGLONG ReturnLength OPTIONAL
    );
    typedef NTSTATUS (NTAPI *FUNC_NtWow64QueryInformationProcess64) 
    (
        IN  HANDLE ProcessHandle,
        IN  ULONG  ProcessInformationClass,
        OUT PVOID  ProcessInformation64,
        IN  ULONG  Length,
        OUT PULONG ReturnLength OPTIONAL
    );

    struct PROCESS_BASIC_INFORMATION64 {

        SYM Reserved1;
        SYM PebBaseAddress;
        SYM Reserved2[2];
        SYM UniqueProcessId;
        SYM Reserved3;
        /*
        NTSTATUS ExitStatus;
        ULONG64 PebBaseAddress;
        ULONG64 AffinityMask;
        LONG    BasePriority;
        UINT64  Reserved1;
        ULONG64 UniqueProcessId;
        ULONG64 InheritedFromUniqueProcessId;
        */
    };



    HINSTANCE ntdll = LoadLibrary("ntdll.dll");
    FUNC_NtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (FUNC_NtWow64QueryInformationProcess64)GetProcAddress(ntdll, NT_WOW64_QUERY_INFORMATION_PROCESS_64_NAME);
    FUNC_NtReadVirtualMemory64 NtReadVirtualMemory64 = (FUNC_NtReadVirtualMemory64)GetProcAddress(ntdll, NT_WOW64_READ_VIRTUAL_MEMORY_64_NAME);

    int Init32To64MemoryRead(const char* windowClass, const char* caption, SYM addressOffset)
    {

        DWORD cbNeeded;
        DWORD dwdResult;
        HMODULE mainModule;
        BOOL enumResult;
        ULONG read_length=0;
        HINSTANCE ntdll; 
        PROCESS_BASIC_INFORMATION64 procInfo;
        ZeroMemory(&procInfo, sizeof(procInfo));



        //Get the window handle
        WINDOW_HANDLE = FindWindow(windowClass, NULL);
        if (WINDOW_HANDLE == NULL)
        {
            //Window was not foud
            return 10;
        }

        //Get the process ID
        dwdResult = GetWindowThreadProcessId(WINDOW_HANDLE, &PROC_ID);

        if (dwdResult == 0)
        {
            //Getting Process ID failed
            return 20;
        }

        //Open the process
        PROC_HANDLE = OpenProcess(PROCESS_ALL_ACCESS, false, PROC_ID);

        if (PROC_HANDLE == NULL)
        {
            //Process failed to open
            return 30;
        }
        DWORD result;

        //Query Proc Information to get .exe entry point
        result = NtWow64QueryInformationProcess64( PROC_HANDLE, 0, &procInfo, sizeof(procInfo), &read_length);
        if (result != 0)
        {
            cerr << "Query Information Process has failed" << endl;

            return 40;
        }

        address64 =  (procInfo.PebBaseAddress + addressOffset);
        cerr << address64 << endl;

        string number;
        stringstream stristream;

        stristream << address64;
        stristream >> number;

        byte testByte = 0;
        (byte)ReadMemory64<byte>(testByte);

        system("PAUSE");
        return 1;
    }


template <typename _ret_t> _ret_t ReadMemory64(_ret_t& ret)
{

    NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL);
    ///* Debug # when too lazy for breakpoints
    cerr <<"value: " << ret << endl;
    cerr << "Error Code: " << GetLastError() << endl;
    if (result != 0)
    {
        cerr << "ReadMemory Failed.\r\nAddress: " << address64 << "\r\nSize: " << sizeof(_ret_t) << "\r\nResult: " << result << endl;
        cerr << "NtReadVirtualMemory64 has failed" << endl;
        system("PAUSE");

    } //*/
    return ret;
 };
#定义过程基本信息0
#定义NT\u WOW64\u查询\u信息\u流程\u 64\u名称“NTWOW64查询信息流程64”
#定义NT_WOW64_读取_虚拟_内存_64_名称“NTWOW64读取虚拟内存64”
类型定义UINT64 SYM;
typedef SIZE_T SIZE_T64;
窗口把手;
句柄进程句柄;
德沃德程序ID;
UINT地址;
UINT64地址64;
大小字节读取;
大小_T64字节读取64;
使用名称空间std;
//初始化用于导入基本64位读取函数的变量
//从ntdll
typedef NTSTATUS(NTAPI*FUNC_NtReadVirtualMemory64)
( 
在handleprocesshandle中,
在PVOID64基地址中,
输出PVOID缓冲区,
在长缓冲区中,
OUT PULONGLONG返回长度可选
);
typedef NTSTATUS(NTAPI*函数NTWOW64查询信息处理64)
(
在handleprocesshandle中,
在ULONG ProcessInformationClass中,
输出PVOID进程信息64,
长度,
出普隆返回长度可选
);
结构过程基本信息64{
SYM储备1;
SYM PebBaseAddress;
SYM储备2[2];
SYM UniqueProcessId;
SYM储备3;
/*
NTSTATUS存在状态;
ULONG64 PebBaseAddress;
ULONG64仿射导弹;
长期优先权;
UINT64保留区1;
ULONG64唯一进程ID;
ULONG64继承自UniqueProcessId;
*/
};
HINSTANCE ntdll=LoadLibrary(“ntdll.dll”);
FUNC\u NtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64=(FUNC\u NtWow64QueryInformationProcess64)GetProcAddress(ntdll,NT\u WOW64\u查询信息\u进程\u 64\u名称);
FUNC_NtReadVirtualMemory64 NtReadVirtualMemory64=(FUNC_NtReadVirtualMemory64)GetProcAddress(ntdll,NT_WOW64_READ_virtualmemory_64_NAME);
int init32to64内存读取(常量字符*窗口类,常量字符*标题,符号地址偏移)
{
德沃德;
德沃德·德德雷苏特;
模块主模块;
布尔枚举结果;
ULONG read_length=0;
HINSTANCE ntdll;
处理基本信息64 procInfo;
零内存(&procInfo,sizeof(procInfo));
//去拿窗户把手
WINDOW_HANDLE=FindWindow(windowClass,NULL);
if(窗口句柄==NULL)
{
//窗户没关上
返回10;
}
//获取进程ID
dwdResult=GetWindowThreadProcessId(窗口句柄和进程ID);
if(dwdResult==0)
{
//获取进程ID失败
返回20;
}
//打开流程
PROC\u HANDLE=OpenProcess(PROCESS\u ALL\u ACCESS,false,PROC\u ID);
if(PROC_HANDLE==NULL)
{
//进程无法打开
返回30;
}
德沃德结果;
//查询进程信息以获取.exe入口点
结果=NtWow64QueryInformationProcess64(进程句柄,0,&procInfo,sizeof(进程信息),&read_长度);
如果(结果!=0)
{

cerr我运行了一个简单的测试,发现当插入函数“NtWow64ReadVirtualMemory64”时,我的缓冲区“ret”的值没有改变。
代码在编译和运行时没有出现错误(编译和运行时),除了NtReadMemory64返回一个奇怪的数字(没有可用于ntdll NtWow64函数的文档,因此谷歌搜索它不会产生任何有用的结果)。
所以我想我要么提供了一个错误的缓冲区,要么没有从一个有效的内存地址读取数据

    #define PROC_BASIC_INFO 0
    #define NT_WOW64_QUERY_INFORMATION_PROCESS_64_NAME  "NtWow64QueryInformationProcess64"
    #define NT_WOW64_READ_VIRTUAL_MEMORY_64_NAME  "NtWow64ReadVirtualMemory64"

    typedef UINT64 SYM;
    typedef SIZE_T SIZE_T64;

    HWND   WINDOW_HANDLE;
    HANDLE PROC_HANDLE;
    DWORD PROC_ID;
    UINT address;
    UINT64 address64;
    SIZE_T bytesRead;
    SIZE_T64 bytesRead64;

    using namespace std;


    //initialize variables for importing of essential 64 bit reading functions
    //from ntdll
    typedef NTSTATUS(NTAPI *FUNC_NtReadVirtualMemory64)
    ( 
        IN  HANDLE  ProcessHandle,
        IN  PVOID64 BaseAddress,
        OUT PVOID   Buffer,
        IN  ULONGLONG BufferLength,
        OUT PULONGLONG ReturnLength OPTIONAL
    );
    typedef NTSTATUS (NTAPI *FUNC_NtWow64QueryInformationProcess64) 
    (
        IN  HANDLE ProcessHandle,
        IN  ULONG  ProcessInformationClass,
        OUT PVOID  ProcessInformation64,
        IN  ULONG  Length,
        OUT PULONG ReturnLength OPTIONAL
    );

    struct PROCESS_BASIC_INFORMATION64 {

        SYM Reserved1;
        SYM PebBaseAddress;
        SYM Reserved2[2];
        SYM UniqueProcessId;
        SYM Reserved3;
        /*
        NTSTATUS ExitStatus;
        ULONG64 PebBaseAddress;
        ULONG64 AffinityMask;
        LONG    BasePriority;
        UINT64  Reserved1;
        ULONG64 UniqueProcessId;
        ULONG64 InheritedFromUniqueProcessId;
        */
    };



    HINSTANCE ntdll = LoadLibrary("ntdll.dll");
    FUNC_NtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (FUNC_NtWow64QueryInformationProcess64)GetProcAddress(ntdll, NT_WOW64_QUERY_INFORMATION_PROCESS_64_NAME);
    FUNC_NtReadVirtualMemory64 NtReadVirtualMemory64 = (FUNC_NtReadVirtualMemory64)GetProcAddress(ntdll, NT_WOW64_READ_VIRTUAL_MEMORY_64_NAME);

    int Init32To64MemoryRead(const char* windowClass, const char* caption, SYM addressOffset)
    {

        DWORD cbNeeded;
        DWORD dwdResult;
        HMODULE mainModule;
        BOOL enumResult;
        ULONG read_length=0;
        HINSTANCE ntdll; 
        PROCESS_BASIC_INFORMATION64 procInfo;
        ZeroMemory(&procInfo, sizeof(procInfo));



        //Get the window handle
        WINDOW_HANDLE = FindWindow(windowClass, NULL);
        if (WINDOW_HANDLE == NULL)
        {
            //Window was not foud
            return 10;
        }

        //Get the process ID
        dwdResult = GetWindowThreadProcessId(WINDOW_HANDLE, &PROC_ID);

        if (dwdResult == 0)
        {
            //Getting Process ID failed
            return 20;
        }

        //Open the process
        PROC_HANDLE = OpenProcess(PROCESS_ALL_ACCESS, false, PROC_ID);

        if (PROC_HANDLE == NULL)
        {
            //Process failed to open
            return 30;
        }
        DWORD result;

        //Query Proc Information to get .exe entry point
        result = NtWow64QueryInformationProcess64( PROC_HANDLE, 0, &procInfo, sizeof(procInfo), &read_length);
        if (result != 0)
        {
            cerr << "Query Information Process has failed" << endl;

            return 40;
        }

        address64 =  (procInfo.PebBaseAddress + addressOffset);
        cerr << address64 << endl;

        string number;
        stringstream stristream;

        stristream << address64;
        stristream >> number;

        byte testByte = 0;
        (byte)ReadMemory64<byte>(testByte);

        system("PAUSE");
        return 1;
    }


template <typename _ret_t> _ret_t ReadMemory64(_ret_t& ret)
{

    NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL);
    ///* Debug # when too lazy for breakpoints
    cerr <<"value: " << ret << endl;
    cerr << "Error Code: " << GetLastError() << endl;
    if (result != 0)
    {
        cerr << "ReadMemory Failed.\r\nAddress: " << address64 << "\r\nSize: " << sizeof(_ret_t) << "\r\nResult: " << result << endl;
        cerr << "NtReadVirtualMemory64 has failed" << endl;
        system("PAUSE");

    } //*/
    return ret;
 };
因为我确实在函数外部显式初始化了缓冲区,所以我认为 我的问题是后者(没有提供有效的内存地址)

我在调用NtReadVirtualMemory时使用了以下命令

NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL);
显然,在调用NtWow64ReadVirtualMemory64时,我将addr强制转换为32位的void指针
(void*)address64
,由于address64是UINT64类型,强制转换截断了地址,我试图读取无法读取的内存段 我通过将强制转换更改为
(PVOID64)address64
将其强制转换为本机64位指针

比我想象的要简单,但在谷歌搜索和审查代码数天之后,发现它简直是地狱

编辑: 因为我的地址错了,所以这没有切断它。 我需要通过进程主模块在内存中的位置获取“.exe”的入口点。
查看“现在如何操作”。

非常感谢您的帮助!

这家伙似乎在那个主题上工作过。看一看,谢谢!我会进一步研究。但我们似乎在做同样的事情,只是他使用asm访问ntdll函数,并启用x64 ntdll函数