首页
论坛
专栏
课程

[.NET平台] [讨论]对程序流程分析和优化熟悉的TX进来谈谈,如何对付switch做的混淆

2008-10-27 22:56 9170

[.NET平台] [讨论]对程序流程分析和优化熟悉的TX进来谈谈,如何对付switch做的混淆

2008-10-27 22:56
9170
siwtch混淆就是指利用switch指令将程序流程打乱(MSIL中的switch可以理解为C中的switch..case),然后利用一个int32常数变量,给该变量不同的值代表不同的执行顺序,最终保证原程序的正确执行。但这种混淆后的.net程序是无法反编译为高级语言的。

有没有熟悉这方面的朋友,谈谈反混淆有什么好的方法,或是好的算法。

示例代码如下:
L_0000: br.s L_004f
    L_0002: ldloc num2//num2就是switch的循环变量
    L_0006: switch (L_010e, L_0137, L_0165, L_0193, L_0089, ....//等等)
    L_004f: nop
   L_0050: ldc.i4 9//num2=9
    L_0055: stloc num2
    L_0059: br.s L_0002//跳回switch
    L_005b: ldsfld bool io::g
    L_0060: brtrue.s L_00d7
    L_0062: ldc.i4 14//num2=14
    L_0067: stloc num2
    L_006b: br.s L_0002//跳回switch

这种混淆对流程的影响可以在IDA 的流程图中看出来:


[公告]看雪20周年会 | 感恩有你,一路同行

上传的附件:
  • 1.JPG (163.59kb,538次下载)
最新回复 (15)
forgot 26 2008-10-27 23:14
2
0
只是个DFA吧,直接根据每个stloc num2得到流程不行吗

import re, string
s = '''
L_0000: br.s L_004f
L_0002: ldloc num2
L_0006: switch (L_010e, L_0137, L_0165, L_0193, L_0089, L_case5, L_case6, L_case7, L_case8, L_case9, L_case10, L_case11, L_case12, L_case13, L_case14)
L_004f: nop 
L_0050: ldc.i4 9
L_0055: stloc num2
L_0059: br.s L_0002
L_005b: ldsfld bool io::g
L_0060: brtrue.s L_00d7
L_0062: ldc.i4 14
L_0067: stloc num2
L_006b: br.s L_0002
'''
nl = '\n*L_[0-9a-f]+:\s+'
xl = '\n*L_([0-9a-f]+):\s+'
path = re.findall( xl + 'ldc.i4 (\d+)'
                 + nl + 'stloc num2'
                 + nl + 'br.s', s)
t, = re.findall(nl + 'switch \(([^\)]+)\)', s)
handlers = map(string.strip, t.split(','))
for i, j in path:
    print 'L_%s: br.s %s' % (i, handlers[int(j)])
#OUTPUT
#L_0050: br.s L_case9
#L_0062: br.s L_case14

贴的代码太少, 不知道具体是啥样, 按这个结果重写一下br.s就变成标准的流程混乱了
tankaiha 29 2008-10-28 12:26
3
0
我在一楼贴的代码,相对还有顺序可遵循,forgot给出的方法应该可行。但如果要通用,还得考虑更多情况。最基本的,要分辨原程序中真的switch和混淆软件后添加的switch,甚至有的switch中的跳转表、部分是真的,部分是后加上去的,这时就不能简单的把switch删除。

有时还有其它情况,下面再给个代码

   L_0001: ldc.i4 0x11//这里是首次跳进switch时num2的值
   L_0006:br L_007e  //如何确定这种首次跳转switch的指令?有时br会跳至switch之前,有时跳至switch之后。

   ...
    L_007e: stloc num2
    L_0082: ldloc num2
    L_0086: switch (L_0137, L_0035, L_02a6, L_02e3, L_01ea, L_034d, L_0286, //等等)
    L_0113: ldc.i4 9
    L_0118: stloc num2
    L_011c: call bool fw1EVUdHk05sAm1BhHQ.1E3tqPdlbHrwXtZ1nbw::m2f40ZKjNxjvXPpu1CDQ()
    L_0121: brtrue L_0082//存在不定的跳转情况
    L_0126: ldc.i4.0
    L_0127: stloc.1
    L_0128: ldc.i4 30
    L_012d: stloc num2
    L_0131: ldc.i4.1
    L_0132: brtrue L_0082// if(1==true) br,这种情况倒是好处理

   ...
    L_026b: ldc.i4 14
    L_0270: br L_0086//不经过num2,直接跳转
   ...
    L_037f: ldc.i4 11
    L_0384:br L_007E//不跳到L_0082了,先跳再给num2赋值

先列这么多,forgot给出出主意。
forgot 26 2008-10-28 16:04
4
0
复杂的情况需要生成一个树,结点类似 { next, branches, code },

相连的代码从一侧可以遍历,找到顺序出现的

ldc XX
stloc num2
ldloc num2
switch

可以判断是回归到 switch。fake jcc 可以通过遍历树发现后调整为 next。

关于条件跳转,不知道情况多复杂,如果只是个 call 人肉加个模式就行,否则就非常麻烦要分析堆栈。

即使真的 switch 也可能是个状态机,也能按这个整理。
okdodo 2 2008-11-4 14:44
5
0
写通用代码很难 修改下SAE针对性处理也可以
ccfer 13 2008-11-4 15:33
6
0
forgot同学也研究这玩意啊
海风月影 17 2008-11-4 15:44
7
0
原来TX=同学啊,我以为TX=腾讯
foxabu 13 2008-11-4 15:53
8
0
我来膜拜楼上所有牛s

‘只是个DFA吧,直接根据每个stloc num2得到流程不行吗 ’
我也是这么处理的,另外用那个PHX 跑一下优化各个prases好像也可以。但是可操作性不强,有些东西还是只有手动处理,这个库有BUG,经常莫名其妙raise exception..。其实Net下面反混淆感觉比x86简单多咯,又不需要考虑花指令,而且指令就这么一些,也不需要重定位,修正jcc offset也很简单,有几个现成的代码类库来处理,比起x86的那个xde貌似好很多。
互联网有用这种类似混淆技术的反混淆的工具以及文章。LZ有兴趣可以参阅一下。


膜拜fg,膜拜所有的人
xiaofu 8 2008-11-8 22:29
9
0
膜拜啊!膜拜啊
longsir 2008-11-24 16:36
10
0
okdodo:
对您的景仰如滔滔江水!
但我是个初学者,能否发那个修改过的SAE(源码)给我,学习下。
longsir_2008@163.com
lhhanlove 2008-12-8 05:56
11
0
forgot 看看这个代码,应该比较详细的啦.

    L_0000: br.s L_0057
    L_0002: ldloc num2
    L_0006: switch (L_028e, L_026b, L_01ec, L_00ba, L_0073, L_00a0, L_01d9, L_008d, L_0111, L_0303, L_02a1, L_015e, L_02c4, L_019a, L_0258, L_0241, L_013b, L_00e3, L_0206)
    L_0057: ldarg.0 
    L_0058: ldstr "filmid"
    L_005d: ldc.i4.0 
    L_005e: call int32 [Demo.Common]Demo.Common.DNTRequest::GetQueryInt(string, int32)
    L_0063: stfld int32 Demo.Web.film::filmID
    L_0068: ldc.i4 4
    L_006d: stloc num2
    L_0071: br.s L_0002
    L_0073: ldarg.0 
    L_0074: ldfld int32 Demo.Web.film::filmID
    L_0079: ldc.i4.0 
    L_007a: ble L_0308
    L_007f: ldc.i4 7
    L_0084: stloc num2
    L_0088: br L_0002
    L_008d: br L_020b
    L_0092: ldc.i4 5
    L_0097: stloc num2
    L_009b: br L_0002
    L_00a0: ldarg.0 
    L_00a1: ldfld int32 Demo.Web.film::provenanceID
    L_00a6: ldc.i4.0 
    L_00a7: ble L_0308
    L_00ac: ldc.i4 3
    L_00b1: stloc num2
    L_00b5: br L_0002
    L_00ba: br L_025d
    L_00bf: ldarg.0 
    L_00c0: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::secondClassDic
    L_00c5: ldarg.0 
    L_00c6: ldfld int32 Demo.Web.film::secondClassID
    L_00cb: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::get_Item(!0)
    L_00d0: stfld string Demo.Web.film::secondClass
    L_00d5: ldc.i4 0x11
    L_00da: stloc num2
    L_00de: br L_0002
    L_00e3: ldc.i4.1 
    L_00e4: br.s L_00e9
    L_00e6: ldc.i4.0 
    L_00e7: br.s L_00e9
    L_00e9: brfalse.s L_00eb
    L_00eb: br.s L_0092
    L_00ed: ldarg.0 
    L_00ee: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::topClassDic
    L_00f3: ldarg.0 
    L_00f4: ldfld int32 Demo.Web.film::topClassID
    L_00f9: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::get_Item(!0)
    L_00fe: stfld string Demo.Web.film::topClass
    L_0103: ldc.i4 8
    L_0108: stloc num2
    L_010c: br L_0002
    L_0111: br L_01de
    L_0116: ldarg.0 
    L_0117: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::provenanceDic
    L_011c: ldarg.0 
    L_011d: ldfld int32 Demo.Web.film::provenanceID
    L_0122: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::get_Item(!0)
    L_0127: stfld string Demo.Web.film::provenance
    L_012c: ret 
    L_012d: ldc.i4 0x10
    L_0132: stloc num2
    L_0136: br L_0002
    L_013b: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::topClassDic
    L_0140: ldarg.0 
    L_0141: ldfld int32 Demo.Web.film::topClassID
    L_0146: callvirt instance bool [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::ContainsKey(!0)
    L_014b: brfalse L_02c9
    L_0150: ldc.i4 11
    L_0155: stloc num2
    L_0159: br L_0002
    L_015e: br.s L_00ed
    L_0160: ldarg.0 
    L_0161: ldarg.0 
    L_0162: ldfld int32 Demo.Web.film::secondClassID
    L_0167: call class [Demo.Entity]Demo.Entity.FilmClassInfo [Demo.Vod]Demo.Vod.FilmClass::GetFilmClassInfo(int32)
    L_016c: callvirt instance string [Demo.Entity]Demo.Entity.FilmClassInfo::get_Name()
    L_0171: stfld string Demo.Web.film::secondClass
    L_0176: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::secondClassDic
    L_017b: ldarg.0 
    L_017c: ldfld int32 Demo.Web.film::secondClassID
    L_0181: ldarg.0 
    L_0182: ldfld string Demo.Web.film::secondClass
    L_0187: callvirt instance void [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::Add(!0, !1)
    L_018c: ldc.i4 13
    L_0191: stloc num2
    L_0195: br L_0002
    L_019a: br L_0092
    L_019f: ldarg.0 
    L_01a0: ldarg.0 
    L_01a1: ldfld int32 Demo.Web.film::provenanceID
    L_01a6: call class [Demo.Entity]Demo.Entity.FilmProvenanceInfo [Demo.Vod]Demo.Vod.FilmProvenance::GetFilmProvenanceInfo(int32)
    L_01ab: callvirt instance string [Demo.Entity]Demo.Entity.FilmProvenanceInfo::get_Name()
    L_01b0: stfld string Demo.Web.film::provenance
    L_01b5: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::provenanceDic
    L_01ba: ldarg.0 
    L_01bb: ldfld int32 Demo.Web.film::provenanceID
    L_01c0: ldarg.0 
    L_01c1: ldfld string Demo.Web.film::provenance
    L_01c6: callvirt instance void [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::Add(!0, !1)
    L_01cb: ldc.i4 6
    L_01d0: stloc num2
    L_01d4: br L_0002
    L_01d9: br L_0308
    L_01de: ldc.i4 2
    L_01e3: stloc num2
    L_01e7: br L_0002
    L_01ec: ldarg.0 
    L_01ed: ldfld int32 Demo.Web.film::secondClassID
    L_01f2: ldc.i4.0 
    L_01f3: ble L_0092
    L_01f8: ldc.i4 0x12
    L_01fd: stloc num2
    L_0201: br L_0002
    L_0206: br L_0293
    L_020b: ldarg.0 
    L_020c: call instance void Demo.Web.film::GetClassIDByFilmID()
    L_0211: ldarg.0 
    L_0212: ldarg.0 
    L_0213: ldfld int32 Demo.Web.film::filmID
    L_0218: call class [Demo.Entity]Demo.Entity.FilmInfo [Demo.Vod]Demo.Vod.Films::GetFilmInfo(int32)
    L_021d: stfld class [Demo.Entity]Demo.Entity.FilmInfo Demo.Web.film::filmInfo
    L_0222: ldarg.0 
    L_0223: ldarg.0 
    L_0224: ldfld class [Demo.Entity]Demo.Entity.FilmInfo Demo.Web.film::filmInfo
    L_0229: callvirt instance string [Demo.Entity]Demo.Entity.FilmInfo::get_Name()
    L_022e: stfld string [Demo.Vod]Demo.Vod.PageBase::pagetitle
    L_0233: ldc.i4 15
    L_0238: stloc num2
    L_023c: br L_0002
    L_0241: ldarg.0 
    L_0242: ldfld int32 Demo.Web.film::topClassID
    L_0247: ldc.i4.0 
    L_0248: ble.s L_01de
    L_024a: ldc.i4 14
    L_024f: stloc num2
    L_0253: br L_0002
    L_0258: br L_012d
    L_025d: ldc.i4 1
    L_0262: stloc num2
    L_0266: br L_0002
    L_026b: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::provenanceDic
    L_0270: ldarg.0 
    L_0271: ldfld int32 Demo.Web.film::provenanceID
    L_0276: callvirt instance bool [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::ContainsKey(!0)
    L_027b: brfalse L_019f
    L_0280: ldc.i4 0
    L_0285: stloc num2
    L_0289: br L_0002
    L_028e: br L_0116
    L_0293: ldc.i4 10
    L_0298: stloc num2
    L_029c: br L_0002
    L_02a1: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::secondClassDic
    L_02a6: ldarg.0 
    L_02a7: ldfld int32 Demo.Web.film::secondClassID
    L_02ac: callvirt instance bool [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::ContainsKey(!0)
    L_02b1: brfalse L_0160
    L_02b6: ldc.i4 12
    L_02bb: stloc num2
    L_02bf: br L_0002
    L_02c4: br L_00bf
    L_02c9: ldarg.0 
    L_02ca: ldarg.0 
    L_02cb: ldfld int32 Demo.Web.film::topClassID
    L_02d0: call class [Demo.Entity]Demo.Entity.FilmClassInfo [Demo.Vod]Demo.Vod.FilmClass::GetFilmClassInfo(int32)
    L_02d5: callvirt instance string [Demo.Entity]Demo.Entity.FilmClassInfo::get_Name()
    L_02da: stfld string Demo.Web.film::topClass
    L_02df: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::topClassDic
    L_02e4: ldarg.0 
    L_02e5: ldfld int32 Demo.Web.film::topClassID
    L_02ea: ldarg.0 
    L_02eb: ldfld string Demo.Web.film::topClass
    L_02f0: callvirt instance void [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::Add(!0, !1)
    L_02f5: ldc.i4 9
    L_02fa: stloc num2
    L_02fe: br L_0002
    L_0303: br L_01de
    L_0308: ret
forgot 26 2008-12-8 08:31
12
0
用re胡写了一个,贴个片段:

ldc 0 ble没处理,分支也没处理:D

L_0003: ldarg.0 
L_0004: ldstr "filmid"
L_0005: ldc.i4.0 
L_0006: call int32 [Demo.Common]Demo.Common.DNTRequest::GetQueryInt(string, int32)
L_0007: stfld int32 Demo.Web.film::filmID
L_0011: ldarg.0 
L_0012: ldfld int32 Demo.Web.film::filmID
L_0013: ldc.i4.0 
L_0014: ble L_0180
L_0117: ldarg.0 
L_0118: call instance void Demo.Web.film::GetClassIDByFilmID()
L_0119: ldarg.0 
L_0120: ldarg.0 
L_0121: ldfld int32 Demo.Web.film::filmID
L_0122: call class [Demo.Entity]Demo.Entity.FilmInfo [Demo.Vod]Demo.Vod.Films::GetFilmInfo(int32)
L_0123: stfld class [Demo.Entity]Demo.Entity.FilmInfo Demo.Web.film::filmInfo
L_0124: ldarg.0 
L_0125: ldarg.0 
L_0126: ldfld class [Demo.Entity]Demo.Entity.FilmInfo Demo.Web.film::filmInfo
L_0127: callvirt instance string [Demo.Entity]Demo.Entity.FilmInfo::get_Name()
L_0128: stfld string [Demo.Vod]Demo.Vod.PageBase::pagetitle
L_0132: ldarg.0 
L_0133: ldfld int32 Demo.Web.film::topClassID
L_0134: ldc.i4.0 
L_0135: ble.s L_0106
L_0065: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::topClassDic
L_0066: ldarg.0 
L_0067: ldfld int32 Demo.Web.film::topClassID
L_0068: callvirt instance bool [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::ContainsKey(!0)
L_0069: brfalse L_0164
L_0045: ldarg.0 
L_0046: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::topClassDic
L_0047: ldarg.0 
L_0048: ldfld int32 Demo.Web.film::topClassID
L_0049: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::get_Item(!0)
L_0050: stfld string Demo.Web.film::topClass
L_0109: ldarg.0 
L_0110: ldfld int32 Demo.Web.film::secondClassID
L_0111: ldc.i4.0 
L_0112: ble L_0019
L_0155: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::secondClassDic
L_0156: ldarg.0 
L_0157: ldfld int32 Demo.Web.film::secondClassID
L_0158: callvirt instance bool [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::ContainsKey(!0)
L_0159: brfalse L_0074
L_0030: ldarg.0 
L_0031: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::secondClassDic
L_0032: ldarg.0 
L_0033: ldfld int32 Demo.Web.film::secondClassID
L_0034: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::get_Item(!0)
L_0035: stfld string Demo.Web.film::secondClass
L_0039: ldc.i4.1 
L_0043: brfalse.s L_0044
L_0022: ldarg.0 
L_0023: ldfld int32 Demo.Web.film::provenanceID
L_0024: ldc.i4.0 
L_0025: ble L_0180
L_0143: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::provenanceDic
L_0144: ldarg.0 
L_0145: ldfld int32 Demo.Web.film::provenanceID
L_0146: callvirt instance bool [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::ContainsKey(!0)
L_0147: brfalse L_0090
L_0055: ldarg.0 
L_0056: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string> [Demo.Vod]Demo.Vod.Caches::provenanceDic
L_0057: ldarg.0 
L_0058: ldfld int32 Demo.Web.film::provenanceID
L_0059: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::get_Item(!0)
L_0060: stfld string Demo.Web.film::provenance
L_0061: ret 
nbw 24 2008-12-8 09:35
13
0
膜拜啊   !
lhhanlove 2008-12-8 17:05
14
0
forgot 贴中所提到的re是什么?
forgot 26 2008-12-9 01:14
15
0
re=正则表达式
dreamzgj 2 2008-12-27 21:22
16
0
在些膜拜啊

8楼的牛人太强了 发的信息都搞夹带式隐藏啊

鼠标选中,有一段文字竟然隐藏着在,嘿嘿
游客
登录 | 注册 方可回帖
返回