吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8042|回复: 19
收起左侧

CrackMe破解

[复制链接]
mycsy 发表于 2008-5-22 19:41
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。

我靠 今天 S哥发的那个 太难了

差点把我给ME了。。。。。。

我在发一个

这个比较简单的点的

作者初中时让人家破解

没说算法还是爆破

我爆出来了。

比较下他的破文看下 他是算出的注册码

我是爆出来的 都提示正确了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| mycsy 发表于 2008-5-22 19:42
图一 是我看过作者破文后用他的注册码注册的

图二 是我自己爆的。。。。

哈哈

--------------------------------------------------------------

不带照着抄人家的。。。。。

看了人家破文在回来装自己的 就没意思了
 楼主| mycsy 发表于 2008-5-22 19:44
加载后,看到

00401368 >/$ 55       PUSH EBP    <------- 我们在这里
00401369 |. 8BEC      MOV EBP,ESP
0040136B |. 6A FF     PUSH -1
0040136D |. 68 E8404000  PUSH ncrackme.004040E8
00401372 |. 68 9C1E4000  PUSH ncrackme.00401E9C          ; SE handler installation
00401377 |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0040137D |. 50       PUSH EAX
0040137E |. 64:8925 000000>MOV DWORD PTR FS:[0],ESP
00401385 |. 83EC 58    SUB ESP,58
00401388 |. 53       PUSH EBX



这样的一大堆,便是程序开始的地方。一般程序的入口点都是 40xxxx 这样的,如果程序加了壳,入口点会不同。
程序的入口点,是可以由作者自行设定的,没有特别规定

在程序开始段常见的 API : KERNEL32.GetVersion, GetCommandLineA, GetStartupInfoA

我们在这片密麻麻的字海里,是很难找到我们要破解的地方,我们第一步是要找出检查序号的部份。程序多数会用 GetWindowTextA,
GetDlgItemTextA 这类 API 来得到文字方块里的字符串。此外,当我们输入错误序号的时候,程序会弹出一个失败信息,这个信息由
MessageBoxA 所提供。假若我们要分析算法,便需要在 GetWindowTextA 下断,一步一步跟踪。现在我们想从内存中找出序号,比较
快速的方法是在 MessageBoxA 下断。


在 OD 上方的 Plugins ,选 Commandline ,这里可以像 softice 一样输入命令行

设下一个断点 :

bp MessageBoxA


输入这行后,当程序使用 MessageBoxA ,程序便会断下

现在,我们把程序正常运行 (按 F9),输入一个名字,我在里输入了 riijj ,在序号那行输入了 AAAABBBBCCCC

按下 "Register" ,这时候程序遇到断点,停在以下地方

77E16544 > 55        PUSH EBP  <---停在这里
77E16545  8BEC       MOV EBP,ESP
77E16547  51        PUSH ECX
77E16548  833D 1893E477 00 CMP DWORD PTR DS:[77E49318],0
77E1654F  0F85 EA220100  JNZ USER32.77E2883F
77E16555  6A 00      PUSH 0
77E16557  FF75 14     PUSH DWORD PTR SS:[EBP+14]
77E1655A  FF75 10     PUSH DWORD PTR SS:[EBP+10]
77E1655D  FF75 0C     PUSH DWORD PTR SS:[EBP+C]
77E16560  FF75 08     PUSH DWORD PTR SS:[EBP+8]
77E16563  E8 04000000   CALL USER32.MessageBoxExA
77E16568  C9        LEAVE
77E16569  C2 1000     RETN 10
77E1656C > 55        PUSH EBP




看看 OD 的上方,写着 "CPU - main thread, module USER32" ,这说明了我们身处 user32.dll 的领空里,这是系统的程序
部份,我们是不会修改这里的。

(注 : 如果你把文字窗口向上卷的时候,发现 OD 的编码出现不正常现象 (例如刚刚那行 77E16544 的上方变成了 ??? ) ,
这可能是 OD 的对位出错)

我们要返回 crackme 的领空里,有几个方法

1. 不停接 F8 ,一步一步地执行直至程序遇上 retn ,这是返回指令,它会带我们回去
2. 按 Ctrl + F9 ,这样 OD 会不停执行,直至遇到 retn 停下
3. 按一下返回的 retn ,再按 F4 ,程序会执行到光标所在的地方
4. 打开 OD 的 call stack window,看看我们从那里飞来,便设一个断点在那地方,之后 F9 运行

