mirror of
https://github.com/toneillcodes/windows-process-injection
synced 2026-06-21 14:11:25 +00:00
Adding module stomping resources and information
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
#include "peb-eat-utils.h"
|
||||
#include "utils.h"
|
||||
|
||||
// Ensure NTSTATUS success is defined
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
|
||||
|
||||
// obtain the local process TEB
|
||||
void* GetLocalTebAddress(void) {
|
||||
#ifdef _WIN64
|
||||
|
||||
@@ -12,6 +12,23 @@
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
|
||||
#endif
|
||||
|
||||
// 1. Define the COMPLETE structure since winternl.h cuts out the fields we need
|
||||
typedef struct _FULL_LDR_DATA_TABLE_ENTRY {
|
||||
LIST_ENTRY InLoadOrderLinks;
|
||||
LIST_ENTRY InMemoryOrderLinks; // This is what we use to offset math!
|
||||
LIST_ENTRY InInitializationOrderLinks;
|
||||
PVOID DllBase;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STRING FullDllName;
|
||||
UNICODE_STRING BaseDllName; // Now visible!
|
||||
ULONG Flags;
|
||||
WORD ObsoleteLoadCount;
|
||||
WORD TlsIndex;
|
||||
LIST_ENTRY HashLinks;
|
||||
ULONG TimeDateStamp;
|
||||
} FULL_LDR_DATA_TABLE_ENTRY, *PFULL_LDR_DATA_TABLE_ENTRY;
|
||||
|
||||
// Returns the TEB address for the current thread
|
||||
void* GetLocalTebAddress(void);
|
||||
|
||||
|
||||
@@ -25,4 +25,28 @@ extern "C" DWORD FindPidByName(const wchar_t* processName) {
|
||||
CloseHandle(snapshot);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
HANDLE GetProcessHandle(DWORD targetPID) {
|
||||
// Request ONLY the minimum permissions needed for the job:
|
||||
// 1. PROCESS_QUERY_INFORMATION - needed for NtQueryInformationProcess (PEB location)
|
||||
// 2. PROCESS_VM_READ - needed for ReadProcessMemory (reading the DLL list)
|
||||
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, targetPID);
|
||||
|
||||
if (hProcess == NULL) {
|
||||
DWORD error = GetLastError();
|
||||
//printf("[-] OpenProcess failed! Error code: %lu\n", error);
|
||||
|
||||
// Quick troubleshooting tips based on common error codes:
|
||||
if (error == ERROR_ACCESS_DENIED) {
|
||||
//printf("[!] Hint: Access Denied. Try running your tool as Administrator,\n");
|
||||
//printf(" or check if you are targeting a protected system process (like lsass.exe).\n");
|
||||
} else if (error == ERROR_INVALID_PARAMETER) {
|
||||
//printf("[!] Hint: Invalid Parameter. Double-check that the PID actually exists.\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//printf("[+] Successfully obtained handle for PID %lu\n", targetPID);
|
||||
return hProcess;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
DWORD FindPidByName(const wchar_t* processName);
|
||||
HANDLE GetProcessHandle(DWORD pid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+225
-34
@@ -9,45 +9,236 @@ Module Stomping is a process injection technique where a legitimate, image-backe
|
||||
| **Tactical Goal** | **Evade Memory Scanners:** Bypasses detections that flag `RX` memory regions not backed by a file on disk (`MEM_PRIVATE`). |
|
||||
| **Stealth** | **Moderate.** While it solves the "unbacked memory" problem, it introduces another IoC "Module Mismatch" (the memory content no longer matches the file on disk). |
|
||||
|
||||
## DLL Scanner
|
||||
[find-stompable-dlls.py](find-stompable-dlls.py)
|
||||
## DLL Discovery
|
||||
Identify a target process and the process ID.
|
||||
```
|
||||
PS C:\Users\Administrator\Desktop\Tools > python .\find-stompable-dlls.py 0x80000
|
||||
c:\Users\Administrator\Desktop\module-stomping>tasklist /fi "imageName eq rufus.exe"
|
||||
|
||||
Image Name PID Session Name Session# Mem Usage
|
||||
========================= ======== ================ =========== ============
|
||||
rufus.exe 1988 RDP-Tcp#0 2 27,636 K
|
||||
|
||||
c:\Users\Administrator\Desktop\module-stomping>
|
||||
```
|
||||
Output the list of modules loaded by the target process
|
||||
```
|
||||
c:\Users\Administrator\Desktop\module-stomping>.\list-process-dlls.exe -p 1988
|
||||
[+] Successfully obtained handle for PID 1988
|
||||
[+] Enumerating loaded modules:
|
||||
--------------------------------------------------
|
||||
[0x00007FF7F8A30000] rufus.exe
|
||||
[0x00007FFFFC060000] ntdll.dll
|
||||
[0x00007FFFFA990000] KERNEL32.DLL
|
||||
[0x00007FFFF97E0000] KERNELBASE.dll
|
||||
[0x00007FFFF6CA0000] apphelp.dll
|
||||
[0x00007FFFFAB60000] USER32.dll
|
||||
[0x00007FFFF96F0000] win32u.dll
|
||||
[0x00007FFFFB5C0000] GDI32.dll
|
||||
[0x00007FFFF9300000] gdi32full.dll
|
||||
[0x00007FFFF9430000] msvcp_win.dll
|
||||
[0x00007FFFF91B0000] ucrtbase.dll
|
||||
[0x00007FFFF9E10000] IMM32.DLL
|
||||
[0x00007FFFFB3A0000] ADVAPI32.dll
|
||||
[0x00007FFFFA2E0000] msvcrt.dll
|
||||
[0x00007FFFFAF60000] sechost.dll
|
||||
[0x00007FFFFA7E0000] RPCRT4.dll
|
||||
[0x00007FFFF8200000] SspiCli.dll
|
||||
[0x00007FFFFB6F0000] SHELL32.dll
|
||||
[0x00007FFFF9BE0000] wintypes.dll
|
||||
[0x00007FFFFB010000] combase.dll
|
||||
[0x00007FFFF07D0000] windows.storage.dll
|
||||
[0x00007FFFFB4B0000] SHCORE.dll
|
||||
[0x00007FFFFAD30000] shlwapi.dll
|
||||
[0x00007FFFF90D0000] profapi.dll
|
||||
[0x00007FFFF9570000] CRYPT32.dll
|
||||
[0x00007FFFF94E0000] WINTRUST.DLL
|
||||
[0x00007FFFF8800000] MSASN1.dll
|
||||
[0x00007FFFFA7A0000] imagehlp.dll
|
||||
[0x00007FFFFA410000] ole32.dll
|
||||
[0x00007FFFF75D0000] kernel.appcore.dll
|
||||
[0x00007FFFF9D50000] bcryptPrimitives.dll
|
||||
[0x00007FFFF6EA0000] uxtheme.dll
|
||||
[0x00007FFFFADA0000] clbcatq.dll
|
||||
[0x00007FFFE1890000] vds_ps.dll
|
||||
[0x00007FFFF8870000] Wldp.DLL
|
||||
[0x00007FFFD7D10000] Riched20.DLL
|
||||
[0x00007FFFE5080000] USP10.dll
|
||||
[0x00007FFFD9880000] msls31.dll
|
||||
[0x00007FFFEB580000] VERSION.dll
|
||||
[0x00007FFFFBEB0000] MSCTF.dll
|
||||
[0x00007FFFEB020000] comctl32.dll
|
||||
[0x00007FFFF7130000] dwmapi.dll
|
||||
[0x00007FFFFAE60000] OLEAUT32.dll
|
||||
[0x00007FFFEEAB0000] textinputframework.dll
|
||||
[0x00007FFFF53E0000] WindowsCodecs.dll
|
||||
[0x00007FFFEE460000] IconCodecService.dll
|
||||
[0x00007FFFD93E0000] oleacc.dll
|
||||
[0x00007FFFEF500000] TextShaping.dll
|
||||
[0x00007FFFD9120000] explorerframe.dll
|
||||
[0x00007FFFFAA60000] ComDlg32.DLL
|
||||
[0x00007FFFF68A0000] CoreMessaging.dll
|
||||
[0x00007FFFF3DD0000] CoreUIComponents.dll
|
||||
[0x00007FFFF8790000] CRYPTBASE.DLL
|
||||
[0x00007FFFF9E50000] SETUPAPI.dll
|
||||
[0x00007FFFF8D50000] DEVOBJ.dll
|
||||
[0x00007FFFF8CF0000] cfgmgr32.dll
|
||||
|
||||
c:\Users\Administrator\Desktop\module-stomping>
|
||||
```
|
||||
Save the list of module names to a file named `rufus-modules-loaded.txt`
|
||||
```
|
||||
c:\Users\Administrator\Desktop\module-stomping>.\list-process-dlls.exe -p 1988 -n -o rufus-modules-loaded.txt
|
||||
[+] Successfully obtained handle for PID 1988
|
||||
[+] Output will also be dumped to: rufus-modules-loaded.txt
|
||||
[+] Enumerating loaded modules:
|
||||
--------------------------------------------------
|
||||
rufus.exe
|
||||
ntdll.dll
|
||||
KERNEL32.DLL
|
||||
KERNELBASE.dll
|
||||
apphelp.dll
|
||||
USER32.dll
|
||||
win32u.dll
|
||||
GDI32.dll
|
||||
gdi32full.dll
|
||||
msvcp_win.dll
|
||||
ucrtbase.dll
|
||||
IMM32.DLL
|
||||
ADVAPI32.dll
|
||||
msvcrt.dll
|
||||
sechost.dll
|
||||
RPCRT4.dll
|
||||
SspiCli.dll
|
||||
SHELL32.dll
|
||||
wintypes.dll
|
||||
combase.dll
|
||||
windows.storage.dll
|
||||
SHCORE.dll
|
||||
shlwapi.dll
|
||||
profapi.dll
|
||||
CRYPT32.dll
|
||||
WINTRUST.DLL
|
||||
MSASN1.dll
|
||||
imagehlp.dll
|
||||
ole32.dll
|
||||
kernel.appcore.dll
|
||||
bcryptPrimitives.dll
|
||||
uxtheme.dll
|
||||
clbcatq.dll
|
||||
vds_ps.dll
|
||||
Wldp.DLL
|
||||
Riched20.DLL
|
||||
USP10.dll
|
||||
msls31.dll
|
||||
VERSION.dll
|
||||
MSCTF.dll
|
||||
comctl32.dll
|
||||
dwmapi.dll
|
||||
OLEAUT32.dll
|
||||
textinputframework.dll
|
||||
WindowsCodecs.dll
|
||||
IconCodecService.dll
|
||||
oleacc.dll
|
||||
TextShaping.dll
|
||||
explorerframe.dll
|
||||
ComDlg32.DLL
|
||||
CoreMessaging.dll
|
||||
CoreUIComponents.dll
|
||||
CRYPTBASE.DLL
|
||||
SETUPAPI.dll
|
||||
DEVOBJ.dll
|
||||
cfgmgr32.dll
|
||||
|
||||
c:\Users\Administrator\Desktop\module-stomping>
|
||||
```
|
||||
|
||||
[find-stompable-dlls.py](find-stompable-dlls.py)
|
||||
|
||||
Locate qualifying modules that are already loaded using the `includes` list
|
||||
```
|
||||
c:\Users\Administrator\Desktop\module-stomping>python find-stompable-dlls.py 0x80000 -i rufus-modules-loaded.txt
|
||||
[*] Loading INCLUDE_MODULES from: 'rufus-modules-loaded.txt'
|
||||
[+] Loaded 56 modules into INCLUDE_MODULES filter.
|
||||
[*] Scanning Target Directory: 'C:\Windows\System32'
|
||||
[*] Filtering for Files : > 1.0MB
|
||||
[*] Required .text Space : 0x80000 bytes
|
||||
------------------------------------------------------------------------------------------
|
||||
DLL Name | File Size (MB) | Size of .text | Virtual Address
|
||||
------------------------------------------------------------------------------------------
|
||||
aadtb.dll | 1.48 | 0xff60c | 0x1000
|
||||
ActiveSyncProvider.dll | 1.73 | 0x14abe2 | 0x1000
|
||||
aeinv.dll | 1.60 | 0x13495a | 0x1000
|
||||
aemarebackup.dll | 1.23 | 0xf8a64 | 0x1000
|
||||
aepic.dll | 1.25 | 0xf2afa | 0x1000
|
||||
APMon.dll | 1.57 | 0xe395c | 0x1000
|
||||
appraiser.dll | 3.18 | 0x26b133 | 0x1000
|
||||
AppVEntSubsystemController.dll | 1.22 | 0xc941c | 0x1000
|
||||
AppVEntSubsystems64.dll | 1.63 | 0x10565c | 0x1000
|
||||
AppVEntVirtualization.dll | 1.56 | 0x108d1c | 0x1000
|
||||
AppVIntegration.dll | 1.37 | 0xd648c | 0x1000
|
||||
AppXDeploymentClient.dll | 1.45 | 0xe89d0 | 0x1000
|
||||
AppXDeploymentExtensions.desktop.dll | 2.68 | 0x1ab07c | 0x1000
|
||||
AppXDeploymentExtensions.onecore.dll | 3.44 | 0x23493c | 0x1000
|
||||
[*] Targeted Include Filter : Active (56 specific targets allowed)
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Full File Path | File Size (MB) | Size of .text | Virtual Address
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------
|
||||
C:\Windows\System32\combase.dll | 3.54 | 0x269ca2 | 0x1000
|
||||
C:\Windows\System32\CoreMessaging.dll | 1.17 | 0xd1175 | 0x1000
|
||||
C:\Windows\System32\CoreUIComponents.dll | 2.89 | 0x19bf50 | 0x1000
|
||||
C:\Windows\System32\crypt32.dll | 1.46 | 0x124e7b | 0x1000
|
||||
C:\Windows\System32\ExplorerFrame.dll | 2.73 | 0x21677c | 0x1000
|
||||
C:\Windows\System32\gdi32full.dll | 1.18 | 0xb32bc | 0x1000
|
||||
C:\Windows\System32\KernelBase.dll | 3.94 | 0x1a392f | 0x1000
|
||||
C:\Windows\System32\msctf.dll | 1.38 | 0x114f70 | 0x1000
|
||||
C:\Windows\System32\ntdll.dll | 2.41 | 0x16ae9c | 0x1000
|
||||
C:\Windows\System32\ole32.dll | 1.61 | 0xd5c4c | 0x1000
|
||||
C:\Windows\System32\rpcrt4.dll | 1.11 | 0xd3e99 | 0x1000
|
||||
C:\Windows\System32\setupapi.dll | 4.58 | 0xebc1e | 0x1000
|
||||
C:\Windows\System32\shell32.dll | 7.37 | 0x5aa034 | 0x1000
|
||||
C:\Windows\System32\TextInputFramework.dll | 1.30 | 0xf8d0c | 0x1000
|
||||
C:\Windows\System32\ucrtbase.dll | 1.31 | 0xf5f61 | 0x1000
|
||||
C:\Windows\System32\user32.dll | 1.79 | 0xa7fee | 0x1000
|
||||
C:\Windows\System32\windows.storage.dll | 8.43 | 0x64cc4e | 0x1000
|
||||
C:\Windows\System32\WindowsCodecs.dll | 2.21 | 0x1a226c | 0x1000
|
||||
C:\Windows\System32\WinTypes.dll | 1.43 | 0xa1318 | 0x1000
|
||||
C:\Windows\System32\downlevel\ucrtbase.dll | 1.31 | 0xf559c | 0x1000
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------
|
||||
[*] Found 20 potential candidates matching the criteria.
|
||||
|
||||
c:\Users\Administrator\Desktop\module-stomping>
|
||||
```
|
||||
Locate qualifying modules that are NOT already loaded using the `excludes` list
|
||||
```
|
||||
c:\Users\Administrator\Desktop\module-stomping>python find-stompable-dlls.py 0x80000 -x rufus-modules-loaded.txt
|
||||
[*] Loading EXCLUDE_MODULES from: 'rufus-modules-loaded.txt'
|
||||
[+] Loaded 56 modules into EXCLUDE_MODULES filter.
|
||||
[*] Scanning Target Directory: 'C:\Windows\System32'
|
||||
[*] Filtering for Files : > 1.0MB
|
||||
[*] Required .text Space : 0x80000 bytes
|
||||
[*] Exclusion Filter : Active (56 modules blacklisted)
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Full File Path | File Size (MB) | Size of .text | Virtual Address
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------
|
||||
C:\Windows\System32\aadtb.dll | 1.48 | 0xff60c | 0x1000
|
||||
C:\Windows\System32\ActiveSyncProvider.dll | 1.73 | 0x14abe2 | 0x1000
|
||||
C:\Windows\System32\aeinv.dll | 1.60 | 0x13495a | 0x1000
|
||||
C:\Windows\System32\aemarebackup.dll | 1.23 | 0xf8a64 | 0x1000
|
||||
C:\Windows\System32\aepic.dll | 1.25 | 0xf2afa | 0x1000
|
||||
C:\Windows\System32\APMon.dll | 1.57 | 0xe395c | 0x1000
|
||||
C:\Windows\System32\appraiser.dll | 3.18 | 0x26b133 | 0x1000
|
||||
C:\Windows\System32\AppVEntSubsystemController.dll | 1.22 | 0xc941c | 0x1000
|
||||
...
|
||||
PrintConfig.dll | 3.66 | 0x1c497c | 0x1000
|
||||
PS5UI.DLL | 1.19 | 0xa993c | 0x1000
|
||||
UNIDRVUI.DLL | 1.27 | 0xb840c | 0x1000
|
||||
cimwin32.dll | 1.75 | 0x12f3dc | 0x1000
|
||||
DMWmiBridgeProv.dll | 3.75 | 0x244a1c | 0x1000
|
||||
Microsoft.Uev.AgentWmi.dll | 1.09 | 0xc3d6c | 0x1000
|
||||
NetPeerDistCim.dll | 1.39 | 0xffe3a | 0x1000
|
||||
wbemcore.dll | 1.77 | 0xee98c | 0x1000
|
||||
Microsoft.Windows.Appx.PackageManager.Commands.Core.dll | 2.68 | 0x2acd98 | 0x2000
|
||||
AuthFWSnapIn.Resources.dll | 2.98 | 0x2f9674 | 0x2000
|
||||
Microsoft.Windows.ServerManager.Plugins.Ipam.resources.dll | 2.72 | 0x2b6d04 | 0x2000
|
||||
------------------------------------------------------------------------------------------
|
||||
[*] Found 433 potential candidates.
|
||||
PS C:\Users\Administrator\Desktop\Tools >
|
||||
C:\Windows\System32\ru\Microsoft.Windows.ServerManager.Plugins.Ipam.resources.dll | 2.84 | 0x2d6354 | 0x2000
|
||||
C:\Windows\System32\SecurityHealth\10.0.29429.1000-0\SecurityHealthAgent.dll | 1.36 | 0xb748c | 0x1000
|
||||
C:\Windows\System32\SecurityHealth\10.0.29429.1000-0\SecurityHealthCore.dll | 1.31 | 0xeb64c | 0x1000
|
||||
C:\Windows\System32\ShellExperiences\WindowsInternal.Xaml.Controls.Tabs.dll | 1.68 | 0x14766c | 0x1000
|
||||
C:\Windows\System32\Speech\Common\sapi.dll | 1.45 | 0xdcaab | 0x1000
|
||||
C:\Windows\System32\Speech\SpeechUX\SpeechUX.dll | 1.46 | 0x8f343 | 0x1000
|
||||
C:\Windows\System32\Speech_OneCore\Common\sapi_onecore.dll | 4.26 | 0x2aad27 | 0x1000
|
||||
C:\Windows\System32\Speech_OneCore\Common\Windows.Speech.Shell.dll | 1.03 | 0xc2818 | 0x1000
|
||||
C:\Windows\System32\Speech_OneCore\Engines\SR\spsreng_onecore.dll | 1.41 | 0x10ae0b | 0x1000
|
||||
C:\Windows\System32\Speech_OneCore\Engines\TTS\MSTTSEngine_OneCore.dll | 1.87 | 0x16bb0c | 0x1000
|
||||
C:\Windows\System32\spool\drivers\W32X86\3\mxdwdrv.dll | 1.12 | 0x10e418 | 0x1000
|
||||
C:\Windows\System32\spool\drivers\W32X86\3\PrintConfig.dll | 3.12 | 0x1da306 | 0x1000
|
||||
C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll | 3.66 | 0x1c497c | 0x1000
|
||||
C:\Windows\System32\spool\drivers\x64\3\PS5UI.DLL | 1.19 | 0xa993c | 0x1000
|
||||
C:\Windows\System32\spool\drivers\x64\3\UNIDRVUI.DLL | 1.27 | 0xb840c | 0x1000
|
||||
C:\Windows\System32\wbem\cimwin32.dll | 1.75 | 0x12f3dc | 0x1000
|
||||
C:\Windows\System32\wbem\DMWmiBridgeProv.dll | 3.75 | 0x244a1c | 0x1000
|
||||
C:\Windows\System32\wbem\Microsoft.Uev.AgentWmi.dll | 1.09 | 0xc3d6c | 0x1000
|
||||
C:\Windows\System32\wbem\NetPeerDistCim.dll | 1.39 | 0xffe3a | 0x1000
|
||||
C:\Windows\System32\wbem\wbemcore.dll | 1.77 | 0xee98c | 0x1000
|
||||
C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Appx\Microsoft.Windows.Appx.PackageManager.Commands.Core.dll | 2.68 | 0x2acd98 | 0x2000
|
||||
C:\Windows\System32\zh-HANS\AuthFWSnapIn.Resources.dll | 2.98 | 0x2f9674 | 0x2000
|
||||
C:\Windows\System32\zh-HANS\Microsoft.Windows.ServerManager.Plugins.Ipam.resources.dll | 2.72 | 0x2b6d04 | 0x2000
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------
|
||||
[*] Found 411 potential candidates matching the criteria.
|
||||
|
||||
c:\Users\Administrator\Desktop\module-stomping>
|
||||
```
|
||||
|
||||
## Execution Steps
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "..\includes\peb-eat-utils.h"
|
||||
#include "..\includes\ps-utils.h"
|
||||
|
||||
void InventoryRemoteDlls(HANDLE hProcess, bool namesOnly, const char* outputFilePath) {
|
||||
PVOID remotePebAddr = GetRemotePebAddress(hProcess);
|
||||
if (!remotePebAddr) {
|
||||
printf("[-] Failed to locate remote PEB.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
PEB localPeb;
|
||||
if (!ReadProcessMemory(hProcess, remotePebAddr, &localPeb, sizeof(PEB), NULL)) {
|
||||
printf("[-] Failed to read remote PEB structure. Error: %lu\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
PEB_LDR_DATA localLdr;
|
||||
if (!ReadProcessMemory(hProcess, localPeb.Ldr, &localLdr, sizeof(PEB_LDR_DATA), NULL)) {
|
||||
printf("[-] Failed to read remote LDR data.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Try opening the file if a path was provided
|
||||
FILE* outputFile = NULL;
|
||||
if (outputFilePath) {
|
||||
outputFile = fopen(outputFilePath, "w");
|
||||
if (!outputFile) {
|
||||
printf("[-] Failed to open output file: %s. Defaulting to console only.\n", outputFilePath);
|
||||
} else {
|
||||
printf("[+] Output will also be dumped to: %s\n", outputFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
LIST_ENTRY* headRemoteLink = &((PPEB_LDR_DATA)localPeb.Ldr)->InMemoryOrderModuleList;
|
||||
LIST_ENTRY currentLink = localLdr.InMemoryOrderModuleList;
|
||||
|
||||
printf("[+] Enumerating loaded modules:\n");
|
||||
printf("--------------------------------------------------\n");
|
||||
|
||||
while (currentLink.Flink != headRemoteLink) {
|
||||
ULONG_PTR remoteEntryAddr = (ULONG_PTR)currentLink.Flink - sizeof(LIST_ENTRY);
|
||||
|
||||
FULL_LDR_DATA_TABLE_ENTRY localEntry;
|
||||
if (!ReadProcessMemory(hProcess, (LPCVOID)remoteEntryAddr, &localEntry, sizeof(FULL_LDR_DATA_TABLE_ENTRY), NULL)) {
|
||||
printf("[-] Failed to read a module entry from the list.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
USHORT nameLen = localEntry.BaseDllName.Length;
|
||||
WCHAR* localBuffer = (WCHAR*)malloc(nameLen + sizeof(WCHAR));
|
||||
|
||||
if (localBuffer) {
|
||||
ZeroMemory(localBuffer, nameLen + sizeof(WCHAR));
|
||||
|
||||
if (ReadProcessMemory(hProcess, localEntry.BaseDllName.Buffer, localBuffer, nameLen, NULL)) {
|
||||
|
||||
// Formulate the line based on the user's formatting preference
|
||||
if (namesOnly) {
|
||||
// Raw string only
|
||||
printf("%ws\n", localBuffer);
|
||||
if (outputFile) {
|
||||
fprintf(outputFile, "%ws\n", localBuffer);
|
||||
}
|
||||
} else {
|
||||
// Standard Base Address + String
|
||||
printf("[0x%p] %ws\n", localEntry.DllBase, localBuffer);
|
||||
if (outputFile) {
|
||||
fprintf(outputFile, "[0x%p] %ws\n", localEntry.DllBase, localBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(localBuffer);
|
||||
}
|
||||
|
||||
currentLink = localEntry.InMemoryOrderLinks;
|
||||
}
|
||||
|
||||
// Wrap up file handles if open
|
||||
if (outputFile) {
|
||||
fclose(outputFile);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintUsage(const char* programName) {
|
||||
printf("Usage: %s [options]\n", programName);
|
||||
printf("Options:\n");
|
||||
printf(" -p, --pid Target process ID.\n");
|
||||
printf(" -n, --names-only Only print out the raw DLL names (omit base addresses)\n");
|
||||
printf(" -o, --output <filename> Dump the inventory out to a text file\n");
|
||||
printf(" -h, --help Show this help screen\n");
|
||||
}
|
||||
|
||||
// command line args: output names only, output to a file?
|
||||
int main(int argc, char *argv[]) {
|
||||
bool namesOnly = false;
|
||||
const char* outputFilePath = NULL;
|
||||
DWORD targetPid;
|
||||
|
||||
// Loop through command line parameters
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--pid") == 0) {
|
||||
// Check if there's an actual argument following -p
|
||||
if (i + 1 < argc) {
|
||||
targetPid = atoi(argv[i + 1]);
|
||||
i++; // Skip next argument since we consumed it here
|
||||
} else {
|
||||
printf("[-] Error: -p/--pid requires a target process ID.\n");
|
||||
PrintUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--names-only") == 0) {
|
||||
namesOnly = true;
|
||||
}
|
||||
else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output") == 0) {
|
||||
// Check if there's an actual argument following -o
|
||||
if (i + 1 < argc) {
|
||||
outputFilePath = argv[i + 1];
|
||||
i++; // Skip next argument since we consumed it here
|
||||
} else {
|
||||
printf("[-] Error: -o/--output requires a file path argument.\n");
|
||||
PrintUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
|
||||
PrintUsage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
printf("[-] Unknown parameter: %s\n", argv[i]);
|
||||
PrintUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Locate target and execute
|
||||
|
||||
if (targetPid == 0) {
|
||||
printf("[-] Could not find target process execution context.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
HANDLE pHandle = GetProcessHandle(targetPid);
|
||||
if (!pHandle) {
|
||||
printf("[-] Failed to open handle to target process.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
InventoryRemoteDlls(pHandle, namesOnly, outputFilePath);
|
||||
|
||||
CloseHandle(pHandle);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user