首页
社区
课程
招聘
讨论:如何编程清理混淆代码?
发表于: 2006-4-25 20:28 7548

讨论:如何编程清理混淆代码?

2006-4-25 20:28
7548
这是themida vm的部分混淆后代码,第1列为原始代码,第2列未做修改,只去掉了完全无用的垃圾。第3列为简单合并后的代码。第4列为结果,只有6行。为了小点把dump出的东西贴在notepad上了,所以地址为4xxxxx。

这是硬看的,我想用程序实现,但想不出什么有效的办法从第1列得到第2列的结果。

我试过些笨办法,但效果不好

[课程]Linux pwn 探索篇!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (23)
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
2
我在教室,回去找点资料。

这种东西一般是难以逆向的。

1、去掉完全的垃圾。
2、按一定模式扫描。
想象如果你是这个meta的作者,你不会造出AI让程序自己变形吧?
所以还是有一定规律可循的,不过费人工啊。
3、把一些常规的替换都变成某一种,扫描模式的时候按照那种扫描。

4、实在不行还可以比较执行结果,做出同义指令?

看了看上面也是废话。

最厉害的可能是逐行理解了,这个说起来容易做来难。

我觉得他的vm是膨胀了好几次的结果,如果能找出替换类型一遍一遍shrink都是可以还原的。毕竟还没有AI。

以前看过一个meta自己有可逆函数expend/shrink

我考试脑子乱着呢,有时间我们细细讨论
2006-4-26 18:13
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
3
我试了试,还没有结果,时间精力有限 。forgot说的是MetaPHOR吗?我看了一点,太多了,头晕。不过,壳和病毒不同,我相信themida本身不会包含shrinker。

我试了一下:

纯粹的垃圾代码,基本是寄存器操作。可用的有eax/edx/ecx/ebx/ebp。

esp不能动的。esi和edi没有用。我试了一下按内存访问指令(mod != 11)把代码分成片,每次考虑一片,逆序往前处理。使用了esi/edi的,只要dst_set包含esi/edi应该不能清除。使用堆栈的不能清除。加上跟内存相关的,组合起来可以去掉大半。只要能到达文件中的第2列,就可以用上模式简化了。我觉得最麻烦的是第1步,也许正向expand的时候,是分析出空闲的寄存器来乱搞的,反过来就难了。不过这样也不是一般性的办法,只是凑合。

现在的结果还不好,有不少的误判。不过感觉可以继续。有点意思,慢慢玩了,不行也没关系。我脑子也乱着呢,喝了点。
2006-4-26 22:31
0
雪    币: 303
活跃值: (461)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
都是牛
2006-4-26 22:33
0
雪    币: 184
活跃值: (108)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
5
一步一步的攻,我感觉forgot对themida的判断是对的,就是它肯定有它的一个固定的套路,然后它自己做VM混淆代码的时候,就按照固定套路来做,就像以前各个壳抽代码(当然对于现在来说它们简单了),但是这个套路它只能这样的固定混淆的套路.现在的方向是在摸索它的套路上,而不是现在就简单的判定进行简单的程序还原.只要把它的套路的思维摸到了,那么,离它被完整肢解也不远了.

在对付VM上,最好是大牛们统一行动,拿一个具体的分析摸索,分解后分头摸套路,这样估计才有戏,否则,独自为战的年代看样子对付急剧膨胀的VM套路是不可能了.从现在来看,壳可以使用的后门越来越少,手段也快使的差不多了,它们的方向都在Vm上,而对于unpack来说,方向也应该在VM上.今后pack和unpack的斗争在VM上,我的感觉.近期拿到的强壳都是被VM顶回来不得要领.
2006-4-26 23:12
0
雪    币: 184
活跃值: (108)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
6
最初由 softworm 发布
也许正向expand的时候,是分析出空闲的寄存器来乱搞的.

我试了一下:

纯粹的垃圾代码,基本是寄存器操作。可用的有eax/edx/ecx/ebx/ebp。
........


