0

I had the following question regarding the searching of all dependencies of a dll during runtime.

I have general.dll which reads different files (other dlls, *.amd etc.) according to the used methods. I use this dll in my application, for example, Sample.exe (C#).

I am able to detect all dependencies (for Sample.exe) during runtime using Process Monitor (using filter by process name).

Please, prompt me how I can detect programmatically all dependencies which Sample.exe (with embedded general.dll) uses (reads) during runtime, i.e. what I need use in order to develop (in C#) similar functionality like in Process Monitor.

Thanks!

Community
  • 1
  • 1
elias
  • 53
  • 6
  • Do you want a process monitor in C# or you want only the information of mentioned dll in your application – DNamto Apr 18 '14 at 08:31
  • @DNamto I want to develope the functionallity like in Process Monitor, i.e. specify a process name and detect all dependencies of the process during runtime of the process. – elias Apr 18 '14 at 09:01
  • Way back I have implemented the same by dll injection method which I have briefed in below answer. I know its not complete answer but it will definitely give a approach to move ahead. Will update the spac in case I get something new – DNamto Apr 18 '14 at 09:05

2 Answers2

0

One of the possible approach could be that you dynamically inject a seperate dll (which can return back all the information) in process Sample.exe. For concept please refer

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

Once the dll is loaded in Sample.exe you can extract all necessary information through your application

Edit: Please refer below link, it could be helpful http://www.codeproject.com/Articles/38438/Monitoring-Process-Statistics-in-C-WPF

DNamto
  • 1,342
  • 1
  • 21
  • 42
  • The fact in that, general.dll can reads different files according to the used method from this dll. For example, if I use "Method1" of general.dll in my Sample.exe then general.dll reads "File1.dll", but if I use "Method2" then general.dll reads "File2.dll". – elias Apr 18 '14 at 09:07
  • So I want to develop an application in which specify process name (`Sample.exe`) and this application will detect all dependencies of `Sample.exe` during runtime of `Sample.exe` and after that will copy detected dependencies to a folder. – elias Apr 18 '14 at 09:14
0

For C#/.NET directly:

You can use classes from System.Diagnostics, the property Process.Modules will fetch you a list of modules that have been loaded by the associated process, you can list all processes by calling Processes.GetProcesses().


For C++ side or if you want to invoke platform APIs:

You are looking for Win32 function EnumProcessModules(), which allows you to list all the modules (DLLs) loaded in a process referenced by a handle (which you can OpenProcess() by PID or whatever).

There is even a full example called Enumerating All Modules For a Process.


Detecting also other opened files:

I noticed late you wanted to detect also any other opened files, so I suggest the following hack: Hook Win32 API CreateFileW() (the Wide version is enough, Ascii one is just its wrapper) and log whatever is being opened (not only created, the function name can be misleading).

This is a working example code which shows what you'd need to do:

#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;
}

Example output:

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

This won't log any low-level system operations like loading DLLs, because such things are using NT call NtCreateFile() directly, but should work for most cases of file access fine. Also more error checking, converting into Managed C++/CLR or whatever is left as an exercise to the reader.

Yirkha
  • 12,737
  • 5
  • 38
  • 53
  • Thanks for your advice! However, `Process.Modules` provides only the list of `*.dll` files which a process loaded. But in my case, my `Sample.exe` (`general.dll`) also reads files with other extensions (`.amd`, etc.). Do you have any ideas how I can detect also such files (`*.amd`, etc.)? – elias Apr 21 '14 at 02:42
  • Ah, I see. Hmm, that would be hard. Process Monitor does that by having a kernel driver which hooks internal functions and reports the calls to the application itself. You could make an user land hook on CreateFile() Windows API function, that might report the most of opened files. It would need some serious hacking though. – Yirkha Apr 21 '14 at 10:16
  • Thanks! Perhaps, I will try to develop such functionality, but it is will be hard :) – elias Apr 21 '14 at 10:27
  • I added some C++ example code to show you how to do that, hope that helps. – Yirkha Apr 22 '14 at 01:44