2017-11-01 29 views
0

時々GetModuleFileNameが正しい文字列を返しますが、文字列を使用している現在のコードで現在時刻の99%が正しい値であるE:\Windows\system32\HID.DLLではなくÀÙáøÛáws\system32\HID.DLLとして返されます。このことを念頭に置いて、文字列をリストに入れるかどうかを調べるためにロードする必要があるすべてのモジュールのリストとその文字列を比較することはできません。C++ GetModuleFileNameが正しい文字列を返しません

このコードは以下のコードでは最適ではないかもしれませんが、これは私がこのコードで使用しようとしているコードです。私は、TCHARを使わず、EnumProcessModulesからの返事を調べるようなことを理解するために、あらゆる種類のコード変更を試みました。

void _scan_dll_data(VBTrpSetup_t &setup, VBTrp_DetectData_t &_ret, VBTrp_InjectData_t &_dlllists) { 
    bool _detected_injected_dll = false; 
    std::vector<std::string> _ModuleContainer; 
    std::string _ModuleName; 
    HMODULE hMods[1024]; /* Hopefully enough for this. */ 
    DWORD cbNeeded; 
    if (EnumProcessModules(setup.GameProcHandle, hMods, sizeof(hMods), &cbNeeded)) { 
     for (unsigned int i = 0; i < (cbNeeded/sizeof(HMODULE)); i++) { 
      char szModName[MAX_PATH]; 
      if (GetModuleFileName(hMods[i], szModName, sizeof(szModName)/sizeof(char))) { 
       _ModuleName = szModName; 
       for (unsigned int i = 0; i < _dlllists.ModuleExcludeList.size(); i++) { 
        // item must not be in the ModuleExcludeList!!! 
        if (!_dlllists.ModuleExcludeList[i].compare(_ModuleName)) { 
         _ModuleContainer.push_back(_ModuleName); 
        } 
       } 
      } 
     } 
    } 
    if (_dlllists.ModuleList != _ModuleContainer) { 
     _detected_injected_dll = true; 
     _ret.DLLName = reinterpret_cast<LPCSTR>(_ModuleName.c_str()); 
    } 
    if (_detected_injected_dll) { 
     _ret.value = TRUE; 
    } 
    else { 
     _ret.value = FALSE; 
    } 
    if (_ret.value == TRUE) { 
     _ret.int_value = -1; 
    } else { 
     _ret.int_value = NULL; 
    } 
} 

私が逃したはずの簡単な答えです。私はMSDNの例に基づいてこれのいくつかの部分をしました。たぶんそれらの例は間違っていたでしょう。私は確信していません。 誰もこの文字列の問題を解決する方法を知っていますか?

+1

結果は、このコードです。別のことは、何かが失敗した理由をチェックして、静かに無視するだけで ':: GetLastError'を呼び出さないということです。 – VTT

+0

'' EnumProcessModules''は、 '' setup''構造体にハンドルがキャッシュされているにもかかわらず、 '' ERROR_INVALID_HANDLE''を返します。 – PSXGamerPro1

答えて

0

修正点は、Unicodeバージョンを確実に使用し、関数全体がワイドユニコード文字列を使用するようにすることでした。その理由は、ntdll.dllに内部的で文書化されていない構造体(PEBに関連する)の​​ためです。

だから、基本的にので、私はとにかく、後でそれらをベース名としていた事実をGetModuleBaseNameW機能にすべてを変え、wstringの、ループの外にiの上書きを引き起こし、それを取り除くiを用いて第2のループに気付いて、 Handleが無効化されたときにGetLastErrorのチェックを追加し、クリーンアップを処理するためにエラーコードをエンドユーザーに返すことができます。まず最初に、あなたの代わりに、 `どこでもchar`と機能の幅広いバリエーションに対応する` wchar_t`を使用する必要があるということです

void _scan_dll_data(VBTrpSetup_t &setup, VBTrp_DetectData_t &_ret, VBTrp_InjectData_t &_dlllists) { 
    BOOL _detected_injected_dll = FALSE; 
    std::vector<std::wstring> _ModuleContainer; 
    HANDLE hProcess; 
    std::vector<HMODULE> hMods; 
    DWORD cbNeeded; 
    hProcess = GetCurrentProcess(); 
    _ret.int_value = 0; 
    if (EnumProcessModulesEx(hProcess, hMods.data(), setup.NumOfModules, &cbNeeded, LIST_MODULES_ALL)) { 
     for (unsigned int i = 0; i < (cbNeeded/sizeof(HMODULE)); i++) { 
      wchar_t *szModName = L'\x0'; 
      std::wstring _ModuleName; 
      if (GetModuleBaseNameW(hProcess, hMods[i], reinterpret_cast<LPWSTR>(szModName), MAX_PATH)) { 
       _ModuleName = szModName; 
       // item must not be in the ModuleExcludeList!!! 
       if (!_dlllists.ModuleExcludeList[i].compare(_ModuleName)) { 
        _ModuleContainer.push_back(_ModuleName); 
       } 
      } else { 
       _ret.error_code = GetLastError(); 
      } 
     } 
    } else { 
     _ret.error_code = GetLastError(); 
    } 
    if (_ret.error_code != ERROR_INVALID_HANDLE) { 
     for (unsigned int j = 0; j < _dlllists.ModuleList.size(); j++) { 
      if (_dlllists.ModuleList[j] != _ModuleContainer[j]) { 
       _detected_injected_dll = TRUE; 
       _ret.int_value = -1; 
       _ret.DLLName = (LPWSTR)_ModuleContainer[j].c_str(); 
       // to avoid overwriting the first one. 
       break; 
      } 
     } 
     _ret.value = _detected_injected_dll; 
    } 
} 
関連する問題