刚才仔细的体会了一下你的思路,这上面这一句好像不太成立.空闲的寄存器不可能有AI智能分析的,它必须先分小段,在这个小段内,提取分析出什么寄存器是没用用到的,本身这样的方式从编程角度来说是合理的,剩下就好办了,爱怎么折腾怎么折腾.就是吧这段expand到1000000行也无所谓,反正就是来回倒腾.那么,核心思想应该是它"必须"分段,怎么分段,如何分段,才是关键的关键,抓它这一点!!!!不知道胡言乱语的对不对.你不是也有分段扫描的思路么?为什么你不逆向思考对方也是这样思考的??一句一句硬顶分析绝对不是出路.

BTW:它的分段不可能长,应该短到2个巴掌可以数的过来,否则,寄存器都给使用了,它所腾挪的空间就很小很小了.而只要明白了它的倒腾的目的就是乱你的视线,我假设拿到加壳软件,我们写一个连续的寄存器操作小程序,将所有的寄存器操作占满,加壳跟入VM后,它肯定能原形毕露,比如:
mov eax,1
mov ebx,1
.........
硬顶一次分析,看它是不是以分段模式来玩,就可以验证我的想法.

异想天开中:如果我想法正确,那么后面的事情就好办了,假设是6句为一个段.一遍一遍的扫,收缩后的代码能轻易的根据对称原则,拿掉无用代码.因为出来的6句带回到作者的思路来判定这样的分析出来的是否正确来进行验证.因为这六句中不能包含空闲的寄存器 我再说下去就思维混乱了
2006-4-27 00:03
0
雪    币: 184
活跃值: (108)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
7
给软虫折腾的不能睡觉,那么,只好爬起来继续,贴上来的东西,没法看,看压缩包吧,我要杀呢softworm.

Region01:004CA817    push    edx----------     这样的对称句中,堆栈操作那么肯定可以拿掉 *                 
Region01:00477AD6    mov     edx, 0         | 对称堆栈操作,edx属于无用寄存器,被用,保留看      +   
Region01:00477ADB    mov     eax, 95BFh  |            不明,保留           
Region01:00477AE0    add     edx, edi         | 对称堆栈操作,edx属于无用寄存器,被用,保留看      +                          
Region01:00477AE2    sub     esp, 4------|--                            +-对称句,拿掉      *         
Region01:00477AE8    mov     [esp], ebx--| |----                      对称句,拿掉      *
Region01:00477AEB    mov     ebx, 0         | |   | 对称操作,ebx属于无用寄存器,被用,保留看    +           
Region01:00477AF0    add     ebx, edx    | |   | 对称操作,edx,ebx属于无用寄存器,被用,保留看+
Region01:00477AF2    mov     esi, [ebx]  | |   | 对称操作,edx,ebx属于无用寄存器,被用,保留看+
                        mov        esi,[edi]| |   |
Region01:00477AF4    and     ah, bh      | |   |      不明,保留              
Region01:00477AF6    mov     ebx, [esp]--| |----                    +-对称句,拿掉      *
Region01:00477AF9    and     ch, cl      | |          不明,保留
Region01:0044DADB    add     esp, 4------|--                              对称句,拿掉      *         
Region01:0044DADE    pop     edx----------             这样的对称句中,那么肯定可以拿掉 *------而从简单判定来看,假设堆栈对称为这就是一个VM expand段.

上下分析,如果设想第一次为堆栈对称操作为一个 VM expand段,那么,第一轮扫描排除掉的对称操作有6句,
堆栈操作中,EDX应该是属于无用寄存器,那么,中间给使用判为过渡寄存器,给疑问
如果对称的寄存器为无用寄存器,中间又使用了,如果假设成立,那么esp,ebx都属于疑问寄存器.

将疑问寄存器edx,esp,ebx的句子都提出来,那么整理出来
成了如下的句子

mov edx,0
add edx,edi
mov ebx,0
add ebx,edx
mov esi,[ebx]

整理后,为  mov esi,[edi]
剩下的不明东西???你说它干什么,我们找找绿色和平组织会告诉我们干什么  :)

下面的如法炮制,那么结果呢 ???
                                                                                                      
