在应用层调试驱动程序 vgk.sys

***以下记录如何在应用层调试驱动程序vgk.sys,以及调试过程中获得的一些数据。

 

1,如何让vgk.sys 在应用层跑起来?

vgk.sys 是某游戏反作弊程序的一部分,是一个驱动文件;本文调试的vgk.sys 版本是1.0.0.3,64位。正常情况下,驱动程序需要在ring0环境中运行。但是vgk.sys 经过混淆虚拟化处理了,windbg双机调试/交互会很慢。之前在其他论坛上有人提起:可以在ring3调试驱动文件。于是,我就试了试。

 首先,看一下驱动程序和普通程序文件之间的相同点与不同点(大部分情况下):

相同点                                                                不同点

有一个入口函数 :DriverEntry/main                     驱动加载是会校验CheckSum

有导入表                                                             DriverEntry的参数类型是固定的,main可以变化

PE结构                                                                SubSystem(子系统),驱动是Native,应用程序                                                                              是console

                                                                            DllCharacteristics(文件属性),驱动程序更严格,                                                                              有 Code Intergrity Image 

vgk.sys的SubSystem和DllCharacteristics,如下图

 ntdll.dll的SubSystem和DllCharacteristics,如下图:

 知道了,驱动程序和应用程序之间的联系,就可以大胆的尝试:写个普通的PE加载器来运行vgk.sys,然后用WinDbg调试。

然后,vgk.sys 文件的处理:

    *清除OptionalHeader中CheckSum

    *将SubSystem设置为console

    *去掉Code Integrity Image属性

    *去掉导入表

     *去掉签名信息

最后,处理后vgk.sys 被加载到内存中,并调用其入口函数DriverEntry(DriverObject,RegistrPath),参数由应用程提供。后续的调试过程相当于模拟了一个ring0环境,各种数据都得有应用层提供了。

2,调试过程中相关的细节

好不容易把驱动程序跑起来了,接下来又要面对VMProtect。能力有限,无法写出反虚拟化程序,只能硬干。

VMProtect 处理后的代码如下:

(这简直不是人看到,让WinDbg看吧) 

一个handler,winDbg单步调试,按f10,按了一天才走完。VMProtect 防护确实厉害。这个版本里面,到目前为止发现了10个handler.各个handler内部结构有点类似(还需要深入研究)。如下图:

    

 handler内部用的非常多的跳转(jmp 指令),人肉去跟踪,基本不现实。控制流转移相关代码片段:

push+retn

 jmp register

   调试的过程中会遇到大量的内存访问异常(0xc0000005,access violation),这些地方都是关键点,会提供许多有用的信息;通过修改相应的寄存器值,使程序能够继续运行(保证逻辑正常)。

 ***###@@@¥¥¥%%%^^^&&&((()))___+++===---

vmprotect 使用了大量的花指令,使得ida 反汇编出错误的逻辑代码

   可以看到上图中,1到5的位置都是没有实际意义的花指令,这是经过人为设置后,ida 反汇编得到的结果。如果不进行设置,花指令的效果如0x1405c7a9b开始的代码可以看出,无法识别真正的逻辑;call handler6 前面应该是一个push 指令。手动设置后,如下图:

 

3,调试过程中获得到的一些数据:

   vgk.sys 前期会进行运行环境的检查,获取系统时间,系统目录等,会动态获取大量api地址;后期逻辑还没分析(不过看到api列表,对后面的逻辑应该有个大致掌握)。静态的导入函数截图如下:

 动态获取api函数列表如下:

