gpt4 book ai didi

c++ - 通过调用 CreateRemoteThread : crash 弹出 dll

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:50:40 25 4
gpt4 key购买 nike

我正在尝试为自己制作一个从进程中提取/释放 dll 的工具。我已经体验过 LoadLibrary 和注入(inject),但这次逻辑似乎不适用。这是我的代码:

HMODULE findModuleOffset(HANDLE proc, char *mod_name) {
//Finds module address in specified process. 0 if not found
HMODULE hMods[2048];
DWORD modules_byte_size;
if (EnumProcessModules(proc, hMods, sizeof(hMods), &modules_byte_size))
{
for (unsigned long i = 0; i < (modules_byte_size / sizeof(HMODULE)); i++) {
CHAR module_name[MAX_PATH];

// Get the full path to the module's file.

if (GetModuleFileNameExA(proc, hMods[i], module_name, sizeof(module_name))) {
if (strcmp(strrchr(module_name,'.')+1,"exe")!=0 && compareExeName(module_name, mod_name)) {
return hMods[i];
}
}
}
}
return 0;
}
bool compareExeName(char *path, char *partial_name) {
//This will substract the filename from path and compare it with partial_name
char *lastSlash = strrchr(path, '\\') + 1;
if (lastSlash != NULL && strstr(lastSlash, partial_name) == lastSlash) return 1;
return 0;
}

void unload_all_dll(char *dll_name) {
DWORD process_ids[2048];
DWORD process_byte_size; //size of filled process_ids in BYTES (after the call)
DWORD process_count; //count of all elements in process_ids
HMODULE ext_dll_module;
HANDLE opened_process;
HANDLE Hthread;
DWORD thread_exit_code = 1;
CHAR exe_path[1024];

if (EnumProcesses(process_ids, sizeof(process_ids), &process_byte_size)) {
process_count = process_byte_size / sizeof(DWORD);

for (int i = 0; i < process_count; i++) {
thread_exit_code = 0;
if ((opened_process = OpenProcess(PROCESS_ALL_ACCESS, false, process_ids[i])) == NULL) continue;

GetModuleFileNameExA(opened_process, 0, exe_path, MAX_PATH);

if ((ext_dll_module = findModuleOffset(opened_process, dll_name)) != 0) {

while (thread_exit_code == 0) {
if ((Hthread = CreateRemoteThread(opened_process, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "FreeLibrary"), (void*)ext_dll_module, 0, NULL)) == NULL) {
cout<<"Process closed meanwhile or dll unloaded";
break; //process has closed meanwhile
}
while (WaitForSingleObject(Hthread, 1000) == WAIT_TIMEOUT);
GetExitCodeThread(Hthread, &thread_exit_code);
}
cout << "Dll unloaded from " << exe_path << endl;
}

}
}
}

警告:一些变量名称可能会混淆(我很着急)但每次我尝试弹出一个 dll 时,一切都会崩溃(当然,只有包含指定 dll 的应用程序)。我测试了我能做的一切,一切似乎都很好:findModuleOffset 返回的模块地址是好的(根据进程资源管理器给出的值进行检查)。我不知道 createremotethread 或 thread_exit_code 的返回值是什么,因为应用程序崩溃(它包含要弹出的 dll..so...)。你能帮帮我吗?

最佳答案

(从评论中移出)

鉴于目标进程中有线程正在运行正在卸载的 dll 中的代码,它们将在 dll 被释放后立即崩溃 - 毕竟,CPU 正在执行的代码页面正在被取消映射!

为避免此问题,必须以某种方式通知正在运行的线程,以便它们可以在卸载 dll 之前终止; Windows 提供了很多 IPC 方法,一种很少使用的方法特别适合这种情况,即 mailslots .

当 dll 被注入(inject)时,被创建的“主”线程将创建一个具有众所周知名称的邮槽,并定期检查是否有任何消息给他。当你想卸载 dll 时,不要粗暴地注入(inject)一个强制释放 dll 的线程,只需询问你的“内部人员”:向邮槽发送一条消息,要求它终止1

线程将看到邮槽中有一条消息,注意可能终止在目标进程内启动的其他线程(可以使用共享原子变量 + WaitForSingleObject),并且,清理完成后,调用 FreeLibraryAndExitThread 结束最后一个线程和 dll。


注意事项

  1. 邮槽的一个特别有趣的特性是,如果它们以相同的名称多次创建,发送到这样一个名称的消息将被传递给所有它们,所以如果,看起来,你想同时关闭所有注入(inject)的 dll,这大大简化了控制程序——甚至不需要枚举正在运行的进程。

关于c++ - 通过调用 CreateRemoteThread : crash 弹出 dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45828096/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com