Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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++ 如何检测使用LoadLibraryEx加载的模块_C++_.net_Process_Clr - Fatal编程技术网

C++ 如何检测使用LoadLibraryEx加载的模块

C++ 如何检测使用LoadLibraryEx加载的模块,c++,.net,process,clr,C++,.net,Process,Clr,我需要使用像或这样的windows函数来确定特定dll是否在代码执行的同一进程中加载 我正在寻找的一个模块是System.Windows.Forms.dll,但即使它是在进程中加载的。。。(在这里,您可以使用Process Explorer查看它) GetModuleHandle仍然找不到它 HMODULE modHandle = GetModuleHandle(L"System.Windows.Forms.dll"); GetLastError()返回找不到的错误 如果函数成功,则

我需要使用像或这样的windows函数来确定特定dll是否在代码执行的同一进程中加载

我正在寻找的一个模块是System.Windows.Forms.dll,但即使它是在进程中加载的。。。(在这里,您可以使用Process Explorer查看它)

GetModuleHandle仍然找不到它

    HMODULE modHandle = GetModuleHandle(L"System.Windows.Forms.dll");

GetLastError()返回找不到的错误

如果函数成功,则返回值是指定模块的句柄。 如果函数失败,则返回值为NULL

我认为这可能与CLR如何加载这些DLL有关。我注意到,如果使用LOAD_LIBRARY_AS_DATAFILE标志,则:

如果使用此值,系统将文件映射到调用 进程的虚拟地址空间,就好像它是一个数据文件一样。什么都不是 完成以执行或准备执行映射文件。所以你 无法调用诸如GetModuleFileName、GetModuleHandle或 使用此DLL的GetProcAddress

<> P>这也许是我的问题,但是不管原因是什么,有人知道在使用原生/C++代码的过程中找到一个被管理的dotnet DLL的方法吗? 谢谢

编辑: 根据Castorix在评论中的建议,我尝试使用EnumProcessModule:

    HMODULE modules[100];
    void* hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, GetCurrentProcessId());
    if (hProcess)
    {
        DWORD bytesNeeded;
        BOOL rc = EnumProcessModules(hProcess, modules, sizeof(modules), &bytesNeeded);
        if (rc)
        {
            int count = (int)(bytesNeeded / sizeof(HMODULE));
            for (int i = 0; i < count; i++)
            {
                wchar_t moduleName[260];
                GetModuleFileName(modules[i], moduleName, 260);
            }
        }
    }
    CloseHandle(hProcess);