我们按一下 F2 清除断点,再按一下 77E16569 (retn) 那行,按 F4 执行到那里,再按一下 F7 进入 retn。



00401050  . 817C24 08 1101>CMP DWORD PTR SS:[ESP+8],111
00401058  . 75 74     JNZ SHORT ncrackme.004010CE
0040105A  . 8B4424 0C   MOV EAX,DWORD PTR SS:[ESP+C]
0040105E  . 66:3D EA03   CMP AX,3EA
00401062  . 75 42     JNZ SHORT ncrackme.004010A6
00401064  . E8 C7010000  CALL ncrackme.00401230
00401069  . 85C0      TEST EAX,EAX
0040106B  . 6A 00     PUSH 0                  ; /Style = MB_OK|MB_APPLMODAL
0040106D  . 68 80504000  PUSH ncrackme.00405080          ; |Title = "ncrackme"
00401072  . 75 1B     JNZ SHORT ncrackme.0040108F       ; |
00401074  . A1 B8564000  MOV EAX,DWORD PTR DS:[4056B8]      ; |
00401079  . 68 64504000  PUSH ncrackme.00405064          ; |Text = "Registration successful."
0040107E  . 50       PUSH EAX                 ; |hOwner => 001C0218 (&#39;Newbie smallsize crackme -

v1&#39;,class=&#39;myWindowClass&#39;)
0040107F  . FF15 C0404000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00401085  . E8 A6020000  CALL ncrackme.00401330
0040108A  . 33C0      XOR EAX,EAX
0040108C  . C2 1000    RETN 10
0040108F  > 8B0D B8564000 MOV ECX,DWORD PTR DS:[4056B8]      ; |
00401095  . 68 50504000  PUSH ncrackme.00405050          ; |Text = "Registration fail."
0040109A  . 51       PUSH ECX                 ; |hOwner => 001C0218 (&#39;Newbie smallsize crackme -

v1&#39;,class=&#39;myWindowClass&#39;)
0040109B  . FF15 C0404000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
004010A1  . 33C0      XOR EAX,EAX            <--------------- 我们停在这里
004010A3  . C2 1000    RETN 10
004010A6  > 66:3D EB03   CMP AX,3EB
004010AA  . 75 22     JNZ SHORT ncrackme.004010CE
004010AC  . A1 C0564000  MOV EAX,DWORD PTR DS:[4056C0]
004010B1  . 85C0      TEST EAX,EAX
004010B3  . 74 19     JE SHORT ncrackme.004010CE




我们看见了这里是 MessageBox 跳出的程序,这里是成功信息和失败信息的地方。 (读者可能已经大叫,只要把跳往失败信息的跳转修改
一下,便可以成功爆破) 。这是对的,假如我们要爆破它,只要把 00401072 的 JNZ (jump if not zero),修改成 JZ 便可以。


那么,假若我们不想修改软件,而是找出正确的序号,那又怎办呢 ? 我们需要往那个 jump 的上面看看。在 00401069 这里有一个 TEST
,这就是进行比较的指令,它的结果用在其后的 jnz 上。

这句 TEST EAX,EAX 是检查 EAX 是否等于 0 的典型语句,假如 EAX 不等于 0,JNZ 便会跳。我们就是不想它跳,所以我们要找出让 EAX
等于 0 的条件。在 TEST 的上方是 CALL ncrackme.00401230,这个 CALL 的返回值就是 EAX 的值。

我们按右键选 Go to,在 expression 输入 00401230 这个位置

我们来到了检查序号的地方,一看之下便感到这里是一堆很麻烦的运算。今次我们的目的是检出一个给
自己用的序号,我们有没有方法可以从算法中看出序号呢 ?



[PART. 2 第二部分]


按 F7 单步跟踪,细心观察它在干甚么


00401230 /$ 8B0D BC564000 MOV ECX,DWORD PTR DS:[4056BC]
00401236 |. 83EC 30    SUB ESP,30            // 在 stack 划出空间,作为变量
00401239 |. 8D4424 00   LEA EAX,DWORD PTR SS:[ESP]
0040123D |. 53       PUSH EBX
0040123E |. 56       PUSH ESI
0040123F |. 8B35 94404000 MOV ESI,DWORD PTR DS:[<&USER32.GetDlgIte>; USER32.GetDlgItemTextA
00401245 |. 6A 10     PUSH 10                 ; /Count = 10 (16.)
00401247 |. 50       PUSH EAX                 ; |Buffer          // <---- 注意这里,
00401248 |. 68 E8030000  PUSH 3E8                 ; |ControlID = 3E8 (1000.) // 可以看出存放字符串的地方
0040124D |. 51       PUSH ECX                 ; |hWnd => NULL      
0040124E |. 33DB      XOR EBX,EBX               ; |
00401250 |. FFD6      CALL ESI                 ; \GetDlgItemTextA
00401252 |. 83F8 03    CMP EAX,3             // 找到注册名字,如果字名的长度不小于 3,便跳,否则便完结
00401255 |. 73 0B     JNB SHORT ncrackme.00401262
00401257 |. 5E       POP ESI
00401258 |. B8 01000000  MOV EAX,1
0040125D |. 5B       POP EBX
0040125E |. 83C4 30    ADD ESP,30
00401261 |. C3       RETN               // 如果来了这里,便完结了
00401262 |> A1 BC564000  MOV EAX,DWORD PTR DS:[4056BC]   // 从 JNB 来了这里
00401267 |. 8D5424 28   LEA EDX,DWORD PTR SS:[ESP+28]
0040126B |. 6A 10     PUSH 10
0040126D |. 52       PUSH EDX             // <----- 注意这里,可以看出存放序号字符串的地方
0040126E |. 68 E9030000  PUSH 3E9
00401273 |. 50       PUSH EAX
00401274 |. FFD6      CALL ESI             // 再用 GetDlgItemTextA ,得到序号
00401276 |. 0FBE4424 08  MOVSX EAX,BYTE PTR SS:[ESP+8]   // 把名字的第一个位,放入 EAX
0040127B |. 0FBE4C24 09  MOVSX ECX,BYTE PTR SS:[ESP+9]   // 把名字的第二个位,放入 ECX
00401280 |. 99       CDQ                // 把 EAX 扩展,成为 EDX:EAX 的 QWORD(64 位长)
00401281 |. F7F9      IDIV ECX             // 把 EDX:EAX 除以 ECX,余数放在 EDX
00401283 |. 8BCA      MOV ECX,EDX            
00401285 |. 83C8 FF    OR EAX,FFFFFFFF          // EAX = 0xffffffff
00401288 |. 0FBE5424 0A  MOVSX EDX,BYTE PTR SS:[ESP+A]   // 把名字的第一个位,放入 EDX
0040128D |. 0FAFCA     IMUL ECX,EDX           // 把刚才的余数乘以 EDX
00401290 |. 41       INC ECX              // ECX 增加 1
00401291 |. 33D2      XOR EDX,EDX            // EDX = 0
00401293 |. F7F1      DIV ECX              // 以 0xffffffff 除以 ECX

以 C 语言表达,想象成

EAX 的值: 0xFFFFFFFF / (1+(buffer[0] % buffer[1] * buffer[2])

数值相等于 4546e6


00401295 |. 50       PUSH EAX             // push 了 4546e6
00401296 |. E8 A5000000  CALL ncrackme.00401340      // 进去看看


00401340 /$ 8B4424 04   MOV EAX,DWORD PTR SS:[ESP+4]   // 把刚才传进来的值 (4546e6),放到 EAX
00401344 |. A3 AC504000  MOV DWORD PTR DS:[4050AC],EAX   // 又由 EAX 放到 DS:[4050AC]
00401349 \. C3       RETN

这两行把上面的运算结果放到 DS:[4050AC] 去,不明白原因,继续跟下去

回到外面

0040129B |. 83C4 04    ADD ESP,4             // 清理 stack
0040129E |. 33F6      XOR ESI,ESI            // 设 ESI 为 0
004012A0 |> E8 A5000000  /CALL ncrackme.0040134A      // 走进去看看


0040134A /$ A1 AC504000  MOV EAX,DWORD PTR DS:[4050AC]   // 把那个值 (4546e6) 放入 EAX
0040134F |. 69C0 FD430300 IMUL EAX,EAX,343FD        // EAX 乘以 343FD
00401355 |. 05 C39E2600  ADD EAX,269EC3          // 再加 269EC3
0040135A |. A3 AC504000  MOV DWORD PTR DS:[4050AC],EAX   // 把结果放回 DS:[4050AC]
0040135F |. C1F8 10    SAR EAX,10            // 向右方 bit shift 10 位
00401362 |. 25 FF7F0000  AND EAX,7FFF           // 再 AND 了 7fff
00401367 \. C3       RETN               // 得到一个古怪的值,返回了

没有甚么特别,只是一大轮运算,得到一个新的值 3add

返回外面


004012A5 |. 99       |CDQ               // 把那个值扩展成 EDX:EAX
004012A6 |. B9 1A000000  |MOV ECX,1A            // ECX = 1a
004012AB |. F7F9      |IDIV ECX             // 把 EDX:EAX 除以 1a
004012AD |. 80C2 41    |ADD DL,41            // 把余数加 41,说起来,41 是 ASCII 的大写 A
004012B0 |. 885434 18   |MOV BYTE PTR SS:[ESP+ESI+18],DL // 把这个余数的下 8 位,放入 SS:[ESP+ESI+18] 的地方
004012B4 |. 46       |INC ESI             // ESI 增加 1 了
004012B5 |. 83FE 0F    |CMP ESI,0F            // 检查 ESI 是否已经等于 0f
004012B8 |.^72 E6     \JB SHORT ncrackme.004012A0    // 跳回上面,这像是一个小型 loop

从这里的结构,我们估计 ESI 由 0 增加至 0f ,不停把一组数字放入 stack 里面,这是一个回圈十六次的 loop
要注意这些数值都加上了 41 (ASCII A),它们都是由 41 开始

我们在 OD 下方的数值窗口,把数值打开来看

0012FC34 50 49 5A 49 56 4A 45 44 PIZIVJED
0012FC3C 42 47 5A 41 50 53 49 00 BGZAPSI.

这像是一堆 ASCII 字

我们继续看


004012BA |. 57       PUSH EDI             // 没有特别,只是保存 EDI,我们看见程序末段会有一个 pop edi
004012BB |. 8D7C24 0C   LEA EDI,DWORD PTR SS:[ESP+C]   // 从 OD 发现,SS:[ESP+C] 是注册名字位置,现在位置放入EDI
004012BF |. 83C9 FF    OR ECX,FFFFFFFF          // ECX = 0xffffffff
004012C2 |. 33C0      XOR EAX,EAX            // EAX = 0
004012C4 |. 33F6      XOR ESI,ESI            // ESI = 0
004012C6 |. F2:AE     REPNE SCAS BYTE PTR ES:[EDI]   

这里有一个 REPNE SCAS 的设置,它扫瞄注册名字,最多 ECX 次 (这里 ECX 是 0xffffffff 次),
或是遇上 AL 便停止 (这里 AL 是 0)

看来它在注册名字中寻找出 0 (字符串结尾位)

004012C8 |. F7D1      NOT ECX              // 把 ECX 反转,变成了扫瞄的次数
004012CA |. 49       DEC ECX              // ECX 减 1

现在 ECX 得到了注册名字的长度,是 6

004012CB |. 74 59     JE SHORT ncrackme.00401326    // 如果 ECX 是 0,跳到完结处
004012CD |> 8A4434 0C   /MOV AL,BYTE PTR SS:[ESP+ESI+C]  // 把注册名字第 esi 个位,放入 AL (刚开始是第 0 个)
004012D1 |. C0F8 05    |SAR AL,5             // 向右方 bit shift 5 位
004012D4 |. 0FBEC0     |MOVSX EAX,AL           // 把 AL 扩展到 EAX
004012D7 |. 8D1480     |LEA EDX,DWORD PTR DS:[EAX+EAX*4] // EDX = EAX + (EAX * 4)
004012DA |. 8D04D0     |LEA EAX,DWORD PTR DS:[EAX+EDX*8] // EAX = EAX + (EDX * 8)
004012DD |. 8D0440     |LEA EAX,DWORD PTR DS:[EAX+EAX*2] // EAX = EAX + (EAX * 2)
004012E0 |. 85C0      |TEST EAX,EAX           // 检查结果是否 0
004012E2 |. 7E 0A     |JLE SHORT ncrackme.004012EE   // 如果 0,便跳
004012E4 |. 8BF8      |MOV EDI,EAX           // EAX 放入 EDI
004012E6 |> E8 5F000000  |/CALL ncrackme.0040134A     // 很面熟,这是刚才的 call,把 EAX 进行一堆运算
004012EB |. 4F       ||DEC EDI             // EDI 减 1
004012EC |.^75 F8     |\JNZ SHORT ncrackme.004012E6   // 当 EDI 不等于 0 的时候,便跳上去,这是 loop

这个小型 loop 会循环 EDI 次,不停呼叫 ncrackme.0040134A,这个 call 我们刚才看过,
它会把 DS:[4050AC] 这个值改变。这样看来,随着我注册名字的位不同, EDI 的值
不同,它循环的次数便会不同

char X, Y

X = (buffer[esi] >> 5)
Y = X + (X * 4)
X = X + (Y * 8)
X = X + (X * 2)  

呼叫 ncrackme.0040134A X 次

继续看下去

004012EE |> E8 57000000  |CALL ncrackme.0040134A      // 再呼叫一次,现在 EAX 是返回值
004012F3 |. 99       |CDQ               // 把 EAX 扩展到 EDX:EAX
004012F4 |. B9 1A000000  |MOV ECX,1A            // ECX = 1a ( decimal 26)
004012F9 |. 8D7C24 0C   |LEA EDI,DWORD PTR SS:[ESP+C]   // 把注册名字的位置放在 EDI
004012FD |. F7F9      |IDIV ECX             // EDX:EAX 除以 ECX (1a)
004012FF |. 0FBE4C34 2C  |MOVSX ECX,BYTE PTR SS:[ESP+ESI+2C]  

从 OD 查看,SS:[ESP+ESI+2C] 是序号字符串,这里把序号的第 esi 个字符放进 ECX


00401304 |. 80C2 41    |ADD DL,41            // 把 DL (除数的余值,低位值) 加 41
00401307 |. 0FBEC2     |MOVSX EAX,DL           // 把 DL 放入 EAX
0040130A |. 2BC1      |SUB EAX,ECX           // EAX 减 ECX ,得到一个新的值,放在 EAX
0040130C |. 885434 1C   |MOV BYTE PTR SS:[ESP+ESI+1C],DL

  从 OD 查看,SS:[ESP+ESI+1C] 是那一组特别字符的位置,

  0012FC34 50 49 5A 49 56 4A 45 44 PIZIVJED
  0012FC3C 42 47 5A 41 50 53 49 00 BGZAPSI.

  这行把 DL 放入这里,取代原有的值

00401310 |. 99       |CDQ               // 把 EAX 扩展成 EDX:EAX
00401311 |. 33C2      |XOR EAX,EDX           // 把 EAX 跟 EDX 进行 XOR 合并
00401313 |. 83C9 FF    |OR ECX,FFFFFFFF         // ECX = 0xffffffff
00401316 |. 2BC2      |SUB EAX,EDX           // 把 EAX 减 EDX
00401318 |. 03D8      |ADD EBX,EAX           

  把 EBX 加 EAX,这真是奇怪,那里来的 EBX ? 我们向上追查,发现 EBX 一直没有使用, EBX 在 0040124E
  这一行被清空,它的初始值是 0。


0040131A |. 33C0      |XOR EAX,EAX           // EAX = 0
0040131C |. 46       |INC ESI             // ESI 增加 1
0040131D |. F2:AE     |REPNE SCAS BYTE PTR ES:[EDI]   

  看看 004012F9 这一行,发现 EDI 是注册名字的位置。
  现在 SCAS 扫瞄注册名字,找出 AL (0)


0040131F |. F7D1      |NOT ECX             // 还记得上面的结构吗 ? 把 ECX 反转,便是注册名字的长度 + 1
00401321 |. 49       |DEC ECX             // 把 ECX 减 1,现在 ECX 是注册名字长度
00401322 |. 3BF1      |CMP ESI,ECX           // 比较 ESI 和注册名字长度
00401324 |.^72 A7     \JB SHORT ncrackme.004012CD    // 当 ESI 小于注册名字长度,便往上跳,这是 loop

  以上的结构,是一个大型的 loop,以不停增加 ESI 的值,把注册名字和序号进行运算,
  其运算结果便累加到 EBX 上


00401326 |> 5F       POP EDI              // 这是完结部分,复原 EDI
00401327 |. 8BC3      MOV EAX,EBX            // 把 EBX 的最后值,放入 EAX ,EAX 将会是这个 CALL 的返回值
00401329 |. 5E       POP ESI              // 复原 ESI
0040132A |. 5B       POP EBX              // 复原 EBX
0040132B |. 83C4 30    ADD ESP,30            // 清理 stack 空间
0040132E \. C3       RETN               // 离开


  还记得我们在 PART. 1 的结尾部份吗 ? 我们遇上了跳出成功注册信息的检查程序,如果这个 CALL 的返回值是 0 的话,
  我们便会成功注册。我们的任务是分析上面的算法,找出一个序号,可以使返回值 (前身是 EBX) 最后的结果是 0。

  用 OD 跟踪后,我们可以观察到以下特点:

  1. EBX 的初始值是 0,它在每一次循环都会被增加,只会增加,不会减少

  2. 如果要 EBX 的值保持是 0,那么它上面 SUB EAX,EDX 这一行的结果,必须是 0,也就是说, EAX 和 EDX 必须相等

  3. 再往上看,发现 EAX 和 EDX 是由 00401310 这一行, CDQ 指令产生的。 CDQ 把原来的 EAX 扩展成 EDX:EAX (带正负值),
    这个指令把 EAX 的第 31 bit 复制到 EDX 的每一个 bit 上。例如 :

    假设 EAX 是 FFFFFFFB (-5) ,它的第 31 bit (最左边) 是 1,
    执行 CDQ 后, CDQ 把第 31 bit 复制至 EDX 所有 bit

    EDX 变成 FFFFFFFF

    这时候, EDX:EAX 变成 FFFFFFFF FFFFFFFB ,它是一个 64 bit 的大型数字,数值依旧是 -5


    我们发现, 00401310 和 00401311 这两行,执行了 CDQ 和 XOR EAX,EDX ,这说明了它的目的,当 EAX 的值是一个
    负数,执行 CDQ 后 EDX 变成 FFFFFFFF,它再跟 EAX 进行 XOR,便会使 EAX 反转,变成一个正数。假如 EAX 本来
    是一个正数,执行 CDQ 后 EDX 是 0,它再跟 EAX 进行 XOR ,没有任何效果,保留 EAX 的值

    由始可见,

00401310 |. 99       |CDQ     
00401311 |. 33C2      |XOR EAX,EDX

    这两行其实是从 EAX 得出 "绝对值"。如果 EAX 是 -5,便会变成 5,如果 EAX 是 5,便依然是 5


  4. 由上面的分析可见,要使 SUB EAX,EDX 这一行的结果是 0,只有一个可能性,这就是 EAX 本来是 0 。因为当 EAX 是 0
    的时候, CDQ EAX 才会使 EDX 和 EAX 成为 0,这种情况下 SUB EAX,EDX 便会是 0

  5. 再往上追查,我们发现了这行

0040130A |. 2BC1      |SUB EAX,ECX

    这行把 EAX 减去 ECX,这里的 ECX 是甚么 ? 再往上追查 004012FF,发现它正是我们的序号字符串
   

004012FF |. 0FBE4C34 2C  |MOVSX ECX,BYTE PTR SS:[ESP+ESI+2C]

    由此可见,这个 EAX 的值会减去相对位置的序号字符。

    只要我们得到每一个 EAX 的值,把它们串行成序号,便可以用它顺利成功注册,我们找到了光明之路了 !

   

  我们把 crackme 再运行一次,在 0040130A 设下断点,记录每一个 EAX 的值

  50 4d 51 4a 44

  把这些值转换成 ASCII,那就是

  P M Q J D

  现在,我们再运行 crackme ,以 riijj 作为名字, PMQJD 作为序号,成功注册了 !!
Tale 发表于 2008-5-22 19:52
只会爆破 [s:38]
00401072   /75 1B     JNZ SHORT ncrackme.0040108F       ; |
//NOP
 楼主| mycsy 发表于 2008-5-22 19:57
哈哈 爆破的 和我也不一样啊

::00401072:: 75 1B  JNE SHORT 0040108F  
改为   
::00401072:: 74 1B  JE SHORT 0040108F
注册成功  Registration successful
luzechao 发表于 2008-5-22 20:00
爆破,这个很简单嘛....
HOHO...
JE也行....

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x
淫乱一世纪 发表于 2008-5-22 20:12
晕,mycsy 你自己都自言自语 不留悬念地先干掉,
叫我们咋整?
 楼主| mycsy 发表于 2008-5-22 20:15
我晕 是个问题哦

哈哈 膜拜淫乱大牛

我去改
luzechao 发表于 2008-5-22 20:18
引用第2楼mycsy于2008-05-22 19:44发表的 :
浏览此贴需要威望
小子,你隐藏了些什么东西?
淫乱一世纪 发表于 2008-5-22 20:21
晕,什么大牛。。菜鸟~

http://www.crackmes.de 这里的crackme很多。。~~~


又是算法,只能呼叫 徐超了~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 04:36

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表