在运行时检测应用程序的所有依赖项

时间:2014-04-18 08:26:34

标签: c# c++ .net dll

关于在运行时搜索dll的所有依赖项,我有以下question

我有general.dll根据使用的方法读取不同的文件(其他dlls*.amd等)。我在我的应用程序中使用此dll,例如Sample.exeC#)。

我可以在运行时使用Process Monitor检测所有依赖项(对于Sample.exe)(使用按进程名称过滤)。

请提示我如何以编程方式检测Sample.exe(嵌入式general.dll)在运行时使用(读取)的所有依赖项,即我需要用于开发的内容(在{{1类似于Process Monitor中的功能。

谢谢!

2 个答案:

答案 0 :(得分:0)

其中一种可能的方法是在进程Sample.exe中动态注入一个单独的dll(可以返回所有信息)。有关概念,请参阅

http://support.microsoft.com/kb/197571

在Sample.exe中加载dll后,您可以通过应用程序提取所有必要的信息

编辑:请参考以下链接,它可能会有所帮助 http://www.codeproject.com/Articles/38438/Monitoring-Process-Statistics-in-C-WPF

答案 1 :(得分:0)

直接用于C#/。NET:

您可以使用System.Diagnostics中的类,属性Process.Modules将获取已由关联进程加载的模块列表,您可以通过调用Processes.GetProcesses()列出所有进程。


对于C ++方面或者如果要调用平台API:

您正在寻找Win32函数EnumProcessModules(),它允许您列出句柄引用的进程中加载​​的所有模块(DLL)(您可以通过PID或其他任何方式OpenProcess())。< / p>

甚至还有一个名为Enumerating All Modules For a Process的完整示例。


还检测其他已打开的文件:

我很晚才注意到你想要检测任何其他打开的文件,所以我建议以下hack:Hook Win32 API CreateFileW()(宽版本就足够了,Ascii只是它的包装器)并记录任何正在进行的操作打开(不仅创建,功能名称可能会产生误导)。

这是一个工作示例代码,显示了您需要执行的操作:

#include <windows.h>
#include <cstdio>
#include <cassert>

typedef HANDLE (WINAPI *CreateFileWType)(LPCWSTR, DWORD, DWORD,
  LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);

CreateFileWType origCreateFile;

HANDLE WINAPI myCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess,
  DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
  HANDLE hTemplateFile)
{
  // Log something about the file
  printf("*** %S [%c%c]\n",
    lpFileName,
    (dwDesiredAccess & GENERIC_READ)  ? 'R' : '-',
    (dwDesiredAccess & GENERIC_WRITE) ? 'W' : '-');

  // Call the original function
  return origCreateFile(lpFileName, dwDesiredAccess, dwShareMode,
    lpSecurityAttributes, dwCreationDisposition,
    dwFlagsAndAttributes, hTemplateFile);
}

int main()
{
  // Get pointer to the function and verify it can be hot-patched
  HMODULE hKernelBase = GetModuleHandle(TEXT("KernelBase"));
  BYTE* addr = reinterpret_cast<BYTE*>(GetProcAddress(hKernelBase, "CreateFileW"));
  assert(addr != NULL);
  assert(addr[0] == 0x8B && addr[1] == 0xFF); // `mov edi, edi` prologue

  // Save the original function location (after the prologue)
  origCreateFile = reinterpret_cast<CreateFileWType>(addr + 2);

  // Hot-patch the function to call our hook
  DWORD dwOldProtect;
  VirtualProtect(addr - 5, 7, PAGE_EXECUTE_READWRITE, &dwOldProtect);
  addr[-5] = 0xE9; // jmp ...
  *reinterpret_cast<DWORD*>(&addr[-4]) = reinterpret_cast<BYTE*>(&myCreateFileW) - addr;
  *reinterpret_cast< WORD*>(&addr[ 0]) = 0xF9EB; // jmps $-5
  VirtualProtect(addr - 5, 7, dwOldProtect, &dwOldProtect);

  // Test that it all works - original application would continue here
  fopen("input.txt", "r");
  fopen("output.txt", "w");

  return 0;
}

示例输出:

*** input.txt [R-]
*** output.txt [-W]

这不会记录任何低级系统操作,例如加载DLL,因为这些事情直接使用NT调用NtCreateFile(),但是对于大多数文件访问情况应该可以正常工作。还有更多错误检查,转换为托管C ++ / CLR或其他任何留给读者的练习。

相关问题