抄的,原文很详细的说明了原理
作者:沉疴
出处:https://www.cnblogs.com/lsh123/p/8295774.html
.h
#pragma once
#include <windows.h>
#include <winternl.h>
#include <ntstatus.h>
#include <TlHelp32.h>
#include <Psapi.h>
#include <vector>
using namespace std;
enum MODULE_TYPE
{
MODULE_X86,
MODULE_X64,
};
struct _PROCESS_MODULE_INFORMATION_
{
ULONG64 ModuleBase; //操作系统中可能存在64位与32位的程序
size_t ModuleSize;
WCHAR ModuleFullPathData[MAX_PATH];
MODULE_TYPE ModuleType;
};
template <typename T>
struct _LIST_ENTRY_
{
T Flink;
T Blink;
};
template <typename T>
struct _UNICODE_STRING_
{
WORD BufferLength;
WORD MaximumLength;
T BufferData;
};
template <typename T, typename NGF, int A>
struct _PEB_
{
typedef T type;
union
{
struct
{
BYTE InheritedAddressSpace;
BYTE ReadImageFileExecOptions;
BYTE BeingDebugged;
BYTE BitField;
};
T dummy01;
};
T Mutant;
T ImageBaseAddress;
T Ldr;
T ProcessParameters;
T SubSystemData;
T ProcessHeap;
T FastPebLock;
T AtlThunkSListPtr;
T IFEOKey;
T CrossProcessFlags;
T UserSharedInfoPtr;
DWORD SystemReserved;
DWORD AtlThunkSListPtr32;
T ApiSetMap;
T TlsExpansionCounter;
T TlsBitmap;
DWORD TlsBitmapBits[2];
T ReadOnlySharedMemoryBase;
T HotpatchInformation;
T ReadOnlyStaticServerData;
T AnsiCodePageData;
T OemCodePageData;
T UnicodeCaseTableData;
DWORD NumberOfProcessors;
union
{
DWORD NtGlobalFlag;
NGF dummy02;
};
LARGE_INTEGER CriticalSectionTimeout;
T HeapSegmentReserve;
T HeapSegmentCommit;
T HeapDeCommitTotalFreeThreshold;
T HeapDeCommitFreeBlockThreshold;
DWORD NumberOfHeaps;
DWORD MaximumNumberOfHeaps;
T ProcessHeaps;
T GdiSharedHandleTable;
T ProcessStarterHelper;
T GdiDCAttributeList;
T LoaderLock;
DWORD OSMajorVersion;
DWORD OSMinorVersion;
WORD OSBuildNumber;
WORD OSCSDVersion;
DWORD OSPlatformId;
DWORD ImageSubsystem;
DWORD ImageSubsystemMajorVersion;
T ImageSubsystemMinorVersion;
T ActiveProcessAffinityMask;
T GdiHandleBuffer[A];
T PostProcessInitRoutine;
T TlsExpansionBitmap;
DWORD TlsExpansionBitmapBits[32];
T SessionId;
ULARGE_INTEGER AppCompatFlags;
ULARGE_INTEGER AppCompatFlagsUser;
T pShimData;
T AppCompatInfo;
_UNICODE_STRING_<T> CSDVersion;
T ActivationContextData;
T ProcessAssemblyStorageMap;
T SystemDefaultActivationContextData;
T SystemAssemblyStorageMap;
T MinimumStackCommit;
T FlsCallback;
_LIST_ENTRY_<T> FlsListHead;
T FlsBitmap;
DWORD FlsBitmapBits[4];
T FlsHighIndex;
T WerRegistrationData;
T WerShipAssertPtr;
T pContextData;
T pImageHeaderHash;
T TracingFlags;
T CsrServerReadOnlySharedMemoryBase;
};
typedef _PEB_<DWORD, DWORD64, 34> _PEB32_;
typedef _PEB_<DWORD64, DWORD, 30> _PEB64_;
template<typename T>
struct _PEB_T
{
typedef typename std::conditional<std::is_same<T, DWORD>::value, _PEB32_, _PEB64_>::type type;
};
template<typename T>
struct _PEB_LDR_DATA_
{
unsigned long Length;
unsigned char Initialized;
T SsHandle;
_LIST_ENTRY_<T> InLoadOrderModuleList;
_LIST_ENTRY_<T> InMemoryOrderModuleList;
_LIST_ENTRY_<T> InInitializationOrderModuleList;
T EntryInProgress;
unsigned char ShutdownInProgress;
T ShutdownThreadId;
};
template<typename T>
struct _LDR_DATA_TABLE_ENTRY_
{
_LIST_ENTRY_<T> InLoadOrderLinks;
_LIST_ENTRY_<T> InMemoryOrderLinks;
_LIST_ENTRY_<T> InInitializationOrderLinks;
T DllBase;
T EntryPoint;
unsigned long SizeOfImage;
_UNICODE_STRING_<T> FullDllName;
_UNICODE_STRING_<T> BaseDllName;
unsigned long Flags;
unsigned short LoadCount;
unsigned short TlsIndex;
_LIST_ENTRY_<T> HashLinks;
unsigned long TimeDateStamp;
T EntryPointActivationContext;
T PatchInformation;
};
template<typename T>
struct _PROCESS_BASIC_INFORMATION_
{
NTSTATUS ExitStatus;
ULONG Reserved0;
T PebBaseAddress;
T AffinityMask;
LONG BasePriority;
ULONG Reserved1;
T UniqueProcessId;
T InheritedFromUniqueProcessId;
};
typedef decltype(&NtQueryInformationProcess) LPFN_NTQUERYINFORMATIONPROCESS;
typedef NTSTATUS(NTAPI *LPFN_NTWOW64QUERYINFORMATIONPROCESS64)(
IN HANDLE ProcessHandle,
IN ULONG ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL);
typedef NTSTATUS(NTAPI *LPFN_NTWOW64READVIRTUALMEMORY64)(
IN HANDLE ProcessHandle,
IN ULONG64 BaseAddress,
OUT PVOID BufferData,
IN ULONG64 BufferLength,
OUT PULONG64 ReturnLength OPTIONAL);
struct _PROCESS_INFORMATION_
{
ULONG ProcessID;
char ImageNameData[MAX_PATH];
char ProcessFullPathData[MAX_PATH];
};
typedef struct
{
DWORD ExitStatus;
DWORD PebBaseAddress;
DWORD AffinityMask;
DWORD BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} __PROCESS_BASIC_INFORMATION__;
typedef LONG(__stdcall *PROCNTQSIP)(HANDLE, UINT, PVOID, ULONG, PULONG);
SIZE_T SeEnumProcessModuleList(ULONG ProcessID, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo);
SIZE_T SeEnumModuleInfoByPeb(ULONG ProcessID, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo);
template<typename T>
SIZE_T EnumModuleInfoByPeb(HANDLE ProcessHandle, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo);
ULONG64 GetPeb(HANDLE ProcessHandle, _PEB64_* Peb);
ULONG32 GetPeb(HANDLE ProcessHandle, _PEB32_* Peb);
BOOL SeReadProcessMemory(HANDLE ProcessHandle, DWORD BaseAddress, LPVOID BufferData, size_t BufferLength, DWORD64* ReturnLength);
BOOL SeReadProcessMemory(HANDLE ProcessHandle, DWORD64 BaseAddress, LPVOID BufferData, size_t BufferLength, DWORD64 *ReturnLength);
.cpp
BOOL EnumDllLoaderedProcess(vector<_PROCESS_INFORMATION_> ProcessInfo, string DllName)
{
OnInitMember();
vector<_PROCESS_INFORMATION_>::iterator i;
string DllFullPath;
int j = 0;
for (i = ProcessInfo.begin(); i != ProcessInfo.end(); i++)
{
ULONG ProcessID = i->ProcessID;
vector<_PROCESS_MODULE_INFORMATION_>ProcessModuleInfomationVector;
SeEnumProcessModuleList(ProcessID, ProcessModuleInfomationVector);
int index = 0;
vector<_PROCESS_MODULE_INFORMATION_>::iterator m;
for (m = ProcessModuleInfomationVector.begin(); m != ProcessModuleInfomationVector.end(); m++)
{
DllFullPath = SeUtf16ToUtf8(m->ModuleFullPathData);
index = DllFullPath.find(DllName);
if (index == -1)
{
continue;
}
else
{
printf("%s", i->ProcessFullPathData);
printf("-----------------------------\n\n");
break;
}
}
}
return TRUE;
}
SIZE_T SeEnumProcessModuleList(ULONG ProcessID, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo)
{
SeEnumModuleInfoByPeb(ProcessID, ProcessModuleInfo);
return ProcessModuleInfo.size();
}
SIZE_T SeEnumModuleInfoByPeb(ULONG ProcessID, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo)
{
HANDLE ProcessHandle = NULL;
BOOL IsWow64 = FALSE;
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessID);
int a = GetLastError();
if (ProcessHandle == NULL)
{
goto Error;
}
IsWow64Process(ProcessHandle, &IsWow64);
if (IsWow64 == TRUE)
{
EnumModuleInfoByPeb<DWORD>(ProcessHandle, ProcessModuleInfo);
}
else
{
EnumModuleInfoByPeb<DWORD64>(ProcessHandle, ProcessModuleInfo);
}
Error:
if (ProcessHandle != NULL)
{
CloseHandle(ProcessHandle);
ProcessHandle = NULL;
}
return ProcessModuleInfo.size();
}
template<typename T>
SIZE_T EnumModuleInfoByPeb(HANDLE ProcessHandle, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo)
{
typename _PEB_T<T>::type Peb = { { { 0 } } };
_PEB_LDR_DATA_<T> PebLdrData = { 0 };
ProcessModuleInfo.clear();
if (GetPeb(ProcessHandle, &Peb) != 0 && SeReadProcessMemory(ProcessHandle,
Peb.Ldr, &PebLdrData, sizeof(PebLdrData), 0) == TRUE)
{
for (T CheckPtr = PebLdrData.InLoadOrderModuleList.Flink;
CheckPtr != (Peb.Ldr + FIELD_OFFSET(_PEB_LDR_DATA_<T>, InLoadOrderModuleList));
SeReadProcessMemory(ProcessHandle, static_cast<ULONG64>(CheckPtr), &CheckPtr, sizeof(CheckPtr), 0))
{
_PROCESS_MODULE_INFORMATION_ v1;
wchar_t ModuleFullPathData[MAX_PATH] = { 0 };
_LDR_DATA_TABLE_ENTRY_<T> LdrDataTableEntry = { { 0 } };
SeReadProcessMemory(ProcessHandle, CheckPtr, &LdrDataTableEntry, sizeof(LdrDataTableEntry), 0);
SeReadProcessMemory(ProcessHandle, LdrDataTableEntry.FullDllName.BufferData, ModuleFullPathData,
LdrDataTableEntry.FullDllName.BufferLength, 0);
v1.ModuleBase = LdrDataTableEntry.DllBase;
v1.ModuleSize = LdrDataTableEntry.SizeOfImage;
wmemcpy(v1.ModuleFullPathData, ModuleFullPathData, MAX_PATH);
printf("%ls\n", v1.ModuleFullPathData);
v1.ModuleType = std::is_same<T, DWORD>::value ? MODULE_X86 : MODULE_X64;
ProcessModuleInfo.emplace_back(v1);
}
}
return ProcessModuleInfo.size();
}
ULONG64 GetPeb(HANDLE ProcessHandle, _PEB64_* Peb)
{
_PROCESS_BASIC_INFORMATION_<DWORD64> ProcessBasicInfo = { 0 };
ULONG ReturnLength = 0;
if (NT_SUCCESS(__NtWow64QueryInformationProcess64(ProcessHandle, ProcessBasicInformation, &ProcessBasicInfo,
(ULONG)sizeof(ProcessBasicInfo), &ReturnLength)) && Peb)
{
__NtWow64ReadVirtualMemory64(ProcessHandle, ProcessBasicInfo.PebBaseAddress, Peb, sizeof(_PEB64_), NULL);
}
return ProcessBasicInfo.PebBaseAddress;
}
ULONG32 GetPeb(HANDLE ProcessHandle, _PEB32_* Peb)
{
PROCESS_BASIC_INFORMATION ProcessBasicInfo = { 0 };
ULONG ReturnLength = 0;
if (NT_SUCCESS(__NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &ProcessBasicInfo,
(ULONG)sizeof(ProcessBasicInfo), &ReturnLength)) && Peb)
{
ReadProcessMemory(ProcessHandle, ProcessBasicInfo.PebBaseAddress, Peb, sizeof(_PEB32_), NULL);
}
return reinterpret_cast<ULONG32>(ProcessBasicInfo.PebBaseAddress);
}
BOOL SeReadProcessMemory(HANDLE ProcessHandle, DWORD BaseAddress, LPVOID BufferData, size_t BufferLength, DWORD64* ReturnLength)
{
return ReadProcessMemory(ProcessHandle, reinterpret_cast<LPVOID>(BaseAddress), BufferData,
BufferLength, reinterpret_cast<SIZE_T*>(ReturnLength));
}
BOOL SeReadProcessMemory(HANDLE ProcessHandle, DWORD64 BaseAddress, LPVOID BufferData, size_t BufferLength, DWORD64 *ReturnLength)
{
if (__NtWow64ReadVirtualMemory64(ProcessHandle,
BaseAddress, BufferData, BufferLength, ReturnLength) != STATUS_SUCCESS)
{
return FALSE;
}
return TRUE;
}
BOOL OnInitMember()
{
HMODULE NtdllModuleBase = NULL;
NtdllModuleBase = GetModuleHandle("Ntdll.dll");
if (NtdllModuleBase == NULL)
{
return FALSE;
}
__NtWow64QueryInformationProcess64 = (LPFN_NTWOW64QUERYINFORMATIONPROCESS64)GetProcAddress(NtdllModuleBase,
"NtWow64QueryInformationProcess64");
__NtWow64ReadVirtualMemory64 = (LPFN_NTWOW64READVIRTUALMEMORY64)GetProcAddress(NtdllModuleBase,
"NtWow64ReadVirtualMemory64");
__NtQueryInformationProcess = (LPFN_NTQUERYINFORMATIONPROCESS)GetProcAddress(NtdllModuleBase,
"NtQueryInformationProcess");
if (__NtWow64QueryInformationProcess64 == NULL || __NtWow64ReadVirtualMemory64 == NULL || __NtQueryInformationProcess == NULL)
{
return FALSE;
}
return TRUE;
}