找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 12474|回复: 1

[纯VB仅支持XP]利用DKOM无视进程保护实现取得进程完整路径

[复制链接]

78

主题

190

回帖

9

精华

贵宾会员

积分
15605
发表于 2015-10-10 22:05:17 | 显示全部楼层 |阅读模式
本帖最后由 tangptr@126.com 于 2015-10-10 22:09 编辑

首先先说一下为什么仅支持XP,因为这段纯VB的代码使用了ZwSystemDebugControl,因此只能支持XP。
如果我们要用DKOM实现取得路径,势必要取得EPROCESS,而Ring3下取得EPROCESS只能通过查询句柄的方式,故我们构造函数ZwLookupProcessByProcessId来实现PsLookupProcessByProcessId的功能,代码如下
  1. Public Sub ZwLookupProcessByProcessId(ByVal ProcessId As Long, ByRef Process As Long)
  2. Dim st As Long
  3. Dim PID As Long
  4. Dim NumOfHandle As Long
  5. Dim i As Long
  6. st = 0
  7. Dim bytBuf() As Byte
  8. Dim arySize As Long: arySize = 1
  9. Do
  10.     ReDim bytBuf(arySize)
  11.     st = ZwQuerySystemInformation(SystemHandleInformation, VarPtr(bytBuf(0)), arySize, 0&)
  12.     If (Not NT_SUCCESS(st)) Then
  13.         If (st <> STATUS_INFO_LENGTH_MISMATCH) Then
  14.             Erase bytBuf
  15.             Exit Sub
  16.         End If
  17.     Else
  18.         Exit Do
  19.     End If
  20.     arySize = arySize * 2
  21.     ReDim bytBuf(arySize)
  22. Loop
  23. NumOfHandle = 0
  24. Call CopyMemory(VarPtr(NumOfHandle), VarPtr(bytBuf(0)), Len(NumOfHandle))
  25. Dim h_info() As SYSTEM_HANDLE_TABLE_ENTRY_INFO
  26. ReDim h_info(NumOfHandle)
  27. Call CopyMemory(VarPtr(h_info(0)), VarPtr(bytBuf(0)) + Len(NumOfHandle), Len(h_info(0)) * NumOfHandle)
  28. For i = LBound(h_info) To UBound(h_info)
  29.     With h_info(i)
  30.         ReadKernelMemory VarPtr(PID), .pObject + &H84, 4
  31.         If PID = ProcessId And .ObjectTypeIndex = 5 Then
  32.             Process = .pObject
  33.         End If
  34.     End With
  35. Next
  36. End Sub
复制代码

