好友
阅读权限 40
听众
最后登录 1970-1-1
关于Crackme
评定等级:
优秀:得到算法,写出注册机
良好:得到算法的思路,取得以自己名字作为用户名的注册码
及格:取得以自己名字作为用户名的注册码
不及格:……
主要考察内容:
1、手动脱简单的壳(S-ICE/TRW2K)
2、静态分析能力(W32DASM,尽量不要用IDA )
3、S-ICE/TRW2K 下下断点的能力
4、汇编的基本功
提示:
首先脱壳 ,然后用静态分析的方法得出算法,制作出注册机。
或者用S-ICE/TRW2K分析出算法也可(较难)。
作者: dOSKEY lEE (doskey_lee@sohu.com )
==============================================================
自己菜的要歇菜了~
又重新看了下这个CM
重新分析下!(就是看……不敢称分析!)
壳:UPX
UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo
开脱!
脱壳机满天飞……不过鉴于自己能早日脱离壳盲
手动ESP(其实还是没有含量!)保持为UP.EXE……
------------------------------------------------------------
看下机制!
状态栏默认 显示 Write by dOSKEY lEE
两个个文本框
两个按钮
两个TAB
|||||||||||||||||||||||||||||||||||||||||||||||||||||
注册成功 Very good!,You are a clever student!
用户名密码不足4位 Username is less then 4 chararter!
密码不写 Password is empty!
全都不写 Username is empty!
这些在查找字符串的时候其实都能看到这里只是为了
更好的了解下CM的样子
||||||||||||||||||||||||||||||||||||||||||||||||||||||
------------------------------------------------------------
OD载入裸体CM……
004019F0 > 55 push ebp ; (initial cpu selection) 停点!
004019F1 8BEC mov ebp, esp
004019F3 6A FF push -1
004019F5 68 28254000 push 00402528
004019FA 68 761B4000 push <jmp.&msvcrt._except_handler3>
004019FF 64:A1 00000000 mov eax, dword ptr fs:[0]
00401A05 50 push eax
00401A06 64:8925 0000000>mov dword ptr fs:[0], esp
00401A0D 83EC 68 sub esp, 68
00401A10 53 push ebx
00401A11 56 push esi
00401A12 57 push edi
00401A13 8965 E8 mov dword ptr [ebp-18], esp
00401A16 33DB xor ebx, ebx
00401A18 895D FC mov dword ptr [ebp-4], ebx
00401A1B 6A 02 push 2
采用最常用的方法 查找字符串………………
——————————————————————————————————————
Ultra String Reference
Address Disassembly Text String
00401262 push 00401C69 赴%@
004013A2 push 00401C88 葛%@
0040145D push 004030A4 write by doskey lee
0040161D push 00403118 username is empty!
00401639 push 00403104 password is empty!
00401650 push 004030E0 username is less then 4 chararter!
00401723 push 004030B8 very good!,you are a clever student!
004019F0 push ebp (initial cpu selection)
字符串蛮少的……
00401723 push 004030B8 very good!,you are a clever student! //如果没错的话大家都应该喜欢用这句话开刀……
点进去!
——————————————————————————————————————
004016F6 E8 9F020000 call <jmp.&MFC42.#5856_CString::SetAt>
004016FB 8B4424 0C mov eax, dword ptr [esp+C]
004016FF 46 inc esi
00401700 3B70 F8 cmp esi, dword ptr [eax-8]
00401703 ^ 7C D3 jl short 004016D8
00401705 8B77 64 mov esi, dword ptr [edi+64]
00401708 8B58 F8 mov ebx, dword ptr [eax-8]
0040170B 3B5E F8 cmp ebx, dword ptr [esi-8]
0040170E 75 34 jnz short 00401744
00401710 33C9 xor ecx, ecx
00401712 85DB test ebx, ebx
00401714 7E 0D jle short 00401723
00401716 8A1401 mov dl, byte ptr [ecx+eax]
00401719 3A140E cmp dl, byte ptr [esi+ecx]
0040171C 75 26 jnz short 00401744
0040171E 41 inc ecx
0040171F 3BCB cmp ecx, ebx
00401721 ^ 7C F3 jl short 00401716
00401723 68 B8304000 push 004030B8 ; very good!,you are a clever student!
00401728 8D4F 60 lea ecx, dword ptr [edi+60]
//载入后发现 在其上方的跳转很多……点下看看
最近的是 00401721 ^ 7C F3 jl short 00401716 回跳!
其次 0040171C 75 26 jnz short 00401744 跳过成功提示进入错误提示,虽然这个CM没有错误提示 //这是个误区!通常就会立刻改掉他!其实应该看看
其上方还有什么没有!
还有一个未完成跳 00401714 7E 0D jle short 00401723 这个跳直接跳到成功提示处!
00401710 33C9 xor ecx, ecx
00401712 85DB test ebx, ebx //这里做运算!
0040170E 75 34 jnz short 00401744 //还是跳到错误提示
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
00401703 ^ 7C D3 jl short 004016D8
00401705 8B77 64 mov esi, dword ptr [edi+64]
00401708 8B58 F8 mov ebx, dword ptr [eax-8]
0040170B 3B5E F8 cmp ebx, dword ptr [esi-8]
上方出现赋值
重新整理下思路啊!
因为我们是倒过来看的!
这里赋值后往下走走到
00401710 33C9 xor ecx, ecx
00401712 85DB test ebx, ebx //开始做运算!
0040170E 75 34 jnz short 00401744 //是否跳!
那我们在 00401705 8B77 64 mov esi, dword ptr [edi+64]这里下断!
F9跑起!
输入试练号 123456 注册码 11111(注册码大于4个即可)
断下
堆栈 ds:[0012FEEC]=00384008, (ASCII "1222222")
esi=0000000C
寄存器中出现
EAX 003840F8 ASCII "z-57ywnivj5q" //试用下是否是注册码! 结果告诉我是!
ECX 0012F871
EDX 0000000B
EBX 00000001
ESP 0012F7F8
EBP 0012F820
ESI 0000000C
EDI 0012FE88
EIP 00401705 UP.00401705
及格:取得以自己名字作为用户名的注册码
做到这里 算及格了
做个内存注册机
中断地址 401705
中断次数 1
第一字节 8B
指令长度 2
这是内存注册机……
下一步
良好:得到算法的思路
004016F6 E8 9F020000 call <jmp.&MFC42.#5856_CString::SetAt> //这是一个CALL(废话)
找关键CALL的时候我都找离提示比较近的CALL 为什么呢!其实我也不知道因为我不能确定真正的CALL在哪
所以采用编程的就近原则……
下断 004016F6 F9跑
再次 输入假码 123456
断下!
高手F7跟进 我就算了 进去逛了下发现怎么进去怎么出来……
F8
单步到 00401703 ^\7C D3 jl short 004016D8
未完成跳转处 回跳
004016D8 0FBE0406 movsx eax, byte ptr [esi+eax] 回跳后出现一组ASCII
ds:[003840F9]=70 ('p')
eax=003840F8, (ASCII "zpe3*d5/74eb") //和得到的注册码不一样!
继续F8
回跳后又一次出现
ds:[003840FA]=65 ('e')
eax=003840F8, (ASCII "z-e3*d5/74eb")
相比较有所改变
ds:[003840F9]=70 ('p')
eax=003840F8, (ASCII "zpe3*d5/74eb")
ds:[003840FA]=65 ('e')
eax=003840F8, (ASCII "z-e3*d5/74eb")
ds:[003840FB]=33 ('3')
eax=003840F8, (ASCII "z-53*d5/74eb")
ds:[003840FC]=2A ('*')
eax=003840F8, (ASCII "z-57*d5/74eb")
我不一一的走了!
一共是十二循环然后跳出
用户名是6位 123456
取得 12位的注册码
我换用户名为7位
注册码位 14位!
zpe3*d5/74eb
z-e3*d5/74eb
z-53*d5/74eb
z-57*d5/74eb
z-57yd5/74eb
z-57yw5/74eb
z-57ywn/74eb
z-57ywni74eb
z-57ywniv4eb
z-57ywnivjeb
z-57ywnivj5b
z-57ywnivj5q
=====================
注册码位数与用户名位数成正比 一直是 2 : 1
=====================
良好:得到算法的思路,取得以自己名字作为用户名的注册码
(其思路分析的比较垃圾 只知道注册码比用户名多……)
优秀:得到算法,写出注册机(我那内存的就不拿出来做大头了……)
----------------------------------------------------------------
总结 这个CM很适合新手!
发帖前要善用【论坛搜索 】 功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。