Region01:0044DADF    mov     eax, 73D5h
Region01:0044DAE4    push    ebx-------------                 
Region01:0044DAE5    mov     ebx, 0Ch         |                 
Region01:0044DAEA    add     ebx, esi         |                 
Region01:0044DAEC    sub     ax, cx         |
Region01:0044DAEF    sub     esp, 4         |                 
Region01:0044DAF5    mov     [esp], edx     |   
Region01:0043AAAA    and     eax, edx       |
Region01:0043AAAC    mov     edx, 0         |                 
Region01:0043AAB1    xor     ah, ch         |
Region01:0043AAB3    add     edx, ebx       |       
Region01:0043AAB5    mov     cl, [edx]      |               
                        mov        cl,[esi+0Ch]|
Region01:0043AAB7    shr     al, 3          |
Region01:0043AABA    mov     edx, [esp]         |                 
Region01:0043AABD    add     esp, 4         |                 
Region01:0043AAC0    mov     al, dl         |
Region01:0043AAC2    pop     ebx-------------
上传的附件:
2006-4-27 01:38
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
8
总算考试完了,喝多了写得还真乱...

很多meta engine都有shrinker和expender,当然themida不可能有shrinker,难道给你一把枪让你枪毙它吗?

关于esp得一般都是简短的变化, not esp/not esp或者neg
还有xchg reg, esp/xchg reg, esp之类的

expending的时候不会分析reg的,因为分析不准确,起码也没有谁这么做过.
除非不是expending,根本就是building,这样程序会使用一个flag
选择寄存器之后标记其他为空闲,然后为所欲为...

还有一种情况就是约定,约定不使用什么寄存器,然后故意插入垃圾.
但是不使用什么分析比较难...这点先保留

我要特别强调,堆栈是一个重点,可以模拟执行,堆栈每次变化的时候都要比较寄存器的变化,一种是赋值/运算
特殊的譬如esi++/--&&edi++/--&&ecx--就是movsb/cmpsb之类的了.

怎么利用堆栈突破,还在想,最近被私事弄得很烦.
2006-4-27 11:11
0
雪    币: 184
活跃值: (108)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
9
我只是分析了softworm给的例子,都能很好的符合,而且分离出了softworm遗漏的二句nop,说明我的初步设想方向是对头的。

如果我是编程者,我思路上,先对应于成对句,分离出相对应的REG(非常好实现),然后利用这个reg进行操作,这样即不破坏现场,又能完成任务,否则不可测因素太多。

从softworm给出的例子上来看,比我昨天初步的想法要简单,原先我初步认为是以段来expand,现在看来是单句expand。
2006-4-27 11:21
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
10
expend能识别得范围有限,如果你写过应该发现只是一些简单的变换
expend也不能理解一段,那样的话也就是AI了

但是expend可以把一句变成一段,然后又可以把这一段变好几段
2006-4-27 11:26
0
雪    币: 184
活跃值: (108)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
11
我给出的分析中以就这样的现象,如NOP句,我感觉是,expand后又再次嵌套的结果是成了如我附件所列的样子。理论上反复嵌套的可能性很大,expand-》expand的难度在变大。
2006-4-27 11:36
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
12
例如mov eax, 123
可能被expend成为
pushfd
nop
mov eax, 100
nop
xor eax, 456
nop
xor eax, 789
nop
xor eax, 456
nop
xor eax, 789
nop
add eax, 23
nop
popfd

nop代表花花

然后里面的mov eax, 100又变成了另外一段
这样就识别不出来第一次变换
但是可以先shrink mov eax, 100
再次去掉花,就可以shrink原来得
可能两次变换得类型不一样
2006-4-27 11:57
0
雪    币: 184
活跃值: (108)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
13
你的这个设想完全可以实现而且实现起来方式简单,并且可以随意扩展到任意多行,而对于逆向来说,如何判断为最终代码就有点悬了。比如随机对expand代码进行expand几段,并不影响结果,而 shrink如何进行判断嵌套,这又是一个恶
2006-4-27 12:08
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
14
forgot在12楼的例子,可以用仿真方式合并成1句,这个我以前干过了,前提是能把中间以nop代表的垃圾清除掉。

我没有好的办法清除,只能尽量,土法上马。搜了一些相关文章,都理论性太强了,我看不懂。themida干嘛不把所有的壳代码都这么干呢

hnhuqiong的想法也很有意思。把pdb贴出来,彻底击溃你的睡眠。
对了,你文中认为是nop的,其实是变形的pop。491B21的pop抵消43AAC3和40E51A的2个push。
上传的附件:
2006-4-27 12:43
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
15
part 2
上传的附件:
2006-4-27 12:44
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
16
可能themida觉得太慢了,或者怕你脱不掉