KdDebuggerNotPresent
KdDebuggerEnabled
KdEnteredDebugger
PsProcessType
PsThreadType
MmUserProbeAddress
MmSectionObjectType
PsInitialSystemProcess
ExCreateCallback
KdChangeOption
ObfDerefenceObject
PsGetProcessDebugPort
PsCreateSystemThread
PsTerminateSystemThread
KeStackAttachProcess
KeUnStackDetachProcess
PsLookupProcessByProcessId
PsGetThreadId
ObOpenObjectByPointer
ObRegisterCallbacks
PsSetCreateProcessNotifyRoutine
PsSetCreateProcessNotifyRoutineEx
PsSetLoadImageNotifyRoutine
PsRemoveLoadImageNotifyRoutine
PsIsProtectedProcess
IoCreateSymbolicLink
PsGetProcessPeb
ZwLoadDriver
MmGetPhysicalMemoryRanges
MmGetPhysicalAddress
ZwQueryVirtualMemory
MmMapMemoryDumpMdl
ZwQueryInformationFile
ZwCreateSection
ExEnumHandleTable
ObGetObjectType
ExAcquireFastMutex
ExReleaseFastMutex
IoGetCurrentProcess
ZwClose
ZwQueryObject
ZwWaitFOrSingleObject
PsGetProcessImageFileName
ZwQuerySystemInformation
RtlInitUnicodeString
RtlFreeUnicodeString
ZwOpenKey
InitializeSListLink
FirstEntrySLint
ExpInterlockedPopEntrySList
ZwQueryInformationProcess
PsGetProcessWow64Process
KeInitializeApc
KeInsertQueueApc
KeTestAlertThread
RtlGetVersion
ZwCreateFile
ZwDeviceIoControlFile
KeDelayExecutionThread
ZwReadFile
IofCompleteRequest
IoDeleteDevice
IoDeleteSymbolicLink
IoRegisterShutdownNotification
IoUnregisterShutdownNotification
ExfUnblockPushLock
PsGetProcessId
PsGetProcessSectionBaseAddress
ZwQueryValueKey
IoCreateDevice
ZwWriteFile
IoGetInitialStack
PsLookupThreadByThreadId
IoGetDeviceObjectPointer
KeInitializeEvent
IoBuildDeviceIoControlRequest
IofCallDriver
ObfReferenceObject
RtlEqualUnicodeString
IoALlocateMdl
MmProbeAndLockPages
MmMapLockedPageSpecifyCache
MmProtectMdlSystemMdl
MmUnlockPages
IoFreeMdl
MmUnmapLockedPages
ExInitializeRundownProtection
ExWaitForRundownProtectionRelease
ExAcquireRundownProtection
ExReleaseRundownProtection
PsGetProcessSessionId
KeSetEvent
ExAcquierSpinlockExclusive
ExAcquireSpinLockShared
ExReleaseSpinLockExclusive
ExReleaseSpinLockShared
ExTryConvertSharedSpinLockExclusive
PsGetProcessExitProcessCalled
ObReferenceObjectByHandle
ZwMapViewOfSection
ZwUnmapViewOfSection
ZwOpenSection
ZwMakeTemporaryObject
KeIniGenericCall
KeReadStateTimer
KeInitializeTimer
KeSetTimer
KeCancelTimer
CmRegisterCallbackEx
CmUnRegisterCallback
ObQueryNameString
ZwSetValueKey
ZwDeleteValueKey
RtlStringFromGUID
swprintf_s
RtlInitAnsiString
RtlAnsiStringToUnicodeString
ExRegisterCallback
ExUnRegisterCallback
RtlDuplicateUnicodeString
RtlRandomEx
KeAreAllApcDisabled
HalPrivateDispatchTable
MmFreeContiguousMemorySpecifyCache
MmAllocateContigousMemorySpecifyCache
SeLocateProcessImageName
ZwTerminateProcess
ZwDisplayString
RtlAreBitsSet
RtlSetBits
KeQueryPriorityThread
KeSetPriorityThread
IoCreateFileEx
CiFreePolicyInfo
CiCheckSignedFile
CiVerifyHashInCatalog
BCryptOpenAlgorithmProvider
BCryptGetProperty
BCryptCrateHash
BCryptHashData
BCryptFinshHash
PsIsProtectedProcessLight
PsReleaseProcessExitSynchronization
ObFindHandleForObject

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值