发现论坛中很多兄弟在询问:什么是 2次内存断点 3次内存断点还有很多人对内存断点原理不是很明白其实只要懂得壳是如何解压代码那么就完全可以按自己喜欢来下断
本文要解决问题是:
1.什么是内存断点?
2.如何在寻找OEP时使用内存断点
3.内存断点局限性
2.内存断点寻找OEP原理
i.首先在OD中内存断点硬件断点和普通断点(F2下断)是有本质区别硬件断点等效和SoftICE命令bpm他中断要用到DR0-DR7调试寄存器也就是说OD通过这些DR0-DR7调试寄存器来判断是否断下
普通断点(F2下断)等效于bpx他是在所执行代码当前地址个字节修改为CC(3)当运行到3时候就会产生个异常而这个异常将交给OD处理把这个异常regEIP-1以后就正好停在了需要中断地方(这个根据系统区别会不样)同时OD在把上面3修改回原来代码
而内存断点基本上使用是对代码使用保护属性来实现中断
内存断点分为:内存访问断点内存写入断点
我们知道在运行时候会有3种基本状态产生:读取写入执行
004AE242 A100104000 moveax,dwordptrds:[004AE24C] //004AE24C处内存读取
004AE247 A300104000 movdwordptrds:[004AE24C],eax //004AE24C处内存写入
004AE24C 83C001 addeax,1 //004AE24C处内存执行
那么我们应该如何中断在上面几行呢?1.当我们对004AE24C下内存访问断点时候可以中断在004AE242也可以中断在004AE247
2.当我们对004AE24C下内存写入断点时候只能中断在004AE247
3.当我们对004AE24C下内存访问断点时候能中断在004AE24C
到这里你可能不明白了为什么内存访问断点能中断在004AE247这句对004AE24C写入而且还能中断在004AE24C执行呢?
其实很简单我们只要仔细体会下“内存访问”这 4个字含义遍可以知道当我们对004AE24C进行读取时候需要“访问”他吧当我对004AE24C进行写入时候也需要“访问”他吧!!当然我们要执行内存地址004AE24C代码时候也是还是要“访问”他!
所以我们不难得出下面结论:
1.内存写入中断地方定是也可以用内存访问中断
2.内存执行地方也可以用内存访问中断
如果这时你认为那么内存写入岂不是没用了呵呵~那我要告诉你当然不是如果你想快速准确定位到004AE247这行时候那么他就大有作用了!
整理总结下:内存断点不修改改原代码不会像普通断点那样修改代码被校验而导致中断失败;对于区段访问只是区域大了点其原理和上面分析 3行代码是样
ii.如何使用内存断点来寻找OEP呢?
要回答这个问题首先要回答这个问题:壳是如何解压代码?
正如我们知道壳如果要把原来加密或压缩代码运行起来就必须要解压和解密原来代码而这个过程我们难道不能将他看做是对代码段(code段)写入吗?好了解压完毕了我们要从壳代码区段JMP到原来代码段时候难道不正是对代码段(code段)执行吗?
理清了上面关系就好办了那么如果载入OD后我们直接对code段下内存访问断点时候定会中断在壳对code段写入代码上面就像上面004AE247这行而如果当他把code段代码全部解压解密完毕了以后JMP到OEP时候我们是不是还可以停在OEP代码上面呢?而且每按下F9都会中断这时code段在执行中哦!
相信很多人到这里已经明白了为什么在教程中到达了某个时候某行时候牛人们就叫我们对code段下内存访问断点了吧
而如果你还要继续问我为什么定要到那个地方才可以下断呢?我难道不可以开始就下断吗?
正入我上面所说如果你在前面下断很可能壳对code段还没解压完毕呢这时如果你不停按F9你将会看到OD下方不断在提示你“对401000写入中断”“对401002写入中断”“对401004写入中断”.......如果你不介意按F9到他把正个code段写完话我除了同情你“F9”以外没什么其他意见!
那么我们就没有别更快点办法了吗?
有!那就是我们呼的欲出两次内存断点办法
如何理解两次内存断点呢?
让我来做个假设吧假设我是个壳作者个EXE文件有code段data段rsrc段.....依次排列在你内存空间中那么我会如何解码呢?呵呵~我比较笨点我会先将code段解码然后再将data段解压接着是rsrc段......那么聪明你不难发现只要你在data断或者rsrc段下内存访问断点那么中断时候code段就已经解压完毕了这时我们再对code段下内存反问断点不就可以到达OEP了吗?
这里注意上面虽然下了两次内存访问断点但是本质是不样目也是不样
1.对data段下内存访问断点而中断是内存写入中断目是断在对对data段解压时这时壳要对data段写数据但是code段已经解压完毕
2.对code段下内存访问断点而中断是内存执行中断目当然就是寻找OEP了
整理总结下:如果我们知道壳在什么地方对code段解压完毕我们就可以使用内存断点找到OEP如果不知道那么我们就依靠2次内存断点去找如果还不行就用多次内存断点总的明白了原理在多次内存断点其实都样从这个过程中我们了解是壳在对区段解码顺序!
iii.实战
说了这么多我想大家都越越欲试了吧
好吧来弄个猛壳如何样:
注:本节例子有些难度不适合新手练习新手可以跳过这个例子学习等找到合适例子会补充上来
本节例子下载:unpackme.rar
这个壳是个hying旧版我们用他来实验下我们内存断点法
OD载入以后来到这里
0040D000u> 56 pushesi //这里
0040D001 52 pushedx
0040D002 51 pushecx
0040D003 53 pushebx
0040D004 55 pushebp
0040D005 E815010000 callunpackme.0040D11F
根据跟过次经验我们将先设置除3异常以外忽略其他异常SHIFT+F9003725B1 64:89250000000> mov fs:[0],esp
003725B8 CC 3
003725B9 90 nop //到这里
003725BA 8BCD movecx,ebp
然后再设置除“除零”异常外忽略其他异常SHIFT+F900372660 F7F3 divebx //到这里
00372662 90 nop
下面是很多单步异常太麻烦我们不管他现在开始用内存断点思路方法(记得将所有异常忽略)对code段下内存访问断点希望他已经解压完毕思路方法是按ALT+M键打开内存窗口在.code段按F2设断:
SHIFT+F9执行:
0040D19D A4 movsptres:[edi],ptrds:[esi] //还没解完呢
0040D19E B302 movbl,2
对data段下内存“写入”断点试试看他是不是要写data段00372712 F3:A4 repmovsptres:[edi],ptrds:[esi] //断到这里
00372714 5E popesi
下面再对code段下内存访问断点F900372855 8907 movdwordptrds:[edi],eax ;SHELL32.DragFinish //这里是对IAT加密地方了!!!
00372857 5A popedx
00372858 0FB642FF movzxeax,ptrds:[edx-1]
0037285C 03D0 addedx,eax
0037285E 42 incedx
0037285F 83C704 addedi,4
00372862 59 popecx
00372863 ^E2A9 loopd0037280E
00372865 ^E963FFFFFF jmp003727CD
0037286A 8BB593060000 movesi,dwordptrss:[ebp+693] //到这里下断F2
现在如果再对data下访问断点已经是没用了这时应该格外小心我们现在就想既然这段是对code解码那么我们就绕过他吧!
到0037286A下断F2然后清除内存断点!!!!
F9以后停在这里继续对code下内存访问断点
看看左下角还在解码哎~真是麻烦!
003728E1 /EB1D jmp00372900
003728E3 |25FFFFFF7F andeax,7FFFFFFF
003728E8 |038583060000 addeax,dwordptrss:[ebp+683]
003728EE |2B858F060000 subeax,dwordptrss:[ebp+68F]
003728F4 |8BDE movebx,esi
003728F6 |2BD8 subebx,eax
003728F8 |8958FC movdwordptrds:[eax-4],ebx //停在这里
003728FB |83C708 addedi,8
003728FE ^|EBDB jmp003728DB
00372900 64:FF3530000000 pushdwordptrfs:[30] //清除内存断点以后到这里下断F9
又是段解码代码再次使用上面办法手动跳出去现在继续对code段下内存访问断点!!F9以后到达这里
004010CC FFD7 calledi ;unpackme.004010CE //OEP哦
004010CE 58 popeax
004010CF 83EC44 subesp,44
004010D2 56 pushesi
004010D3 90 nop
004010D4 E8B518F7FF call0037298E
004010D9 8BF0 movesi,eax
呵呵~虽然不是我们熟悉OEP但是地址是没错了况且根据我们步骤我可以很肯定说这是code段第次“执行”中断!所以这就是OEP了
整理总结下:当我们在寻找OEP时候要多次对code下断“赌”“赌”他解压完毕如果不是就对别段试试~如果跑飞了那就没办法了重来呗~其实说起来要赌是:当data段idata段rsrc段摆在你面前你会好好“珍惜”那个段不过还好上天还会给我们从来次机会(ctrl+F2^_^)那么我们会对那个不会跑飞段说3个字----“先断你”如果非要在上面加个次数我希望是“次内存断点就好了”
vi.下面来讨论下内存断点局限性问题
是不是什么壳都可以用内存中断啊?
不是每个都可以些像UPX和ASPACK就不行
为什么?
呵呵~follewme!
情况1.
我们来看看UPX壳
首先他壳代码在UPX1段
这里是他要跳到OEP地方
0040ED4F /7711 jaNOTEPAD_.0040ED62
0040ED51 |01C3 addebx,eax
0040ED53 |8B03 moveax,dwordptrds:[ebx]
0040ED55 |86C4 xchgah,al
0040ED57 |C1C010 roleax,10 //在解码
0040ED5A |86C4 xchgah,al
0040ED5C |01F0 addeax,esi
0040ED5E |8903 movdwordptrds:[ebx],eax
0040ED60 ^|EBE2 jmpNOTEPAD_.0040ED44
0040ED62 240F andal,0F
0040ED64 C1E010 shleax,10
0040ED67 66:8B07 movax,wordptrds:[edi]
0040ED6A 83C702 addedi,2
0040ED6D ^EBE2 jmpNOTEPAD_.0040ED51 //回跳解码
0040ED6F 61 popad
0040ED70 -E95723FFFF jmpNOTEPAD_.004010CC //跳到OEP
我们看到他在对code段解压完毕时候马上就JMP到OEP去了那么我们根本就来不及使用内存断点办法你可能说我可以在
0040ED6F 61 popad//这句下段然后使用啊
呵呵~~当然可以不过你把花在下内存断点时间多按下几次F8不更好?!
也就是说当个壳如果他在JMP到OEP前行代码仍在都在对code段解压那么我们就不能再使用这种办法了!
或者说我们没必要使用内存断点更贴切点!
情况2.
对于些在OEP处有stolencode代码
我们来看看个OEP
0049E2F4u> 55 pushebp //OEP
0049E2F5 8BEC movebp,esp
0049E2F7 83C4F4 addesp,-0C
0049E2FA B8BCE04900 moveax,unpack.0049E0BC
0049E2FF E8048CF6FF callunpack.00406F08 //这里子
0049E304 A1B8FE4900 moveax,dwordptrds:[49FEB8]
0049E309 50 pusheax
0049E30A 6A00 push0
0049E30C 681F000F00 push0F001F
0049E311 E8E68EF6FF call<jmp.&kernel32.OpenFileMappingA> //API
0049E316 A360194A00 movdwordptrds:[4A1960],eax
0049E31B 833D60194A0000 cmpdwordptrds:[4A1960],0
这个软件Software在被PESPIN加壳了以后这些全被偷掉了!也就是说壳在模拟OEP代码时候必然会执行
0049E2FF E8048CF6FF callunpack.00406F08 //这步
而这个地方是call向code段如果我们使用内存访问断点那么就停在这个子地方
00406F08 50 pusheax //会停在这里
00406F09 6A00 push0
00406F0B E8F8FEFFFF call<jmp.&kernel32.GetModuleHandleA>
00406F10 BA04F14900 movedx,unpack.0049F104
00406F15 52 pushedx
这里既不是处理stolencode地方也不是FOEP地方这就会对我们判断产生误导当然你可以alt+F9返回到壳处理stolen地方然后用内存断点或者按几下F8到达FOEP处但试问如果你拿到个未知壳时候又如何知道应该这么处理呢?
还有其他些情况留给大家整理总结吧!
在下砖已抛出各位玉不久矣
--------------------------------------------------
3.整理总结
好了说了很多大家应该对内存断点办法有了全面了解如果了解了内存断点原理就不难明白他使用思路方法不难明白为什么有写壳不能使用内存断点办法其实任何种办法都需要经验积累相信如果大家在回答开篇3个问题已经不难了
大家可以结合原理再好好体会下手动脱壳进阶第 8篇Skvp1.32这篇文章
最新评论