好友
阅读权限40
听众
最后登录1970-1-1
|
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。
本帖最后由 playboysen 于 2013-12-20 21:17 编辑
本文针对以下CM:
http://www.52pojie.cn/thread-228422-1-2.html
本机Win7 x64直接运行主程序,提示“发现调试器”??好莫名,我的OD还木有打开呢!!
不管它,OD载入后在代码入口点附近发现了“MSVCR90._decode_pointer”的注释,难道这个是MFC程序(一般可以用工具定位按钮事件地址;而且OD可以直接导入库显示出库函数)??
打开菜单“窗口——可执行模块”如图,看到了mfc90u等,好办多了
确保OD\Lib目标下有诸如“mfc90u.lib”之类的lib文件(如有需要请下载附件),然后导入库(未导入库之前mfc函数都显示为“mfc90u.#1048”,如图)
导入库后,重新加载CM,Ctrl+N打开名称窗口MFC函数均已显示出函数名(如图)
OK,我们来研究调试器检测,OD中查看Unicode字符串轻松找到“检测到虚拟机”,猜测调试器检测代码也在附近(注意由于操作系统差异故代码虚拟地址可能不同)
[AppleScript] 纯文本查看 复制代码 013D1A39 . FF15 10413>call dword ptr ds:[<&SkinH.SkinH_Attach>] ; SkinH.SkinH_Attach
013D1A3F . 6A 00 push 0
013D1A41 . 68 EB03000>push 3EB
013D1A46 . 8BCE mov ecx,esi
013D1A48 . E8 310B000>call <jmp.&mfc90u.#2904_CWnd::GetDlgItem> ; 获取某控件句柄?
013D1A4D . 8BC8 mov ecx,eax
013D1A4F . E8 240B000>call <jmp.&mfc90u.#2360_CWnd::EnableWindow> ; 貌似有猫腻儿
013D1A54 . E8 37FAFFF>call CrackMe?013D1490
013D1A59 . 85C0 test eax,eax
013D1A5B . 0F85 AF000>jnz CrackMe?013D1B10 ; 1
013D1A61 . E8 CAFAFFF>call CrackMe?013D1530
013D1A66 . 85C0 test eax,eax
013D1A68 . 0F85 A2000>jnz CrackMe?013D1B10 ; 2
013D1A6E . E8 FDFBFFF>call CrackMe?013D1670
013D1A73 . 85C0 test eax,eax
013D1A75 . 0F85 95000>jnz CrackMe?013D1B10 ; 3
013D1A7B . E8 50FCFFF>call CrackMe?013D16D0
013D1A80 . 85C0 test eax,eax
013D1A82 . 0F85 88000>jnz CrackMe?013D1B10 ; 4
013D1A88 . E8 83F9FFF>call CrackMe?013D1410
013D1A8D . E8 2EF9FFF>call CrackMe?013D13C0
013D1A92 . E8 A9F8FFF>call CrackMe?013D1340
013D1A97 . E8 64F5FFF>call CrackMe?013D1000
013D1A9C . 85C0 test eax,eax
013D1A9E . 75 54 jnz short CrackMe?013D1AF4 ; 5
013D1AA0 . E8 9BF7FFF>call CrackMe?013D1240
013D1AA5 . 85C0 test eax,eax
013D1AA7 . 75 4B jnz short CrackMe?013D1AF4 ; 6
013D1AA9 . E8 F2F7FFF>call CrackMe?013D12A0
013D1AAE . 85C0 test eax,eax
013D1AB0 . 75 42 jnz short CrackMe?013D1AF4 ; 7
013D1AB2 . FF15 6C403>call dword ptr ds:[<&KERNEL32.GetCurrentProcess>] ; [GetCurrentProcess
013D1AB8 . 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
013D1ABC . 51 push ecx
013D1ABD . 50 push eax
013D1ABE . C74424 18 >mov dword ptr ss:[esp+18],0
013D1AC6 . FF15 68403>call dword ptr ds:[<&KERNEL32.CheckRemoteDebuggerPresent>] ; kernel32.CheckRemoteDebuggerPresent
013D1ACC . 837C24 10 >cmp dword ptr ss:[esp+10],1
013D1AD1 . 74 21 je short CrackMe?013D1AF4 ; 8
013D1AD3 . E8 B8F8FFF>call CrackMe?013D1390
013D1AD8 . 85C0 test eax,eax
013D1ADA . 75 18 jnz short CrackMe?013D1AF4 ; 9
013D1ADC . B8 0100000>mov eax,1
013D1AE1 . 8B4C24 14 mov ecx,dword ptr ss:[esp+14]
013D1AE5 . 64:890D 00>mov dword ptr fs:[0],ecx
013D1AEC . 59 pop ecx
013D1AED . 5F pop edi
013D1AEE . 5E pop esi
013D1AEF . 5B pop ebx
013D1AF0 . 83C4 10 add esp,10
013D1AF3 . C3 retn
013D1AF4 > 6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
013D1AF6 . 68 D4473D0>push CrackMe?013D47D4 ; |Title = "错误"
013D1AFB . 68 DC473D0>push CrackMe?013D47DC ; |Text = "检测到调试器"
013D1B00 . 6A 00 push 0 ; |hOwner = NULL
013D1B02 . FF15 28413>call dword ptr ds:[<&USER32.MessageBoxW>] ; \MessageBoxW
013D1B08 . 6A 00 push 0 ; /ExitCode = 0
013D1B0A . FF15 44403>call dword ptr ds:[<&KERNEL32.ExitProcess>] ; \ExitProcess
013D1B10 > 6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
013D1B12 . 68 90473D0>push CrackMe?013D4790 ; |雅蠛蝶
013D1B17 . 68 98473D0>push CrackMe?013D4798 ; |检测到虚拟机 by joychoumessageboxauser32.dll
013D1B1C . 6A 00 push 0 ; |hOwner = NULL
013D1B1E . FF15 2C413>call dword ptr ds:[<&USER32.MessageBoxA>] ; \MessageBoxA
013D1B24 . 6A 00 push 0 ; /ExitCode = 0
013D1B26 . FF15 44403>call dword ptr ds:[<&KERNEL32.ExitProcess>] ; \ExitProcess
注释中标注的1-9跳转,全都会提示调试器或虚拟机,也懒得一个个NOP
要跳就让它使劲跳!直接修改013D1AF4和013D1B10代码为“jmp 013D1AB2”,另存起来即可成功过检测!
打开修改后的主程序,发现有个灰色按钮(我先入为主的以为,应该是填入正确的信息后程序会自动启用“通关”按钮,所以花费近一个小时尝试下API断点、条件断点等等,无论什么断点都无法中断,几欲放弃最后才发现是要先手工启用按钮才会读取编辑框内容,晕!)
再看上段代码的前几行,GetDlgItem和EnableWindow很明显就是程序启动时禁用了按钮,修改013D1A3F代码为“push 1”即可启用“通关”按钮
由于已经导入库,我们Ctrl+N打开名称窗口找到“mfc90u.#2909_CWnd::GetDlgItemTextW”回车,看看有几处调用
在两处call调用上F2断点,随便输入第一关key点击“通关”按钮测试,成功断下
[AppleScript] 纯文本查看 复制代码 00F51D0B . E8 4408000>call <jmp.&mfc90u.#374_CDialog::CDialog>
00F51D10 . C74424 18 >mov dword ptr ss:[esp+18],CrackMe.00F54B44
00F51D18 . 8D4424 0C lea eax,dword ptr ss:[esp+C]
00F51D1C . 50 push eax
00F51D1D . 68 E903000>push 3E9
00F51D22 . 8BCE mov ecx,esi
00F51D24 . C68424 B00>mov byte ptr ss:[esp+B0],1
00F51D2C . E8 6B08000>call <jmp.&mfc90u.#2909_CWnd::GetDlgItemTextW> ; 读取第一关Key
00F51D31 . 8B4C24 0C mov ecx,dword ptr ss:[esp+C]
00F51D35 . 8B41 F4 mov eax,dword ptr ds:[ecx-C]
00F51D38 . 6A 02 push 2
00F51D3A . 83C0 FE add eax,-2
00F51D3D . 50 push eax
00F51D3E . 8D5424 18 lea edx,dword ptr ss:[esp+18]
00F51D42 . 52 push edx
00F51D43 . 8D4C24 18 lea ecx,dword ptr ss:[esp+18]
00F51D47 . FF15 2842F>call dword ptr ds:[<&mfc90u.#4519_ATL::CStringT<wchar_>; Mid
00F51D4D . C68424 A80>mov byte ptr ss:[esp+A8],2
00F51D55 . 8B4424 10 mov eax,dword ptr ss:[esp+10]
00F51D59 . 8B35 0441F>mov esi,dword ptr ds:[<&MSVCR90._wtoi>] ; MSVCR90._wtoi
00F51D5F . 50 push eax
00F51D60 . FFD6 call esi ; <&MSVCR90._wtoi>
00F51D62 . 8B4C24 10 mov ecx,dword ptr ss:[esp+10]
00F51D66 . 51 push ecx
00F51D67 . 8BD8 mov ebx,eax
00F51D69 . C68424 940>mov byte ptr ss:[esp+94],0EF
00F51D71 . C68424 950>mov byte ptr ss:[esp+95],0E3
00F51D79 . C68424 960>mov byte ptr ss:[esp+96],0F0
00F51D81 . C68424 970>mov byte ptr ss:[esp+97],98
00F51D89 . C68424 980>mov byte ptr ss:[esp+98],9D
00F51D91 . C68424 990>mov byte ptr ss:[esp+99],0FD
00F51D99 . C68424 9A0>mov byte ptr ss:[esp+9A],0
00F51DA1 . FFD6 call esi ; <&MSVCR90._wtoi>
......
00F51E9D > 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00F51E9F . C6840C 980>mov byte ptr ss:[esp+ecx+98],0 ; |
00F51EA7 . 8D8C24 980>lea ecx,dword ptr ss:[esp+98] ; |
00F51EAE . 51 push ecx ; |Title
00F51EAF . 8BD1 mov edx,ecx ; |
00F51EB1 . 52 push edx ; |Text
00F51EB2 . 6A 00 push 0 ; |hOwner = NULL
00F51EB4 . FF15 2C41F>call dword ptr ds:[<&USER32.MessageBoxA>] ; \MessageBoxA
00F51EBA . 8D4C24 18 lea ecx,dword ptr ss:[esp+18]
00F51EBE . E8 8905000>call <jmp.&mfc90u.#2208_CDialog::DoModal>
看到了_wtoi,好像是将宽字符转换为整型数字什么的,看来第一关key应该是个数值,接着是很长一堆简单运算然后MessageBox,也懒得一行行分析,IDA加载后F5分析当前过程
大概是这么个意思,试一试
[Python] 纯文本查看 复制代码 for j in range(88888):
if j%3==1 and j%5==2 and j%7==4 and j%13==6 and j%17==8:
print u"第一关key: %d " % j
经测试第一关key输入“18232”会弹出“下一关”对话框,输入其它数字虽弹出乱码不过也可以直接进入第二关,嗯应该没什么问题
还记得上面我们在““mfc90u.#2909_CWnd::GetDlgItemTextW””两处调用call上都设置了断点吗??随便输入第二关key,OD立即断下了
[AppleScript] 纯文本查看 复制代码 00F52091 . E8 0605000>call <jmp.&mfc90u.#2909_CWnd::GetDlgItemTextW> ; 获取第二关key
00F52096 . 8B3D 4065F>mov edi,dword ptr ds:[F56540] ; EDI = 机器码
00F5209C . 8BC7 mov eax,edi ; EAX = EDI =机器码
00F5209E . 33C9 xor ecx,ecx ; ecx = 0
00F520A0 . 8D70 02 lea esi,dword ptr ds:[eax+2]
00F520A3 > 66:8B10 mov dx,word ptr ds:[eax] ; ***begin***
00F520A6 . 83C0 02 add eax,2
00F520A9 . 66:85D2 test dx,dx
00F520AC .^ 75 F5 jnz short CrackMe.00F520A3
00F520AE . 2BC6 sub eax,esi
00F520B0 . D1F8 sar eax,1 ; EAX = LEN(机器码)
00F520B2 . 74 3F je short CrackMe.00F520F3 ; ***end***
00F520B4 . 8BEF mov ebp,edi ; EBP = EDI = 机器码
00F520B6 . 8D5424 30 lea edx,dword ptr ss:[esp+30]
00F520BA . 2BEA sub ebp,edx
00F520BC . 8D6424 00 lea esp,dword ptr ss:[esp]
00F520C0 > 8D444D 00 lea eax,dword ptr ss:[ebp+ecx*2] ; 真正的第二关key生成算法
00F520C4 . 66:8B5404 >mov dx,word ptr ss:[esp+eax+30] ; 机器码从首字节开始逐位参与运算
00F520C9 . 66:42 inc dx
00F520CB . 66:83F2 1F xor dx,1F ; (每一字节 + 1) xor 0x1F
00F520CF . 8BC7 mov eax,edi
00F520D1 . 66:89544C >mov word ptr ss:[esp+ecx*2+30],dx
00F520D6 . 41 inc ecx ; ECX 作为计数器
00F520D7 . 8D70 02 lea esi,dword ptr ds:[eax+2]
00F520DA . 8D9B 00000>lea ebx,dword ptr ds:[ebx]
00F520E0 > 66:8B10 mov dx,word ptr ds:[eax] ; ***begin***
00F520E3 . 83C0 02 add eax,2
00F520E6 . 66:85D2 test dx,dx
00F520E9 .^ 75 F5 jnz short CrackMe.00F520E0
00F520EB . 2BC6 sub eax,esi
00F520ED . D1F8 sar eax,1 ; EAX = LEN(机器码)
00F520EF . 3BC8 cmp ecx,eax ; ***end***
00F520F1 .^ 72 CD jb short CrackMe.00F520C0
00F520F3 > 33C0 xor eax,eax
00F520F5 . 66:89444C >mov word ptr ss:[esp+ecx*2+30],ax ; 最后一字节置零(以截断字符串)
00F520FA . 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
00F520FE . FF15 6042F>call dword ptr ds:[<&mfc90u.#296_ATL::CStringT<wchar_t>
00F52104 . C64424 64 >mov byte ptr ss:[esp+64],1
00F52109 . 8B0D 4065F>mov ecx,dword ptr ds:[F56540] ; 机器码
00F5210F . 8B41 F4 mov eax,dword ptr ds:[ecx-C] ; LEN(机器码)
00F52112 . 8B35 3042F>mov esi,dword ptr ds:[<&mfc90u.#2537_ATL::CStringT<wch>; Format
00F52118 . 8D1400 lea edx,dword ptr ds:[eax+eax] ; EDX = 2*LEN(机器码)
00F5211B . 83F2 11 xor edx,11 ; EDX = EDX ^ 0x11
00F5211E . 52 push edx
00F5211F . 8D4424 18 lea eax,dword ptr ss:[esp+18]
00F52123 . 68 B04CF50>push CrackMe.00F54CB0 ; %d
00F52128 . 50 push eax
00F52129 . FFD6 call esi ; Format
00F5212B . 83C4 0C add esp,0C
00F5212E . 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
00F52132 . FF15 6042F>call dword ptr ds:[<&mfc90u.#296_ATL::CStringT<wchar_t>
00F52138 . 8D4C24 30 lea ecx,dword ptr ss:[esp+30]
00F5213C . 51 push ecx
00F5213D . 8D5424 14 lea edx,dword ptr ss:[esp+14]
00F52141 . 68 2C4BF50>push CrackMe.00F54B2C ; %s
00F52146 . 52 push edx
00F52147 . C64424 70 >mov byte ptr ss:[esp+70],2
00F5214C . FFD6 call esi ; Format
00F5214E . 8D4424 20 lea eax,dword ptr ss:[esp+20]
00F52152 . 50 push eax
00F52153 . 8D4C24 2C lea ecx,dword ptr ss:[esp+2C]
00F52157 . 51 push ecx
00F52158 . 8D4C24 24 lea ecx,dword ptr ss:[esp+24]
00F5215C . E8 2F02000>call CrackMe.00F52390 ; Concatenate
算法一目了然,设ID为机器码
[Python] 纯文本查看 复制代码 regCode = ""
for j in range(len(ID)):
regCode = regCode + chr((ord(ID[j])+1) ^ 0x1F)
regCode = regCode + str((2*len(ID)) ^ 0x11)
OK,完整注册机代码如下
[Python] 纯文本查看 复制代码 #-------------------------------------------------------------------------------
# Name: LoveKido Update-- JoyChou
# Author: Playboysen
# Created: 20/12/2013
# Version: Python2.7 && Win7 X64
#-------------------------------------------------------------------------------
#!/usr/bin/env python
for j in range(88888):
if j%3==1 and j%5==2 and j%7==4 and j%13==6 and j%17==8:
print u"第一关key: %d" % j
ID = raw_input(u"请输入机器码:")
regCode = ""
for j in range(len(ID)):
regCode = regCode + chr((ord(ID[j])+1) ^ 0x1F)
regCode = regCode + str((2*len(ID)) ^ 0x11)
print u"第二关key: %s" % regCode
|
免费评分
-
查看全部评分
|