📄 procpath.asm
字号:
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; S T R U C T U R E S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; These structures are the same on 2000, XP and 2003
OBJECT_HEADER STRUCT ; sizeof = 018h
PointerCount SDWORD ? ; 0000h
union
HandleCount SDWORD ? ; 0004h
SEntry PVOID ? ; 0004h PTR SINGLE_LIST_ENTRY
ends
_Type PVOID ? ; 0008h PTR OBJECT_TYPE (original name Type)
NameInfoOffset BYTE ? ; 000Ch
HandleInfoOffset BYTE ? ; 000Dh
QuotaInfoOffset BYTE ? ; 000Eh
Flags BYTE ? ; 000Fh
union
ObjectCreateInfo PVOID ? ; 0010h PTR OBJECT_CREATE_INFORMATION
QuotaBlockCharged PVOID ? ; 0010h
ends
SecurityDescriptor PVOID ? ; 0014h
; Body QUAD <> ; 0018h
OBJECT_HEADER ENDS
_SEGMENT STRUCT ; sizeof = 40h
ControlArea PVOID ? ; 000 PTR CONTROL_AREA
SegmentBaseAddress PVOID ? ; 004
TotalNumberOfPtes DWORD ? ; 008
NonExtendedPtes DWORD ? ; 00C
SizeOfSegment QWORD ? ; 010 ULONG64
ImageCommitment DWORD ? ; 018
ImageInformation PVOID ? ; 01C PTR SECTION_IMAGE_INFORMATION
SystemImageBase PVOID ? ; 020
NumberOfCommittedPages DWORD ? ; 024
SegmentPteTemplate DWORD ? ; 028 MMPTE
BasedAddress PVOID ? ; 02C
ExtendInfo PVOID ? ; 030 PTR MMEXTEND_INFO
PrototypePte PVOID ? ; 034 PTR MMPTE
ThePtes DWORD 1 dup(?) ; 038 array of MMPTE
_SEGMENT ENDS
CONTROL_AREA STRUCT ; sizeof = 38h
_Segment PVOID ? ; 000 PTR _SEGMENT
DereferenceList LIST_ENTRY <> ; 004
NumberOfSectionReferences DWORD ? ; 00C
NumberOfPfnReferences DWORD ? ; 010
NumberOfMappedViews DWORD ? ; 014
NumberOfSubsections WORD ? ; 018
FlushInProgressCount WORD ? ; 01A
NumberOfUserReferences DWORD ? ; 01C
union u
LongFlags DWORD ? ; 020
Flags DWORD ? ; 020 MMSECTION_FLAGS
ends
FilePointer PVOID ? ; 024 PTR FILE_OBJECT
WaitingForDeletion PVOID ? ; 028 PTR EVENT_COUNTER
ModifiedWriteCount WORD ? ; 02C
NumberOfSystemCacheViews WORD ? ; 02E
PagedPoolUsage DWORD ? ; 030
NonPagedPoolUsage DWORD ? ; 034
CONTROL_AREA ENDS
MMADDRESS_NODE STRUCT ; sizeof = 14h
StartingVpn DWORD ? ; 00 ULONG_PTR
EndingVpn DWORD ? ; 04 ULONG_PTR
Parent PVOID ? ; 08 PTR MMADDRESS_NODE
LeftChild PVOID ? ; 0C PTR MMADDRESS_NODE
RightChild PVOID ? ; 10 PTR MMADDRESS_NODE
MMADDRESS_NODE ENDS
PMMADDRESS_NODE typedef ptr MMADDRESS_NODE
COMMENT ^
It's allmost the same as SECTION but we need SECTION.
SECTION_OBJECT STRUCT ; sizeof = 18h
StartingVa PVOID ? ; 00
EndingVa PVOID ? ; 04
Parent PVOID ? ; 08
LeftChild PVOID ? ; 0C
RightChild PVOID ? ; 10
_Segment PVOID ? ; 14 PTR _SEGMENT ( not SEGMENT_OBJECT as defined in PDB!)
SECTION_OBJECT ENDS
^
SECTION STRUCT ; sizeof = 28h
Address MMADDRESS_NODE <> ; 00
_Segment PVOID ? ; 14 PTR _SEGMENT
SizeOfSection LARGE_INTEGER <> ; 18
union u
LongFlags DWORD ? ; 20
Flags DWORD ? ; 20 MMSECTION_FLAGS
ends
InitialPageProtection DWORD ? ; 24
SECTION ENDS
PSECTION typedef ptr SECTION
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; E Q U A T E S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
WINVER_UNINITIALIZED equ -1
WINVER_2K equ 0
WINVER_XP_OR_HIGHER equ 1
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; I N I T I A L I Z E D D A T A
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.data
g_dwWinVer DWORD WINVER_UNINITIALIZED
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; IsAddressInPoolRanges
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IsAddressInPoolRanges proc uses ebx pAddress:PVOID
; The purpose of this routine is check to see
; if specified address is in the range of system pools.
; (80000000 < pAddress < A0000000) || (E1000000 < pAddress < FFBE0000)
comment ^
+- MmSystemRangeStart = 80000000 -----------+
| | sizeof = 20000000 MB
| System code (ntoskrnl and hal) |
| and initial nonpaged pool |
| |
+- MiSystemViewStart = A0000000 -----------+
| |
. . . . . .
| |
+- MmPagedPoolStart = E1000000 -----------+
| | sizeof = 1EBE0000 MB
| Paged pool |
| |
| System page table entries (PTEs) |
| |
| Expanded nonpaged pool |
| |
+- MmPagedPoolEnd (calculated at boot time) +
Note:
Above system space layout is for system
with 2Gb system space (non-PAE and no /3GB boot.ini option)
MiSystemViewStart = A0000000 without Terminal Services
MiSystemViewStart = A3000000 with Terminal Services
MmPagedPoolEnd is less then MmNonPagedPoolEnd = FFBE0000
and is less then Crash Dump structures also starting at FFBE0000
^
local fOk:BOOL
and fOk, FALSE
mov eax, MmSystemRangeStart
mov eax, [eax]
mov eax, [eax]
.if eax == 80000000h
; OK. 2Gb system space
mov ebx, pAddress
xor ecx, ecx ; LowerRange flag
xor edx, edx ; UpperRange flag
.if ( ebx > 80000000h ) && ( ebx < 0A0000000h )
inc ecx ; In LowerRange
.endif
.if ( ebx > 0E1000000h ) && ( ebx < 0FFBE0000h )
inc edx ; In UpperRange
.endif
or ecx, edx
.if !ZERO?
mov fOk, TRUE ; OK
.endif
.endif
mov eax, fOk
ret
IsAddressInPoolRanges endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; IsLikeObjectPointer
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IsLikeObjectPointer proc uses esi pObject:PVOID
;
; Determines whether pointer seems to be a valid object pointer.
; If pointer is in system pools range & at least 8 bytes aligned
; & points to valid memory & (pObject - sizeof OBJECT_HEADER) is also valid
; we make reasonable decision about pObjectis probably points to some object.
;
; You MUST NOT make any assumption that it is really some object pointer!!!
;
; You are only guaranteed (if call to this function is successful)
; that your subsequent call to ObReferenceObjectByPointer at IRQL <= DISPATCH_LEVEL
; doesn't bugcheck. And if and only if ObReferenceObjectByPointer,,,UserMode
; returns STATUS_SUCCESS you are 100% shure that pObject is particular object pointer.
; See comments in GetImageFilePath about UserMode parameter.
;
local fOk:BOOL
and fOk, FALSE
mov esi, pObject
invoke IsAddressInPoolRanges, esi
.if eax == TRUE
;
; Check alignment.
;
; Object body immediately follows the object header in memory. Optionaly
; four structures immediately precede object header. They are:
; OBJECT_HEADER_QUOTA_INFO, OBJECT_HEADER_HANDLE_INFO, OBJECT_HEADER_NAME_INFO
; and OBJECT_HEADER_CREATOR_INFO. The size of each structure and OBJECT_HEADER
; is divisible by 8.
;
; The object body with all accompanion structures is part of a single memory
; allocation, and memory allocations of less than PAGE_SIZE are aligned
; on an 8-byte boundary. So objects body is always at least 8 aligned.
;
mov eax, esi
and eax, (8 - 1)
.if eax == 0
; Object body should resides in valid memory
invoke MmIsAddressValid, esi
.if al
; Object header also must be valid
mov eax, esi
and eax, (PAGE_SIZE-1)
.if eax < sizeof OBJECT_HEADER
; Object header crosses a page boundary
; We have to call MmIsAddressValid again
; against object header
sub esi, sizeof OBJECT_HEADER
invoke MmIsAddressValid, esi
.if al
mov fOk, TRUE
.endif
.else
; Object header is in the same page as its body
; So no need to call MmIsAddressValid once more
mov fOk, TRUE
.endif
.endif
.endif
.endif
mov eax, fOk
ret
IsLikeObjectPointer endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; GetImageFilePath
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
GetImageFilePath proc uses ebx esi edi peProcess:PVOID, pusImageFilePath:PUNICODE_STRING
;
; This routine returns a fool path to image file of the process.
; Caller of this routine must be running at IRQL = PASSIVE_LEVEL.
; If siccessful the caller of this routine must call ExFreePool
; on pusImageFilePath->Buffer when it is no longer needed.
; peProcess must be valid pointer to EPROCESS
;
local status:NTSTATUS
local pSection:PVOID ; PTR SECTION
local usDosName:UNICODE_STRING
mov status, STATUS_UNSUCCESSFUL
; Check object type and reference it for shure
;
; In ObReferenceObjectByPointer description DDK stands that ObjectType can be
; either [IoFileObjectType] or [ExEventObjectType]. It's not true!
; It can be valid pointer to any ObjectType: [PsProcessType], [PsJobType],
; [MmSectionObjectType], [ExWindowStationObjectType] etc...
;
; BUT !
;
; If KernelMode specified in AccessMode parameter, ObReferenceObjectByPointer doesn't
; check object type at all !!!
;
; So, calling it this way, for example, will be successful !!!
; (with only one exception for not exported ObpSymbolicLinkObjectType)
;
; mov ecx, ExWindowStationObjectType
; mov ecx, [ecx]
; mov ecx, [ecx]
; invoke ObReferenceObjectByPointer, peProcess, 12345678h, ecx, KernelMode
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -