4.流程控制类
我曾经教过一个小DD写脚本,他老是把OD的运行流程和ODbgScript的流程搞混淆了,这个概念要
弄清除,作为新手常常弄不清这两个概念,而这两个概念是必须要弄明白的!要知道ODbgScript是一个
脚本插件,它执行脚本的流程,靠脚本运行过程中各种返回值/计算值判断后,修改/控制/影响OD的流程.
还是打个比方吧:
ODbgScript是铁路传感/信号/道岔控制系统,OD就是列车,而各种返回值就是各种信号灯和传感器,列车
的运行过程中,传感器系统不断的给出列车的各种运行状态,而ODbgScript就根据这些运行状态来调相
应的运行时刻表让列车在控制的范围内运行.那么ODbgScript控制道岔系统就完成了一趟完整的调度系统.
大家都坐过火车吧??你喜欢的是打着信号灯的铁道工人?还是现代化的排灯/道岔控制系统???
对应上一章的中断系统,我们又换概念打比方了(呵呵,对于新手我还是感觉自己有自己的一套办法来教
大家弄清这些的),断点在这里就是在铁轨上的信号灯,传感器它感受到了列车(OD)到这里了,马上给控制系统
(ODbgScript)发回信号,控制系统知道列车在什么位置后,相应的控制---信号灯/道岔系统,列车就乖乖的
听从我们的调度来运行了.脚本其实就是列车时刻表!!!而脚本内的标号就是所管理的机务段!
邓爷爷说:实现四个现代化,靠的是科技!
hnhuqiong说:OD逆向实现自动化,靠的是ODbgScript! (被愤怒的群众痛殴中!!!)
-----ODbgScript流程控制类
EOB :在下次中断发生时,跳转到指定标签处
COB :发生中断后,让脚本继续执行(移除EOB指令)
EOE :在下次异常发生时,跳转到指定标签处
COE :发生异常后,让脚本继续执行(移除EOE指令)
JA :大于则跳到指定标签处,在cmp命令后使用
JAE :大于等于则跳到指定标签处
JB :小于则跳到指定标签处,在cmp命令后使用
JBE :小于等于则跳到指定标签处
JE :等于则跳到指定标签处
JNE :不等于则跳到指定标签处
JMP :跳转到指定标签.
PAUSE :暂停脚本运行
RET :退出脚本
-----OD流程控制类
RUN :相当于在OllyDbg中按 F9
GO :执行到指定地址处 F4
ESTI :相当于在OllyDbg按 SHIFT-F7
ESTO :相当于在OllyDbg按 SHIFT-F9
STI :单步步入,相当于在OllyDbg中按 F7
STO :单步步过,相当于在OllyDbg中按 F8
RTR :相当于在OllyDbg中执行 "Run to return"操作 [Ctrl+F9]
RTU :相当于在OllyDbg中执行 "Run to user code"操作 [Alt+F9]
AI :在OllyDbg中执行“自动步入” [Animate into]操作 [Ctrl+F7]
AO :在OllyDbg中执行“自动步过” [Animate over]操作 [Ctrl+F8]
TI :相当于在OllyDbg中执行 "Trace into" 操作 [Ctrl+F11]
TO :相当于在OllyDbg中执行 "Trace over" 操作 [Ctrl+F12]
TICND :执行 "Trace into" 操作,直到条件为真时停止
TOCND :执行 "Trace over" 操作,直到条件为真时停止
TC :关闭Trace
LBL :在指定地址处插入一个标签
现在大家明白了ODbgScript可以给我们带来多少便利了吧????概念恐怕大家已清楚了,就不多讲解了.
其实,这些都是自动控制专业范围内的东西,刚好我本科是这个专业,所以比较轻车熟路. :)
现代化社会这些自动控制无所不在,只是你用上了却不一定留心它!
用一个复杂一点的脚本示意图我们简单的来进行类比,让大家牢牢记住它的(感谢FLY的FSG V1.X-2.X脚本)
5.计算和寄存器操作类
有了刚才的概念,那么这里的计算概念就好办了,这些都是ODbgScript内的计算.这里就不多讲解了.
就是现在命令有点少,我争取在下一个版本加多命令,这样调度起来不至于不会计算了,只好上铁轨手工
操作了..
INC :对变量进行加一操作
ADD :源操作数与目的操作数相加,并把相加的结果保存到目的操作数中
DEC :对变量进行减一操作
SUB :和汇编里的sub一样,两个数相减
AND :源操作数与目的操作数进行逻辑与操作,并将结果保存到到目的操作数中
XOR :源操作数与目的操作数进行异或操作,并将结果保存到到目的操作数中
OR :源操作数和目的操作数做逻辑或操作,并将结果保存到到目的操作数中
SHL :左移目的操作数,n比特位;并将结果保存到到目的操作数中
SHR :右移目的操作数,n 比特位;并将结果保存到到目的操作数中
CMP :比较 目的操作数与源操作数的大小,和其对应的汇编指令作用相同, 现支持字符串比较
REV :字节反转.
MOV :将源操作数移动到目的操作数中
6.字符串操作类
LEN :获得字符串长度
FIND :从指定地址开始在内存中查找指定的内容
FINDOP :从指定地址开始查找指定一个指令,这个指令是以指定内容为开始的
FINDMEM :全内存中查找指定的内容
ATOI :转换一个字符到整数,返回结果保存到保留变量$RESULT中
ITOA :字符串进制转换
EVAL :计算含义变量的表达式
EXEC/ENDE :对当前调试进程,执行在EXEC和ENDE之间的指令
FILL :从指定地址处,填充指定长度的值
REPL :在指定地址开始,在指定长度字节内,用“替换字符串”替换“查找字符串”
SCMP :比较字符串,目的和源比
SCMPI :比较字符串,只不过是源和目的比
PREOP :获得当前地址的汇编指令
REF :交叉参考
OPCODE :反汇编当前指令
这里是一个很强技术概念类的类,为什么这样说呢?因为完全靠系统信息来定位断点是远远不够的,那么
我们必须寻找程序内的"特征代码串",这个和杀病毒软件是一个概念,杀病毒软件是怎么干活的??就是
搜索内存,找各个程序的可疑的"特征字符串或者特征码".和人的DNA一样,各个程序的DNA是不同的
但又有相同的地方这就是亲子鉴定中心赚钱的秘方 :).
从逆向角度来说,某个系列的加壳,加密软件它有它的一贯性,因为它的开发架构已经定死了,除非
它大规模推倒从来.这里我就自己创造一个叫法叫"程序的DNA"吧,这个不是我提出来的,很多大侠早就
提出了这个概念,比如FLY的"特定码",OPcode其实就那么多,但是就是这些,简简单单的OPcode就组成
了千千万万的程序,但有些东西是具有一贯性的,这个和生物学上的遗传概念一模一样.药剂学上有一个
东西叫生物试剂,就是利用生物的特定DNA来检测的.
一旦我们找到某个"程序的DNA",那么很多东西就简单多了,大侠级别的就是"程序DNA试剂工厂",
他们能够通过他们长年累月的积累总结出了大量的"程序DNA特征"检测手段,并且能够敏感的捕捉到
新的"程序DNA特征",这些才是逆向水平高低的所在.
为什么呢会这样呢?因为程序必须某时某刻要干某件事,这就注定了它的死结,大侠们能一眼就看明白
这段OPcode它是在干什么(这需要长年累月的积累),你要动态解码,那么你解码的一小节就是你的命门,
你要ANTi,你anti前必须做准备工作,这个准备工作就是命门等等诸如此类.你要干什么,我就在你要干什么
前定位你的"特征码",在你干什么前把你的手段给残废了(大侠们够残忍了吧?呜~~~我的ANTI,我的解码)
这就是矛和盾永远可以斗争的地方,我anti你,你定位我的ANTI,好,那么我要动态解码后才ANTI,
大侠就盯上你的动态解码的回写内存,我把我动态解码一段花了,那么,我用花特征分离出你的花.......
..逆向反ANTI的手段就是在你动手前我先动手!!!!这叫先发制人,一招快,招招快!!!!可怜程序它必须
按照列车时刻表来跑,最搞笑的是脱壳领域,有的大侠懒得理哪些大规模的ANTi了不费哪个劲脱你了,就干脆
写个小东西Loader带跑.穿透壳后用特征码一步步定位后patch掉,何必处处脱呢........
这里,我说了一通,大家可以看图一,第20行命令find eip,#fe??0f84#, 这个句话的含义就是寻找
特征字符串fe??0f84,而这个特征字符串是什么含义呢,??代表的是可以是Hex任何数, 说明被2.0版FSG保护程序
在第一次运行系统函数LoadlibraryA后,从这里取出ESP指针所指的内存地址,下断点后,就会出现了这个特征字符
码.这个是2.0版特有的.大侠们发现了它的这个特征码.它出一定会出现在被FSG2.0保护程序经过上面运行步
骤后的某个内存地址中.
大家是不是有点豁然开朗的感觉??
我们来分析一下轰动一时的特征串:
00B2C27C 68 A78FC31F PUSH 1FC38FA7
f9,改eip
00B7266A CALL 00B7267C
68A78FC31F就是在程序还没有启动运行的时候,就存在的一个特征字符串,它存在于加载到内存后
的地址00b2c27c上,大侠发现了它的这个BUG,就是在00b2c27c处,直接将列车扳道岔到00b7266a上,火
车一下子变轨到b7266a处,从而跳过了themida的验证.
我们用脚本来实现这个思想是什么样的?
var bugaddress1
var bugaddress2
find eip,#68A78FC31F# //查找<特征字符串>
mov bugadr1,$RESULT //保存查找到的地址
bphws bugaddress1,"x" //给bugaddress1处信号灯传感器系统下命令(断点)
run //列车放行,会被bugaddress1处的信号系统命令停下来
bchwc bugaddress1 //信号灯系统复位,但列车还是停在原位等待放行 :)
mov bugaddress2,b7266a //将b7266a的地址给变量
mov eip,bugaddress2 //扳轨改变列车时刻表,从bugaddress1-bugaddress2处的
//所有站点都不过了,直接走近道到bugaddress2.
//这下这些站点的"乘客"们傻眼了,被脚本指挥的列车拒载了.
esto //列车放行
这个特征字符串仅仅存在于themida的1.3.3.0中,而不是全系列的themida的特征字符串,但是这个思想只要有
了就容易了,可你是否具备了一眼就能从全系列themida中利用它的这个思想来定位它的<特征字符串>的能力,那就
需要你不断的加强你的功力了.其实1.3.3.0爆出这个BUG,各路大侠马上行动,先从1.3.3.0版本中定位b2c27c和
00b7266a地址处上下文中有什么可以进行再定位的地方,其实这就是这个系列的DNA指纹.从而一代枭雄轰然倒地!
而上面的脚本的bugaddress1,和bugaddress2就是大侠们利用ODbgScript来进行反复搜索的利器.
(习题,你能从1.3.3.0版本里面找到通用于1.3.3.5版bugaddress1的DNA指纹么?)