创建挂起进程后查找基地址
Finding the base address after creating suspended process
我正在尝试学习如何进行流程挖空/替换(为了学习)。我在挂起状态下创建了一个 32 位进程,之后我需要该进程的基地址以便稍后从内存中取消映射并替换为其他内容。
根据我的研究,我可以从进程的 PEB 中获取它,其中包括该地址。同样据我了解,PEB 始终位于 ebx 寄存器中,入口点位于 eax 寄存器中。
HOWEVER,当我获得主线程的上下文(其中包含寄存器的内容)时,它全为零,这对我来说毫无意义,但事实并非如此失败。
第二个问题。当我读取进程内存时,我得到 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:我在网上找到的所有内容都是为了查找 运行 进程的基址,我尝试并成功了,但是由于尚未加载任何模块处于挂起状态(因为它出现在 taskmanager 中,因为有没有过程的名称,但可能是错误的),它对我不起作用。
注 4:我也是 C 语言编码的新手,如果有什么地方看起来很奇怪,请见谅。
我们将很乐意提供任何帮助。如果您有其他获取基地址的方法,我很乐意听到。
对不起,如果代码有点乱,或者我不清楚。我会尽力解释...
忘了补充:我的系统是Windows10 64bit
编辑:修复了问题。需要做 context.ContextFlags=CONTEXT_INTEGER。
这让我可以阅读。 readprocess 内存也失败了,因为我给了它错误的读取地址(基本上是 0+8=8),我认为这是一个 64 位进程
您从未设置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 实现
我正在尝试学习如何进行流程挖空/替换(为了学习)。我在挂起状态下创建了一个 32 位进程,之后我需要该进程的基地址以便稍后从内存中取消映射并替换为其他内容。
根据我的研究,我可以从进程的 PEB 中获取它,其中包括该地址。同样据我了解,PEB 始终位于 ebx 寄存器中,入口点位于 eax 寄存器中。
HOWEVER,当我获得主线程的上下文(其中包含寄存器的内容)时,它全为零,这对我来说毫无意义,但事实并非如此失败。
第二个问题。当我读取进程内存时,我得到 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:我在网上找到的所有内容都是为了查找 运行 进程的基址,我尝试并成功了,但是由于尚未加载任何模块处于挂起状态(因为它出现在 taskmanager 中,因为有没有过程的名称,但可能是错误的),它对我不起作用。
注 4:我也是 C 语言编码的新手,如果有什么地方看起来很奇怪,请见谅。
我们将很乐意提供任何帮助。如果您有其他获取基地址的方法,我很乐意听到。 对不起,如果代码有点乱,或者我不清楚。我会尽力解释...
忘了补充:我的系统是Windows10 64bit
编辑:修复了问题。需要做 context.ContextFlags=CONTEXT_INTEGER。 这让我可以阅读。 readprocess 内存也失败了,因为我给了它错误的读取地址(基本上是 0+8=8),我认为这是一个 64 位进程
您从未设置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 实现