Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过调用CreateRemoteThread:崩溃弹出dll_C++_Dll - Fatal编程技术网

C++ 通过调用CreateRemoteThread:崩溃弹出dll

C++ 通过调用CreateRemoteThread:崩溃弹出dll,c++,dll,C++,Dll,我正在尝试为自己制作一个从进程中提取/释放DLL的工具。我已经体验过LoadLibrary和注入,但这次的逻辑似乎不适用。 这是我的代码: 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

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

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;
            }

        }
    }
}
HMODULE findModuleOffset(HANDLE proc,char*mod_name){
//在指定进程中查找模块地址。如果未找到,则为0
HMODULE-hMods[2048];
DWORD模块\字节\大小;
if(enumProcessModule(proc、hMods、sizeof(hMods)和modules\u byte\u size))
{
对于(无符号长i=0;i<(模块\字节\大小/sizeof(HMODULE));i++){
字符模块名称[最大路径];
//获取模块文件的完整路径。
if(GetModuleFileNameExA(proc,hMods[i],module_name,sizeof(module_name))){
if(strcmp(strrchr(模块名称,'.')+1,“exe”)!=0和&compareExeName(模块名称,模块名称)){
返回hMods[i];
}
}
}
}
返回0;
}
bool compareExeName(字符*路径,字符*部分名称){
//这将从路径中减去文件名,并将其与部分名称进行比较
char*lastsslash=strrchr(路径“\\”)+1;
if(lastSlash!=NULL&&strstrstr(lastSlash,partial_name)==lastSlash)返回1;
返回0;
}
无效卸载所有dll(字符*dll\U名称){
德沃德进程[2048];
DWORD process_byte_size;//已填充的进程ID的大小(字节)(在调用之后)
DWORD进程\u计数;//进程\u ID中所有元素的计数
HMODULE ext_dll_模块;
处理开放式流程;
处理Hthread;
DWORD线程出口代码=1;
CHAR exe_路径[1024];
if(枚举进程(进程ID、进程ID和进程字节大小)){
进程计数=进程字节大小/大小(DWORD);
for(int i=0;i
假设目标进程中有线程正在运行正在卸载的dll中的代码,那么它们将在dll释放后立即崩溃—毕竟,CPU正在执行的代码页正在被取消映射

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

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

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


注释

  • MailSlot的一个特别有趣的特性是,如果使用相同的名称多次创建它们,则发送到该名称的消息将传递给所有这些名称,因此,如果您希望同时关闭所有注入的DLL,这将大大简化控制程序-甚至不需要枚举e运行进程

  • 嗯,除非你自己注入dll,在目标进程实际使用的dll上调用
    freebrary
    ,否则代码将以崩溃告终……不过,在尝试从目标进程卸载dll之前,你始终可以将调试器附加到目标进程,并查看它崩溃的位置。是的,确实,我应该提到。dll是我的并且大部分是空的。其中有几个循环。这是原因吗?freelibrary不应该强制卸载dll吗?我现在无法使用调试器进行检查。明天我将返回一个响应。如果目标进程中有线程正在该dll中运行代码(那些循环?),当然它会崩溃-这不会有任何不同,运行的线程无法知道它们正在运行的代码正在从内存中取消映射。确定更多详细信息:我使用CreateRemoteThread注入该dll,因此有一个。在dll中,我创建了另外两个线程,其中一个线程正在检查注册表的值(在循环中).就是这样。那么这些线程是导致问题的还是第一个线程(用于注入)?