[纯VB仅支持XP]利用DKOM无视进程保护实现取得进程完整路径
本帖最后由 tangptr@126.com 于 2015-10-10 22:09 编辑首先先说一下为什么仅支持XP,因为这段纯VB的代码使用了ZwSystemDebugControl,因此只能支持XP。
如果我们要用DKOM实现取得路径,势必要取得EPROCESS,而Ring3下取得EPROCESS只能通过查询句柄的方式,故我们构造函数ZwLookupProcessByProcessId来实现PsLookupProcessByProcessId的功能,代码如下
Public Sub ZwLookupProcessByProcessId(ByVal ProcessId As Long, ByRef Process As Long)
Dim st As Long
Dim PID As Long
Dim NumOfHandle As Long
Dim i As Long
st = 0
Dim bytBuf() As Byte
Dim arySize As Long: arySize = 1
Do
ReDim bytBuf(arySize)
st = ZwQuerySystemInformation(SystemHandleInformation, VarPtr(bytBuf(0)), arySize, 0&)
If (Not NT_SUCCESS(st)) Then
If (st <> STATUS_INFO_LENGTH_MISMATCH) Then
Erase bytBuf
Exit Sub
End If
Else
Exit Do
End If
arySize = arySize * 2
ReDim bytBuf(arySize)
Loop
NumOfHandle = 0
Call CopyMemory(VarPtr(NumOfHandle), VarPtr(bytBuf(0)), Len(NumOfHandle))
Dim h_info() As SYSTEM_HANDLE_TABLE_ENTRY_INFO
ReDim h_info(NumOfHandle)
Call CopyMemory(VarPtr(h_info(0)), VarPtr(bytBuf(0)) + Len(NumOfHandle), Len(h_info(0)) * NumOfHandle)
For i = LBound(h_info) To UBound(h_info)
With h_info(i)
ReadKernelMemory VarPtr(PID), .pObject + &H84, 4
If PID = ProcessId And .ObjectTypeIndex = 5 Then
Process = .pObject
End If
End With
Next
End Sub
解决了EPROCESS的问题,接下来便是找到存储路径的位置,首先先查看EPROCESS的结构
lkd> dt _EPROCESS 864b6da0
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x06c ProcessLock : _EX_PUSH_LOCK
+0x070 CreateTime : _LARGE_INTEGER 0x1d10357`475407e4
+0x078 ExitTime : _LARGE_INTEGER 0x0
+0x080 RundownProtect : _EX_RUNDOWN_REF
+0x084 UniqueProcessId: 0x000009c0 Void
+0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x85f5f538 - 0x8604a208 ]
+0x090 QuotaUsage : 0x1e78
+0x09c QuotaPeak : 0x1fe0
+0x0a8 CommitCharge : 0x463
+0x0ac PeakVirtualSize: 0x53d9000
+0x0b0 VirtualSize : 0x51b1000
+0x0b4 SessionProcessLinks : _LIST_ENTRY [ 0x85f5f564 - 0x8604a234 ]
+0x0bc DebugPort : (null)
+0x0c0 ExceptionPort : 0xe1009030 Void
+0x0c4 ObjectTable : 0xe1df9f10 _HANDLE_TABLE
+0x0c8 Token : _EX_FAST_REF
+0x0cc WorkingSetLock : _FAST_MUTEX
+0x0ec WorkingSetPage : 0x33b68
+0x0f0 AddressCreationLock : _FAST_MUTEX
+0x110 HyperSpaceLock : 0
+0x114 ForkInProgress : (null)
+0x118 HardwareTrigger: 0
+0x11c VadRoot : 0x85ded208 Void
+0x120 VadHint : 0x85ded208 Void
+0x124 CloneRoot : (null)
+0x128 NumberOfPrivatePages : 0x2e5
+0x12c NumberOfLockedPages : 0
+0x130 Win32Process : 0xe1d51368 Void
+0x134 Job : (null)
+0x138 SectionObject : 0xe2092230 Void
+0x13c SectionBaseAddress : 0x00400000 Void
+0x140 QuotaBlock : 0x863d3510 _EPROCESS_QUOTA_BLOCK
+0x144 WorkingSetWatch: (null)
+0x148 Win32WindowStation : 0x00000038 Void
+0x14c InheritedFromUniqueProcessId : 0x000006d4 Void
+0x150 LdtInformation : (null)
+0x154 VadFreeHint : (null)
+0x158 VdmObjects : (null)
+0x15c DeviceMap : 0xe17a2928 Void
+0x160 PhysicalVadList: _LIST_ENTRY [ 0x864b6f00 - 0x864b6f00 ]
+0x168 PageDirectoryPte : _HARDWARE_PTE
+0x168 Filler : 0
+0x170 Session : 0xf7b19000 Void
+0x174 ImageFileName : "VB6.EXE"
+0x184 JobLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x18c LockedPagesList: (null)
+0x190 ThreadListHead : _LIST_ENTRY [ 0x86383fd4 - 0x85f586bc ]
+0x198 SecurityPort : (null)
+0x19c PaeTop : 0xf7bb61e0 Void
+0x1a0 ActiveThreads : 4
+0x1a4 GrantedAccess : 0x1f0fff
+0x1a8 DefaultHardErrorProcessing : 0x8000
+0x1ac LastThreadExitStatus : 0n0
+0x1b0 Peb : 0x7ffd4000 _PEB
+0x1b4 PrefetchTrace : _EX_FAST_REF
+0x1b8 ReadOperationCount : _LARGE_INTEGER 0xc8
+0x1c0 WriteOperationCount : _LARGE_INTEGER 0x8
+0x1c8 OtherOperationCount : _LARGE_INTEGER 0x284
+0x1d0 ReadTransferCount : _LARGE_INTEGER 0x11bda
+0x1d8 WriteTransferCount : _LARGE_INTEGER 0xdd
+0x1e0 OtherTransferCount : _LARGE_INTEGER 0x1584
+0x1e8 CommitChargeLimit : 0
+0x1ec CommitChargePeak : 0x46a
+0x1f0 AweInfo : (null)
+0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
+0x1f8 Vm : _MMSUPPORT
+0x238 LastFaultCount : 0
+0x23c ModifiedPageCount : 0x35b
+0x240 NumberOfVads : 0xad
+0x244 JobStatus : 0
+0x248 Flags : 0xd0800
+0x248 CreateReported : 0y0
+0x248 NoDebugInherit : 0y0
+0x248 ProcessExiting : 0y0
+0x248 ProcessDelete : 0y0
+0x248 Wow64SplitPages: 0y0
+0x248 VmDeleted : 0y0
+0x248 OutswapEnabled : 0y0
+0x248 Outswapped : 0y0
+0x248 ForkFailed : 0y0
+0x248 HasPhysicalVad : 0y0
+0x248 AddressSpaceInitialized : 0y10
+0x248 SetTimerResolution : 0y0
+0x248 BreakOnTermination : 0y0
+0x248 SessionCreationUnderway : 0y0
+0x248 WriteWatch : 0y0
+0x248 ProcessInSession : 0y1
+0x248 OverrideAddressSpace : 0y0
+0x248 HasAddressSpace: 0y1
+0x248 LaunchPrefetched : 0y1
+0x248 InjectInpageErrors : 0y0
+0x248 VmTopDown : 0y0
+0x248 Unused3 : 0y0
+0x248 Unused4 : 0y0
+0x248 VdmAllowed : 0y0
+0x248 Unused : 0y00000 (0)
+0x248 Unused1 : 0y0
+0x248 Unused2 : 0y0
+0x24c ExitStatus : 0n259
+0x250 NextPageColor : 0xeef5
+0x252 SubSystemMinorVersion : 0 ''
+0x253 SubSystemMajorVersion : 0x4 ''
+0x252 SubSystemVersion : 0x400
+0x254 PriorityClass : 0x2 ''
+0x255 WorkingSetAcquiredUnsafe : 0 ''
+0x258 Cookie : 0x46a1aed5
注意偏移+0x1f4的位置,这是个嵌入EPROCESS的SE_AUDIT_PROCESS_CREATION_INFO结构体,这个结构体很简单,只包含一个指针,指向OBJECT_NAME_INFORMATION,这个结构体也很简单,只包含一个嵌入的UNICODE_STRING,结构查看结果如下:
lkd> dt _SE_AUDIT_PROCESS_CREATION_INFO 864b6f94
nt!_SE_AUDIT_PROCESS_CREATION_INFO
+0x000 ImageFileName : 0x85dec4a8 _OBJECT_NAME_INFORMATION
lkd> dt _OBJECT_NAME_INFORMATION 85dec4a8
nt!_OBJECT_NAME_INFORMATION
+0x000 Name : _UNICODE_STRING "\Device\HarddiskVolume1\Program Files\Microsoft Visual Studio\VB98\VB6.EXE"
大家可以看到,这个路径是NT风格的,至于如何从NT风格转换到DOS风格,Tesla.Angela发表过文章《[抄袭]发个兼容R3/R0的NtPathToDosPath+DosPathToNtPath(C语言版|A+W)》,其链接是http://www.m5home.com/bbs/thread-7622-1-1.html可以看出其根本原理是用Win32API函数QueryDosDevice函数从A枚举到Z,看看哪个符合NT路径,于是代码就很简单了,如下
Public Sub NtPathToDosPath(ByVal NtPath As String, ByRef DosPath As String)
Dim i As Long
Dim DosDevice As String
Dim MyNtPath As String
MyNtPath = Space(255)
For i = 65 To 26 + 65 Step 1
DosDevice = Chr(i) & ":"
If QueryDosDevice(DosDevice, MyNtPath, 64) Then
If Left(MyNtPath, Len(NtPath)) = NtPath Then
DosPath = DosDevice
Exit Sub
End If
End If
Next i
End Sub
接下来就要从中取得UNICODE_STRING并根据UNICODE_STRING->Buffer取得字符串,代码如下
Public Sub GetProcessImagePath(ByVal Process As Long, ByRef FilePath As String)
Dim ObjName As Long
Dim UniName As UNICODE_STRING
Dim MyBuff() As Integer
Dim TmpPath As String
Dim NtDev As String, DosDev As String
Dim FileName As String
Dim i As Long
ReadKernelMemory VarPtr(ObjName), Process + &H1F4, 4
ReadKernelMemory VarPtr(UniName), ObjName, 8
ReDim MyBuff(UniName.Length / 2 - 1)
ReadKernelMemory VarPtr(MyBuff(0)), UniName.pBuffer, UniName.Length
For i = 0 To UniName.Length / 2 - 1
TmpPath = TmpPath & ChrW(MyBuff(i))
Next i
SplitPath TmpPath, NtDev, FileName
NtPathToDosPath NtDev, DosDev
FilePath = DosDev & "\" & FileName
End Sub
效果很不错,即便是带有进程保护的软件依旧能取得路径,比如Call Hook NtOpenProcess->ObOpenObjectByPointer的PCHunter。而且即便有汉字也能正确取得。如图所示:
只要修改硬编码,并编写一个读写内核内存的驱动程序,就可以通用于32位NT系列。
p.s:假设Hovi.Delphic还更新UTM4XP的话,强烈建议修改掉其获取进程路径的方式。改成我这样的{:soso_e113:} 除了DAN.TENG之外想不到第二个词语。。。{:soso_e147:}
页:
[1]