为什么80%的码农都做不了架构师?>>>
#pragma pack(4)
typedef struct _UNICODE_STRING32
{
USHORT Length;
USHORT MaximumLength;
ULONG Buffer;
} UNICODE_STRING32, *PUNICODE_STRING32;
typedef struct _PEB32
{
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
UCHAR BitField;
ULONG Mutant;
ULONG ImageBaseAddress;
ULONG Ldr;
ULONG ProcessParameters;
ULONG SubSystemData;
ULONG ProcessHeap;
ULONG FastPebLock;
ULONG AtlThunkSListPtr;
ULONG IFEOKey;
ULONG CrossProcessFlags;
ULONG UserSharedInfoPtr;
ULONG SystemReserved;
ULONG AtlThunkSListPtr32;
ULONG ApiSetMap;
} PEB32, *PPEB32;
typedef struct _PEB_LDR_DATA32
{
ULONG Length;
BOOLEAN Initialized;
ULONG SsHandle;
LIST_ENTRY32 InLoadOrderModuleList;
LIST_ENTRY32 InMemoryOrderModuleList;
LIST_ENTRY32 InInitializationOrderModuleList;
ULONG EntryInProgress;
} PEB_LDR_DATA32, *PPEB_LDR_DATA32;
typedef struct _LDR_DATA_TABLE_ENTRY32
{
LIST_ENTRY32 InLoadOrderLinks;
LIST_ENTRY32 InMemoryOrderModuleList;
LIST_ENTRY32 InInitializationOrderModuleList;
ULONG DllBase;
ULONG EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING32 FullDllName;
UNICODE_STRING32 BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY32 HashLinks;
ULONG SectionPointer;
};
ULONG CheckSum;
union
{
ULONG TimeDateStamp;
ULONG LoadedImports;
};
ULONG EntryPointActivationContext;
ULONG PatchInformation;
} LDR_DATA_TABLE_ENTRY32, *PLDR_DATA_TABLE_ENTRY32;
#pragma pack()
#pragma pack(8)
typedef struct _PROCESS_BASIC_INFORMATION64 {
ULONG64 ExitStatus;
ULONG64 PebBaseAddress;
ULONG64 AffinityMask;
ULONG64 BasePriority;
ULONG64 UniqueProcessId;
ULONG64 InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION64, *PPROCESS_BASIC_INFORMATION64;
typedef struct _PEB64
{
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
UCHAR BitField;
ULONG64 Mutant;
ULONG64 ImageBaseAddress;
ULONG64 Ldr;
ULONG64 ProcessParameters;
ULONG64 SubSystemData;
ULONG64 ProcessHeap;
ULONG64 FastPebLock;
ULONG64 AtlThunkSListPtr;
ULONG64 IFEOKey;
ULONG64 CrossProcessFlags;
ULONG64 UserSharedInfoPtr;
ULONG SystemReserved;
ULONG AtlThunkSListPtr32;
ULONG64 ApiSetMap;
} PEB64, *PPEB64;
typedef struct _PEB_LDR_DATA64
{
ULONG Length;
BOOLEAN Initialized;
ULONG64 SsHandle;
LIST_ENTRY64 InLoadOrderModuleList;
LIST_ENTRY64 InMemoryOrderModuleList;
LIST_ENTRY64 InInitializationOrderModuleList;
ULONG64 EntryInProgress;
} PEB_LDR_DATA64, *PPEB_LDR_DATA64;
typedef struct _UNICODE_STRING64
{
USHORT Length;
USHORT MaximumLength;
ULONG64 Buffer;
} UNICODE_STRING64, *PUNICODE_STRING64;
typedef struct _LDR_DATA_TABLE_ENTRY64
{
LIST_ENTRY64 InLoadOrderLinks;
LIST_ENTRY64 InMemoryOrderModuleList;
LIST_ENTRY64 InInitializationOrderModuleList;
ULONG64 DllBase;
ULONG64 EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING64 FullDllName;
UNICODE_STRING64 BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY64 HashLinks;
ULONG64 SectionPointer;
};
ULONG CheckSum;
union
{
ULONG TimeDateStamp;
ULONG64 LoadedImports;
};
ULONG64 EntryPointActivationContext;
ULONG64 PatchInformation;
} LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64;
#pragma pack()
ULONG NewEnumProcsssModules(ULONG ProcessId, fnEnumProcessModuleProc fnEnumProc)
{
std::wstring ImagePath;
ULONG nCount = 0;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessId);
if (hProcess)
{
if (IsAMD64())
{
if (IsWow64())//wow64 read 64bit or 32 bit
{
PROCESS_BASIC_INFORMATION64 pbi64 = {0};
if (NT_SUCCESS(NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL)))
{
ULONG64 LdrAddress = 0;
if (InternalReadVirtualMemory(hProcess, (ULONG64)(pbi64.PebBaseAddress + offsetof(PEB64, Ldr)), sizeof(LdrAddress), &LdrAddress, NULL))
{
LIST_ENTRY64 ListEntry = { 0 };
if (InternalReadVirtualMemory(hProcess, (ULONG64)(LdrAddress + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList)), sizeof(LIST_ENTRY64), &ListEntry, NULL))
{
LDR_DATA_TABLE_ENTRY64 CurrentModule = { 0 };
if (InternalReadVirtualMemory(hProcess, (ULONG64)ListEntry.Flink, sizeof(CurrentModule), &CurrentModule, NULL))
{
ULONG64 hFristModule = (ULONG64)CurrentModule.DllBase;
while (1)
{
if (CurrentModule.DllBase)
{
ImagePath.resize(CurrentModule.FullDllName.Length / sizeof(WCHAR));
if (InternalReadVirtualMemory(hProcess, (ULONG64)CurrentModule.FullDllName.Buffer, CurrentModule.FullDllName.Length, (void *)ImagePath.c_str(), NULL))
{
nCount += fnEnumProc(ProcessId, (ULONG64)CurrentModule.DllBase, CurrentModule.SizeOfImage, ImagePath.c_str());
}
}
if (!InternalReadVirtualMemory(hProcess, (ULONG64)CurrentModule.InLoadOrderLinks.Flink, sizeof(CurrentModule), &CurrentModule, NULL))
break;
if (hFristModule == (ULONG64)CurrentModule.DllBase)
break;
}
}
}
}
}
}
else if(!Is64BitProcess(hProcess))//64bit read wow64
{
ULONG Peb32 = 0;
if (NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessWow64Information, &Peb32, sizeof(Peb32), NULL)))
{
ULONG64 LdrAddress = 0;
if (InternalReadVirtualMemory(hProcess, (ULONG64)Peb32 + offsetof(PEB32, Ldr), sizeof(ULONG), &LdrAddress, NULL))
{
LIST_ENTRY32 ListEntry = { 0 };
if (InternalReadVirtualMemory(hProcess, (ULONG64)(LdrAddress + offsetof(PEB_LDR_DATA32, InLoadOrderModuleList)), sizeof(LIST_ENTRY64), &ListEntry, NULL))
{
LDR_DATA_TABLE_ENTRY32 CurrentModule = { 0 };
if (InternalReadVirtualMemory(hProcess, (ULONG64)ListEntry.Flink, sizeof(CurrentModule), &CurrentModule, NULL))
{
PVOID hFirstModule = (PVOID)CurrentModule.DllBase;
while (1)
{
if (CurrentModule.DllBase)
{
ImagePath.resize(CurrentModule.FullDllName.Length / sizeof(WCHAR));
if (InternalReadVirtualMemory(hProcess, (ULONG64)CurrentModule.FullDllName.Buffer, CurrentModule.FullDllName.Length, (void *)ImagePath.c_str(), NULL))
{
nCount += fnEnumProc(ProcessId, (ULONG64)CurrentModule.DllBase, CurrentModule.SizeOfImage, ImagePath.c_str());
}
}
if (!InternalReadVirtualMemory(hProcess, (ULONG64)CurrentModule.InLoadOrderLinks.Flink, sizeof(CurrentModule), &CurrentModule, NULL))
break;
if (hFirstModule == (PVOID)CurrentModule.DllBase)
break;
}
}
}
}
}
}
}//IsAMD64
//Native PEB
PROCESS_BASIC_INFORMATION pbi = { 0 };
if (NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL)))
{
ULONG64 LdrAddress = 0;
if (InternalReadVirtualMemory(hProcess, (ULONG64)pbi.PebBaseAddress + offsetof(PEB, Ldr), sizeof(PVOID), &LdrAddress, NULL))
{
LIST_ENTRY ListEntry = { 0 };
if (InternalReadVirtualMemory(hProcess, (ULONG64)(LdrAddress + offsetof(PEB_LDR_DATA, InLoadOrderModuleList)), sizeof(LIST_ENTRY64), &ListEntry, NULL))
{
LDR_DATA_TABLE_ENTRY CurrentModule = { 0 };
if (InternalReadVirtualMemory(hProcess, (ULONG64)ListEntry.Flink, sizeof(CurrentModule), &CurrentModule, NULL))
{
PVOID hFirstModule = CurrentModule.DllBase;
while (1)
{
if (CurrentModule.DllBase)
{
ImagePath.resize(CurrentModule.FullDllName.Length / sizeof(WCHAR));
if (InternalReadVirtualMemory(hProcess, (ULONG64)CurrentModule.FullDllName.Buffer, CurrentModule.FullDllName.Length, (void *)ImagePath.c_str(), NULL))
{
nCount += fnEnumProc(ProcessId, (ULONG64)CurrentModule.DllBase, CurrentModule.SizeOfImage, ImagePath.c_str());
}
}
if (!InternalReadVirtualMemory(hProcess, (ULONG64)CurrentModule.InLoadOrderLinks.Flink, sizeof(CurrentModule), &CurrentModule, NULL))
break;
if (hFirstModule == CurrentModule.DllBase)
break;
}
}
}
}
}
CloseHandle(hProcess);
}
return nCount;
}