├── DLLFinder.sln
├── DLLFinder
├── DLLFinder.vcxproj
├── DLLFinder.vcxproj.filters
├── Process.cpp
├── Process.h
└── Source.cpp
└── README.md
/DLLFinder.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.30501.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLLFinder", "DLLFinder\DLLFinder.vcxproj", "{CA1A1CF9-9D0D-4EA7-9099-D82C6A081C6C}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {CA1A1CF9-9D0D-4EA7-9099-D82C6A081C6C}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {CA1A1CF9-9D0D-4EA7-9099-D82C6A081C6C}.Debug|Win32.Build.0 = Debug|Win32
16 | {CA1A1CF9-9D0D-4EA7-9099-D82C6A081C6C}.Release|Win32.ActiveCfg = Release|Win32
17 | {CA1A1CF9-9D0D-4EA7-9099-D82C6A081C6C}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/DLLFinder/DLLFinder.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {CA1A1CF9-9D0D-4EA7-9099-D82C6A081C6C}
15 | Win32Proj
16 | DLLFinder
17 |
18 |
19 |
20 | Application
21 | true
22 | v120
23 | Unicode
24 |
25 |
26 | Application
27 | false
28 | v120
29 | true
30 | Unicode
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | true
44 |
45 |
46 | false
47 |
48 |
49 |
50 |
51 |
52 | Level3
53 | Disabled
54 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
55 |
56 |
57 | Console
58 | true
59 |
60 |
61 |
62 |
63 | Level3
64 |
65 |
66 | MaxSpeed
67 | true
68 | true
69 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
70 |
71 |
72 | Console
73 | true
74 | true
75 | true
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/DLLFinder/DLLFinder.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 |
26 |
27 | Header Files
28 |
29 |
30 |
--------------------------------------------------------------------------------
/DLLFinder/Process.cpp:
--------------------------------------------------------------------------------
1 | #include "Process.h"
2 | #include
3 |
4 | Process::Process(std::string Proc) {
5 | Pinfo = GetProcessInfo(Proc);
6 | }
7 |
8 | Process::~Process(){
9 |
10 | }
11 |
12 | #pragma optimize("", off)
13 | //Get the Process Information
14 | Process::Process_INFO Process::GetProcessInfo(std::string & PN){
15 | PVOID buffer = NULL;
16 | PSYSTEM_PROCESS_INFO inf = NULL;
17 | LPWSTR ProcNAME;
18 |
19 | //convert CHAR to WCHAR
20 | /*int nChars = MultiByteToWideChar(CP_ACP, 0, PN, -1, NULL, 0);
21 | LPWSTR P1 = new WCHAR[nChars]; //Release this at some point
22 | MultiByteToWideChar(CP_ACP, 0, PN, -1, (LPWSTR)P1, nChars);
23 | //delete[] P1;
24 | */
25 |
26 | ULONG buffer_size = 512 * 512;
27 |
28 | NTSTATUS Status = STATUS_INFO_LENGTH_MISMATCH;
29 | _ntQSI fpQSI = (_ntQSI)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtQuerySystemInformation");
30 |
31 |
32 | buffer = VirtualAlloc(NULL, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
33 |
34 | if (buffer == NULL){
35 | return Pinfo;
36 | }
37 |
38 | Status = fpQSI((SYSTEM_INFORMATION_CLASS)All_SYS::SystemExtendedProcessInformation, buffer, buffer_size, NULL);
39 |
40 | //if buffer is too small double size
41 | if (Status == STATUS_INFO_LENGTH_MISMATCH) {
42 | VirtualFree(buffer, NULL, MEM_RELEASE);
43 | buffer_size *= 2;
44 | }
45 |
46 | else if (!NT_SUCCESS(Status)) {
47 | VirtualFree(buffer, NULL, MEM_RELEASE);
48 | return Pinfo;
49 | }
50 |
51 | else{
52 | inf = (PSYSTEM_PROCESS_INFO)buffer;
53 |
54 | while (inf) {
55 | ProcNAME = inf->ImageName.Buffer;
56 |
57 | if (inf->ImageName.Buffer != nullptr){
58 |
59 | //List of all the process id on the current system
60 | if (inf->UniqueProcessId > 0){
61 | //System_PID_List.push_back(inf->UniqueProcessId);
62 | }
63 |
64 | //WinAPI - Converts a Wide Char to multibyte
65 | int nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ProcNAME, -1, NULL, NULL, NULL, NULL);
66 | LPSTR P1 = new CHAR[nLen];
67 | WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ProcNAME, -1, P1, nLen, NULL, NULL);
68 | std::string ProcessName(P1);
69 | delete[] P1;
70 | //std::cout << P1 << std::endl;
71 | //if (strcmp(PN, ProcessName) == 0){
72 | if (PN.compare(ProcessName) == 0){
73 | Pinfo.Process_ID = (DWORD)inf->UniqueProcessId;
74 |
75 | Pinfo.Process_Name = ProcessName;
76 | CHAR szTemp[MAX_PATH] = { 0 };
77 | sprintf(szTemp, "%I64d", (inf->CreateTime).QuadPart);
78 | Pinfo.Create_Time = szTemp;
79 | Pinfo.ThreadCount = inf->NumberOfThreads;
80 | Pinfo.HandleCount = inf->HandleCount;
81 |
82 | /*FILETIME ft;
83 | SYSTEMTIME st;
84 | GetSystemTime(&st);
85 | SystemTimeToFileTime(&st, &ft);
86 | LARGE_INTEGER CT = inf->CreateTime;
87 | CHAR szTemp[MAX_PATH] = { 0 };
88 | CHAR szTemp1[MAX_PATH] = { 0 };
89 | sprintf(szTemp, "%I64d", CT.QuadPart);
90 | sprintf(szTemp1, "%I64d", ft);
91 | std::cout << szTemp << std::endl;
92 | std::cout << szTemp1 << std::endl;*/
93 | //std::cout << PID << std::endl;
94 | //delete[] P1;
95 |
96 | //return Pinfo;
97 | }
98 | //delete[] P1;
99 |
100 |
101 | /*//Testing stuff
102 | if (wcscmp(P1, ProcNAME) == 0){
103 | PID = (DWORD)inf->UniqueProcessId;
104 | delete[] P1;
105 | std::cout << PID << std::endl;
106 | return PID;
107 | }*/
108 |
109 | }
110 |
111 | if (!inf->NextEntryOffset)
112 | break;
113 |
114 | inf = (PSYSTEM_PROCESS_INFO)((LPBYTE)inf + inf->NextEntryOffset);
115 | }
116 |
117 | if (buffer) VirtualFree(buffer, NULL, MEM_RELEASE);
118 | }
119 |
120 | return Pinfo;
121 | }
122 |
123 | All_SYS::PLDR_DATA_TABLE_ENTRY Process::GetNextNode(PCHAR nNode, int Offset){
124 | #ifdef _WIN64
125 | nNode -= sizeof(LIST_ENTRY64) * Offset;
126 | #else
127 | nNode -= sizeof(LIST_ENTRY) * Offset;
128 | #endif
129 | return (All_SYS::PLDR_DATA_TABLE_ENTRY)nNode;
130 | }
131 |
132 | //List Modules From PBI
133 | //ListType = 0 - InLoadOrderModuleList
134 | //ListType = 1 - InMemoryOrderModuleList
135 | //ListType = 2 - InInitializationOrderModuleList
136 | //Order = 0 - Flick through list (Forward Order)
137 | //Order = 1 - Blink through list (Backwards Order)
138 | void Process::ListModules(DWORD PID, int ListType, int Order){
139 | pNtQueryInformationProcess NtQIP;
140 | NTSTATUS status;
141 | std::wstring BaseDllName;
142 | std::wstring FullDllName;
143 |
144 | //Check ListType in range
145 | if (ListType > 2 || ListType < 0){
146 | return;
147 | }
148 | if (Order > 1 || Order < 0){
149 | return;
150 | }
151 |
152 | PROCESS_BASIC_INFORMATION PBI = { 0 };
153 | HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
154 | NtQIP = (pNtQueryInformationProcess)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtQueryInformationProcess");
155 | status = NT_SUCCESS(NtQIP(ProcessHandle, ProcessBasicInformation, &PBI, sizeof(PROCESS_BASIC_INFORMATION), NULL));
156 |
157 | if (status){
158 | All_SYS::PEB_LDR_DATA LdrData;
159 | All_SYS::LDR_DATA_TABLE_ENTRY LdrModule;
160 | All_SYS::PPEB_LDR_DATA pLdrData = nullptr;
161 | PBYTE address = nullptr;
162 |
163 | PBYTE LdrDataOffset = (PBYTE)(PBI.PebBaseAddress) + offsetof(struct All_SYS::_PEB, LoaderData);
164 | ReadProcessMemory(ProcessHandle, LdrDataOffset, &pLdrData, sizeof(All_SYS::PPEB_LDR_DATA), NULL);
165 | ReadProcessMemory(ProcessHandle, pLdrData, &LdrData, sizeof(All_SYS::PEB_LDR_DATA), NULL);
166 |
167 | if (Order == 0){
168 | if (ListType == 0)
169 | address = (PBYTE)LdrData.InLoadOrderModuleList.Flink;
170 | else if (ListType == 1)
171 | address = (PBYTE)LdrData.InMemoryOrderModuleList.Flink;
172 | else if (ListType == 2)
173 | address = (PBYTE)LdrData.InInitializationOrderModuleList.Flink;
174 | }
175 | else{
176 | if (ListType == 0)
177 | address = (PBYTE)LdrData.InLoadOrderModuleList.Blink;
178 | else if (ListType == 1)
179 | address = (PBYTE)LdrData.InMemoryOrderModuleList.Blink;
180 | else if (ListType == 2)
181 | address = (PBYTE)LdrData.InInitializationOrderModuleList.Blink;
182 | }
183 |
184 | #ifdef _WIN64
185 | address -= sizeof(LIST_ENTRY64)*ListType;
186 | #else
187 | address -= sizeof(LIST_ENTRY)*ListType;
188 | #endif
189 |
190 | All_SYS::PLDR_DATA_TABLE_ENTRY Head = (All_SYS::PLDR_DATA_TABLE_ENTRY)address;
191 | All_SYS::PLDR_DATA_TABLE_ENTRY Node = Head;
192 |
193 | do
194 | {
195 | BOOL status1 = ReadProcessMemory(ProcessHandle, Node, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
196 | if (status1)
197 | {
198 | if (LdrModule.BaseAddress == 0)
199 | break;
200 |
201 | BaseDllName = std::wstring(LdrModule.BaseDllName.Length / sizeof(WCHAR), 0);
202 | FullDllName = std::wstring(LdrModule.FullDllName.Length / sizeof(WCHAR), 0);
203 | ReadProcessMemory(ProcessHandle, LdrModule.BaseDllName.Buffer, &BaseDllName[0], LdrModule.BaseDllName.Length, NULL);
204 | ReadProcessMemory(ProcessHandle, LdrModule.FullDllName.Buffer, &FullDllName[0], LdrModule.FullDllName.Length, NULL);
205 |
206 | BaseDllName.push_back('\0');
207 | FullDllName.push_back('\0');
208 |
209 | std::wcout << BaseDllName << " \t" << LdrModule.BaseAddress << std::endl;
210 | }
211 |
212 | if (Order == 0){
213 | if (ListType == 0)
214 | Node = GetNextNode((PCHAR)LdrModule.InLoadOrderModuleList.Flink, ListType);
215 | else if (ListType == 1)
216 | Node = GetNextNode((PCHAR)LdrModule.InMemoryOrderModuleList.Flink, ListType);
217 | else if (ListType == 2)
218 | Node = GetNextNode((PCHAR)LdrModule.InInitializationOrderModuleList.Flink, ListType);
219 | }
220 | else{
221 | if (ListType == 0)
222 | Node = GetNextNode((PCHAR)LdrModule.InLoadOrderModuleList.Blink, ListType);
223 | else if (ListType == 1)
224 | Node = GetNextNode((PCHAR)LdrModule.InMemoryOrderModuleList.Blink, ListType);
225 | else if (ListType == 2)
226 | Node = GetNextNode((PCHAR)LdrModule.InInitializationOrderModuleList.Blink, ListType);
227 | }
228 |
229 | } while (Head != Node);
230 | }
231 |
232 | CloseHandle(ProcessHandle);
233 | }
234 |
235 | void Process::SuspendProcess(DWORD dwPID){
236 | pNtSuspendProcess ntSP;
237 | HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
238 |
239 | ntSP = (pNtSuspendProcess) GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtSuspendProcess");
240 |
241 | if (NT_SUCCESS(ntSP(hProc))){
242 | std::cout << "Process: " << Pinfo.Process_Name << " PID: " << Pinfo.Process_ID << " Has Been Suspended\n" << std::endl;
243 | }
244 |
245 | CloseHandle(hProc);
246 | return;
247 | }
248 |
249 | void Process::ResumeProcess(DWORD dwPID){
250 | pNtResumeProcess ntSP;
251 | HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
252 |
253 | ntSP = (pNtResumeProcess)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtResumeProcess");
254 |
255 | if (NT_SUCCESS(ntSP(hProc))){
256 | std::cout << "Process: " << Pinfo.Process_Name << " PID: " << Pinfo.Process_ID << " Has Been Resumeded\n" << std::endl;
257 | }
258 |
259 | CloseHandle(hProc);
260 | return;
261 | }
262 |
263 | //This is not really what you would do although it does work if the PE Header of the file still exists
264 | //You would most likely query the page against a set of blacklisted pages
265 | void Process::ListModulesVQ(DWORD dwPID){
266 | pNtQueryVirtualMemory ntQVM;
267 | All_SYS::MEMORY_BASIC_INFORMATION mbi;
268 |
269 | ULONG sizeMSNBuffer = 512;
270 | PMEMORY_SECTION_NAME msnName = (PMEMORY_SECTION_NAME)VirtualAlloc(NULL, sizeMSNBuffer, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
271 |
272 | HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
273 |
274 | ntQVM = (pNtQueryVirtualMemory)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtQueryVirtualMemory");
275 |
276 | SYSTEM_INFO sysINFO;
277 | GetSystemInfo(&sysINFO);
278 | PBYTE pCurAddr = (PBYTE) sysINFO.lpMinimumApplicationAddress;
279 | PBYTE pMaxAddr = (PBYTE) sysINFO.lpMaximumApplicationAddress;
280 |
281 | while (pCurAddr < pMaxAddr){
282 | //Get the MEMORY_BASIC_INFORMATION
283 | if (NT_SUCCESS(ntQVM(hProc, pCurAddr, MemoryBasicInformation, &mbi, sizeof(All_SYS::MEMORY_BASIC_INFORMATION), NULL))){
284 | //For obvious reasons it is not a good idea to only look for MEM_IMAGE
285 | if (mbi.Type == MEM_IMAGE){
286 |
287 | std::cout << "Addr: " << mbi.AllocationBase << " \t" << "Size: " << mbi.RegionSize
288 | << " \tProtect: " << mbi.Protect << std::endl;
289 |
290 |
291 | //Get the Memory Section Name
292 | if (NT_SUCCESS(ntQVM(hProc, pCurAddr, MemorySectionName, msnName, sizeMSNBuffer, NULL))){
293 | printf("%S\n\n", msnName->SectionFileName.Buffer);
294 | }
295 | }
296 | }
297 |
298 | //Get the Next page
299 | pCurAddr += mbi.RegionSize;
300 | }
301 |
302 | if (msnName) VirtualFree(msnName, NULL, MEM_RELEASE);
303 | CloseHandle(hProc);
304 |
305 | return;
306 | }
307 |
308 | #pragma optimize("", on)
--------------------------------------------------------------------------------
/DLLFinder/Process.h:
--------------------------------------------------------------------------------
1 | #ifndef __Process_H__
2 | #define __Process_H__
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
10 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
11 |
12 | namespace All_SYS{
13 | typedef enum _SYSTEM_INFORMATION_CLASS
14 | {
15 | SystemBasicInformation = 0x0000,
16 | SystemProcessorInformation = 0x0001,
17 | SystemPerformanceInformation = 0x0002,
18 | SystemTimeOfDayInformation = 0x0003,
19 | SystemPathInformation = 0x0004,
20 | SystemProcessInformation = 0x0005,
21 | SystemCallCountInformation = 0x0006,
22 | SystemDeviceInformation = 0x0007,
23 | SystemProcessorPerformanceInformation = 0x0008,
24 | SystemFlagsInformation = 0x0009,
25 | SystemCallTimeInformation = 0x000A,
26 | SystemModuleInformation = 0x000B,
27 | SystemLocksInformation = 0x000C,
28 | SystemStackTraceInformation = 0x000D,
29 | SystemPagedPoolInformation = 0x000E,
30 | SystemNonPagedPoolInformation = 0x000F,
31 | SystemHandleInformation = 0x0010,
32 | SystemObjectInformation = 0x0011,
33 | SystemPageFileInformation = 0x0012,
34 | SystemVdmInstemulInformation = 0x0013,
35 | SystemVdmBopInformation = 0x0014,
36 | SystemFileCacheInformation = 0x0015,
37 | SystemPoolTagInformation = 0x0016,
38 | SystemInterruptInformation = 0x0017,
39 | SystemDpcBehaviorInformation = 0x0018,
40 | SystemFullMemoryInformation = 0x0019,
41 | SystemLoadGdiDriverInformation = 0x001A,
42 | SystemUnloadGdiDriverInformation = 0x001B,
43 | SystemTimeAdjustmentInformation = 0x001C,
44 | SystemSummaryMemoryInformation = 0x001D,
45 | SystemMirrorMemoryInformation = 0x001E,
46 | SystemPerformanceTraceInformation = 0x001F,
47 | SystemCrashDumpInformation = 0x0020,
48 | SystemExceptionInformation = 0x0021,
49 | SystemCrashDumpStateInformation = 0x0022,
50 | SystemKernelDebuggerInformation = 0x0023,
51 | SystemContextSwitchInformation = 0x0024,
52 | SystemRegistryQuotaInformation = 0x0025,
53 | SystemExtendServiceTableInformation = 0x0026,
54 | SystemPrioritySeperation = 0x0027,
55 | SystemVerifierAddDriverInformation = 0x0028,
56 | SystemVerifierRemoveDriverInformation = 0x0029,
57 | SystemProcessorIdleInformation = 0x002A,
58 | SystemLegacyDriverInformation = 0x002B,
59 | SystemCurrentTimeZoneInformation = 0x002C,
60 | SystemLookasideInformation = 0x002D,
61 | SystemTimeSlipNotification = 0x002E,
62 | SystemSessionCreate = 0x002F,
63 | SystemSessionDetach = 0x0030,
64 | SystemSessionInformation = 0x0031,
65 | SystemRangeStartInformation = 0x0032,
66 | SystemVerifierInformation = 0x0033,
67 | SystemVerifierThunkExtend = 0x0034,
68 | SystemSessionProcessInformation = 0x0035,
69 | SystemLoadGdiDriverInSystemSpace = 0x0036,
70 | SystemNumaProcessorMap = 0x0037,
71 | SystemPrefetcherInformation = 0x0038,
72 | SystemExtendedProcessInformation = 0x0039,
73 | SystemRecommendedSharedDataAlignment = 0x003A,
74 | SystemComPlusPackage = 0x003B,
75 | SystemNumaAvailableMemory = 0x003C,
76 | SystemProcessorPowerInformation = 0x003D,
77 | SystemEmulationBasicInformation = 0x003E,
78 | SystemEmulationProcessorInformation = 0x003F,
79 | SystemExtendedHandleInformation = 0x0040,
80 | SystemLostDelayedWriteInformation = 0x0041,
81 | SystemBigPoolInformation = 0x0042,
82 | SystemSessionPoolTagInformation = 0x0043,
83 | SystemSessionMappedViewInformation = 0x0044,
84 | SystemHotpatchInformation = 0x0045,
85 | SystemObjectSecurityMode = 0x0046,
86 | SystemWatchdogTimerHandler = 0x0047,
87 | SystemWatchdogTimerInformation = 0x0048,
88 | SystemLogicalProcessorInformation = 0x0049,
89 | SystemWow64SharedInformationObsolete = 0x004A,
90 | SystemRegisterFirmwareTableInformationHandler = 0x004B,
91 | SystemFirmwareTableInformation = 0x004C,
92 | SystemModuleInformationEx = 0x004D,
93 | SystemVerifierTriageInformation = 0x004E,
94 | SystemSuperfetchInformation = 0x004F,
95 | SystemMemoryListInformation = 0x0050,
96 | SystemFileCacheInformationEx = 0x0051,
97 | SystemThreadPriorityClientIdInformation = 0x0052,
98 | SystemProcessorIdleCycleTimeInformation = 0x0053,
99 | SystemVerifierCancellationInformation = 0x0054,
100 | SystemProcessorPowerInformationEx = 0x0055,
101 | SystemRefTraceInformation = 0x0056,
102 | SystemSpecialPoolInformation = 0x0057,
103 | SystemProcessIdInformation = 0x0058,
104 | SystemErrorPortInformation = 0x0059,
105 | SystemBootEnvironmentInformation = 0x005A,
106 | SystemHypervisorInformation = 0x005B,
107 | SystemVerifierInformationEx = 0x005C,
108 | SystemTimeZoneInformation = 0x005D,
109 | SystemImageFileExecutionOptionsInformation = 0x005E,
110 | SystemCoverageInformation = 0x005F,
111 | SystemPrefetchPatchInformation = 0x0060,
112 | SystemVerifierFaultsInformation = 0x0061,
113 | SystemSystemPartitionInformation = 0x0062,
114 | SystemSystemDiskInformation = 0x0063,
115 | SystemProcessorPerformanceDistribution = 0x0064,
116 | SystemNumaProximityNodeInformation = 0x0065,
117 | SystemDynamicTimeZoneInformation = 0x0066,
118 | SystemCodeIntegrityInformation = 0x0067,
119 | SystemProcessorMicrocodeUpdateInformation = 0x0068,
120 | SystemProcessorBrandString = 0x0069,
121 | SystemVirtualAddressInformation = 0x006A,
122 | SystemLogicalProcessorAndGroupInformation = 0x006B,
123 | SystemProcessorCycleTimeInformation = 0x006C,
124 | SystemStoreInformation = 0x006D,
125 | SystemRegistryAppendString = 0x006E,
126 | SystemAitSamplingValue = 0x006F,
127 | SystemVhdBootInformation = 0x0070,
128 | SystemCpuQuotaInformation = 0x0071,
129 | SystemNativeBasicInformation = 0x0072,
130 | SystemErrorPortTimeouts = 0x0073,
131 | SystemLowPriorityIoInformation = 0x0074,
132 | SystemBootEntropyInformation = 0x0075,
133 | SystemVerifierCountersInformation = 0x0076,
134 | SystemPagedPoolInformationEx = 0x0077,
135 | SystemSystemPtesInformationEx = 0x0078,
136 | SystemNodeDistanceInformation = 0x0079,
137 | SystemAcpiAuditInformation = 0x007A,
138 | SystemBasicPerformanceInformation = 0x007B,
139 | SystemQueryPerformanceCounterInformation = 0x007C,
140 | SystemSessionBigPoolInformation = 0x007D,
141 | SystemBootGraphicsInformation = 0x007E,
142 | SystemScrubPhysicalMemoryInformation = 0x007F,
143 | SystemBadPageInformation = 0x0080,
144 | SystemProcessorProfileControlArea = 0x0081,
145 | SystemCombinePhysicalMemoryInformation = 0x0082,
146 | SystemEntropyInterruptTimingInformation = 0x0083,
147 | SystemConsoleInformation = 0x0084,
148 | SystemPlatformBinaryInformation = 0x0085,
149 | SystemThrottleNotificationInformation = 0x0086,
150 | SystemHypervisorProcessorCountInformation = 0x0087,
151 | SystemDeviceDataInformation = 0x0088,
152 | SystemDeviceDataEnumerationInformation = 0x0089,
153 | SystemMemoryTopologyInformation = 0x008A,
154 | SystemMemoryChannelInformation = 0x008B,
155 | SystemBootLogoInformation = 0x008C,
156 | SystemProcessorPerformanceInformationEx = 0x008D,
157 | SystemSpare0 = 0x008E,
158 | SystemSecureBootPolicyInformation = 0x008F,
159 | SystemPageFileInformationEx = 0x0090,
160 | SystemSecureBootInformation = 0x0091,
161 | SystemEntropyInterruptTimingRawInformation = 0x0092,
162 | SystemPortableWorkspaceEfiLauncherInformation = 0x0093,
163 | SystemFullProcessInformation = 0x0094,
164 | MaxSystemInfoClass = 0x0095
165 | } SYSTEM_INFORMATION_CLASS;
166 |
167 | #ifdef _WIN64
168 | //redefine the struct in windows interal header to include undocumented values
169 | typedef struct _PEB_LDR_DATA {
170 | ULONG Length;
171 | UCHAR Initialized;
172 | ULONG64 SsHandle;
173 | LIST_ENTRY64 InLoadOrderModuleList;
174 | LIST_ENTRY64 InMemoryOrderModuleList;
175 | LIST_ENTRY64 InInitializationOrderModuleList;
176 | PVOID64 EntryInProgress;
177 | UCHAR ShutdownInProgress;
178 | PVOID64 ShutdownThreadId;
179 | } PEB_LDR_DATA, *PPEB_LDR_DATA;
180 |
181 | typedef struct _PEB{
182 | UCHAR InheritedAddressSpace;
183 | UCHAR ReadImageFileExecOptions;
184 | UCHAR BeingDebugged;
185 | BYTE Reserved0;
186 | ULONG Reserved1;
187 | ULONG64 Reserved3;
188 | ULONG64 ImageBaseAddress;
189 | ULONG64 LoaderData;
190 | ULONG64 ProcessParameters;
191 | }PEB, *PPEB;
192 |
193 | /** A structure that holds information about a single module loaded by a process **/
194 | /** LIST_ENTRY is a link list pointing to the prev/next Module loaded **/
195 | typedef struct _LDR_DATA_TABLE_ENTRY
196 | {
197 | LIST_ENTRY64 InLoadOrderModuleList;
198 | LIST_ENTRY64 InMemoryOrderModuleList;
199 | LIST_ENTRY64 InInitializationOrderModuleList;
200 | ULONG64 BaseAddress;
201 | ULONG64 EntryPoint;
202 | ULONG SizeOfImage; //bytes
203 | UNICODE_STRING FullDllName;
204 | UNICODE_STRING BaseDllName;
205 | ULONG Flags;
206 | USHORT LoadCount;
207 | } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
208 |
209 | typedef struct DECLSPEC_ALIGN(16) _MEMORY_BASIC_INFORMATION{
210 | ULONGLONG BaseAddress;
211 | ULONGLONG AllocationBase;
212 | DWORD AllocationProtect;
213 | DWORD __alignment1;
214 | ULONGLONG RegionSize;
215 | DWORD State;
216 | DWORD Protect;
217 | DWORD Type;
218 | DWORD __alignment2;
219 | } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
220 |
221 | #else
222 | //redefine the struct in windows interal header to include undocumented values
223 | typedef struct _PEB_LDR_DATA {
224 | DWORD Length;
225 | UCHAR Initialized;
226 | PVOID SsHandle;
227 | LIST_ENTRY InLoadOrderModuleList;
228 | LIST_ENTRY InMemoryOrderModuleList;
229 | LIST_ENTRY InInitializationOrderModuleList;
230 | PVOID EntryInProgress;
231 | UCHAR ShutdownInProgress;
232 | PVOID ShutdownThreadId;
233 | } PEB_LDR_DATA, *PPEB_LDR_DATA;
234 |
235 | typedef struct _PEB{
236 | UCHAR InheritedAddressSpace;
237 | UCHAR ReadImageFileExecOptions;
238 | UCHAR BeingDebugged;
239 | BYTE Reserved2[9];
240 | PPEB_LDR_DATA LoaderData;
241 | PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
242 | BYTE Reserved3[448];
243 | ULONG SessionId;
244 | }PEB, *PPEB;
245 |
246 | /** A structure that holds information about a single module loaded by a process **/
247 | /** LIST_ENTRY is a link list pointing to the prev/next Module loaded **/
248 | typedef struct _LDR_DATA_TABLE_ENTRY
249 | {
250 | LIST_ENTRY InLoadOrderModuleList;
251 | LIST_ENTRY InMemoryOrderModuleList;
252 | LIST_ENTRY InInitializationOrderModuleList;
253 | PVOID BaseAddress;
254 | PVOID EntryPoint;
255 | ULONG SizeOfImage;
256 | UNICODE_STRING FullDllName;
257 | UNICODE_STRING BaseDllName;
258 | ULONG Flags;
259 | USHORT LoadCount;
260 | USHORT TlsIndex;
261 | LIST_ENTRY HashTableEntry;
262 | union
263 | {
264 | LIST_ENTRY HashLinks;
265 | struct
266 | {
267 | PVOID SectionPointer;
268 | ULONG CheckSum;
269 | };
270 | };
271 | union
272 | {
273 | ULONG TimeDateStamp;
274 | PVOID LoadedImports;
275 | };
276 | _ACTIVATION_CONTEXT * EntryPointActivationContext;
277 | PVOID PatchInformation;
278 | LIST_ENTRY ForwarderLinks;
279 | LIST_ENTRY ServiceTagLinks;
280 | LIST_ENTRY StaticLinks;
281 | PVOID ContextInformation;
282 | DWORD OriginalBase;
283 | LARGE_INTEGER LoadTime;
284 | } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
285 |
286 | typedef struct _MEMORY_BASIC_INFORMATION {
287 | DWORD BaseAddress;
288 | DWORD AllocationBase;
289 | DWORD AllocationProtect;
290 | DWORD RegionSize;
291 | DWORD State;
292 | DWORD Protect;
293 | DWORD Type;
294 | } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
295 |
296 | #endif
297 | }
298 |
299 | typedef struct _SYSTEM_PROCESS_INFO
300 | {
301 | ULONG NextEntryOffset;
302 | ULONG NumberOfThreads;
303 | LARGE_INTEGER SpareLi1;
304 | LARGE_INTEGER SpareLi2;
305 | LARGE_INTEGER SpareLi3;
306 | LARGE_INTEGER CreateTime;
307 | LARGE_INTEGER UserTime;
308 | LARGE_INTEGER KernelTime;
309 | UNICODE_STRING ImageName;
310 | ULONG BasePriority;
311 | #ifdef _WIN64
312 | ULONG pad1;
313 | ULONG UniqueProcessId;
314 | ULONG pad2;
315 | ULONG InheritedFromUniqueProcessId;
316 | ULONG pad3, pad4, pad5;
317 | #else
318 | ULONG UniqueProcessId;
319 | ULONG InheritedFromUniqueProcessId;
320 | #endif
321 | ULONG HandleCount;
322 | ULONG SessionId;
323 | PVOID PageDirectoryBase;
324 | ULONG VirtualMemoryCounters;
325 | SIZE_T PrivatePageCount;
326 | IO_COUNTERS IoCounters;
327 | PVOID Reserved[1];
328 | }SYSTEM_PROCESS_INFO, *PSYSTEM_PROCESS_INFO;
329 |
330 | typedef NTSTATUS(NTAPI *_ntQSI)(
331 | IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
332 | IN OUT PVOID SystemInformation,
333 | IN ULONG SystemInformationLength,
334 | OUT PULONG ReturnLength OPTIONAL
335 | );
336 |
337 | typedef NTSTATUS(NTAPI * pNtQueryInformationProcess)
338 | (
339 | HANDLE,
340 | PROCESSINFOCLASS,
341 | PVOID,
342 | ULONG,
343 | PULONG
344 | );
345 |
346 | typedef enum _MEMORY_INFORMATION_CLASS
347 | {
348 | MemoryBasicInformation,
349 | MemoryWorkingSetList,
350 | MemorySectionName,
351 | MemoryBasicVlmInformation
352 | } MEMORY_INFORMATION_CLASS;
353 |
354 | typedef struct _MEMORY_SECTION_NAME
355 | {
356 | UNICODE_STRING SectionFileName;
357 | } MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
358 |
359 | typedef NTSTATUS(NTAPI * pNtQueryVirtualMemory)(
360 | IN HANDLE ProcessHandle,
361 | IN PVOID BaseAddress,
362 | IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
363 | OUT PVOID MemoryInformation,
364 | IN ULONG MemoryInformationLength,
365 | OUT PULONG ReturnLength OPTIONAL
366 | );
367 |
368 | typedef NTSTATUS(NTAPI * pNtSuspendProcess)(
369 | IN HANDLE ProcessHandle
370 | );
371 |
372 | typedef NTSTATUS(NTAPI * pNtResumeProcess)(
373 | IN HANDLE ProcessHandle
374 | );
375 |
376 | class Process{
377 | private:
378 | All_SYS::PLDR_DATA_TABLE_ENTRY GetNextNode(PCHAR nNode, int Offset);
379 |
380 | public:
381 | Process(std::string Proc);
382 | ~Process();
383 |
384 | struct Process_INFO{
385 | DWORD Process_ID = 0;
386 | std::string Process_Name = "";
387 | std::string Create_Time = "";
388 | ULONG HandleCount = 0;
389 | ULONG ModuleCount = 0;
390 | ULONG ThreadCount = 0;
391 | }Pinfo;
392 |
393 | Process_INFO GetProcessInfo(std::string & PN);
394 |
395 | void SuspendProcess(DWORD dwPID);
396 | void ResumeProcess(DWORD dwPID);
397 |
398 | void ListModules(DWORD PID, int ListType, int Order);
399 | void ListModulesVQ(DWORD dwPID);
400 | };
401 |
402 | #endif
--------------------------------------------------------------------------------
/DLLFinder/Source.cpp:
--------------------------------------------------------------------------------
1 | #include "Process.h"
2 | #include
3 |
4 | int main(){
5 | std::cout << "-----DLL Finder v1.0-----\n" << std::endl;
6 |
7 | Process * A = new Process("firefox.exe");
8 |
9 | //You can do this without suspending in most cases just
10 | //be aware of the fact the more memory maybe allocated as
11 | //the process runs
12 | A->SuspendProcess(A->Pinfo.Process_ID);
13 |
14 | //Listing the modules using the process' PEB
15 | //A->ListModules(A->Pinfo.Process_ID, 1, 0);
16 |
17 | //Listing the Modules using NtQueryVirtualMemory
18 | A->ListModulesVQ(A->Pinfo.Process_ID);
19 |
20 | //Resume the process after enum finishes
21 | A->ResumeProcess(A->Pinfo.Process_ID);
22 |
23 | delete A;
24 |
25 | system("pause");
26 |
27 | return 0;
28 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DLLFinder
2 | Enumerate the DLLs/Modules using NtQueryVirtualMemory
3 |
4 | ##Summary
5 | A basic application showing the use of NtQueryVirtualMemory to enumerate the memory to list the Modules and DLLs in an application. All in all you would most likely not use this to enumerate modules as opposed to scan the memory pages in the real world.
6 |
7 | ##Limitations
8 | The only real limitation is that if the PE Header of the DLL has been stripped it may fail. The only other limitation is that if NtQueryVirtualMemory is hooked in the SSDT the obvious outcome will result.
9 |
--------------------------------------------------------------------------------