从 32 位进程获取 64 位进程内存的入口点
get the entry point to a 64bit process memory from a 32bit process
我想获取我从 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;
};
我想知道我做错了什么。
编辑:
经过进一步检查,我注意到 NtWow64ReadVirtualMemory 没有在用作缓冲区的变量 "ret" 中存储值。
我运行一个简单的测试,发现我的buffer-"ret"的值在插入函数"NtWow64ReadVirtualMemory64"[=31时没有改变=].
代码确实编译并且 运行 没有错误(编译和 运行time)除了 NtReadMemory64 返回一个奇怪的数字(没有可用于 ntdll NtWow64 函数的文档,所以 goolgling 它没有产生任何有用的东西) .
所以我想我要么提供了错误的缓冲区,要么没有从有效的内存地址读取。
因为我确实在函数之外显式地初始化了缓冲区,所以我想
我的问题是后者(没有提供有效的内存地址)。
我在调用 NtReadVirtualMemory 时使用了以下内容
NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL);
显然,当调用 NtWow64ReadVirtualMemory64 时,我将 addr 转换为 32 位空指针 (void*)address64
,并且由于 address64 是 UINT64 类型,因此转换 t运行cated 地址,我试图读取我无法读取的内存段
我通过将演员表更改为 (PVOID64)address64
来解决它
将其转换为本机 64 位指针。
比我想象的要简单,但经过几天的谷歌搜索和审查代码后发现它很糟糕。
编辑:
这并没有成功,因为我的地址是错误的。
我需要通过进程主模块在内存中的位置来获取“.exe”的入口点。
看看现在如何。
感谢您的帮助!
我想获取我从 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;
};
我想知道我做错了什么。
编辑: 经过进一步检查,我注意到 NtWow64ReadVirtualMemory 没有在用作缓冲区的变量 "ret" 中存储值。
我运行一个简单的测试,发现我的buffer-"ret"的值在插入函数"NtWow64ReadVirtualMemory64"[=31时没有改变=].
代码确实编译并且 运行 没有错误(编译和 运行time)除了 NtReadMemory64 返回一个奇怪的数字(没有可用于 ntdll NtWow64 函数的文档,所以 goolgling 它没有产生任何有用的东西) .
所以我想我要么提供了错误的缓冲区,要么没有从有效的内存地址读取。
因为我确实在函数之外显式地初始化了缓冲区,所以我想 我的问题是后者(没有提供有效的内存地址)。
我在调用 NtReadVirtualMemory 时使用了以下内容
NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL);
显然,当调用 NtWow64ReadVirtualMemory64 时,我将 addr 转换为 32 位空指针 (void*)address64
,并且由于 address64 是 UINT64 类型,因此转换 t运行cated 地址,我试图读取我无法读取的内存段
我通过将演员表更改为 (PVOID64)address64
来解决它
将其转换为本机 64 位指针。
比我想象的要简单,但经过几天的谷歌搜索和审查代码后发现它很糟糕。
编辑:
这并没有成功,因为我的地址是错误的。
我需要通过进程主模块在内存中的位置来获取“.exe”的入口点。
看看现在如何。
感谢您的帮助!