1+ /*
2+ PEB Offset calculator
3+ @5mukx
4+ */
5+
6+
7+ use ntapi:: {
8+ ntpebteb:: PEB ,
9+ ntrtl:: RTL_USER_PROCESS_PARAMETERS ,
10+ } ;
11+ use std:: arch:: asm;
12+
13+ use memoffset:: offset_of;
14+
15+
16+ fn get_peb ( ) -> * mut PEB {
17+ #[ cfg( target_arch = "x86_64" ) ]
18+ {
19+ let peb: * mut PEB ;
20+ unsafe { asm ! ( "mov {}, gs:[0x60]" , out( reg) peb) } ;
21+ peb
22+ }
23+ #[ cfg( target_arch = "x86" ) ]
24+ {
25+ let peb: * mut PEB ;
26+ unsafe { asm ! ( "mov {}, fs:[0x30]" , out( reg) peb) } ;
27+ peb
28+ }
29+ }
30+
31+ fn print_peb_offsets ( ) {
32+ println ! ( "[*] PEB Field Offsets:" ) ;
33+ println ! ( "----Field: Offset----" ) ;
34+ println ! ( "[+] InheritedAddressSpace: {:#x}" , offset_of!( PEB , InheritedAddressSpace ) ) ;
35+ println ! ( "[+] ReadImageFileExecOptions: {:#x}" , offset_of!( PEB , ReadImageFileExecOptions ) ) ;
36+ println ! ( "[+] BeingDebugged: {:#x}" , offset_of!( PEB , BeingDebugged ) ) ;
37+ println ! ( "[+] BitField: {:#x}" , offset_of!( PEB , BitField ) ) ;
38+ println ! ( "[+] Mutant: {:#x}" , offset_of!( PEB , Mutant ) ) ;
39+ println ! ( "[+] ImageBaseAddress: {:#x}" , offset_of!( PEB , ImageBaseAddress ) ) ;
40+ println ! ( "[+] Ldr: {:#x}" , offset_of!( PEB , Ldr ) ) ;
41+ println ! ( "[+] ProcessParameters: {:#x}" , offset_of!( PEB , ProcessParameters ) ) ;
42+ println ! ( "[+] SubSystemData: {:#x}" , offset_of!( PEB , SubSystemData ) ) ;
43+ println ! ( "[+] ProcessHeap: {:#x}" , offset_of!( PEB , ProcessHeap ) ) ;
44+ println ! ( "[+] FastPebLock: {:#x}" , offset_of!( PEB , FastPebLock ) ) ;
45+ println ! ( "[+] AtlThunkSListPtr: {:#x}" , offset_of!( PEB , AtlThunkSListPtr ) ) ;
46+ println ! ( "[+] IFEOKey: {:#x}" , offset_of!( PEB , IFEOKey ) ) ;
47+ println ! ( "[+] CrossProcessFlags: {:#x}" , offset_of!( PEB , CrossProcessFlags ) ) ;
48+
49+ // u handle filed
50+ let u_offset = offset_of ! ( PEB , u) ;
51+ println ! ( "[+] u.KernelCallbackTable: {:#x}" , u_offset) ;
52+ println ! ( "[+] u.UserSharedInfoPtr: {:#x}" , u_offset) ;
53+ println ! ( "[+] SystemReserved: {:#x}" , offset_of!( PEB , SystemReserved ) ) ;
54+ println ! ( "[+] AtlThunkSListPtr32: {:#x}" , offset_of!( PEB , AtlThunkSListPtr32 ) ) ;
55+ println ! ( "[+] ApiSetMap: {:#x}" , offset_of!( PEB , ApiSetMap ) ) ;
56+ println ! ( "[+] TlsExpansionCounter: {:#x}" , offset_of!( PEB , TlsExpansionCounter ) ) ;
57+ println ! ( "[+] TlsBitmap: {:#x}" , offset_of!( PEB , TlsBitmap ) ) ;
58+ println ! ( "[+] TlsBitmapBits: {:#x}" , offset_of!( PEB , TlsBitmapBits ) ) ;
59+ println ! ( "[+] ReadOnlySharedMemoryBase: {:#x}" , offset_of!( PEB , ReadOnlySharedMemoryBase ) ) ;
60+ println ! ( "[+] SharedData: {:#x}" , offset_of!( PEB , SharedData ) ) ;
61+ println ! ( "[+] ReadOnlyStaticServerData: {:#x}" , offset_of!( PEB , ReadOnlyStaticServerData ) ) ;
62+ println ! ( "[+] AnsiCodePageData: {:#x}" , offset_of!( PEB , AnsiCodePageData ) ) ;
63+ println ! ( "[+] OemCodePageData: {:#x}" , offset_of!( PEB , OemCodePageData ) ) ;
64+ println ! ( "[+] UnicodeCaseTableData: {:#x}" , offset_of!( PEB , UnicodeCaseTableData ) ) ;
65+ println ! ( "[+] NumberOfProcessors: {:#x}" , offset_of!( PEB , NumberOfProcessors ) ) ;
66+ println ! ( "[+] NtGlobalFlag: {:#x}" , offset_of!( PEB , NtGlobalFlag ) ) ;
67+ println ! ( "[+] CriticalSectionTimeout: {:#x}" , offset_of!( PEB , CriticalSectionTimeout ) ) ;
68+ println ! ( "[+] HeapSegmentReserve: {:#x}" , offset_of!( PEB , HeapSegmentReserve ) ) ;
69+ println ! ( "[+] HeapSegmentCommit: {:#x}" , offset_of!( PEB , HeapSegmentCommit ) ) ;
70+ println ! ( "[+] HeapDeCommitTotalFreeThreshold: {:#x}" , offset_of!( PEB , HeapDeCommitTotalFreeThreshold ) ) ;
71+ println ! ( "[+] HeapDeCommitFreeBlockThreshold: {:#x}" , offset_of!( PEB , HeapDeCommitFreeBlockThreshold ) ) ;
72+ println ! ( "[+] NumberOfHeaps: {:#x}" , offset_of!( PEB , NumberOfHeaps ) ) ;
73+ println ! ( "[+] MaximumNumberOfHeaps: {:#x}" , offset_of!( PEB , MaximumNumberOfHeaps ) ) ;
74+ println ! ( "[+] ProcessHeaps: {:#x}" , offset_of!( PEB , ProcessHeaps ) ) ;
75+ println ! ( "[+] GdiSharedHandleTable: {:#x}" , offset_of!( PEB , GdiSharedHandleTable ) ) ;
76+ println ! ( "[+] ProcessStarterHelper: {:#x}" , offset_of!( PEB , ProcessStarterHelper ) ) ;
77+ println ! ( "[+] GdiDCAttributeList: {:#x}" , offset_of!( PEB , GdiDCAttributeList ) ) ;
78+ println ! ( "[+] LoaderLock: {:#x}" , offset_of!( PEB , LoaderLock ) ) ;
79+ println ! ( "[+] OSMajorVersion: {:#x}" , offset_of!( PEB , OSMajorVersion ) ) ;
80+ println ! ( "[+] OSMinorVersion: {:#x}" , offset_of!( PEB , OSMinorVersion ) ) ;
81+ println ! ( "[+] OSBuildNumber: {:#x}" , offset_of!( PEB , OSBuildNumber ) ) ;
82+ println ! ( "[+] OSCSDVersion: {:#x}" , offset_of!( PEB , OSCSDVersion ) ) ;
83+ println ! ( "[+] OSPlatformId: {:#x}" , offset_of!( PEB , OSPlatformId ) ) ;
84+ println ! ( "[+] ImageSubsystem: {:#x}" , offset_of!( PEB , ImageSubsystem ) ) ;
85+ println ! ( "[+] ImageSubsystemMajorVersion: {:#x}" , offset_of!( PEB , ImageSubsystemMajorVersion ) ) ;
86+ println ! ( "[+] ImageSubsystemMinorVersion: {:#x}" , offset_of!( PEB , ImageSubsystemMinorVersion ) ) ;
87+ println ! ( "[+] ActiveProcessAffinityMask: {:#x}" , offset_of!( PEB , ActiveProcessAffinityMask ) ) ;
88+ println ! ( "[+] GdiHandleBuffer: {:#x}" , offset_of!( PEB , GdiHandleBuffer ) ) ;
89+ println ! ( "[+] PostProcessInitRoutine: {:#x}" , offset_of!( PEB , PostProcessInitRoutine ) ) ;
90+ println ! ( "[+] TlsExpansionBitmap: {:#x}" , offset_of!( PEB , TlsExpansionBitmap ) ) ;
91+ println ! ( "[+] TlsExpansionBitmapBits: {:#x}" , offset_of!( PEB , TlsExpansionBitmapBits ) ) ;
92+ println ! ( "[+] SessionId: {:#x}" , offset_of!( PEB , SessionId ) ) ;
93+ println ! ( "[+] AppCompatFlags: {:#x}" , offset_of!( PEB , AppCompatFlags ) ) ;
94+ println ! ( "[+] AppCompatFlagsUser: {:#x}" , offset_of!( PEB , AppCompatFlagsUser ) ) ;
95+ println ! ( "[+] pShimData: {:#x}" , offset_of!( PEB , pShimData) ) ;
96+ println ! ( "[+] AppCompatInfo: {:#x}" , offset_of!( PEB , AppCompatInfo ) ) ;
97+ println ! ( "[+] CSDVersion: {:#x}" , offset_of!( PEB , CSDVersion ) ) ;
98+ println ! ( "[+] ActivationContextData: {:#x}" , offset_of!( PEB , ActivationContextData ) ) ;
99+ println ! ( "[+] ProcessAssemblyStorageMap: {:#x}" , offset_of!( PEB , ProcessAssemblyStorageMap ) ) ;
100+ println ! ( "[+] SystemDefaultActivationContextData: {:#x}" , offset_of!( PEB , SystemDefaultActivationContextData ) ) ;
101+ println ! ( "[+] SystemAssemblyStorageMap: {:#x}" , offset_of!( PEB , SystemAssemblyStorageMap ) ) ;
102+ println ! ( "[+] MinimumStackCommit: {:#x}" , offset_of!( PEB , MinimumStackCommit ) ) ;
103+ println ! ( "[+] FlsCallback: {:#x}" , offset_of!( PEB , FlsCallback ) ) ;
104+ println ! ( "[+] FlsListHead: {:#x}" , offset_of!( PEB , FlsListHead ) ) ;
105+ println ! ( "[+] FlsBitmap: {:#x}" , offset_of!( PEB , FlsBitmap ) ) ;
106+ println ! ( "[+] FlsBitmapBits: {:#x}" , offset_of!( PEB , FlsBitmapBits ) ) ;
107+ println ! ( "[+] FlsHighIndex: {:#x}" , offset_of!( PEB , FlsHighIndex ) ) ;
108+ println ! ( "[+] WerRegistrationData: {:#x}" , offset_of!( PEB , WerRegistrationData ) ) ;
109+ println ! ( "[+] WerShipAssertPtr: {:#x}" , offset_of!( PEB , WerShipAssertPtr ) ) ;
110+ println ! ( "[+] pUnused: {:#x}" , offset_of!( PEB , pUnused) ) ;
111+ println ! ( "[+] pImageHeaderHash: {:#x}" , offset_of!( PEB , pImageHeaderHash) ) ;
112+ println ! ( "[+] TracingFlags: {:#x}" , offset_of!( PEB , TracingFlags ) ) ;
113+ println ! ( "[+] CsrServerReadOnlySharedMemoryBase: {:#x}" , offset_of!( PEB , CsrServerReadOnlySharedMemoryBase ) ) ;
114+ println ! ( "[+] TppWorkerpListLock: {:#x}" , offset_of!( PEB , TppWorkerpListLock ) ) ;
115+ println ! ( "[+] TppWorkerpList: {:#x}" , offset_of!( PEB , TppWorkerpList ) ) ;
116+ println ! ( "[+] WaitOnAddressHashTable: {:#x}" , offset_of!( PEB , WaitOnAddressHashTable ) ) ;
117+ println ! ( "[+] TelemetryCoverageHeader: {:#x}" , offset_of!( PEB , TelemetryCoverageHeader ) ) ;
118+ println ! ( "[+] CloudFileFlags: {:#x}" , offset_of!( PEB , CloudFileFlags ) ) ;
119+ println ! ( "[+] CloudFileDiagFlags: {:#x}" , offset_of!( PEB , CloudFileDiagFlags ) ) ;
120+ println ! ( "[+] PlaceholderCompatibilityMode: {:#x}" , offset_of!( PEB , PlaceholderCompatibilityMode ) ) ;
121+ println ! ( "[+] PlaceholderCompatibilityModeReserved: {:#x}" , offset_of!( PEB , PlaceholderCompatibilityModeReserved ) ) ;
122+ println ! ( "[+] LeapSecondData: {:#x}" , offset_of!( PEB , LeapSecondData ) ) ;
123+ println ! ( "[+] LeapSecondFlags: {:#x}" , offset_of!( PEB , LeapSecondFlags ) ) ;
124+ println ! ( "[+] NtGlobalFlag2: {:#x}" , offset_of!( PEB , NtGlobalFlag2 ) ) ;
125+ }
126+
127+ fn print_rtl_user_process_parameters_offsets ( ) {
128+ println ! ( "[*] RTL_USER_PROCESS_PARAMETERS Field Offsets:" ) ;
129+ println ! ( "----Field: Offset----" ) ;
130+ println ! ( "[+] MaximumLength: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , MaximumLength ) ) ;
131+ println ! ( "[+] Length: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , Length ) ) ;
132+ println ! ( "[+] Flags: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , Flags ) ) ;
133+ println ! ( "[+] DebugFlags: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , DebugFlags ) ) ;
134+ println ! ( "[+] ConsoleHandle: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , ConsoleHandle ) ) ;
135+ println ! ( "[+] ConsoleFlags: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , ConsoleFlags ) ) ;
136+ println ! ( "[+] StandardInput: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , StandardInput ) ) ;
137+ println ! ( "[+] StandardOutput: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , StandardOutput ) ) ;
138+ println ! ( "[+] StandardError: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , StandardError ) ) ;
139+ println ! ( "[+] CurrentDirectory: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , CurrentDirectory ) ) ;
140+ println ! ( "[+] DllPath: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , DllPath ) ) ;
141+ println ! ( "[+] ImagePathName: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , ImagePathName ) ) ;
142+ println ! ( "[+] CommandLine: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , CommandLine ) ) ;
143+ println ! ( "[+] Environment: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , Environment ) ) ;
144+ println ! ( "[+] StartingX: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , StartingX ) ) ;
145+ println ! ( "[+] StartingY: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , StartingY ) ) ;
146+ println ! ( "[+] CountX: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , CountX ) ) ;
147+ println ! ( "[+] CountY: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , CountY ) ) ;
148+ println ! ( "[+] CountCharsX: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , CountCharsX ) ) ;
149+ println ! ( "[+] CountCharsY: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , CountCharsY ) ) ;
150+ println ! ( "[+] FillAttribute: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , FillAttribute ) ) ;
151+ println ! ( "[+] WindowFlags: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , WindowFlags ) ) ;
152+ println ! ( "[+] ShowWindowFlags: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , ShowWindowFlags ) ) ;
153+ println ! ( "[+] WindowTitle: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , WindowTitle ) ) ;
154+ println ! ( "[+] DesktopInfo: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , DesktopInfo ) ) ;
155+ println ! ( "[+] ShellInfo: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , ShellInfo ) ) ;
156+ println ! ( "[+] RuntimeData: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , RuntimeData ) ) ;
157+ println ! ( "[+] CurrentDirectories: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , CurrentDirectories ) ) ;
158+ println ! ( "[+] EnvironmentSize: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , EnvironmentSize ) ) ;
159+ println ! ( "[+] EnvironmentVersion: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , EnvironmentVersion ) ) ;
160+ println ! ( "[+] PackageDependencyData: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , PackageDependencyData ) ) ;
161+ println ! ( "[+] ProcessGroupId: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , ProcessGroupId ) ) ;
162+ println ! ( "[+] LoaderThreads: {:#x}" , offset_of!( RTL_USER_PROCESS_PARAMETERS , LoaderThreads ) ) ;
163+ }
164+
165+
166+ // example runtime
167+ fn validate_offsets_runtime ( ) {
168+ unsafe {
169+ println ! ( "\n [*] Runtime Offset Validation:" ) ;
170+ let peb = get_peb ( ) ;
171+ if peb. is_null ( ) {
172+ println ! ( "[*] PEB is null" ) ;
173+ return ;
174+ }
175+ let peb_base = peb as usize ;
176+ let process_parameters = ( * peb) . ProcessParameters ;
177+ if process_parameters. is_null ( ) {
178+ println ! ( "[*] ProcessParameters is null" ) ;
179+ return ;
180+ }
181+ let params_base = process_parameters as usize ;
182+
183+ // PEB.ProcessParameters
184+ let process_parameters_offset = ( process_parameters as usize ) . wrapping_sub ( peb_base) ;
185+ println ! ( "[*] PEB.ProcessParameters: Calculated Offset = {:#x}, Expected = {:#x}" ,
186+ process_parameters_offset, offset_of!( PEB , ProcessParameters ) ) ;
187+
188+ // PEB.u.KernelCallbackTable
189+ let kernel_callback_table_offset = ( & ( * peb) . u as * const _ as usize ) . wrapping_sub ( peb_base) ;
190+ println ! ( "[*] PEB.u.KernelCallbackTable: Calculated Offset = {:#x}, Expected = {:#x}" ,
191+ kernel_callback_table_offset, offset_of!( PEB , u) ) ;
192+
193+ // Example !
194+ // RTL_USER_PROCESS_PARAMETERS fields
195+ let current_directory_offset = ( & ( * process_parameters) . CurrentDirectory as * const _ as usize ) . wrapping_sub ( params_base) ;
196+ let command_line_offset = ( & ( * process_parameters) . CommandLine as * const _ as usize ) . wrapping_sub ( params_base) ;
197+ let environment_offset = ( & ( * process_parameters) . Environment as * const _ as usize ) . wrapping_sub ( params_base) ;
198+
199+ println ! ( "[*] RTL_USER_PROCESS_PARAMETERS.CurrentDirectory: Calculated Offset = {:#x}, Expected = {:#x}" ,
200+ current_directory_offset, offset_of!( RTL_USER_PROCESS_PARAMETERS , CurrentDirectory ) ) ;
201+
202+ println ! ( "[*] RTL_USER_PROCESS_PARAMETERS.CommandLine: Calculated Offset = {:#x}, Expected = {:#x}" ,
203+ command_line_offset, offset_of!( RTL_USER_PROCESS_PARAMETERS , CommandLine ) ) ;
204+
205+ println ! ( "[*] RTL_USER_PROCESS_PARAMETERS.Environment: Calculated Offset = {:#x}, Expected = {:#x}" ,
206+ environment_offset, offset_of!( RTL_USER_PROCESS_PARAMETERS , Environment ) ) ;
207+
208+ println ! ( "[*] PEB Address: {:#x}" , peb_base) ;
209+ println ! ( "[*] ProcessParameters Address: {:#x}" , process_parameters as usize ) ;
210+ println ! ( "[*] u.KernelCallbackTable Address: {:#x}" , ( * peb) . u. KernelCallbackTable as usize ) ;
211+ println ! ( "[*] Environment Address: {:#x}" , ( * process_parameters) . Environment as usize ) ;
212+ }
213+ }
214+
215+
216+ fn main ( ) {
217+
218+ print_peb_offsets ( ) ;
219+
220+ print_rtl_user_process_parameters_offsets ( ) ;
221+
222+ validate_offsets_runtime ( ) ;
223+
224+ }
0 commit comments