创建远程线程后进程异常退出
运行环境WIN10 x64,尝试使用CreateRemoteThread在计算器中创建远程进程后,计算器程序直接异常退出。。GetLastError的返回值为0(差不多是没能找到错误)想请教以下各位大佬程序为啥会异常退出{:10_266:}
以下是代码:
#include<stdio.h>
#include<windows.h>
HWND window_handle;
void t_main();
void t_end();
int main()
{
HANDLE process_handle;
HANDLE thread_handle=0;
DWORD process_ID;
DWORD64 thread_address;
DWORD thread_ID;
BOOL result;
int code_size=(LPBYTE)t_end-(LPBYTE)t_main;
printf("待嵌入的代码大小为:%d字节\n",code_size);
window_handle = FindWindow(NULL, "计算器");
printf("获取到的窗口句柄为0x%X\n",window_handle);
GetWindowThreadProcessId(window_handle,&process_ID);
process_handle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,process_ID);
printf("获取到的进程句柄为0x%X\n", process_handle);
thread_address = VirtualAllocEx(process_handle,NULL,code_size,MEM_COMMIT,PAGE_EXECUTE_READ);
printf("申请到的进程中合适的地址为:0x%X\n",thread_address);
result = WriteProcessMemory(process_handle,thread_address,&t_main,code_size,NULL);
if (result != 0)
{
printf("在内存中写入数据成功!\n");
}
else
{
printf("在内存中写入数据失败。\n");
}
thread_handle = CreateRemoteThread(process_handle,NULL,0,thread_address,NULL,0,NULL);
printf("创建的线程句柄为0x%X\n", thread_handle);
// CloseHandle(window_handle);
// CloseHandle(process_handle);
// CloseHandle(thread_handle);
if (GetLastError())
{
printf("出现错误,错误代码为:%d\n", GetLastError()); //运行下来返回值为0
}
getchar();
}
static void t_main()
{
MessageBox(window_handle, "成功!","无",NULL);
}
static void t_end()
{
;
}
问你,当前进程的MessageBox地址和目标进程的MessageBox地址一样吗?不一样?那你为什么在目标进程中使用当前进程的MessageBox地址?
在目标进程中如何使用MessageBox ?
LoadLibrary和GetProcAddress了解一下
#include <stdio.h>
#include <windows.h>
#include <psapi.h>
HWND window_handle;
static DWORD WINAPI t_main(LPVOID lpParameter) {
void *(*parameter) = (void *)lpParameter;
HMODULE (*LoadLibraryA)(LPCSTR lpLibFileName) = (*parameter);
FARPROC (*GetProcAddress)(HMODULE hModule, LPCSTR lpProcName) = (*parameter);
const char str_kernel32[] = "kernel32.dll";
HMODULE kernel32 = LoadLibraryA(str_kernel32);
const char str_user32[] = "user32.dll";
HMODULE user32 = LoadLibraryA(str_user32);
const char str_FreeLibrary[] = "FreeLibrary";
BOOL (*FreeLibrary)(HMODULE hLibModule) = (void *)GetProcAddress(kernel32, str_FreeLibrary);
const char str_MessageBoxA[] = "MessageBoxA";
int (*MessageBoxA)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) = (void *)GetProcAddress(user32, str_MessageBoxA);
const char str_ok[] = "ok!";
const char str_none[] = "none";
MessageBoxA(NULL, str_ok, str_none, MB_OK);
FreeLibrary(user32);
FreeLibrary(kernel32);
return 123;
}
static void WINAPI t_end(void) {}
static void *find_proc_address(HANDLE hProcess, const char *proc_name) {
HMODULE hMods;
DWORD cbNeeded;
if(!EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) return NULL;
for(size_t i = 0; i < cbNeeded / sizeof(HMODULE); ++i) {
FARPROC proc = GetProcAddress(hMods, proc_name);
if(proc) return proc;
}
return NULL;
}
int main(void) {
HANDLE process_handle;
HANDLE thread_handle = 0;
DWORD process_ID;
LPVOID thread_address;
BOOL result;
int code_size = (LPBYTE)t_end - (LPBYTE)t_main;
printf("待嵌入的代码大小为:%d字节\n", code_size);
window_handle = FindWindowW(NULL, L"计算器");
printf("获取到的窗口句柄为%p\n", window_handle);
GetWindowThreadProcessId(window_handle, &process_ID);
process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_ID);
printf("获取到的进程句柄为%p\n", process_handle);
thread_address = VirtualAllocEx(process_handle, NULL, code_size, MEM_COMMIT, PAGE_EXECUTE_READ);
printf("申请到的进程中合适的地址为:%p\n", thread_address);
result = WriteProcessMemory(process_handle, thread_address, t_main, code_size, NULL);
if (result != 0) printf("在内存中写入数据成功!\n");
else printf("在内存中写入数据失败。\n");
void *parameter = {find_proc_address(process_handle, "LoadLibraryA"), find_proc_address(process_handle, "GetProcAddress")};
LPVOID thread_parameter = VirtualAllocEx(process_handle, NULL, sizeof(parameter), MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(process_handle, thread_parameter, ¶meter, sizeof(parameter), NULL);
thread_handle = CreateRemoteThread(process_handle, NULL, 0, thread_address, thread_parameter, 0, NULL);
printf("创建的线程句柄为%p\n", thread_handle);
WaitForSingleObject(thread_handle, INFINITE);
DWORD ExitCode;
GetExitCodeThread(thread_handle, &ExitCode);
printf("ExitCode: %u\n", ExitCode);
CloseHandle(thread_handle);
VirtualFreeEx(process_handle, thread_parameter, 0, MEM_RELEASE);
VirtualFreeEx(process_handle, thread_address, 0, MEM_RELEASE);
CloseHandle(process_handle);
return 0;
}
人造人 发表于 2022-9-10 16:48
问你,当前进程的MessageBox地址和目标进程的MessageBox地址一样吗?不一样?那你为什么在目标进程中使用当 ...
大佬,顺便问一句,你在电脑上尝试给进程创建远程线程时,进程会异常终止吗 玛丽亚在伯大尼 发表于 2022-9-10 18:15
大佬,顺便问一句,你在电脑上尝试给进程创建远程线程时,进程会异常终止吗
用你的代码会,我改的代码不会
人造人 发表于 2022-9-10 18:21
用你的代码会,我改的代码不会
跪求大佬解答,运行修改好的代码出现了一样的问题{:10_266:}显示ExitCode: 3221225477 玛丽亚在伯大尼 发表于 2022-9-10 19:40
跪求大佬解答,运行修改好的代码出现了一样的问题显示ExitCode: 3221225477
那就调试程序么,下断点,一条语句一条语句执行程序,看返回值,看看在哪一行的返回值有问题
人造人 发表于 2022-9-10 19:44
那就调试程序么,下断点,一条语句一条语句执行程序,看返回值,看看在哪一行的返回值有问题
折腾了一天,发现只要远程线程中存在函数调用行为(确定好了地址的)就会出现0xC0000005错误,然后进程异常终止,但是只要没有调用函数,啥问题都没有{:10_269:}。不管是我后来写的,还是大佬你给的代码都会出现这样的问题。。敢问大佬,这可能是运行环境的问题吗(win10,vs2017,其他什么没乱动过) 玛丽亚在伯大尼 发表于 2022-9-11 22:54
折腾了一天,发现只要远程线程中存在函数调用行为(确定好了地址的)就会出现0xC0000005错误,然后进程异 ...
你什么时候有时间,远程给你调试一下?
qq:1440332527
玛丽亚在伯大尼 发表于 2022-9-11 22:54
折腾了一天,发现只要远程线程中存在函数调用行为(确定好了地址的)就会出现0xC0000005错误,然后进程异 ...
不应该,重定位过地址的函数是可以调用的,不能调用函数,说明函数的地址没有进行重定位
人造人 发表于 2022-9-11 23:15
不应该,重定位过地址的函数是可以调用的,不能调用函数,说明函数的地址没有进行重定位
最后想不出什么办法,干脆写个程序自己打印MessageBoxA在其中的函数地址,然后在远程线程中使用汇编来调用函数。虽然最终成了,但是还是有一些奇怪的局限性。。
(试过C语言直接改写函数地址然后调用,会出错)
static void t_main()
{
_asm {
push 0x0 //MB_OK
push 0x4FF85C //正文的字符串地址
push 0x4FF84C //标题的字符串地址
push 0x0 //父窗口句柄
mov edi, 0x77A809A0 //MessageBoxA地址,这里很奇怪,直接call 0x77A809A0会出现之前一样的错误。。
call edi //不知道为啥只有这样写才成功?
}
return 0;
}
static void t_end()
{
;
} 玛丽亚在伯大尼 发表于 2022-9-12 09:37
最后想不出什么办法,干脆写个程序自己打印MessageBoxA在其中的函数地址,然后在远程线程中使用汇编来调 ...
我倒是想看看,你那边用我改的程序还不能运行,究竟错哪了
终于改出来一个能用的了{:10_266:} 此贴该完结了。
#include <stdio.h>
#include <windows.h>
#include <psapi.h>
HWND window_handle;
static DWORD WINAPI t_main(LPVOID lpParameter) { //前一个参数的第一个元素是LoadLibraryA的地址,第二个元素是GetProcAddress的地址,第三个元素是字符串资源地址
void *(*parameter) = (void *)lpParameter;
HMODULE(*LoadLibraryA)(LPCSTR lpLibFileName);
LoadLibraryA = (*parameter);
FARPROC(*GetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
GetProcAddress = (*parameter);
char* str_addr = (*parameter);
char* str_kernel32 = str_addr;
HMODULE kernel32 = LoadLibraryA(str_kernel32);
char* str_user32 = (str_addr += 13);
HMODULE user32 = LoadLibraryA(str_user32);
char* str_FreeLibrary = (str_addr += 11);
BOOL(*FreeLibrary)(HMODULE hLibModule);
FreeLibrary = (void *)GetProcAddress(kernel32, str_FreeLibrary);
char* str_MessageBoxA = (str_addr += 12);
int(*MessageBoxA)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
MessageBoxA = (void *)GetProcAddress(user32, str_MessageBoxA);
char* str_text = (str_addr += 12);
char* str_title = (str_addr += 7);
MessageBoxA(0, str_text, str_title, 0);
FreeLibrary(user32);
FreeLibrary(kernel32);
return 0;
}
static void WINAPI t_end(void) {}
static void *find_proc_address(HANDLE hProcess, const char *proc_name) {
HMODULE hMods;
DWORD cbNeeded;
if (!EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) return NULL;
for (size_t i = 0; i < cbNeeded / sizeof(HMODULE); ++i) {
FARPROC proc = GetProcAddress(hMods, proc_name);
if (proc) return proc;
}
return NULL;
}
int main(void) {
HANDLE process_handle;
HANDLE thread_handle = 0;
DWORD process_ID;
LPVOID thread_address;
BOOL result;
char str_resource = "kernel32.dll\0user32.dll\0FreeLibrary\0MessageBoxA\0Hello?\0Greeting\0";
int code_size = (LPBYTE)t_end - (LPBYTE)t_main;
printf("待嵌入的代码大小为:%d字节\n", code_size);
window_handle = FindWindowW(NULL, L"计算器");
printf("获取到的窗口句柄为%p\n", window_handle);
GetWindowThreadProcessId(window_handle, &process_ID);
process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_ID);
printf("获取到的进程句柄为%p\n", process_handle);
thread_address = VirtualAllocEx(process_handle, NULL, code_size, MEM_COMMIT, PAGE_EXECUTE_READ);
printf("申请到的进程中合适的地址为:%p\n", thread_address);
result = WriteProcessMemory(process_handle, thread_address, t_main, code_size, NULL);
if (result != 0) printf("在内存中写入数据成功!\n");
else printf("在内存中写入数据失败。\n");
LPVOID string_address = VirtualAllocEx(process_handle, NULL, sizeof(str_resource), MEM_COMMIT, PAGE_READWRITE);//将字符串资源载入进程
WriteProcessMemory(process_handle, string_address, str_resource, 128, NULL);
void *parameter = { find_proc_address(process_handle, "LoadLibraryA"), find_proc_address(process_handle, "GetProcAddress"), string_address };
LPVOID thread_parameter = VirtualAllocEx(process_handle, NULL, sizeof(parameter), MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(process_handle, thread_parameter, ¶meter, sizeof(parameter), NULL);
thread_handle = CreateRemoteThread(process_handle, NULL, 0, (LPTHREAD_START_ROUTINE)thread_address, thread_parameter, 0, NULL);
printf("创建的线程句柄为%p\n", thread_handle);
WaitForSingleObject(thread_handle, INFINITE);
DWORD ExitCode;
GetExitCodeThread(thread_handle, &ExitCode);
printf("ExitCode: 0x%X\n", ExitCode);
CloseHandle(thread_handle);
VirtualFreeEx(process_handle, thread_parameter, 0, MEM_RELEASE);
VirtualFreeEx(process_handle, thread_address, 0, MEM_RELEASE);
CloseHandle(process_handle);
return 0;
}
人造人 发表于 2022-9-12 10:57
我倒是想看看,你那边用我改的程序还不能运行,究竟错哪了
我发现在线程内定义的字符串会出问题,然后我把字符串作为资源写入进程中调用就没问题了。还有,把函数定义和函数地址设置写在一起也会有问题,我也不知道为啥,分开就没事。就这两点改一下线程就能正常运行,Exitcode=0,万事大吉。总而言之,这两个问题很奇怪,想不通。 玛丽亚在伯大尼 发表于 2022-9-12 15:07
我发现在线程内定义的字符串会出问题,然后我把字符串作为资源写入进程中调用就没问题了。还有,把函数定 ...
需要帮你调试一下吗?
人造人 发表于 2022-9-12 15:11
需要帮你调试一下吗?
不用了,谢谢
页:
[1]