tangptr@126.com 发表于 2015-10-10 22:05:17

[纯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:}

Tesla.Angela 发表于 2015-10-10 23:17:17

除了DAN.TENG之外想不到第二个词语。。。{:soso_e147:}
页: [1]
查看完整版本: [纯VB仅支持XP]利用DKOM无视进程保护实现取得进程完整路径