敌敌畏过保护【3】【源码】
(负责讲师:天道酬勤)采用NewBulePil的框架改造而成基于VT技术的OllyDbg插件Ddvp随着软件产业的发展, 在Windows平台上, 为了防止软件被逆向, 破解, 出现了很多保护软件的手段, 其中一种就是反调试, 在反调试领域, 最强的莫过于在网络游戏方面.在网络游戏反调试上, 总是有一拨孜孜不倦的人, 不断的突破游戏公司的封锁, 而游戏公司又不断的改进反调试的方法.有没有一种一劳永逸的方法呢? 这时候VT技术进入了我的视野.这些反调试系统大致功能都是让OllyDbg不能调试, Cheat Engine( CE ) 不能查看搜索被保护程序的内存. 让人们无法逆向它们.对抗从来都没有停止过. 每当这些反调试公司研究出新的反调试手段的时候, 又不断的有人对它进行破解, 绕过. 过去的手段是每当出现一种新的保护的时候, 就要重复性的再破解一次. 而且每种游戏保护采用的手段虽然大致相同, 但是还是略有区别.这种状态一直持续到滴水公司出的DTDebug. 当时它们的调试器推出以后, 号称可以无视任何反调试. 根据我个人使用情况来看, 对于市面上常见的游戏保护是有效果的. 当然是2年前了. 最近据说一直没有更新. 被人提串了..
从DTDebug上面,Virtualization Technolegy(VT)技术进入我们的视野. 经过一段时间的研究, 我准备写点VT的东西出来, 最开始我写了一个基于VT技术的单机内核调试器, 算是对VT技术的演练. 后面我想, 为什么不写一个有实际应用的调试插件呢?写这个插件需要时间, 感谢cncert的王明华处长和李佳处长给的机会. 给我空间发挥. 于是我准备写一个Ollydbg的插件, 套上VT技术. 经过几个月码代码. 终于写的差不多了. 对于cncert来说. 写这个插件是一种研究性的目的. 而我也放弃了将这个插件商业化的想法. 所以项目搁浅.这里再重点说说cncert http://www.cert.org.cn/ 一直非常关注最前沿的安全技术, 为我们国家的安全事业做出了不可磨灭的贡献. 同时cncert刚成立的前沿网络安全技术实验室也是牛人的摇篮. 摆了一段时间以后, 有几个朋友想找个要源码过去观摩下,看到看雪论坛也放出来VT技术的项目, 这个提醒了我, 在我征得cncert的同意下. 我想还是把他开源吧, 还算能够给大家做点贡献. 烂在硬盘里面总归不是上策. 我把这个插件的名字叫Ddvp. Ddvp是敌敌畏的缩写, 显示这个插件调试Bug确实很厉害.
技术细节项目总共分成3部分. 分别是Ollydbg的插件部分. 调试函数调用界面. 和内核调试框架.
2.1 OllyDbg插件部分:这部分的代码主要是显示一个开启VT调试框,用于开启和关闭调试框架..目前开多个调试器也是支持的.也就是说可以运行多份调试器.
在选择开启调试引擎以后, 程序会枚举符号. 这个要看你网络的情况了. 如果中间一直处于枚举符号状态, 请检查网络. 并在任务管理器中停止程序, 重新开启.
2.1 调试函数调用界面:调试调用界面我写成的是一个DLL.DbgObj.dll 模拟了Windows和调试相关的大部分函数. 这些函数会以自己的方式进内核. 当时整这个DLL的时候, 我想到有一天可能在其他的地方使用, 比如Cheat Engine(CE)上面, 所以设计的还是比较满意的, 如果CE需要使用反调试框架, 那么只要勾住CE调用的函数使用我们DbgObj.dll中的函数就可以了. 细节请查看源码.
2.3 内核调试框架.这是整个项目的重点, 里面的内容也可以分成几部分. 重写Windows调试框架. 重载内核. VT技术. 我分别说下这几部分.
在重写Windows调试框架部分. 我没有用系统原来的DbugPort. 另外自己维护了一份调试器与被调试进程的结构. 在采集调试消息的时候, 都是走我们的例程.. 和Windows的DebugPort类似, 下面这个是我写的调试框架的DebugPort.
typedef struct tagDbgItem{LIST_ENTRYListEntry;PEPROCESS Debugger;ULONG_PTR DebuggerCr3;PEPROCESS Debugged;ULONG_PTRDebuggedCr3;ULONG Active;ULONG RefCount;ULONG ProcessFlags;NTSTATUS Status;BYTE Buffer;DEBUG_OBJECT DebugObject;DEBUGGED_THREAD DebuggedThread;} DBG_ITEM, *PDBG_ITEM;
细节方面, 请查看源码.
重载内核部分, 分成几步查找系统内核模块. 不是ntkrnlpa.exe就是ntoskrnl.exe, 其中之一映射内核文件重定位模块修复输入表, ( ntos 的输入表有3个DLL依赖项. 需要修复)修改新的内核SSDT表删除我们新的镜像PE头VT 技术方面, 因为VT技术比较新, 如果你对VT技术还不甚明白, 请先查看intel 文档. 中文不大好可以配合newbluepill那本书看, VT技术方面, 我使用它的下面几个特性.
重定向中断. 对于1号中断, 属于硬件中断, 我会在windows中搜索0x20一下的中断号给1号中断使用. 对于3号中断属于软中断, 随便在IDT中搜索一个空的就OK了.
MSR寄存器保护, 我在插件开启的时候会将MSR_IA32_SYSENTER_EIP 0x176 换掉, 换成我们实现的KiFastCallEntry. 在这里判断是否是我们需要出来的SSDT调用, 根据不同的SSDT调用我们转到不同的内核模块中. (我们重定位的模块, 或者是系统本身的模块)
VT技术还有很多特性, 比如CR寄存器访问, DR寄存器访问. 本来都想用上, 但是发现, 不行. 因为在CR寄存器访问, 和DR寄存器访问的时候, 我没有办法确定线程的运行上下文在那个进程, 线程环境中.. 所以针对Cr3的保护, 和DRx寄存器保护没有做.
另外还有一个比较遗憾的地方是, 本来我决定要给整一个无限断点的. 后面因为项目搁置没有弄. 绝对不是不会整. 另外一个是想写一个类似NewBluePill的内存隐藏. 如果给台硬件调试器, 可以试试.
后记如果你也想拿源码改改自己用, 那么你还需要再了解点东西, 首先代码大部分是在windbg+vmware双机调试下写出来的. 关于VT部分的代码是在bochs里面写出来的. Bochs很好很强大, 如果有时间真的应该把bochs的源码下载过来看看. 我在写VT的时候, 有些技术细节不懂的时候, 我就看看bochs的实现. 看看鞋子, 脚就懂了!
不过说到bochs的时候, 不得不说他这个东西非常的慢, 你需要一台非常好的电脑. 我的I7电脑运行起来依然慢的让我伤心.. 当然如果你有钱搞硬件调试器, 我就没话说了.
用bochs调试的时候在配置文件中加入这么一句 magic_break: enabled=1 那么遇到xchg bx, bx.. Bochs就会停下来, 类似windbg的. Int 3中断. 加入这么一句的时候, 在进入windows系统的时候, 好像windows的代码会不停的阻断在这个xchg bx, bx上面, 恶心至极. 在我恶心的受不了的时候. 我做出了改变. 改动了bochs的源码, 整个世界, 一瞬间清静了..下面这个帖子有告诉你bochs怎么开启VT. 怎么改变xchg bx, bx.http://www.joenchen.com/archives/801
用bochs安装系统也是一个折磨人的工作, 当然你不需要做了. 如果你需要windows xp sp3的系统, 或者win 7 的系统可以联系我给你传. 链接我就不放了. 免得你告我盗版..
另外一方面, 目前NP, HS的反调试除了对系统的一些检测以外, 还提取了OllyDbg的特征码. 我就好人做到底,送佛送到西. 下面的下载链接里面已经有一个完整可以运行的OllyDbg. 可以调试HS. 已经修改过特征码了. 我用的是网上的OllyDbg加强版改的. 版权该谁还是谁的.
代码编译编译代码请先设置$(WINDDK)环境变量设置成你自己安装的DDK目录. 因为要编译驱动. 运行代码请在Intel 的Cpu上. AMD的虚拟化没写. 倒…并且BIOS开启了VT技术.
Windows xp sp3系统, 最好原版安装的. 不要使用什么ghost的系统, 以免出现神奇的错误.
插件运行目前程序可以稳定的调试TP, HS的游戏, TP我测试的是dnf. HS测试的是冒险岛. StrongOD我已经设置好了. 不要随便去改动, 除非你自己知道在做什么..
另外请先开启调试器, 再开启游戏调试. 注意了. HS如果不先开启调试器, 并开启引擎. 那么是调试不了的..
需要自己支持其他的插件的话, 将插件的输入表修改成DdvpOD.EXE就可以了. 原本是OllyDbg.exe..
DdvpOD插件可以按Atl+Q呼出来, 或者自己在插件菜单开启, 首次运行的时候有可能需要枚举符号, 需要一点时间, 具体看你网络了. 目前只支持原版xp sp3系统, 其他的没有测试过.. 使用Intel的Cpu. AMD还不支持..
1. 首先你应该开启DebugView. 程序处于调试版本状态. 开启DebugView会有助于确定程序崩溃的地方.
2. 点击DdvpOD.exe开启程序. Ddvp已经以插件的形式提供给OD使用. 同时OD的特征码也被我修改过. 放心使用.
3. Alt+Q呼出插件(或者在插件菜单开启). 点击开启调试引擎. 开启调试引擎的时候, 容易出错, 请确定你是用的是windows xp sp3系统intel的cpu. 同时你的cpu支持VT技术, BIOS里面也已经开启.
4. 确认你的电脑处于联网状态, 首次运行需要联网枚举符号. 所以首次运行请联网..
程序组成结构:
原本OllyDbg.exe的东西, 我就不多说了. Ddvp在OD的目录下添加的文件作用我说一说..
这是基于VT技术的调试框架的R3函数实现,基本上都是模拟Windows的函数调用. 比如CreateProcess. DebugActiveProcess
2.DbgSys.sysDbgObj.dll启动以后会释放一个驱动文件在OD的主目录下面. 是负责调试框架的R0层..
3.Dichlorvos.dll这是开放给OD使用的插件, 符合OD插件编写规范. 这个插件主要的功能是现实开启调试框架界面, Hook OD的调试有关函数Hook以后走DbgObj.dll这边.
另外我修改了OD使用的DbgHelp.dll, OD自带的版本太旧了. 还有为了支持符号枚举, 添加了3个文件pingme.txt, symsrv.dll, symsrv.yes.这几个文件都是和符号枚举有关的.http://img.woaidaima.com//upload/image/20170106/1483668989878014374.pnghttp://img.woaidaima.com//upload/image/20170106/1483668989961068249.pnghttp://img.woaidaima.com//upload/image/20170106/1483668990444035360.png2012年10月10日 16:53:37:
恩, 0.01版本就算搭了个框架, 然后解决了视频显示的问题. 0.02版本, 我想我们可以朝着开启VT的方向发展了.即使不写VT. 现在知道了直接写
屏的方法还是挺高兴的, 当然直接写屏的方法简单, 难点在于控制像素显示, 控制字体显示. 想想Windows吧, 真的有一种想跪的感觉.2012年10月11日 14:18:34:中午忙了一中午, 没有写代码, 基本上就是弄工作了. 并且午睡了. 倒. 现在开始写进入VT的代码, 这边大部分还是看NewBluePill的来写, 不是
说没有其他的参考, 只是其他人写的代码实在是太烂了. 很多非常简单的错误都犯了. 他申请了内存不是忘记释放了. 而是从来就没有释放这么
一个概念, 比如代码是这样的. 最前面申请了内存, 完了下面有几个判断, 条件不成立就返回失败, 好几个判断里面一个释放内存的也没有, 假如
说少一个还说的过去, 是忘记了. 这么多都没有, 说明根本就没有把这个当回事情嘛.还有其他很多方面, 一看国人写的代码就觉得质量特别差, 其实我自己的也挺差的, 因为我看到人家的好, 所以我肯定知道我的不好了. 在这方面
应该再加强啊..刚才在NewBluePill里面也发现一处Bug. HvmSpitOutBluepill()函数里面忘记释放互斥锁了. KeReleaseMutex ( &g_HvmMutex, FALSE );
恩, 我应该把这个都记下来, 作为经验.2012年10月11日 17:12:37:
终于进入了VT的世界了. 这边我将这个VMCS的结构罗列下吧. 主要是参考两本书,
[系统虚拟化--原理与实现]/*
* 这里是按照Intel 手册描述的VMCS的数据区组成部分依次填写
* 详细信息参考[开发日志2].VMCS数据区总共6个组成部分. 分别是
*
* 1.客户区状态域(Guest State Area)
*
* 2.宿主机状态域(Host State Area )
*
* 3.虚拟机运行控制域( VM-Execuction Control Fields )
*
* 4.VMEntry行为控制域( VM-Entry Control Fields )
*
* 5.VMExit行为控制域( VM-Exit Control Fields )
*
* 6.VMExit相关信息域( VM-Exit Information Fields )(只读)
1.客户区状态域(Guest State Area): 1.1客户机寄存器状态内容(Guest Register State )
控制寄存器: CR0, CR3, CR4
调试寄存器: DR7
Esp, Eip, 和Eflags
CS, SS, DS, ES, FS, GS, LDTR, TR选择子, 基址, 段长, 属性
GDTR, IDTR, 基址, 段长
一些MSR寄存器的值, IA32_DEBUGCTL, IA32_SYSENTER_CS, IA32_SYSENTER_ESP,
IA32_SYSENTER_EIP,IA32_PERF_GLOBAL_CTRL, IA32_PAT, IA32_EFER
1.2客户机非寄存器状态内容(Guest Non-Register State )
活动性状态(Activity State):活跃的(Active), 中断的(hlt), 关闭的(Shutdown), 等待SIPI中断(Wait-for-SIPI)
只有活跃的可以自行Guest指令, 其他都表示发生错误
中断能力状态
推迟调试异常
VMCS连接指针(保留)
VMX抢占计时器
PDPTE项(开启了EPT模式会用到此域)PDPTE0-PDPTE32.宿主机状态域(Host State Area ):
这个域只存储Hypervisor的寄存器信息, 在发生#VMExit事件的时候恢复到相应寄存器
控制寄存器: CR0, CR3, CR4
Esp,Eip
CS, SS, DS, ES, FS, GS和TR寄存器, 选择子
FS, GS, TR, GDTR, IDTR信息, 基址
一些MSR寄存器, IA32_SYSENTER_CS, IA32_SYSENTER_ESP,
IA32_SYSENTER_EIP,IA32_PERF_GLOBAL_CTRL, IA32_PAT, IA32_EFER3.虚拟机运行控制域(VM-Execution Control Fields ):
这个域用来控制CPU在Non-Root模式下运行行为, 控制某条指令是否产生VM-Exit,还有异常
和中断的配置, 可以看出来, 这个地方很重要了. 要控制什么指令.中断, 异常.产生异常,就是配置这里 3.1基于针脚的虚拟机执行控制(Pin-Based VM-Execution Controls ):
管理中断等异步事件, 如果启用抢占计时器就是在这个域中设置的.
设置要参考IA32_VMX_PINBASED_CTLS和IA32_VMX_TRUE_PINBASED_CTLS两个MSR寄存器的值
3.2基于处理器的虚拟机执行控制(Processor-Based VM-Exection Controls ):
这里就是配置一些指令是否产生#VM-Exit事件的地方了, 还有师傅开启EPT地址翻译
开启VPID, 开启虚拟APIC
3.3异常位图(Exception Bitmap):
该域32位长, 每一位代表当某种异常发生时, 硬件会自动产生#VM-Exit时间, 如果某位
为0, 表示这个异常会通过IDT表正常处理. 要捕获异常就是这里了.当然缺页在另外地方配置
3.4IO位图地址(IO Bitmap Addresses ):
64位长的物理地址, 指向两块IO位图, 只有在Primary Processor-Based VM-Execution Controls.Use I/O
Bitmaps=1的情况下才会被使用. 在处理IO指令时根据位图相应产生#VM-Exit.地址要4K对齐
3.5时间戳计数器偏移(Time-Stamp Counter Offset ):
当Guest 利用RDTSC TDTSCP指令或者访问IA32_TIME_STAMP_COUNTER MSR寄存器的时候, 得到的结果是
真实的值+上这个偏移量的和
3.6虚拟机/Hypervisor屏蔽和 CR0/CR4访问隐藏设置:
这个域主要对CR0/CR4进行保护, 虚拟机/Hypervisor屏蔽中置位1的部分说明会产生#VM-Exit事件.
3.7 CR3访问控制.
包含最多4个CR3目标值, 如果是这几个CR3中的一个那么赋值CR3的时候不产生#VM-Exit
3.8 APIC访问控制:
VT技术对APIC的虚拟化, 这边先不管
3.9 MSR 位图地址(MSR Bitmap Address ):
指向MSR位图区域的物理地址, 当Primary Processor-Based VM-Execution Controls.Use MSR Bitmaps = 1
使用, MSR位图4K大小, 当配置好时, 相应的MSR访问会产生#VM-Exit.
3.10 执行体VMCS指针(Executive-VMCS Pointer ):
64位, 用于VT技术对系统管理中断(SMI)和系统管理模式(SMM)进行监管.
3.11 EPT指针( Extended Page Table Pointer ):
指向EPT页表的基地址(EPML4级页表的物理地址)以及一些EPT的配置信息.
当Secondary Processor-Based VM-Execution Controls.Enable EPT=1时启用.
3.12 虚拟机标识符(Virtual Processor Identifier, VPID):
虚拟机标识符16位长, 当Secondary Processor-Based VM-Execution Controls.Enable EPT=1时启用
4.VMEntry行为控制域( VM-Entry Control Fields ) :
定义在#VM-Entry事件发生后, 硬件要立即做的事情 4.1 #VM-Entry 基本操作控制设置
1.加载调试寄存器内容, (DR7, IA32_DEBUGCTL MSR 寄存器.
2.虚拟机是否进入x64模式, x86用于为0
3.进入系统管理模式
4.关闭Dual-Monitor Treatment
5.加载IA32_PERF_GLOBAL_CTRL MSR寄存器
6.加载IA32_PAT MSR寄存器
7.加载IA32_EFER MSR寄存器
4.2 #VM-Entry MSR寄存器操作控制设置
这个域可以配置在进入#VM-Entry的时候加载一些有关虚拟机状态的MSR寄存器.
4.3 #VM-Entry 注入事件控制设置
#VM-Entry可以在所有虚拟机状态恢复完毕后, 通过客户机IDT表触发一个中断.通过这个域配置5.VMExit行为控制域( VM-Exit Control Fields ):
定义在#VM-Exit事件发生后, 硬件要立即做的事情. 5.1 #VM-Exit 基本操作控制设置
1.保存调试寄存器内容, (DR7, IA32_DEBUGCTL MSR 寄存器.
2.Hypervisor地址空间大小(x86永远为0)
3.加载IA32_PERF_GLOBAL_CTRL MSR 寄存器
4.VMExit保留外部中断原因信息(Acknowledge Interrupt on Exit )
5.保存IA32_PAT MSR寄存器
6.加载IA32_PAT MSR寄存器
7.保存IA32_EFER MSR寄存器
8.加载IA32_EFER MSR寄存器
9.保存VMX抢占计时器值.
5.2 #VM-Exit MSR寄存器操作控制设置
和#VM-Entry类似6.VMExit相关信息域(只读区域) 6.1 #VM-Exit事件基本信息区(Basic VM-Exit Information):
1. 退出原因( Exit Reason)
2. 退出条件( Exit Qualification )
3. 客户机线性地址( Guest-Linear Address )
4. 客户机物理地址( Guest-Physical Address )
6.2 向量化事件 #VM-Exit 信息区(VM Exits Due to Vectored Events ):
1. #VM-Exit中断信息
2. #VM-Exit中断异常号
6.3 事件分发时#VM-Exit信息区(VM Exits Occur During Event Delivery):
1. IDT向量表信息
2. IDT向量表异常号
6.4 指令执行时VMExit信息区(VM Exits Due to Instruction Execution ):
1. VMExit指令长度
2. VMExit指令信息
6.5 VM指令错误信息区(VM Instruction Error Field ):
描述了执行虚拟机操作指令, 发生的最后一个Non-Faulting 错误的信息
*/是的人都可以看出来了. 信息比较多. 所以基本上这里也是一个难点, 能够最基本的开启VT以后, 那么这应该就算0.02版本了.
信息很多, 但是并不复杂, 基本上都是填字游戏..2012年10月12日 09:36:38:昨天基本没有做什么事情了.. 就是昨晚回去看了下, 工资条上面社保+个税居然2K多了. 诶. 太纠结了. 2K多.. 日.功能方面今天还是
填写VMCB中的信息结构吧. 又多又繁复, 这边千万不要急躁, 急躁了后面就会遇到问题, 出现知识断层..2012年10月15日 17:48:35:今天的工作基本上就是忙工作. 分析[无界], 都已经被拖壳的程序了. 还有什么难度. 直接就是耗时间了. 今天找到了无界打印日志的
地方. 差不多就是这样了. 无界是MFC写的标准程序, 现在就是对这个网络查找节点方面还不是很明白. 其他的我感觉难度都不大. 无界这种
程序为了躲避 大墙的封杀估计是用了一些猥琐的方法. 以前我对这个也没有什么研究, 只能慢慢来了..2012年10月23日 14:33:34:一下你看这么多天没有写VT代码了. 呵呵. 一方面忙工作, 另外一方面上个星期礼拜4的时候就去参加扩展培训了. 天融信是一个不错的公司,
后劲足. 在这里干一段时间就越来越想一直干下去. 挺好..另外一方面的话, 就是分析公司的[无界]了. 这个软件我现在已经分析出来50多个函数了. 只是一个时间问题而已. 只要慢慢来一定是有成果
的.调试VT代码的话, 必须用bochs, 这个软件的安装, 还有配置, 花了我不少时间, 关于bochs的代码编译什么的, 我都已经放在我的博客上面了.
这也花了一天的时间, 所以就到23号了.
页:
[1]