解决了EPROCESS的问题,接下来便是找到存储路径的位置,首先先查看EPROCESS的结构
  1. lkd> dt _EPROCESS 864b6da0
  2. nt!_EPROCESS
  3.    +0x000 Pcb              : _KPROCESS
  4.    +0x06c ProcessLock      : _EX_PUSH_LOCK
  5.    +0x070 CreateTime       : _LARGE_INTEGER 0x1d10357`475407e4
  6.    +0x078 ExitTime         : _LARGE_INTEGER 0x0
  7.    +0x080 RundownProtect   : _EX_RUNDOWN_REF
  8.    +0x084 UniqueProcessId  : 0x000009c0 Void
  9.    +0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x85f5f538 - 0x8604a208 ]
  10.    +0x090 QuotaUsage       : [3] 0x1e78
  11.    +0x09c QuotaPeak        : [3] 0x1fe0
  12.    +0x0a8 CommitCharge     : 0x463
  13.    +0x0ac PeakVirtualSize  : 0x53d9000
  14.    +0x0b0 VirtualSize      : 0x51b1000
  15.    +0x0b4 SessionProcessLinks : _LIST_ENTRY [ 0x85f5f564 - 0x8604a234 ]
  16.    +0x0bc DebugPort        : (null)
  17.    +0x0c0 ExceptionPort    : 0xe1009030 Void
  18.    +0x0c4 ObjectTable      : 0xe1df9f10 _HANDLE_TABLE
  19.    +0x0c8 Token            : _EX_FAST_REF
  20.    +0x0cc WorkingSetLock   : _FAST_MUTEX
  21.    +0x0ec WorkingSetPage   : 0x33b68
  22.    +0x0f0 AddressCreationLock : _FAST_MUTEX
  23.    +0x110 HyperSpaceLock   : 0
  24.    +0x114 ForkInProgress   : (null)
  25.    +0x118 HardwareTrigger  : 0
  26.    +0x11c VadRoot          : 0x85ded208 Void
  27.    +0x120 VadHint          : 0x85ded208 Void
  28.    +0x124 CloneRoot        : (null)
  29.    +0x128 NumberOfPrivatePages : 0x2e5
  30.    +0x12c NumberOfLockedPages : 0
  31.    +0x130 Win32Process     : 0xe1d51368 Void
  32.    +0x134 Job              : (null)
  33.    +0x138 SectionObject    : 0xe2092230 Void
  34.    +0x13c SectionBaseAddress : 0x00400000 Void
  35.    +0x140 QuotaBlock       : 0x863d3510 _EPROCESS_QUOTA_BLOCK
  36.    +0x144 WorkingSetWatch  : (null)
  37.    +0x148 Win32WindowStation : 0x00000038 Void
  38.    +0x14c InheritedFromUniqueProcessId : 0x000006d4 Void
  39.    +0x150 LdtInformation   : (null)
  40.    +0x154 VadFreeHint      : (null)
  41.    +0x158 VdmObjects       : (null)
  42.    +0x15c DeviceMap        : 0xe17a2928 Void
  43.    +0x160 PhysicalVadList  : _LIST_ENTRY [ 0x864b6f00 - 0x864b6f00 ]
  44.    +0x168 PageDirectoryPte : _HARDWARE_PTE
  45.    +0x168 Filler           : 0
  46.    +0x170 Session          : 0xf7b19000 Void
  47.    +0x174 ImageFileName    : [16]  "VB6.EXE"
  48.    +0x184 JobLinks         : _LIST_ENTRY [ 0x0 - 0x0 ]
  49.    +0x18c LockedPagesList  : (null)
  50.    +0x190 ThreadListHead   : _LIST_ENTRY [ 0x86383fd4 - 0x85f586bc ]
  51.    +0x198 SecurityPort     : (null)
  52.    +0x19c PaeTop           : 0xf7bb61e0 Void
  53.    +0x1a0 ActiveThreads    : 4
  54.    +0x1a4 GrantedAccess    : 0x1f0fff
  55.    +0x1a8 DefaultHardErrorProcessing : 0x8000
  56.    +0x1ac LastThreadExitStatus : 0n0
  57.    +0x1b0 Peb              : 0x7ffd4000 _PEB
  58.    +0x1b4 PrefetchTrace    : _EX_FAST_REF
  59.    +0x1b8 ReadOperationCount : _LARGE_INTEGER 0xc8
  60.    +0x1c0 WriteOperationCount : _LARGE_INTEGER 0x8
  61.    +0x1c8 OtherOperationCount : _LARGE_INTEGER 0x284
  62.    +0x1d0 ReadTransferCount : _LARGE_INTEGER 0x11bda
  63.    +0x1d8 WriteTransferCount : _LARGE_INTEGER 0xdd
  64.    +0x1e0 OtherTransferCount : _LARGE_INTEGER 0x1584
  65.    +0x1e8 CommitChargeLimit : 0
  66.    +0x1ec CommitChargePeak : 0x46a
  67.    +0x1f0 AweInfo          : (null)
  68.    +0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
  69.    +0x1f8 Vm               : _MMSUPPORT
  70.    +0x238 LastFaultCount   : 0
  71.    +0x23c ModifiedPageCount : 0x35b
  72.    +0x240 NumberOfVads     : 0xad
  73.    +0x244 JobStatus        : 0
  74.    +0x248 Flags            : 0xd0800
  75.    +0x248 CreateReported   : 0y0
  76.    +0x248 NoDebugInherit   : 0y0
  77.    +0x248 ProcessExiting   : 0y0
  78.    +0x248 ProcessDelete    : 0y0
  79.    +0x248 Wow64SplitPages  : 0y0
  80.    +0x248 VmDeleted        : 0y0
  81.    +0x248 OutswapEnabled   : 0y0
  82.    +0x248 Outswapped       : 0y0
  83.    +0x248 ForkFailed       : 0y0
  84.    +0x248 HasPhysicalVad   : 0y0
  85.    +0x248 AddressSpaceInitialized : 0y10
  86.    +0x248 SetTimerResolution : 0y0
  87.    +0x248 BreakOnTermination : 0y0
  88.    +0x248 SessionCreationUnderway : 0y0
  89.    +0x248 WriteWatch       : 0y0
  90.    +0x248 ProcessInSession : 0y1
  91.    +0x248 OverrideAddressSpace : 0y0
  92.    +0x248 HasAddressSpace  : 0y1
  93.    +0x248 LaunchPrefetched : 0y1
  94.    +0x248 InjectInpageErrors : 0y0
  95.    +0x248 VmTopDown        : 0y0
  96.    +0x248 Unused3          : 0y0
  97.    +0x248 Unused4          : 0y0
  98.    +0x248 VdmAllowed       : 0y0
  99.    +0x248 Unused           : 0y00000 (0)
  100.    +0x248 Unused1          : 0y0
  101.    +0x248 Unused2          : 0y0
  102.    +0x24c ExitStatus       : 0n259
  103.    +0x250 NextPageColor    : 0xeef5
  104.    +0x252 SubSystemMinorVersion : 0 ''
  105.    +0x253 SubSystemMajorVersion : 0x4 ''
  106.    +0x252 SubSystemVersion : 0x400
  107.    +0x254 PriorityClass    : 0x2 ''
  108.    +0x255 WorkingSetAcquiredUnsafe : 0 ''
  109.    +0x258 Cookie           : 0x46a1aed5
复制代码

注意偏移+0x1f4的位置,这是个嵌入EPROCESS的SE_AUDIT_PROCESS_CREATION_INFO结构体,这个结构体很简单,只包含一个指针,指向OBJECT_NAME_INFORMATION,这个结构体也很简单,只包含一个嵌入的UNICODE_STRING,结构查看结果如下:
  1. lkd> dt _SE_AUDIT_PROCESS_CREATION_INFO 864b6f94
  2. nt!_SE_AUDIT_PROCESS_CREATION_INFO
  3.    +0x000 ImageFileName    : 0x85dec4a8 _OBJECT_NAME_INFORMATION
  4. lkd> dt _OBJECT_NAME_INFORMATION 85dec4a8
  5. nt!_OBJECT_NAME_INFORMATION
  6.    +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路径,于是代码就很简单了,如下
  1. Public Sub NtPathToDosPath(ByVal NtPath As String, ByRef DosPath As String)
  2. Dim i As Long
  3. Dim DosDevice As String
  4. Dim MyNtPath As String
  5. MyNtPath = Space(255)
  6. For i = 65 To 26 + 65 Step 1
  7.     DosDevice = Chr(i) & ":"
  8.     If QueryDosDevice(DosDevice, MyNtPath, 64) Then
  9.         If Left(MyNtPath, Len(NtPath)) = NtPath Then
  10.             DosPath = DosDevice
  11.             Exit Sub
  12.         End If
  13.     End If
  14. Next i
  15. End Sub
复制代码

接下来就要从中取得UNICODE_STRING并根据UNICODE_STRING->Buffer取得字符串,代码如下
  1. Public Sub GetProcessImagePath(ByVal Process As Long, ByRef FilePath As String)
  2. Dim ObjName As Long
  3. Dim UniName As UNICODE_STRING
  4. Dim MyBuff() As Integer
  5. Dim TmpPath As String
  6. Dim NtDev As String, DosDev As String
  7. Dim FileName As String
  8. Dim i As Long
  9. ReadKernelMemory VarPtr(ObjName), Process + &H1F4, 4
  10. ReadKernelMemory VarPtr(UniName), ObjName, 8
  11. ReDim MyBuff(UniName.Length / 2 - 1)
  12. ReadKernelMemory VarPtr(MyBuff(0)), UniName.pBuffer, UniName.Length
  13. For i = 0 To UniName.Length / 2 - 1
  14.     TmpPath = TmpPath & ChrW(MyBuff(i))
  15. Next i
  16. SplitPath TmpPath, NtDev, FileName
  17. NtPathToDosPath NtDev, DosDev
  18. FilePath = DosDev & "" & FileName
  19. End Sub
复制代码

效果很不错,即便是带有进程保护的软件依旧能取得路径,比如Call Hook NtOpenProcess->ObOpenObjectByPointer的PCHunter。而且即便有汉字也能正确取得。如图所示:

Demo

Demo

只要修改硬编码,并编写一个读写内核内存的驱动程序,就可以通用于32位NT系列。
p.s:假设Hovi.Delphic还更新UTM4XP的话,强烈建议修改掉其获取进程路径的方式。改成我这样的{:soso_e113:}

GetPath.zip

180.77 KB, 下载次数: 2934

下载代码不回帖是一种很欠扁的行为

评分

参与人数 1水晶币 +10 收起 理由
Tesla.Angela + 10 淡定

查看全部评分

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2015-10-10 23:17:17 | 显示全部楼层
除了DAN.TENG之外想不到第二个词语。。。{:soso_e147:}
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表