能力值:
( LV9,RANK:165 )
|
-
-
2 楼
楼主,这个应该让Keygen的
004011D4 90 nop
004011D5 90 nop
004011D6 90 nop
004011D7 90 nop
004011D8 90 nop
004011D9 BE 09304000 mov esi, 00403009 ; ASCII "iscc2015"
004011DE |. BF A8304000 mov edi, 004030A8
004011E3 |. A1 35304000 mov eax, dword ptr [0x403035]
004011E8 |. F3:A6 repe cmps byte ptr es:[edi], byte ptr>
004011EA 90 nop
004011EB 90 nop
004011EC |. 85C9 test ecx, ecx
004011EE 90 nop
004011EF 90 nop
要Key一下才有意思啊
|
能力值:
( LV8,RANK:130 )
|
-
-
3 楼
好像用到了异常反调试
|
能力值:
( LV9,RANK:165 )
|
-
-
4 楼
恩恩,挺精炼
|
能力值:
( LV4,RANK:140 )
|
-
-
5 楼
Serial:1168863433
算法很简单,但是通过异常反调试真的不知道怎么搞…………
看来要好好学学前辈们的反反调试技巧了
|
能力值:
( LV10,RANK:173 )
|
-
-
6 楼
我刚开始也是这样,但后来发现这里不是真正的算法处,作者这儿构造了一个异常。
|
能力值:
( LV10,RANK:173 )
|
-
-
7 楼
和我的情况是一样滴,一起加油学习。
|
能力值:
( LV4,RANK:140 )
|
-
-
8 楼
嗯 一起加油
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
//程序开始会安装一个异常处理程序,cm1.00401255是异常处理的函数地址
0018FF78 00401348 /CALL 到 SetUnhandledExceptionFilter 来自 cm1.00401346
0018FF7C 00401255 \pTopLevelFilter = cm1.00401255
//输入序列号点OK
0040119F 6A 14 PUSH 0x14
004011A1 68 1D304000 PUSH 0040301D ; ASCII "123456789"
004011A6 68 E9030000 PUSH 0x3E9
004011AB FF75 08 PUSH DWORD PTR SS:[EBP+0x8]
004011AE E8 57020000 CALL <JMP.&user32.GetDlgItemTextA> ; 获取序列号
004011B3 A3 35304000 MOV DWORD PTR DS:[0x403035],EAX
004011B8 83F8 14 CMP EAX,0x14
004011BB 77 47 JA SHORT 00401204
004011BD 05 78563412 ADD EAX,0x12345678
004011C2 D1D8 RCR EAX,1
004011C4 83D0 30 ADC EAX,0x30
004011C7 3D 11111111 CMP EAX,0x11111111
004011CC ^ 76 EF JBE SHORT 004011BD
004011CE 0305 51124000 ADD EAX,DWORD PTR DS:[0x401251]
004011D4 A3 51124000 MOV DWORD PTR DS:[0x401251],EAX ;代码段是只读属性,对代码段写入会产生异常
//检测是否有调试器存在
0018F610 76ED9922 /CALL 到 ZwQueryInformationProcess 来自 kernel32.76ED991C
0018F614 FFFFFFFF |hProcess = FFFFFFFF
0018F618 00000007 |InfoClass = 0x7
0018F61C 0018F628 |Buffer = 0018F628 //检测结果输出到这里,结果为FFFFFFFF检测到被调试,结果为0没检测到,函数返回后把FFFFFFFF改0
0018F620 00000004 |Bufsize = 0x4
0018F624 00000000 \pReqsize = NULL
//程序回到开始安装的异常处理函数处理异常cm1.00401255
//计算用户名
00401286 /EB 10 JMP SHORT 00401298
00401288 |8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4]
0040128B |8D0C00 LEA ECX,DWORD PTR DS:[EAX+EAX]
0040128E |0FBE07 MOVSX EAX,BYTE PTR DS:[EDI]
00401291 |32C1 XOR AL,CL
00401293 |03C8 ADD ECX,EAX
00401295 |8BC1 MOV EAX,ECX
00401297 |47 INC EDI
00401298 \803F 00 CMP BYTE PTR DS:[EDI],0x0
0040129B ^ 75 EB JNZ SHORT 00401288
//将字符串序列号转换为数值
004012A7 /EB 10 JMP SHORT 004012B9
004012A9 |8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4]
004012AC |8D0C00 LEA ECX,DWORD PTR DS:[EAX+EAX]
004012AF |0FBE07 MOVSX EAX,BYTE PTR DS:[EDI]
004012B2 |2C 30 SUB AL,0x30
004012B4 |03C8 ADD ECX,EAX
004012B6 |8BC1 MOV EAX,ECX
004012B8 |47 INC EDI
004012B9 \803F 00 CMP BYTE PTR DS:[EDI],0x0
004012BC ^ 75 EB JNZ SHORT 004012A9
004012BE 5B POP EBX
004012BF 3BC3 CMP EAX,EBX ;比较用户名和序列号
//取DOS头的标志MZ,'M'-0x13,'Z'-0x31.变成字符":)"
004012C3 8B0D 39304000 MOV ECX,DWORD PTR DS:[0x403039] ; cm1.00400000
004012C9 0FB701 MOVZX EAX,WORD PTR DS:[ECX]
004012CC 2C 13 SUB AL,0x13
004012CE 80EC 31 SUB AH,0x31
004012D1 66:A3 A3304000 MOV WORD PTR DS:[0x4030A3],AX
004012D7 6A 00 PUSH 0x0
004012D9 68 A3304000 PUSH 004030A3
004012DE 68 A3304000 PUSH 004030A3
004012E3 6A 00 PUSH 0x0
004012E5 FF15 55304000 CALL DWORD PTR DS:[0x403055] ; user32.MessageBoxA
//算法大概就这样
void main()
{
int t = 0;
char szUserName[] = "iscc2015";
for ( int i=0; szUserName[i]!=0; i++ )
{
t = (BYTE)(t * 10 ^ szUserName[i]) + t * 10;
}
printf( "%d", t );
}
由于我的系统是WIN7 64位,SOD等一些强大插件的驱动不起作用才会被反调试,32位系统加载SOD驱动之后,此反调试应该没效果了,有哪里说的不对的地方,大家指正就好,不要扔砖头啊。
|
能力值:
( LV10,RANK:173 )
|
-
-
10 楼
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
可以的,WIN7 64位系统请看下面这里
//检测是否有调试器存在
0018F610 76ED9922 /CALL 到 ZwQueryInformationProcess 来自 kernel32.76ED991C
0018F614 FFFFFFFF |hProcess = FFFFFFFF
0018F618 00000007 |InfoClass = 0x7
0018F61C 0018F628 |Buffer = 0018F628 //检测结果输出到这里,结果为FFFFFFFF检测到被调试,结果为0没检测到,函数返回后把FFFFFFFF改0
0018F620 00000004 |Bufsize = 0x4
0018F624 00000000 \pReqsize = NULL
函数返回后,把BUFFER的值改为0,然后00401255下断点,就可以来到异常处理函数了。
|
能力值:
( LV10,RANK:173 )
|
-
-
12 楼
你是如何调试到下面这一块的?我没能调到这。
//检测是否有调试器存在
0018F610 76ED9922 /CALL 到 ZwQueryInformationProcess 来自 kernel32.76ED991C
0018F614 FFFFFFFF |hProcess = FFFFFFFF
0018F618 00000007 |InfoClass = 0x7
0018F61C 0018F628 |Buffer = 0018F628 //检测结果输出到这里,结果为FFFFFFFF检测到被调试,结果为0没检测到,函数返回后把FFFFFFFF改0
0018F620 00000004 |Bufsize = 0x4
0018F624 00000000 \pReqsize = NULL
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
777E0100 KiUserExceptionDispatcher /$ FC CLD
777E0101 |. 8B4C24 04 MOV ECX,DWORD PTR SS:[ESP+0x4]
777E0105 |. 8B1C24 MOV EBX,DWORD PTR SS:[ESP]
777E0108 |. 51 PUSH ECX ; pContext
777E0109 |. 53 PUSH EBX ; pExceptionRecord
777E010A |. E8 0BB40400 CALL <_RtlDispatchException@8>
777E010F |. 0AC0 OR AL,AL
777E0111 |. 74 0C JE SHORT 777E011F
777E0113 |. 5B POP EBX
777E0114 |. 59 POP ECX
777E0115 |. 6A 00 PUSH 0x0
777E0117 |. 51 PUSH ECX
777E0118 |. E8 63FD0000 CALL ZwContinue
777E011D |. EB 0B JMP SHORT 777E012A
777E011F |> 5B POP EBX
777E0120 |. 59 POP ECX
777E0121 |. 6A 00 PUSH 0x0
777E0123 |. 51 PUSH ECX
777E0124 |. 53 PUSH EBX
777E0125 |. E8 52140100 CALL ZwRaiseException
777E012A |> 83C4 EC ADD ESP,-0x14
777E012D |. 890424 MOV DWORD PTR SS:[ESP],EAX
777E0130 |. C74424 04 01000000 MOV DWORD PTR SS:[ESP+0x4],0x1
777E0138 |. 895C24 08 MOV DWORD PTR SS:[ESP+0x8],EBX
777E013C |. C74424 10 00000000 MOV DWORD PTR SS:[ESP+0x10],0x0
777E0144 |. 54 PUSH ESP
777E0145 |. E8 DEB80400 CALL RtlRaiseException
777E014A \. C2 0800 RETN 0x8
这和系统分发异常有关,在调试器不处理异常或者没有调试器的情况下,系统内核(注意是系统内核,也就是R0调试子系统)就会把控制返回给KiUserExceptionDispatcher函数,然后KiUserExceptionDispatcher开始搜索有没有安装向量化异常,没有安装或者没有处理,就继续搜索SEH(与线程相关的),SEH也没有处理的话就搜索有没有调用SetUnhandledExceptionFilter安装的异常……挺复杂的,我也说不清楚,你去看一下专业的书籍或者其它前辈的文章,比我说的清楚多了。《软件调试》一书中也有介绍。
|
能力值:
( LV10,RANK:173 )
|
-
-
14 楼
非常感谢gs笨笨兄,我去查下相关书籍。
|
能力值:
( LV3,RANK:20 )
|
-
-
15 楼
好困难啊。
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
004012C1 /75 28 jnz short cm1.004012EB
...不会算法。只能爆破了。。。
|
能力值:
( LV3,RANK:20 )
|
-
-
17 楼
真的挺多anti的。00401387 85C0 TEST EAX,EAX ; 监测点1
0040138B CC INT3 ;监测点2
0040138C 85C0 TEST EAX,EAX ;监测点3
004011D4 A3 51124000 MOV DWORD PTR DS:[401251],EAX ; anti点4
上面这些地方nop掉之后就可以正常调试了。爆破点就在anti点4下面,很好找就不发了。作者真的很赞。
|
能力值:
( LV10,RANK:173 )
|
-
-
18 楼
"Well-done, try to do better” 这个并不是正确的提示信息;
所以你说的那个点并不是真正的爆破点。
|
能力值:
( LV3,RANK:20 )
|
-
-
19 楼
|
能力值:
( LV3,RANK:20 )
|
-
-
20 楼
试了一下,突然发现od断在系统断点,会发现神奇的事情。猜测这个就是用到了所谓的tls回调(不懂这个),回去温习温习这个再战
|
能力值:
( LV3,RANK:20 )
|
-
-
21 楼
是不是这个样子的图标
:)
作者大爱。。真的很强的crackme
|
能力值:
( LV10,RANK:173 )
|
-
-
22 楼
Right
|
能力值:
( LV3,RANK:20 )
|
-
-
23 楼
还有啥crackme再放点来。。最好是那种带anti和各种陷阱的。这个crackme真的很猥琐。前面有点解密api,后面偷偷的做了一个陷阱
|
能力值:
( LV2,RANK:10 )
|
-
-
24 楼
调试不了SetUnhandledExceptionFilter里面的代码, 不知道怎么搞,算法写在异常处理代码里面
|
能力值:
( LV10,RANK:173 )
|
-
-
25 楼
调试不了就静态去看算法,这样也是可以解出来的。
|
|
|