Unloading an Injected DLL

后端 未结 2 495
时光说笑
时光说笑 2021-01-14 00:48

I have a DLL I inject into other processes using SetWindowsHookEx. Inside the DLL I increment the module\'s reference counter by calling GetModuleHandleEx

2条回答
  •  灰色年华
    2021-01-14 01:32

    Okay.. here goes.. There are many ways to get the module info from a process. The undocumented way and the "documented" way.

    Results (documented):

    enter image description here

    Here is the "documented" way..

    #include 
    #include 
    #include 
    #include 
    
    
    int strcompare(const char* One, const char* Two, bool CaseSensitive)
    {
        #if defined _WIN32 || defined _WIN64
        return CaseSensitive ? strcmp(One, Two) : _stricmp(One, Two);
        #else
        return CaseSensitive ? strcmp(One, Two) : strcasecmp(One, Two);
        #endif
    }
    
    PROCESSENTRY32 GetProcessInfo(const char* ProcessName)
    {
        void* hSnap = nullptr;
        PROCESSENTRY32 Proc32 = {0};
    
        if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE)
            return Proc32;
    
        Proc32.dwSize = sizeof(PROCESSENTRY32);
        while (Process32Next(hSnap, &Proc32))
        {
            if (!strcompare(ProcessName, Proc32.szExeFile, false))
            {
                CloseHandle(hSnap);
                return Proc32;
            }
        }
        CloseHandle(hSnap);
        Proc32 = { 0 };
        return Proc32;
    }
    
    MODULEENTRY32 GetModuleInfo(std::uint32_t ProcessID, const char* ModuleName)
    {
        void* hSnap = nullptr;
        MODULEENTRY32 Mod32 = {0};
    
        if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)) == INVALID_HANDLE_VALUE)
            return Mod32;
    
        Mod32.dwSize = sizeof(MODULEENTRY32);
        while (Module32Next(hSnap, &Mod32))
        {
            if (!strcompare(ModuleName, Mod32.szModule, false))
            {
                CloseHandle(hSnap);
                return Mod32;
            }
        }
    
        CloseHandle(hSnap);
        Mod32 = {0};
        return Mod32;
    }
    
    std::string ModuleInfoToString(MODULEENTRY32 Mod32)
    {
        auto to_hex_string = [](std::size_t val, std::ios_base &(*f)(std::ios_base&)) -> std::string
        {
            std::stringstream oss;
            oss << std::hex << std::uppercase << val;
            return oss.str();
        };
    
        std::string str;
        str.append("  =======================================================\r\n");
        str.append("  Module Name:             ").append(Mod32.szModule).append("\r\n");
        str.append("  =======================================================\r\n\r\n");
        str.append("  Module Path:             ").append(Mod32.szExePath).append("\r\n");
        str.append("  Process ID:              ").append(std::to_string(Mod32.th32ProcessID).c_str()).append("\r\n");
        str.append("  Load Count (Global):     ").append(std::to_string(static_cast(Mod32.GlblcntUsage != 0xFFFF ? Mod32.GlblcntUsage : -1)).c_str()).append("\r\n");
        str.append("  Load Count (Process):    ").append(std::to_string(static_cast(Mod32.ProccntUsage != 0xFFFF ? Mod32.ProccntUsage : -1)).c_str()).append("\r\n");
        str.append("  Base Address:            0x").append(to_hex_string(reinterpret_cast(Mod32.modBaseAddr), std::hex).c_str()).append("\r\n");
        str.append("  Base Size:               0x").append(to_hex_string(Mod32.modBaseSize, std::hex).c_str()).append("\r\n\r\n");
        str.append("  =======================================================\r\n");
        return str;
    }
    
    int main()
    {
        PROCESSENTRY32 ProcessInfo = GetProcessInfo("notepad.exe");
        MODULEENTRY32 ME = GetModuleInfo(ProcessInfo.th32ProcessID, "uxtheme.dll");
        std::cout<

    The problem with the undocumented API is that I've never figured out why the load counts are always "6" for dynamic modules and "-1" for static modules.. For this reason, I will not post it..

    It is BEST NOT to use undocumented API if you want just the load count. The undocumented API's only advantage is that you can use it to "un-link/hide" a module within a process (like viruses do).. It will "unlink/hide" it.. NOT "unload" it. This means that at any time, you can "re-link" it back into the process's module list.

    Since you only need the module-reference-count, I've only included "documented" API which does exactly that.

提交回复
热议问题