Watermark Software 3.6 算法分析
本帖最后由 hahacker 于 2016-10-10 17:44 编辑1. 查壳,无壳,VC写的
2 下MessageBoxW断点,寻找判断注册成功的条件
用户名为邮箱,如果注册码和邮箱的MD5的32位小写的字符串是相同的,那么就是注册成功了。
3 以邮箱test@qq.com为用户名,则MD5的32位小写字符串为:
4 找关键CALL里面的验证
0041624B|.8B49 F8 mov ecx,dword ptr ds: ;假码长度
0041624E|.8D71 FF lea esi,dword ptr ds: ;最后一位
00416251|.85F6 test esi,esi
00416253|.C645 FC 01 mov byte ptr ss:,0x1
00416257|.7C 53 jl short Watermar.004162AC
00416259|>6A 01 /push 0x1
0041625B|.56 |push esi
0041625C|.8D45 08 |lea eax,dword ptr ss:
0041625F|.50 |push eax
00416260|.8BCB |mov ecx,ebx
00416262|.E8 3CE8FEFF |call Watermar.00404AA3
00416267|.FF30 |push dword ptr ds:
00416269|.C645 FC 02 |mov byte ptr ss:,0x2
0041626D|.E8 83BC0000 |call Watermar.00421EF5
00416272|.6A 09 |push 0x9
00416274|.59 |pop ecx ;ecx=9
00416275|.2BC8 |sub ecx,eax ;9减去假码倒序后的每一位
00416277|.51 |push ecx ;Watermar.00416228
00416278|.8D45 EC |lea eax,dword ptr ss:
0041627B|.68 70394300 |push Watermar.00433970 ;UNICODE "%d"
00416280|.50 |push eax
00416281|.E8 670CFFFF |call Watermar.00406EED ;转十进制
00416286|.83C4 10 |add esp,0x10
00416289|.8D4D 08 |lea ecx,dword ptr ss:
0041628C|.C645 FC 01 |mov byte ptr ss:,0x1
00416290|.E8 8DD6FEFF |call Watermar.00403922
00416295|.8B45 EC |mov eax,dword ptr ss:
00416298|.50 |push eax
00416299|.FF70 F8 |push dword ptr ds:
0041629C|.8D4D E8 |lea ecx,dword ptr ss:
0041629F|.E8 80E3FEFF |call Watermar.00404624 ;字符串连接功能,存入ebp-0x18处
004162A4|.4E |dec esi
004162A5|.^ 79 B2 \jns short Watermar.00416259
004162A7|.A1 64FA4300 mov eax,dword ptr ds:
004162AC|>8B4D E8 mov ecx,dword ptr ss: ;存入处理后字符串,进行下面的验证
004162AF|.8B79 F8 mov edi,dword ptr ds: ;邮箱
004162B2|.33F6 xor esi,esi
004162B4|.8945 08 mov dword ptr ss:,eax
004162B7|.8945 F0 mov dword ptr ss:,eax
004162BA|.85FF test edi,edi
004162BC|.C645 FC 04 mov byte ptr ss:,0x4
004162C0|.0F8E 9B000000 jle Watermar.00416361
004162C6|>6A 02 /push 0x2 ;每两位取一个字串
004162C8|.56 |push esi
004162C9|.8D45 E4 |lea eax,dword ptr ss:
004162CC|.50 |push eax
004162CD|.8D4D E8 |lea ecx,dword ptr ss:
004162D0|.E8 CEE7FEFF |call Watermar.00404AA3 ;取给定长度的字符串,这里取两位
004162D5|.50 |push eax
004162D6|.8D4D F0 |lea ecx,dword ptr ss:
004162D9|.C645 FC 05 |mov byte ptr ss:,0x5
004162DD|.E8 71E7FEFF |call Watermar.00404A53
004162E2|.8D4D E4 |lea ecx,dword ptr ss:
004162E5|.C645 FC 04 |mov byte ptr ss:,0x4
004162E9|.E8 34D6FEFF |call Watermar.00403922
004162EE|.68 20464300 |push Watermar.00434620 ; /String2 = "00"
004162F3|.FF75 F0 |push dword ptr ss: ; |String1 = "test@qq.com"
004162F6|.46 |inc esi ; |
004162F7|.46 |inc esi ; |
004162F8|.FF15 34224300 |call dword ptr ds:[<&KERNEL32.lstrcmpW>>; \lstrcmpW
004162FE|.85C0 |test eax,eax
00416300|.75 2B |jnz short Watermar.0041632D ;当弄两位时为00时,开始取三位
00416302|.6A 03 |push 0x3 ;每三位取一个字串
00416304|.56 |push esi
00416305|.8D45 E0 |lea eax,dword ptr ss:
00416308|.50 |push eax
00416309|.8D4D E8 |lea ecx,dword ptr ss:
0041630C|.E8 92E7FEFF |call Watermar.00404AA3 ;取给定长度的字符串,这里取三位
00416311|.50 |push eax
00416312|.8D4D F0 |lea ecx,dword ptr ss:
00416315|.C645 FC 06 |mov byte ptr ss:,0x6
00416319|.E8 35E7FEFF |call Watermar.00404A53
0041631E|.8D4D E0 |lea ecx,dword ptr ss:
00416321|.C645 FC 04 |mov byte ptr ss:,0x4
00416325|.E8 F8D5FEFF |call Watermar.00403922
0041632A|.83C6 03 |add esi,0x3
0041632D|>FF75 F0 |push dword ptr ss:
00416330|.E8 C0BB0000 |call Watermar.00421EF5 ;转十六进制
00416335|.50 |push eax
00416336|.8D45 EC |lea eax,dword ptr ss:
00416339|.68 18464300 |push Watermar.00434618 ;UNICODE "%c"
0041633E|.50 |push eax
0041633F|.E8 A90BFFFF |call Watermar.00406EED ;之后转字符
00416344|.8B45 EC |mov eax,dword ptr ss:
00416347|.83C4 10 |add esp,0x10
0041634A|.50 |push eax
0041634B|.FF70 F8 |push dword ptr ds:
0041634E|.8D4D 08 |lea ecx,dword ptr ss:
00416351|.E8 CEE2FEFF |call Watermar.00404624
00416356|.3BF7 |cmp esi,edi
00416358|.^ 0F8C 68FFFFFF \jl Watermar.004162C6
0041635E|.8B45 08 mov eax,dword ptr ss:
算法为:
如:123456为假码则
先倒序过来
654321
再用9减每一位
得 345678
每两位两位的取,遇到"00"开始就取三位,
本字符串中没有"00"
34,56,78
先转化为十六进制,再转化为字符
34=0x22 对应"
56=0x38 对应8
78=0x4e 对应N
组成"8N
和邮箱的MD5的32位小写比较
bf58432148b643a8b4c41c3901b81d1b
----------------------------------------------------
已知:
bf58432148b643a8b4c41c3901b81d1b
反推:
'b'对应十六进制的0x62
0x62对应十进制的98
9-xx=98
即xx = 01
再倒序过来
最后xx=10
'f'对应十六进制66
0x66=102
9-xx=102
即xx = 897
再倒序过来
最后xx=798
这里是三位数,所以加上00让程序取三位。
再倒序过来得到注册码
79899
'5'对应十六进制的0x35
0x35对应十进制的53
9-xx=53
即xx = 46
再倒序过来
最后xx=64
'8'对应十六进制的0x38
0x8对应十进制的56
9-xx=56
即xx = 43
再倒序过来
最后xx=34
那么前四位的注册码就是:
34647989910
当然这才只让前四位相同了,要想让32位字符串都相同,这样一个一个的反推当然不是办法,太费时费力,而且还容易出错,这个就要到编程来实现了。。。就分析到这里吧。。
写到最后:
请@wgz001 表哥指点下有没有错误,给点建设性的意见,还有一个就是想问下表哥和论坛的各位高手。有没有办法能快速实现VC系统函数的识别。
如本程序直接拉入OD里分析,IDA导出的MAP文件,对于很多函数还是识别不了,所以不使用MAP了,同样分析费时费力了,因为有些CALL XXX就是系统的函数,
如提取字符串,转十六进制什么的,这种函数如果再分析,真是吃力不讨好了,结果把本应该分析程序验证的时间也都用到没有实质性的体力活上面了。。
而且本身这个程序就简单,如果是复杂的算法,那就更费力了。
0041629F|.E8 80E3FEFF |call Watermar.00404624 ;字符串连接
00416330|.E8 C0BB0000 |call Watermar.00421EF5 ;转十六进制
就像上面的两个函数,貌似就是系统的API的函数,但是还要分析,一步一步的跟出来,才能猜测出来
具体功能是什么的,这太费力了,难道就只有使用IDA制作的sig文件,再MAP导出,OD加载来识别这一种方法吗?
主要是对IDA不熟,所以.....
所以求各位高手指点,谢谢。望@Sound 牛也给点实质性的方法。
wgz001 发表于 2016-10-10 19:40
分析的不错,这个算法我没仔细看,在对注册码解密处理后,跟用户名的MD5比较之前还有一个小小的处理,算是 ...
表哥是怎么识别这些函数的? 有没有使用插件或是MAP之类的,,如果只是单纯的分析,效率提高不上去啊。 only for win 32
自动从lib提取sig的IDA Plugin 还有一个是科锐的兄弟写的
我一般都是装了VS后 Copy lib 然后做成pat 最后转成sig,这样就能全部识别了 其他好方法识别 目前我还没发现。
路过帮顶,{:1_923:}{:1_1:} 分析的不错,这个算法我没仔细看,在对注册码解密处理后,跟用户名的MD5比较之前还有一个小小的处理,算是个小坑吧,你再看看 hahacker 发表于 2016-10-10 20:25
表哥是怎么识别这些函数的? 有没有使用插件或是MAP之类的,,如果只是单纯的分析,效率提高不上去啊。
同求高效识别方法 我只会猜猜简单的而已别当真 :loveliness: 一点都没看懂,不知道楼主是破解算法还是求助破解算法 Sound 发表于 2016-10-11 05:45
only for win 32
自动从lib提取sig的IDA Plugin 还有一个是科锐的兄弟写的
直接从运行库中提取inc ,lib wgz001 发表于 2016-10-10 20:52
同求高效识别方法 我只会猜猜简单的而已别当真
王公子谦虚了啊。。。期望您以后的大作,希望表哥多写分析文章啊,,不要成品、!!!哈哈。。主要是学习表哥的思路和方法。。。 Sound 发表于 2016-10-11 05:45
only for win 32
自动从lib提取sig的IDA Plugin 还有一个是科锐的兄弟写的
看来只有IDA这一种方法了,谢谢Sound牛指点。{:1_927:}
页:
[1]
2