好像有个engine叫做ETMS它生成得垃圾挺复杂的,有时间看看.

hnhuqiong 说得那个不是问题,当你的shrinker运行之后没变化就是原代码了
2006-4-27 13:23
0
雪    币: 184
活跃值: (108)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
17
最初由 softworm 发布
forgot在12楼的例子,可以用仿真方式合并成1句,这个我以前干过了,前提是能把中间以nop代表的垃圾清除掉。

我没有好的办法清除,只能尽量,土法上马。搜了一些相关文章,都理论性太强了,我看不懂。themida干嘛不把所有的壳代码都这么干呢

hnhuqiong的想法也很有意思。把pdb贴出来,彻底击溃你的睡眠。
........


i'll kill you!


我继续跟踪了大约7-8句,没用跳出我的设想,你有空再检查一下,里面有一句不在堆栈里面操作的,我漏了,打问号的,你一看就明白,打了问号,过的时候没用回头检查,刚刚想起来了.

重点突破口在堆栈操作上,方向有了,什么都好办了.
上传的附件:
2006-4-27 14:11
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
18
你的想法很有道理,从堆栈入手是个方向。我原来的做法出现一些漏报和错报。漏了junk code没关系,把有用的错误清除就不行了。

但是你这样还不算完成啊,看出junk code不算新鲜,要写程序清除才行啊。
2006-4-27 19:29
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
19
这就是定式得例子:

===================================================

nop会被翻译成

sub        esp, 4//这个可能会翻译成push [reg]
push        reg
mov        reg, esp
add        reg, 4
add        reg, 4
xchg        [esp], reg
pop        esp

中间还有垃圾

可以对比某两次堆栈变化得寄存器判断这种垃圾

===================================================

mov reg, [esp]
add esp, 4

如我所说, 我觉得确实有约定

好像某一段里edx dl dh eax al ah都是垃圾

某些有用寄存器出现在第二操作数上,也算是个小干扰

========
有些很绕得膨胀我人工分析都很难,何况程序...

某一段vm干扰之后得情况

eax垃圾
ecx=0xE0 似乎是从push/jmp那个值里计算出的表的某个index
edx垃圾
ebx=FFFFBD82,应该也是垃圾
esp没有变化
ebp=0xB8 不明
esi=[edi+44]=1310000+ecx=013100E0
edi没有变化
eip...

所以我还是坚持有个约定.
某些被约定垃圾得寄存器可视为垃圾!
2006-4-27 20:28
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
20
我爆炸了..............
2006-4-27 20:52
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
只要正向和逆向的
分析成本不对称
改进成本不对称
作者的目的就达到了
2006-4-28 00:07
0
雪    币: 184
活跃值: (108)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
22
最初由 softworm 发布
你的想法很有道理,从堆栈入手是个方向。我原来的做法出现一些漏报和错报。漏了junk code没关系,把有用的错误清除就不行了。

但是你这样还不算完成啊,看出junk code不算新鲜,要写程序清除才行啊。


是你求助,明明你说要写东西清除,怎么变成我的活了
加壳的noted放上来,我实验一下吧,看5-1有空不.
2006-4-28 10:38
0
雪    币: 184
活跃值: (108)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
23
最初由 xuanqing 发布
只要正向和逆向的
分析成本不对称
改进成本不对称
作者的目的就达到了


是的,可因为它是壳,依靠它所受益的软件就不计其数了,那么焦点就成了攻击壳的成本无论多大都有人会去逆向.ASP就是下场.

就是因为壳的技术上说,它所使用的手段大部分是可逆,那么现在壳的方向都转上了VM,做大量的反干扰分析,让分析陷入尴尬的地界,所以才有想让大牛出面找出方向,攻击现在流行的VM编码.
2006-4-28 10:48
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
24
最初由 hnhuqiong 发布
是你求助,明明你说要写东西清除,怎么变成我的活了
加壳的noted放上来,我实验一下吧,看5-1有空不.


这个你跟xuruifengc联系吧,我保证过的。实在抱歉!
2006-4-28 13:11
0
游客
登录 | 注册 方可回帖
返回
//