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

本文关键字:依赖 运行时 检测 应用程序 | 更新日期: 2023-09-27 17:58:49

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

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

我能够在运行时使用Process Monitor(使用按进程名称筛选)检测所有依赖项(针对Sample.exe)。

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

谢谢!

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

对于C#/.NET直接:

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


对于C++端,或者如果您想调用平台API:

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

甚至还有一个完整的例子叫做枚举进程的所有模块。


同时检测其他打开的文件:

我注意到最近你还想检测任何其他打开的文件,所以我建议使用以下破解方法:Hook Win32 API CreateFileW()(Wide版本就足够了,Ascii one只是它的包装器),并记录正在打开的任何文件(不仅是创建的,函数名可能会误导)。

这是一个工作示例代码,显示了您需要做的事情:

#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或其他留给读者的练习。

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

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

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

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