ExeIcon 3.6
算法一般,利用程序本身可以得到计算值,但是注册码比较的思路值得借鉴,又是拐弯抹角的又是虚晃一枪的,而且是一次又一次出现,不仅考验耐心,也考验“毅力”,差点儿崩溃。
最近脱壳很郁闷,以此文鼓励自己,纪念在看雪论坛上的百篇之作。
1.断点:
ASPack 2.001 -> Alexey Solodovnikov
Borland C++ 1999
不输入用户名提示:
00416F24 BA A8335300 mov edx,dump.005333A8 ; ASCII "Please input your Full Name!"
用户名长度要大于3:
00416EF2 E8 7D04FFFF call dump.00407374
00416EF7 83F8 03 cmp eax,3 ; yhm lenth
注册码长度要为24位或者40位:
0041739B E8 D4FFFEFF call dump.00407374
004173A0 83F8 18 cmp eax,18
004173A3 0F85 84000000 jnz dump.0041742D
0041742D 8D45 08 lea eax,dword ptr ss:[ebp+8]
00417430 E8 3FFFFEFF call dump.00407374
00417435 83F8 28 cmp eax,28
00417438 0F85 E1010000 jnz dump.0041761F
这样就先挑0041739B作为入手断点。
2.注册码长度为24位的算法过程:
004173D7 8B45 D4 mov eax,dword ptr ss:[ebp-2C]
004173DA 40 inc eax ; 初始值1,递增
004173DB B9 05000000 mov ecx,5
004173E0 99 cdq
004173E1 F7F9 idiv ecx
004173E3 85D2 test edx,edx ; 余数
004173E5 74 3D je short dump.00417424
004173E7 8B45 D4 mov eax,dword ptr ss:[ebp-2C]
004173EA 8A90 D0CF5400 mov dl,byte ptr ds:[eax+54CFD0] ; 0
004173F0 8B4D D4 mov ecx,dword ptr ss:[ebp-2C]
004173F3 32540D 94 xor dl,byte ptr ss:[ebp+ecx-6C] ; 与内置的字符串XOR
004173F7 0FBEC2 movsx eax,dl
004173FA 50 push eax
004173FB E8 6020FFFF call dump.00409460
00417400 59 pop ecx ; 字符
00417401 69C0 F00A0000 imul eax,eax,0AF0 ; ×0AF0
00417407 B9 1A000000 mov ecx,1A
0041740C 99 cdq
0041740D F7F9 idiv ecx ; /1A
0041740F 83C2 41 add edx,41 ; +41
00417412 8B45 D4 mov eax,dword ptr ss:[ebp-2C]
00417415 0FBE4C05 AC movsx ecx,byte ptr ss:[ebp+eax-54] ; zcm第1位
0041741A 3BD1 cmp edx,ecx ;
0041741C 74 06 je short dump.00417424
0041741E C645 DB 00 mov byte ptr ss:[ebp-25],0
00417422 EB 09 jmp short dump.0041742D
00417424 FF45 D4 inc dword ptr ss:[ebp-2C]
00417427 837D D4 14 cmp dword ptr ss:[ebp-2C],14
0041742B ^ 7C AA jl short dump.004173D7
内置字符串:
0012F828 31 7A 31 68 2B 32 61 30 6E 2D 30 67 38 79 2A 39 61 31 6E 7C 1z1h+2a0n-0g8y*9a1n|
顺取内置字符串(如果位数是5的倍数,则略过,再取下一位),×AF0/1A,余数+41,得到的值为注册码的1位,然后与顺取的注册码比较,相等就继续,不等就退出。
依次得到注册码:YMYA-QEGE-GIUU-MEYE
添加到24位:YMYA-QEGE-GIUU-MEYE-9999
但是程序不再对后面的几位计算比较,提示注册码还是错误的。
3.柳暗花明又一村:
于是反复跟踪发现有一个赋值,如果注册码为24位的话,都是0,这个0决定了跳转方向。
它就是:
004173CE C645 DB 00 mov byte ptr ss:[ebp-25],0 ; 赋值=0,12F86F
0041761F 8A45 DB mov al,byte ptr ss:[ebp-25] ; 12F86F
00416FA0 8882 86040000 mov byte ptr ds:[edx+486],al ; 00EC29F2
00416FBD 80B9 86040000 0>cmp byte ptr ds:[ecx+486],0 ; 00EC29F2
00416FC4 /0F84 75020000 je dump.0041723F ; 关键跳转
因此修改注册码为40位的:
8765432112345678876543211234567887654321
4.注册码为40位的算法过程:
这次内置字符串仍然是:
0041743E BE 8B335300 mov esi,dump.0053338B ; ASCII "1z1h+2a0n-0g8y*9a1n|"
4.1先判断注册码第2位是不是25,即%:
0041746F 0FBE8D 69FFFFFF movsx ecx,byte ptr ss:[ebp-97] ; ZCM第2位
00417476 83F9 25 cmp ecx,25
00417479 75 09 jnz short dump.00417484
0041747B C685 69FFFFFF 2>mov byte ptr ss:[ebp-97],23
00417482 EB 23 jmp short dump.004174A7
4.2然后开始运算:
004174C3 C645 DB 01 mov byte ptr ss:[ebp-25],1 ; 这个赋值太重要了
004174C7 C745 D0 02000000 mov dword ptr ss:[ebp-30],2 ; 2,指针
004174CE 8B55 D0 mov edx,dword ptr ss:[ebp-30]
004174D1 0FBE8C15 50FFFFFF movsx ecx,byte ptr ss:[ebp+edx-B0] ; 字符串第[指针+1]位
004174D9 8B45 D0 mov eax,dword ptr ss:[ebp-30] ; 指针
004174DC 0FBE9405 67FFFFFF movsx edx,byte ptr ss:[ebp+eax-99] ; 注册码第[指针]位
004174E4 03CA add ecx,edx ; +
004174E6 8B45 D0 mov eax,dword ptr ss:[ebp-30]
004174E9 0FBE9405 68FFFFFF movsx edx,byte ptr ss:[ebp+eax-98] ; 注册码第[指针+1]位
004174F1 33CA xor ecx,edx ; XOR
004174F3 8B45 D0 mov eax,dword ptr ss:[ebp-30]
004174F6 0FBE9405 50FFFFFF movsx edx,byte ptr ss:[ebp+eax-B0] ; 字符串第[指针+1]位
004174FE 33CA xor ecx,edx ; XOR
00417500 51 push ecx
00417501 E8 5A1FFFFF call dump.00409460
00417506 59 pop ecx
00417507 B9 1A000000 mov ecx,1A
0041750C 99 cdq
0041750D F7F9 idiv ecx ; /1A
0041750F 83C2 41 add edx,41 ; +41
00417512 8B45 D0 mov eax,dword ptr ss:[ebp-30]
00417515 0FBE8405 71FFFFFF movsx eax,byte ptr ss:[ebp+eax-8F] ; 第[指针+10]位注册码
0041751D 3BD0 cmp edx,eax
0041751F 74 06 je short dump.00417527
00417521 C645 DB 00 mov byte ptr ss:[ebp-25],0
00417525 EB 09 jmp short dump.00417530
00417527 FF45 D0 inc dword ptr ss:[ebp-30]
0041752A 837D D0 0A cmp dword ptr ss:[ebp-30],0A ; A-2=8
0041752E ^ 7C 9E jl short dump.004174CE
初始值2,作为取字符串与注册码的指针,递增。
(第[指针+1]位字符串+第[指针]位注册码)XOR 第[指针+1]位注册码 XOR 第[指针+1]位字符串,
值/1A的余数+41=第[指针+10]位注册码。
得到的值:46 4E 58 5A 52 56 4B 4E,即: FNXZRVKN
注册码为:8%654321123 FNXZRVKN 543211234567887654321
4.3 再一轮的计算:
0041754D 8B55 CC mov edx,dword ptr ss:[ebp-34]
00417550 0FBE8415 51FFFFFF movsx eax,byte ptr ss:[ebp+edx-AF] ; zcm第[指针]位
00417558 B9 06000000 mov ecx,6
0041755D 99 cdq
0041755E F7F9 idiv ecx ; /6
00417560 8BCA mov ecx,edx ; 余数
00417562 8B45 CC mov eax,dword ptr ss:[ebp-34]
00417565 0FBE9405 52FFFFFF movsx edx,byte ptr ss:[ebp+eax-AE] ; 注册码第[指针+1]位
0041756D D3E2 shl edx,cl ; ×2~余数
0041756F 8B45 CC mov eax,dword ptr ss:[ebp-34]
00417572 0FBE8C05 53FFFFFF movsx ecx,byte ptr ss:[ebp+eax-AD] ; 注册码第[指针+2]位
0041757A 0BD1 or edx,ecx ; or
0041757C 52 push edx
0041757D E8 DE1EFFFF call dump.00409460
00417582 59 pop ecx
00417583 B9 1A000000 mov ecx,1A
00417588 99 cdq
00417589 F7F9 idiv ecx ; /1A
0041758B 80C2 61 add dl,61 ; +61
0041758E 8B45 CC mov eax,dword ptr ss:[ebp-34]
00417591 889405 24FFFFFF mov byte ptr ss:[ebp+eax-DC],dl ; 值保存
00417598 FF45 CC inc dword ptr ss:[ebp-34]
0041759B 837D CC 28 cmp dword ptr ss:[ebp-34],28 ; 从18到28
0041759F ^ 7C AC jl short dump.0041754D
004175A1 C685 4CFFFFFF 5A mov byte ptr ss:[ebp-B4],5A ; 添一个5A
004175A8 C685 4DFFFFFF 59 mov byte ptr ss:[ebp-B3],59 ; 再添一个59
这次指针还是2,然后递增。
注册码第[指针+1]位×2~(注册码第[指针]位/6的余数) OR 注册码第[指针+2]位,
值/1A的余数61,保存。
运算18到28,共10位=16位(D)
注册码练码:8%654321123FNXZRVKN543211234567887654321
值:0012F7D0 6E 62 7A 6D 72 6C 6B 70 79 6F 79 6D 6F 69 6A 63 nbzmrlkpyoymoijc
循环结束后又添了2个到后面:5A 59
计算值:0012F7D0 6E 62 7A 6D 72 6C 6B 70 79 6F 79 6D 6F 69 6A 63 5A 59 nbzmrlkpyoymoijcZY
4.4 然后对计算值再计算后比较:
004175C2 8B55 C8 mov edx,dword ptr ss:[ebp-38]
004175C5 0FBE8415 24FFFFFF movsx eax,byte ptr ss:[ebp+edx-DC] ; 顺取计算值?
004175CD C1E0 04 shl eax,4
004175D0 8B55 C8 mov edx,dword ptr ss:[ebp-38]
004175D3 0FBE8C15 25FFFFFF movsx ecx,byte ptr ss:[ebp+edx-DB]
004175DB D1F9 sar ecx,1
004175DD 33C1 xor eax,ecx
004175DF 50 push eax
004175E0 E8 7B1EFFFF call dump.00409460
004175E5 59 pop ecx
004175E6 B9 1A000000 mov ecx,1A
004175EB 99 cdq
004175EC F7F9 idiv ecx ; /1A
004175EE 83C2 41 add edx,41 ; +41
004175F1 8B45 C8 mov eax,dword ptr ss:[ebp-38]
004175F4 0FBE8405 68FFFFFF movsx eax,byte ptr ss:[ebp+eax-98] ; 注册码第25位
004175FC 3BD0 cmp edx,eax
004175FE 74 06 je short dump.00417606
00417600 C645 DB 00 mov byte ptr ss:[ebp-25],0
00417604 EB 09 jmp short dump.0041760F
00417606 FF45 C8 inc dword ptr ss:[ebp-38]
00417609 837D C8 28 cmp dword ptr ss:[ebp-38],28 ; 比较16次
0041760D ^ 7C B3 jl short dump.004175C2
(计算值[第n位]×2~4) XOR (计算值[第n+1位]/2),
值/1A+41=注册码[第32+n位]。
即:44 46 53 42 55 4E 49 47 4A 59 49 5A 51 4C 52 46
DFSBUNIGJYIZQLRF
4.5然后比较注册码第11位是不是59=Y:
0041760F 0FBE95 72FFFFFF movsx edx,byte ptr ss:[ebp-8E] ; 注册码第11位
00417616 83FA 59 cmp edx,59 ; 是不是59?
郁闷,这个这么重要最后才比较,前面白算了。
5.思路有了,反推注册码:
从头到尾只有2个是固定的,那就是第2位&第11位注册码,分别为:% Y
修改练码:8%65432112Y45678876543211234567887654321
第一轮运算可以得到第12位到第20位注册码:
46 4E 58 5A 52 56 4B 4E=FNXZRVKN
练码变为:8%65432112YFNXZRVKN543211234567887654321
第2轮运算得到第25位到第40位:
44 46 53 42 55 4E 4C 4B 5A 4B 49 5A 51 4C 52 46=DFSBUNLKZKIZQLRF
得到注册码:
8%65432112YFNXZRVKN54321DFSBUNLKZKIZQLRF
好了,这下关键跳转可以朝正确方向:
00416FBD 80B9 86040000 00 cmp byte ptr ds:[ecx+486],0 ; 00EC29F2
00416FC4 0F84 75020000 je dump.0041723F ; 关键跳转
6.虚晃一枪:
然后又比较第24位注册码:
00417018 0FBE50 17 movsx edx,byte ptr ds:[eax+17] ; 注册码第24位
0041701C 83FA 30 cmp edx,30 ; 是不是小于0?
0041701F 7C 16 jl short dump.00417037
0041702E 0FBE50 17 movsx edx,byte ptr ds:[eax+17] ; 注册码第24位
00417032 83FA 39 cmp edx,39 ; 是不是大于9?
00417035 7E 0F jle short dump.00417046
吓出一身冷汗,还好,有惊无险。
然后写入注册表:
HKCU\Software\XTZY\ExeIcon\NO SUCCESS "8%65432112YFNXZRVKN54321DFSBUNLKZKIZQLRF"
HKCU\Software\XTZY\ExeIcon\Name SUCCESS "cyto"
7.后记:
刚开始比较注册码长度,可以24位,也可以40位,可是怎么跟都没能发现24位可以注册成功,被作者蒙了一把。
后来发现有个赋值,注册码输入24位的怎么都没改变,只有40位才看到赋值不一样。
接下来以为一路顺风了,思路很清楚了,可是等计算好后,它才冷不丁的比较已经计算过的注册码是否没错。只好再来一次。这种算法思路也不错,多搞几次,我可能就会崩溃。
等关键跳转朝正确方向走的时候,又来个比较,还好有惊无险,只是出了一声冷汗而已。
至此搞定。
2006.04.24
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!