在运行时检测应用程序的所有依赖项
本文关键字:依赖 运行时 检测 应用程序 | 更新日期: 2023-09-27 17:58:49
关于在运行时搜索dll的所有依赖项,我有以下问题。
我有general.dll
,它根据使用的方法读取不同的文件(其他dlls
、*.amd
等)。我在我的应用程序中使用这个dll,例如Sample.exe
(C#
)。
我能够在运行时使用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