能力值:
( LV9,RANK:1140 )
|
-
-
2 楼
光爆破也要爆四处~
不懂算法~~
|
能力值:
( LV9,RANK:970 )
|
-
-
3 楼
算法注册机马上放出。
|
能力值:
( LV12,RANK:410 )
|
-
-
4 楼
00401715 /75 31 JNZ SHORT CrackMe_.00401748 ; 4处 JNZ
00401717 |. |A1 B7394000 MOV EAX,DWORD PTR DS:[4039B7]
0040171C |. |3145 F8 XOR DWORD PTR SS:[EBP-8],EAX
0040171F |. |837D F8 FF CMP DWORD PTR SS:[EBP-8],-1
00401723 |. |74 02 JE SHORT CrackMe_.00401727
00401725 |EB 21 JMP SHORT CrackMe_.00401748 ; 3 处JNE
00401727 |> |A1 BB394000 MOV EAX,DWORD PTR DS:[4039BB]
0040172C |. |3145 F4 XOR DWORD PTR SS:[EBP-C],EAX
0040172F |75 17 JNZ SHORT CrackMe_.00401748 ; 2处 JNE
00401731 |. |A1 BF394000 MOV EAX,DWORD PTR DS:[4039BF]
00401736 |. |3145 F0 XOR DWORD PTR SS:[EBP-10],EAX
00401739 |75 0D JNZ SHORT CrackMe_.00401748 ; 1处 JNZ
0040173B |. |68 D2204000 PUSH CrackMe_.004020D2 ; /Text = "GOOD JOB, MAN!"
00401740 |. |FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401743 |. |E8 76000000 CALL <JMP.&user32.SetWindowTextA> ; \SetWindowTextA
00401748 |> \33C0 XOR EAX,EAX
跳转了这4处JNE,好像也没爆破掉... :(
|
能力值:
( LV4,RANK:50 )
|
-
-
5 楼
算法复杂,等待高人
|
能力值:
( LV4,RANK:50 )
|
-
-
6 楼
请问一下
你说用的是Win32asm编的
为什么我用PEID看的结果是MASM32 / TASM32
能给解释一下吗?
我比较菜
见笑了
|
能力值:
( LV10,RANK:170 )
|
-
-
7 楼
都是Win32的汇编..
|
能力值:
( LV6,RANK:90 )
|
-
-
8 楼
最初由 joe-lu 发布 00401715 /75 31 JNZ SHORT CrackMe_.00401748 ; 4处 JNZ 00401717 |. |A1 B7394000 MOV EAX,DWORD PTR DS:[4039B7] 0040171C |. |3145 F8 XOR DWORD PTR SS:[EBP-8],EAX 0040171F |. |837D F8 FF CMP DWORD PTR SS:[EBP-8],-1 00401723 |. |74 02 JE SHORT CrackMe_.00401727 ........
试验码长度是32位,这几个地方爆了才会显示注册成功!
|
能力值:
( LV12,RANK:730 )
|
-
-
9 楼
用户名"yzhr"
注册码"48969FCD8C2EB823FF2AA03DA9319CC7"
[算法分析]
原程序的验证过程大致分为三步:用户名必须是4字节,注册码必须是32字符('0'-'9','A'-'F')
1、先把注册码前16个字符做成两个32位数,比如"12AB90EF"就是0x12AB90EF,与逆运算无关,不必理会。
再分别与常数异或(是可逆的),然后有循环移位、或运算,但实际效果是位交换,所以是容易做逆运算,
最后,第1个32位数还要与根据用户名算出来的一数据再异或一下。
2、后16个字符的处理简单,同样的方法做出两个32位数,分别与常数异或运算。
3、根据用户名计算出4个数据,用于4个关键跳转(爆破点)的比较;因为只与用户名有关,注册机可以直接调用这段程序。
如果编程模仿这个过程,要复制一块预设的常数数据,跟踪发现是在内存地址0040365C开始的64字节和0040369C开始的256字节。
循环只执行一次,内有4个小循环;调用5个小过程。
[注册机]-----不能上传附件,就把做法说一下。
因为原程序的大部分代码可利用,所以用OllyDbg直接修改程序后另存为注册机程序即可。
先找到第二个调用GetDlgItemTextA的地方
0040159D |. E8 F8010000 CALL <JMP.&user32.GetDlgItemTextA>
004015A2 |. 83F8 20 CMP EAX,20
004015A5 |. 74 05 JE SHORT crackme_.004015AC
004015A7 |. E9 9C010000 JMP crackme_.00401748
//从地址004015A2处开始修改:先调用原程序的SUB1和SUB2、FUN1过程
CALL 0040140D ; SUB1过程
LEA EBX,[DWORD DS:4037A0] ; 取用户名地址
CALL 00401435 ; SUB2过程
PUSH EAX ; 备份返回值,还要用一次
PUSH EAX ; 参数3
PUSH 0040302C ; |Format = "%08X"
PUSH 00403530 ; |s = crackme_.00403530
CALL <JMP.&user32.wsprintfA> ; \wsprintfA(汇编"call 00401788"入口表中找到的地址)
ADD ESP,0C ; 平衡堆栈
PUSH 8 ; /Arg2 = 00000008
PUSH crackme_.00403530 ; |Arg1 = 00403530
CALL crackme_.00401114 ; \crackme_.00401114(FUN1过程,计算出4个数据存放在全局变量,地址是004039B3,004039B7,004039BB,004039BF)
//然后开始逆运算,注册码前16个字符;先根据4个关键跳转要求把第2个4数据按位变反
MOV EBX,[DWORD DS:4039B7]
XOR EBX,-1
MOV EAX,[DWORD DS:4039B3]
POP ECX ; 取出SUB2过程的返回值
XOR EAX,ECX
ROL EAX,8 ; EAX和EBX各自循环左移8位后互换最低字节AH和AL
ROL EBX,8
XCHG AL,BL
ROL BX,8 ; EBX高字不变,低字的高低字节互换、字节的高低4位互换
ROL BH,4
ROL BL,4
ROL EAX,10 ; EAX低字不变,高字的高低字节互换、字节的高低4位互换
ROL AX,8
ROL AH,4
ROL AL,4
ROL EAX,10
XOR EAX,0x452821E6 ; 异或之后得到注册码的数据形式
XOR EBX,0x38D01377
MOV ECX,[DWORD DS:4039BB]
MOV EDX,[DWORD DS:4039BF]
ROR CX,4
XOR ECX,0x37D0D724
XOR EDX,0x34E90C6C
//以字符形式打印注册码
PUSH EDX ; /<%08x>
PUSH ECX ; |<%08x>
PUSH EBX ; |<%08x>
PUSH EAX ; |<%08x>
PUSH 0040301B ; |Format = "%08x%08x%08x%08x"
PUSH 004039C3 ; |s = crackme_.004039C3
CALL <JMP.&user32.wsprintfA> ; \wsprintfA(汇编"call 00401788")
ADD ESP,18 ; 平衡堆栈
//小写改大写
XOR ECX,ECX
LEA EAX,[DWORD DS:4039C3]
xxxx: MOV DL,[BYTE DS:ECX+EAX]
CMP DL,61
JB yyyy(说明:yyyy是该指令地址+0000000D,二进制720B)
CMP DL,66(三字节指令)
JA yyyy(两字节指令,写到这里已知跳转地址yyyy了)
SUB DL,20(三字节指令)
MOV [BYTE DS:ECX+EAX],DL(三字节指令)
yyyy: INC ECX
CMP ECX,20
JNZ xxxx(没到32字符就跳到前面再循环)
//调用user32.SendMessageA把注册码32字符串写入标题栏
LEA EAX,[DWORD DS:4039C3]
PUSH EAX ; /lParam
PUSH 0 ; |wParam = 0
PUSH 0C ; |Message = WM_SETTEXT
PUSH [ARG.1] ; |hWnd
CALL <JMP.&user32.SendMessageA> ; \SendMessageA(汇编"call 004017B8",如果用SetDlgItemText更好)
JMP 00401748 ; 完成,遵照输入太长用户名的处理办法
//在汇编窗口中右键菜单->复制到可执行文件->所有修改,在弹出的窗口中点击“全部复制”钮;
弹出文件窗口中右键菜单->保存文件,另存文件为keygen.exe。好了,退出OD运行它。
输入用户名(必须4个字节),点击Check钮,在标题栏显示注册码。
|
能力值:
( LV6,RANK:90 )
|
-
-
10 楼
顶一下.楼上的兄弟强.
|
能力值:
( LV9,RANK:1250 )
|
-
-
11 楼
最初由 Ryosuke 发布 算法注册机马上放出。
Where? I'm always waiting for your KeyGen!
|
能力值:
( LV9,RANK:1250 )
|
-
-
12 楼
最初由 alphabet 发布 请问一下 你说用的是Win32asm编的 为什么我用PEID看的结果是MASM32 / TASM32 能给解释一下吗? 我比较菜 ........
我倒.........
|
能力值:
( LV9,RANK:970 )
|
-
-
13 楼
最初由 happytown 发布 Where? I'm always waiting for your KeyGen!
http://bbs.pediy.com/showthread.php?s=&threadid=25112
|
能力值:
( LV9,RANK:1250 )
|
-
-
14 楼
最初由 月中人 发布 用户名"yzhr" 注册码"48969FCD8C2EB823FF2AA03DA9319CC7" [算法分析] 原程序的验证过程大致分为三步:用户名必须是4字节,注册码必须是32字符('0'-'9','A'-'F') 1、先把注册码前16个字符做成两个32位数,比如"12AB90EF"就是0x12AB90EF,与逆运算无关,不必理会。 ........
1、恭喜你完成了要求中的第2条的70%,还有一些东西在里面仍可发掘;
2、希望再接再厉,做出注册机。
|
能力值:
( LV6,RANK:90 )
|
-
-
15 楼
最初由 月中人 发布 /在汇编窗口中右键菜单->复制到可执行文件->所有修改,在弹出的窗口中点击“全部复制”钮; 弹出文件窗口中右键菜单->保存文件,另存文件为keygen.exe。好了,退出OD运行它。 输入用户名(必须4个字节),点击Check钮,在标题栏显示注册码。 ........
不是做出注册机了么?
|
能力值:
( LV9,RANK:1250 )
|
-
-
16 楼
最初由 rufus 发布 不是做出注册机了么?
能传上来分享一下吗?
|