#include <winternl.h>#include <windows.h>#include <TlHelp32.h>#include <iostream>struct Library
{ HMODULE Module
= nullptr
; Library
(const char* LibraryName
) { Module
= LoadLibrary
(LibraryName
); } ~Library
() { FreeLibrary
(Module
); }};typedef struct _LDR_MODULE
{ LIST_ENTRY InLoadOrderModuleList
; LIST_ENTRY InMemoryOrderModuleList
; LIST_ENTRY InInitializationOrderModuleList
; PVOID BaseAddress
; PVOID EntryPoint
; ULONG SizeOfImage
; UNICODE_STRING FullDllName
; UNICODE_STRING BaseDllName
; ULONG Flags
; SHORT LoadCount
; SHORT TlsIndex
; LIST_ENTRY HashTableEntry
; ULONG TimeDateStamp
;} LDR_MODULE
, *PLDR_MODULE
;typedef NTSTATUS NTAPI
(*pNtQueryInformationProcess
)(HANDLE
, PROCESSINFOCLASS
, PVOID
, ULONG
, PULONG
);PROCESSENTRY32 GetProcessInfo
(const char* ProcessName
){ void* hSnap
= nullptr
; PROCESSENTRY32 Proc32
= {0}; if((hSnap
= CreateToolhelp32Snapshot
(TH32CS_SNAPPROCESS
, 0)) == INVALID_HANDLE_VALUE
) return Proc32
; Proc32.
dwSize = sizeof(PROCESSENTRY32
); while(Process32Next
(hSnap
, &Proc32
)) { if(!stricmp
(ProcessName
, Proc32.
szExeFile)) { CloseHandle
(hSnap
); return Proc32
; } } CloseHandle
(hSnap
); Proc32
= {0}; return Proc32
;}void ListModuleInfo
(std
::string Process
){ SIZE_T dwBytesRead
= 0; PROCESS_BASIC_INFORMATION PBI
= {0}; PROCESSENTRY32 ProcessInfo
= GetProcessInfo
(Process.
c_str()); HANDLE ProcessHandle
= OpenProcess
(PROCESS_ALL_ACCESS
, false, ProcessInfo.
th32ProcessID); Library NTDLL
("ntdll.dll"); pNtQueryInformationProcess NtQIP
= (pNtQueryInformationProcess
) GetProcAddress
(NTDLL.
Module, "NtQueryInformationProcess"); if (NT_SUCCESS
(NtQIP
(ProcessHandle
, ProcessBasicInformation
, &PBI
, sizeof(PBI
), reinterpret_cast
<DWORD
*>(&dwBytesRead
)))) { PEB_LDR_DATA LdrData
; LDR_MODULE LdrModule
; PPEB_LDR_DATA pLdrData
= nullptr
; char* LdrDataOffset
= reinterpret_cast
<char*>(PBI.
PebBaseAddress) + offsetof(PEB
, Ldr
); ReadProcessMemory
(ProcessHandle
, LdrDataOffset
, &pLdrData
, sizeof(pLdrData
), &dwBytesRead
); ReadProcessMemory
(ProcessHandle
, pLdrData
, &LdrData
, sizeof(LdrData
), &dwBytesRead
); LIST_ENTRY
* Head
= LdrData.
InMemoryOrderModuleList.
Flink; LIST_ENTRY
* Node
= Head
; do { if (ReadProcessMemory
(ProcessHandle
, reinterpret_cast
<char*>(Node
) - sizeof(LIST_ENTRY
), &LdrModule
, sizeof(LdrModule
), &dwBytesRead
)) { if (LdrModule.
BaseAddress) { std
::wstring BaseDllName
(LdrModule.
BaseDllName.
Length / sizeof(WCHAR
), 0); std
::wstring FullDllName
(LdrModule.
FullDllName.
Length / sizeof(WCHAR
), 0); ReadProcessMemory
(ProcessHandle
, LdrModule.
BaseDllName.
Buffer, &BaseDllName
[0], LdrModule.
BaseDllName.
Length, &dwBytesRead
); ReadProcessMemory
(ProcessHandle
, LdrModule.
FullDllName.
Buffer, &FullDllName
[0], LdrModule.
FullDllName.
Length, &dwBytesRead
); std
::cout<<"BaseAddress: "<< LdrModule.
BaseAddress<<std
::endl; std
::cout<<"Entry-Point: " << LdrModule.
EntryPoint<<std
::endl; std
::wcout<<"Base DLL-Name: "<< BaseDllName
<<std
::endl; std
::wcout<<"Full DLL-Name: "<< FullDllName
<<std
::endl; std
::cout<<"Reference Count: "<< LdrModule.
LoadCount<<std
::endl; std
::cout<<"Image Size: "<< LdrModule.
SizeOfImage<<std
::endl; std
::cout<<"Time Date Stamp: "<< LdrModule.
TimeDateStamp<<std
::endl; std
::cout<<std
::endl; } } Node
= LdrModule.
InMemoryOrderModuleList.
Flink; } while(Head
!= Node
); } CloseHandle
(ProcessHandle
);}void PrintPEInfo
(std
::string FilePath
){ IMAGE_DOS_HEADER
* pDosHeader
; IMAGE_NT_HEADERS
* pNtHeaders
; IMAGE_SECTION_HEADER
* pSectionHeader
; void* FileHandle
= CreateFile
(FilePath.
c_str(), GENERIC_READ
, FILE_SHARE_READ
, nullptr
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, nullptr
); if (FileHandle
== INVALID_HANDLE_VALUE
) return; void* FileMapping
= CreateFileMapping
(FileHandle
, nullptr
, PAGE_READONLY
, 0, 0, nullptr
); void* MapView
= MapViewOfFile
(FileMapping
, FILE_MAP_READ
, 0, 0, 0); pDosHeader
= reinterpret_cast
<IMAGE_DOS_HEADER
*>(MapView
); if (pDosHeader
->e_magic
== IMAGE_DOS_SIGNATURE
) { std
::cout<<"Valid Dos-Exe File (IMAGE_DOS_HEADER)"<<std
::endl; std
::cout<<"----------------------------------------"<<std
::endl; std
::cout<<"Magic Number: "<<std
::hex<<pDosHeader
->e_magic
<<std
::endl; std
::cout<<"Bytes On Last Page: "<<pDosHeader
->e_cblp
<<std
::endl; std
::cout<<"No. Of Pages: "<<pDosHeader
->e_crlc
<<std
::endl; std
::cout<<"Size Of Header Paragraphs: "<<pDosHeader
->e_cparhdr
<<std
::endl; std
::cout<<"Min. Extra Paragraphs: "<<pDosHeader
->e_minalloc
<<std
::endl; std
::cout<<"Max. Extra Paragraphs: "<<pDosHeader
->e_maxalloc
<<std
::endl; std
::cout<<"Initial SS-Value: "<<pDosHeader
->e_ss
<<std
::endl; std
::cout<<"Initial SP-Value: "<<pDosHeader
->e_sp
<<std
::endl; std
::cout<<"Checksum: "<<pDosHeader
->e_csum
<<std
::endl; std
::cout<<"Initial IP-Value: "<<pDosHeader
->e_ip
<<std
::endl; std
::cout<<"Initial CS-Value: "<<pDosHeader
->e_cs
<<std
::endl; std
::cout<<"File Address Relocation: "<<pDosHeader
->e_lfarlc
<<std
::endl; std
::cout<<"Overlay Number: "<<pDosHeader
->e_ovno
<<std
::endl; std
::cout<<"OEM Identifier: "<<pDosHeader
->e_oemid
<<std
::endl; std
::cout<<"OEM Specific Information: "<<pDosHeader
->e_oeminfo
<<std
::endl; std
::cout<<"RVA Address of PE-Header: "<<pDosHeader
->e_lfanew
<<std
::endl; std
::cout<<std
::endl<<std
::endl; } pNtHeaders
= reinterpret_cast
<IMAGE_NT_HEADERS
*>(((SIZE_T
)(pDosHeader
)) + pDosHeader
->e_lfanew
); if(pNtHeaders
->Signature
== IMAGE_NT_SIGNATURE
) { std
::cout<<"Valid PE-File (IMAGE_NT_HEADER)"<<std
::endl; std
::cout<<"----------------------------------------"<<std
::endl; std
::cout<<"Signature: "<<pNtHeaders
->Signature
<<std
::endl; std
::cout<<"Machine Architecture: "; switch (pNtHeaders
->FileHeader.
Machine) { case IMAGE_FILE_MACHINE_I386
: std
::cout<<"x86 "<<std
::endl; break; case IMAGE_FILE_MACHINE_IA64
: std
::cout<<"Intel Itanium"<<std
::endl; break; case IMAGE_FILE_MACHINE_AMD64
: std
::cout<<"x64 "<<std
::endl; break; default: std
::cout<<"Unknown "<<std
::endl; break; } std
::cout<<"Number Of Sections: "<<pNtHeaders
->FileHeader.
NumberOfSections<<std
::endl; std
::cout<<"Time Date Stamp: "<<pNtHeaders
->FileHeader.
TimeDateStamp<<std
::endl; std
::cout<<"Pointer To Symbol Table: "<<pNtHeaders
->FileHeader.
PointerToSymbolTable<<std
::endl; std
::cout<<"Number Of Symbols: "<<pNtHeaders
->FileHeader.
NumberOfSymbols<<std
::endl; std
::cout<<"Size Of Optional-Header: "<<pNtHeaders
->FileHeader.
SizeOfOptionalHeader<<std
::endl; std
::cout<<"Characteristics: "<<std
::endl<<std
::endl; WORD Characteristics
[] = {IMAGE_FILE_RELOCS_STRIPPED
, IMAGE_FILE_EXECUTABLE_IMAGE
, IMAGE_FILE_LINE_NUMS_STRIPPED
, IMAGE_FILE_LARGE_ADDRESS_AWARE
, IMAGE_FILE_32BIT_MACHINE
, IMAGE_FILE_DEBUG_STRIPPED
, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
, IMAGE_FILE_NET_RUN_FROM_SWAP
, IMAGE_FILE_SYSTEM
, IMAGE_FILE_DLL
, IMAGE_FILE_UP_SYSTEM_ONLY
}; for (std
::size_t I
= 0; I
< sizeof(Characteristics
)/sizeof(WORD
); ++I
) { switch (pNtHeaders
->FileHeader.
Characteristics & Characteristics
[I
]) { case IMAGE_FILE_RELOCS_STRIPPED
: std
::cout<<" Relocation information was stripped from the file."<<std
::endl; break; case IMAGE_FILE_EXECUTABLE_IMAGE
: std
::cout<<" The file is executable."<<std
::endl; break; case IMAGE_FILE_LINE_NUMS_STRIPPED
: std
::cout<<" COFF line numbers were stripped from the file."<<std
::endl; break; case IMAGE_FILE_LARGE_ADDRESS_AWARE
: std
::cout<<" The application can handle addresses larger than 2 GB."<<std
::endl; break; case IMAGE_FILE_32BIT_MACHINE
: std
::cout<<" The computer supports 32-bit words."<<std
::endl; break; case IMAGE_FILE_DEBUG_STRIPPED
: std
::cout<<" Debugging information was removed and stored separately in another file."<<std
::endl; break; case IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
: std
::cout<<" If the image is on removable media, copy it to and run it from the swap file."<<std
::endl; break; case IMAGE_FILE_NET_RUN_FROM_SWAP
: std
::cout<<" If the image is on the network, copy it to and run it from the swap file."<<std
::endl; break; case IMAGE_FILE_SYSTEM
: std
::cout<<" The image is a system file."<<std
::endl; break; case IMAGE_FILE_DLL
: std
::cout<<" The image is a DLL file. It can't be run directly."<<std
::endl; break; case IMAGE_FILE_UP_SYSTEM_ONLY
: std
::cout<<" The file should be run only on a uniprocessor computer."<<std
::endl; break; default: break; } } std
::cout<<"\n\nOptional-Header (IMAGE_OPTIONAL_HEADER)"<<std
::endl; std
::cout<<"----------------------------------------"<<std
::endl; std
::cout<<"Magic Number: "<<pNtHeaders
->OptionalHeader.
Magic<<std
::endl; std
::cout<<"Major Linker Version: "<<static_cast
<int
>(pNtHeaders
->OptionalHeader.
MajorLinkerVersion)<<std
::endl; std
::cout<<"Minor Linker Version: "<<static_cast
<int
>(pNtHeaders
->OptionalHeader.
MajorLinkerVersion)<<std
::endl; std
::cout<<"Code Section Size (.text): "<<pNtHeaders
->OptionalHeader.
SizeOfCode<<std
::endl; std
::cout<<"Size Of Initialized Data: "<<pNtHeaders
->OptionalHeader.
SizeOfInitializedData<<std
::endl; std
::cout<<"Address Of Entry Point: "<<pNtHeaders
->OptionalHeader.
AddressOfEntryPoint<<std
::endl; std
::cout<<"Address Of Code (.code): "<<pNtHeaders
->OptionalHeader.
BaseOfCode<<std
::endl; #ifndef __x86_64 std
::cout<<"Address Of Data (.data): "<<pNtHeaders
->OptionalHeader.
BaseOfData<<std
::endl; #endif std
::cout<<"Base Address Of Image: "<<pNtHeaders
->OptionalHeader.
ImageBase<<std
::endl; std
::cout<<"Section Alignment: "<<pNtHeaders
->OptionalHeader.
SectionAlignment<<std
::endl; std
::cout<<"FileAlignment: "<<pNtHeaders
->OptionalHeader.
FileAlignment<<std
::endl; std
::cout<<"Major OS Version: "<<pNtHeaders
->OptionalHeader.
MajorOperatingSystemVersion<<std
::endl; std
::cout<<"Minor OS Version: "<<pNtHeaders
->OptionalHeader.
MinorOperatingSystemVersion<<std
::endl; std
::cout<<"Major Image Version: "<<pNtHeaders
->OptionalHeader.
MajorImageVersion<<std
::endl; std
::cout<<"Minor Image Version: "<<pNtHeaders
->OptionalHeader.
MinorImageVersion<<std
::endl; std
::cout<<"Major Subsystem Version: "<<pNtHeaders
->OptionalHeader.
MajorSubsystemVersion<<std
::endl; std
::cout<<"Minor Subsystem Version: "<<pNtHeaders
->OptionalHeader.
MinorSubsystemVersion<<std
::endl; std
::cout<<"Size Of Image: "<<pNtHeaders
->OptionalHeader.
SizeOfImage<<std
::endl; std
::cout<<"Size Of Headers: "<<pNtHeaders
->OptionalHeader.
SizeOfHeaders<<std
::endl; std
::cout<<"Checksum: "<<pNtHeaders
->OptionalHeader.
CheckSum<<std
::endl; std
::cout<<"Subsystem: "; switch (pNtHeaders
->OptionalHeader.
Subsystem) { case IMAGE_SUBSYSTEM_UNKNOWN
: std
::cout<<"Unknown subsystem."<<std
::endl; break; case IMAGE_SUBSYSTEM_NATIVE
: std
::cout<<"No subsystem required (device drivers and native system processes)."<<std
::endl; break; case IMAGE_SUBSYSTEM_WINDOWS_GUI
: std
::cout<<"Windows graphical UI (GUI) subsystem."<<std
::endl; break; case IMAGE_SUBSYSTEM_WINDOWS_CUI
: std
::cout<<"Windows character-mode UI (CUI) subsystem."<<std
::endl; break; case IMAGE_SUBSYSTEM_OS2_CUI
: std
::cout<<"OS/2 CUI subsystem."<<std
::endl; break; case IMAGE_SUBSYSTEM_POSIX_CUI
: std
::cout<<"POSIX CUI subsystem."<<std
::endl; break; case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
: std
::cout<<"Windows CE system."<<std
::endl; break; case IMAGE_SUBSYSTEM_EFI_APPLICATION
: std
::cout<<"Extensible Firmware Interface (EFI) application."<<std
::endl; break; case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
: std
::cout<<"EFI driver with boot services."<<std
::endl; break; case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
: std
::cout<<"EFI driver with run-time services."<<std
::endl; break; case IMAGE_SUBSYSTEM_EFI_ROM
: std
::cout<<"EFI ROM image."<<std
::endl; break; case IMAGE_SUBSYSTEM_XBOX
: std
::cout<<"Xbox system."<<std
::endl; break; case IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION
: std
::cout<<"Boot application."<<std
::endl; break; default: break; } std
::cout<<"Dll Characteristics: "<<std
::endl<<std
::endl; WORD DllCharacteristics
[] = {IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
, IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY
, IMAGE_DLLCHARACTERISTICS_NX_COMPAT
, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION
, IMAGE_DLLCHARACTERISTICS_NO_SEH
, IMAGE_DLLCHARACTERISTICS_NO_BIND
, IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
, IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
}; for (std
::size_t I
= 0; I
< sizeof(DllCharacteristics
)/sizeof(WORD
); ++I
) { switch (pNtHeaders
->OptionalHeader.
DllCharacteristics & DllCharacteristics
[I
]) { case IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
: std
::cout<<" The DLL can be relocated at load time."<<std
::endl; break; case IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY
: std
::cout<<" Code integrity checks are forced."<<std
::endl; break; case IMAGE_DLLCHARACTERISTICS_NX_COMPAT
: std
::cout<<" The image is compatible with data execution prevention (DEP)."<<std
::endl; break; case IMAGE_DLLCHARACTERISTICS_NO_ISOLATION
: std
::cout<<" The image is isolation aware, but should not be isolated."<<std
::endl; break; case IMAGE_DLLCHARACTERISTICS_NO_SEH
: std
::cout<<" The image does not use structured exception handling (SEH)."<<std
::endl; break; case IMAGE_DLLCHARACTERISTICS_NO_BIND
: std
::cout<<" Do not bind the image."<<std
::endl; break; case IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
: std
::cout<<" A WDM driver."<<std
::endl; break; case IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
: std
::cout<<" The image is terminal server aware."<<std
::endl; break; default: break; } } std
::cout<<std
::endl; std
::cout<<"Size Of Stack Reserve: "<<pNtHeaders
->OptionalHeader.
SizeOfStackReserve<<std
::endl; std
::cout<<"Size Of Stack Commit: "<<pNtHeaders
->OptionalHeader.
SizeOfStackCommit<<std
::endl; std
::cout<<"Size Of Heap Reserve: "<<pNtHeaders
->OptionalHeader.
SizeOfHeapReserve<<std
::endl; std
::cout<<"Size Of Heap Commit: "<<pNtHeaders
->OptionalHeader.
SizeOfHeapCommit<<std
::endl; std
::cout<<"Number Of Rva And Sizes: "<<pNtHeaders
->OptionalHeader.
NumberOfRvaAndSizes<<std
::endl; int I
= 0; std
::cout<<"\n\nData Directory (IMPORT TABLE RVA):"<<std
::endl; std
::cout<<"----------------------------------"<<std
::endl; for (pSectionHeader
= IMAGE_FIRST_SECTION
(pNtHeaders
); I
< pNtHeaders
->FileHeader.
NumberOfSections; ++pSectionHeader
, ++I
) { std
::cout<<"\n\n Section Info ("<<I
+ 1<<" of "<<pNtHeaders
->FileHeader.
NumberOfSections<<")"<<std
::endl; std
::cout<<" ------------------------------------"<<std
::endl; if ((pNtHeaders
->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT
].
VirtualAddress >= pSectionHeader
->VirtualAddress
) && ((pSectionHeader
->VirtualAddress
+ pSectionHeader
->Misc.
VirtualSize) > pNtHeaders
->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT
].
VirtualAddress)) { std
::cout<<" IAT Entry Point: "<<((pNtHeaders
->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT
].
VirtualAddress - pSectionHeader
->VirtualAddress
) + pSectionHeader
->PointerToRawData
)<<std
::endl; } std
::cout<<" Section Header Name: "<<pSectionHeader
->Name
<<std
::endl; std
::cout<<" Actual .code or .data Size: "<<pSectionHeader
->Misc.
VirtualSize<<std
::endl; std
::cout<<" Virtual Address(RVA): "<<pSectionHeader
->VirtualAddress
<<std
::endl; std
::cout<<" Size Of Raw Data: "<<pSectionHeader
->SizeOfRawData
<<std
::endl; std
::cout<<" Pointer To Raw Data: "<<pSectionHeader
->PointerToRawData
<<std
::endl; std
::cout<<" Pointer To Relocations: "<<pSectionHeader
->PointerToRelocations
<<std
::endl; std
::cout<<" Pointer To Line Numbers: "<<pSectionHeader
->PointerToLinenumbers
<<std
::endl; std
::cout<<" Number Of Relocations: "<<pSectionHeader
->NumberOfRelocations
<<std
::endl; std
::cout<<" Number Of Line Numbers: "<<pSectionHeader
->NumberOfLinenumbers
<<std
::endl; std
::cout<<" Characteristics: "; //For each characteristic.. switch.. sectionheader.. } std
::cout<<std
::endl<<std
::endl; } UnmapViewOfFile
(MapView
); CloseHandle
(FileMapping
); CloseHandle
(FileHandle
);}int main
(){ ListModuleInfo
("notepad.exe"); std
::cout<<"Press Enter/Return To Continue.."<<std
::endl; std
::cin.
get(); PrintPEInfo
("C:/windows/notepad.exe"); std
::cout<<"Press Enter/Return To Exit.."<<std
::endl; std
::cin.
get();}