HMODULE模块[100];
void*hProcess=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,0,GetCurrentProcessId());
if(hProcess)
{
德沃德·拜特斯曼;
BOOL rc=EnumProcessModules(需要hProcess、modules、sizeof(modules)和bytes);
if(rc)
{
int count=(int)(byteseeded/sizeof(HMODULE));
for(int i=0;i
这段代码找到了很多模块,但找不到System.Windows.Forms.dll

好的,这是一个试图回答的问题(或者说,对不起,这是一个太长的评论)

就我个人而言,我从未在Process Explorer窗格中见过托管的.NET DLL,但可能还不够仔细/经常查看。然而,我能(而且总是能)看到的是NGENed图像(
*.ni.dll

还请注意此处存在的
System.Data.dll
,它不是NGENed,而是一个混合模式程序集,包含本机代码和托管代码

因此可以得出结论,您在这里只能看到NGENed和混合模式“程序集”,因为它们仍然由
LoadLibrary
LoadLibraryEx
加载

还要注意我的评论,我在这里复制了这些评论,以便于访问:

我认为CLR不使用LoadLibrary,这可以解释为什么 无法使用您描述的API“查看”它们。事实上 是一篇相关的博客文章。你可以随时查看来源 (CoreCLR,但不重要),特别是关于如何做。我 没有真正好的地方,但你可以开始 然后离开它。改用ICorDebug接口

以下是上面链接的博客条目中的一些相关引用:

你可能会问自己:……谁在乎?嗯,首先很好 知道。我还没有注意到上面的公共服务公告。 这是一个实现细节,但是CLR程序集不是偶数 保证使用文件实现,更不用说中的DLL文件了 使用LoadLibrary Win32 API加载的特定格式

然而,有几个工具和场景已经开始依赖 事实上,CLR使用LoadLibrary加载程序集。例如 直到CLR 4,如果您想知道加载了哪些.NET程序集 在您的过程中,一个相当可靠的启发式方法是启动 Sysinternals Process Explorer并查看给定进程的DLL视图 过程这不适用于CLR 4,您可以在此处看到:

坦白地说,我不知道Process Explorer如何在您的案例中显示程序集(不是NGENed模式,也不是混合模式),因为您正在观看CLR2进程。但是,请注意,PE不仅仅使用Win32 API。它还使用WMI,可能还直接使用CLR获取更多信息。例如,“Process Properties/.NET Assembly”和“Process Properties/.NET Performance”选项卡很可能分别使用
ICorDebug
/
ICorProfile
和性能计数器/ETW

您可能还需要在这些接口中的某个接口上使用,或者通常需要使用或中的其他一些接口


不管是什么,我不认为由于上述原因,
EnumProcessModules
等会让您到达那里。

补充上述答案并提供相关代码;不可能使用像<代码>枚举进程模块< /C>的本机函数来检测非NoGeD的dotnet DLL,而我必须使用C++接口到CLR。< /P> 这里有更多信息:与此特定问题最相关的代码是:

    HRESULT GetAssemblyFromAppDomain(_AppDomain* pAppDomain, LPCWSTR wszAssemblyName, _Deref_out_opt_ _Assembly **ppAssembly)
    {
      *ppAssembly = NULL;
      // get the assemblies into a safearray
      SAFEARRAY *pAssemblyArray = NULL;
      HRESULT hr = pAppDomain->GetAssemblies(&pAssemblyArray);
      if (FAILED(hr)) 
      {
        return hr;
      }
      // put the safearray into a smart ptr, so it gets released
      CComSafeArray<IUnknown*>    csaAssemblies;
      csaAssemblies.Attach(pAssemblyArray);

      size_t cchAssemblyName = wcslen(wszAssemblyName);

      long cAssemblies = csaAssemblies.GetCount();
      for (long i=0; i<cAssemblies; i++)
      {
        CComPtr<_Assembly> spAssembly;
        spAssembly = csaAssemblies[i];
        if (spAssembly == NULL) 
          continue;
        CComBSTR cbstrAssemblyFullName;
        hr = spAssembly->get_FullName(&cbstrAssemblyFullName);
        if (FAILED(hr)) 
          continue;
        // is it the one we want?
        if (cbstrAssemblyFullName != NULL && 
          _wcsnicmp(cbstrAssemblyFullName, 
          wszAssemblyName, 
          cchAssemblyName) == 0)
        {
          *ppAssembly = spAssembly.Detach();
          hr = S_OK;
          break;
        }
      }
      if (*ppAssembly == 0)
      {
        hr = E_FAIL;
      }
      return hr;
    }
HRESULT GetAssemblyFromAppDomain(\u AppDomain*pAppDomain,LPCWSTR wszAssemblyName,\u Deref\u out\u opt\u Assembly**ppAssembly)
{
*ppAssembly=NULL;
//将程序集放入安全数组中
SAFEARRAY*pAssemblyArray=NULL;
HRESULT hr=pAppDomain->getAssemblys(&pAssemblyArray);
如果(失败(小时))
{
返回人力资源;
}
//将safearray放入智能ptr中,使其释放
CCOMSA射线CSA组件;
CSA附件(pAssemblyArray);
size_t cchAssemblyName=wcslen(wszAssemblyName);
long cAssemblies=csaAssemblies.GetCount();
用于(长i=0;iget_全名(&cbstrAssemblyFullName);
如果(失败(小时))
持续
//这是我们想要的吗?
如果(cbstrAssemblyFullName!=NULL&&
_wcsnicmp(cbstrAssemblyFullName,
wszAssemblyName,
cchAssemblyName)==0)