敌敌畏过保护【3】【源码】

[复制链接]

该用户从未签到

2380

主题

2433

帖子

9139

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9139
QQ
跳转到指定楼层
楼主
发表于 2017-6-13 09:59:18 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

(负责讲师:天道酬勤)

采用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_ENTRY  ListEntry;
PEPROCESS   Debugger;
ULONG_PTR   DebuggerCr3;
PEPROCESS   Debugged;
ULONG_PTR  DebuggedCr3;
ULONG       Active;
ULONG    RefCount;
ULONG    ProcessFlags;
NTSTATUS    Status;
BYTE    Buffer[64];
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.sys
DbgObj.dll启动以后会释放一个驱动文件在OD的主目录下面. 是负责调试框架的R0层..

3.[Plugin]Dichlorvos.dll
这是开放给OD使用的插件, 符合OD插件编写规范. 这个插件主要的功能是现实开启调试框架界面, Hook OD的调试有关函数  Hook以后走DbgObj.dll这边.

另外我修改了OD使用的DbgHelp.dll, OD自带的版本太旧了. 还有为了支持符号枚举, 添加了3个文件pingme.txt, symsrv.dll, symsrv.yes.这几个文件都是和符号枚举有关的.
2012年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的结构罗列下吧. 主要是参考两本书, [NewBluePill深入理解硬件虚拟机]
[系统虚拟化--原理与实现]
/*
  * 这里是按照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-PDPTE3
2.宿主机状态域(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_EFER
3.虚拟机运行控制域(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[bit 25]=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[bit 28 ] = 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[bit 1]=1时启用.
  
3.12 虚拟机标识符(Virtual Processor Identifier, VPID):
  虚拟机标识符16位长, 当Secondary Processor-Based VM-Execution Controls.Enable EPT[bit 5]=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号了.

敌敌畏过保护【3】【源码】.txt

113 Bytes, 下载次数: 15

售价: 1 代码豆  [记录]

分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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