首页
社区
课程
招聘
[原创]堆栈的计算
发表于: 2006-10-12 19:25 6483

[原创]堆栈的计算

2006-10-12 19:25
6483

【文章标题】: 堆栈的计算
【文章作者】: coldpine
【下载地址】: http://www.crackmes.de/users/pickled/crackme0x1/
【编写语言】: c++
【使用工具】: od
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  name:heminrui
  serial:123456789
  00401290  /$  55            PUSH    EBP
  00401291  |.  89E5          MOV     EBP, ESP
  00401293  |.  81EC A8000000 SUB     ESP, 0A8
  00401299  |.  83E4 F0       AND     ESP, FFFFFFF0
  0040129C  |.  B8 00000000   MOV     EAX, 0
  004012A1  |.  83C0 0F       ADD     EAX, 0F
  004012A4  |.  83C0 0F       ADD     EAX, 0F
  004012A7  |.  C1E8 04       SHR     EAX, 4
  004012AA  |.  C1E0 04       SHL     EAX, 4
  004012AD  |.  8985 74FFFFFF MOV     DWORD PTR SS:[EBP-8C], EAX
  004012B3  |.  8B85 74FFFFFF MOV     EAX, DWORD PTR SS:[EBP-8C]
  004012B9  |.  E8 92050000   CALL    xtfK1.00401850
  004012BE  |.  E8 2D020000   CALL    xtfK1.004014F0
  004012C3  |.  C70424 002040>MOV     DWORD PTR SS:[ESP], xtfK1.004020>; |||||created by: xtfusion\ncrackme: k1\n\nwelcome to my first crackme! (sorry for my lazy coding)\nalso i had no time to test this crackme! but it should\nwork on 95 , 98 , 2000 , xp\ncreate a keygen and make a tut for crackmes.de\nthats all so injoy.\n\n
  004012CA  |.  E8 91060000   CALL    <JMP.&msvcrt.printf>             ; ||||\printf
  004012CF  |.  C70424 003040>MOV     DWORD PTR SS:[ESP], xtfK1.004030>; ||||name:
  004012D6  |.  E8 85060000   CALL    <JMP.&msvcrt.printf>             ; |||\printf
  004012DB  |.  8D45 98       LEA     EAX, DWORD PTR SS:[EBP-68]       ; |||
  004012DE  |.  890424        MOV     DWORD PTR SS:[ESP], EAX          ; |||
  004012E1  |.  E8 6A060000   CALL    <JMP.&msvcrt.gets>               ; ||\gets
  004012E6  |.  C70424 073040>MOV     DWORD PTR SS:[ESP], xtfK1.004030>; ||serial:
  004012ED  |.  E8 6E060000   CALL    <JMP.&msvcrt.printf>             ; |\printf
  004012F2  |.  8D85 78FFFFFF LEA     EAX, DWORD PTR SS:[EBP-88]       ; |
  004012F8  |.  890424        MOV     DWORD PTR SS:[ESP], EAX          ; |
  004012FB  |.  E8 50060000   CALL    <JMP.&msvcrt.gets>               ; \gets 
  00401300  |.  C745 F4 00000>MOV     DWORD PTR SS:[EBP-C], 0
  00401307  |>  8D45 98       /LEA     EAX, DWORD PTR SS:[EBP-68]      ;
  0040130A  |.  890424        |MOV     DWORD PTR SS:[ESP], EAX         ; 取得用户名
  0040130D  |.  E8 2E060000   |CALL    <JMP.&msvcrt.strlen>            ; \strlen
  00401312  |.  3945 F4       |CMP     DWORD PTR SS:[EBP-C], EAX    ;比较,不大于的时候跳走
  00401315  |.  73 4B         |JNB     SHORT xtfK1.00401362      
  00401317  |.  8D45 F8       |LEA     EAX, DWORD PTR SS:[EBP-8]
  0040131A  |.  0345 F4       |ADD     EAX, DWORD PTR SS:[EBP-C]
  0040131D  |.  83E8 60       |SUB     EAX, 60             ;用户名(循环的时候由于[ebp-c]在逐渐加1,所以可以循环取用户名的每个字符)
  00401320  |.  0FBE10        |MOVSX   EDX, BYTE PTR DS:[EAX]     ;取用户名每个字符的ascii码值,设值为x
  00401323  |.  89D0          |MOV     EAX, EDX            ;eax=x,edx=x             
  00401325  |.  C1E0 02       |SHL     EAX, 2             ;将x左移两位
  00401328  |.  01D0          |ADD     EAX, EDX            ;再求和
  0040132A  |.  89C2          |MOV     EDX, EAX            ;分别将结果保留为两份
  0040132C  |.  C1E2 04       |SHL     EDX, 4                          ;将其中的一份左移四位
  0040132F  |.  8D45 EC       |LEA     EAX, DWORD PTR SS:[EBP-14]      ;12c6cc的地址             ;12e74c
  00401332  |.  0110          |ADD     DWORD PTR DS:[EAX], EDX         ;12c6cc+2080=12e74c        = y1           ;12e74c+1f90=1306dc      =y2
  00401334  |.  8B45 EC       |MOV     EAX, DWORD PTR SS:[EBP-14]   
  00401337  |.  0345 E8       |ADD     EAX, DWORD PTR SS:[EBP-18]      ;12e74c+77c0aead=77d395f9              1306dc+77d395cb=77e69ca7
  0040133A  |.  83F0 32       |XOR     EAX, 32                         ;将结果异或77d395f9 xor 32=77d395cb    77e69ca7 xor 32 =77e69c95
  0040133D  |.  8945 E8       |MOV     DWORD PTR SS:[EBP-18], EAX    [ebp-18]= 77d395cb        = y1'            [ebp-18]=77e69c95        =y2'
  00401340  |.  8B45 E8       |MOV     EAX, DWORD PTR SS:[EBP-18]
  00401343  |.  8D1485 000000>|LEA     EDX, DWORD PTR DS:[EAX*4]       ;edx=DF4E572C                         edx=DF9A7254
  0040134A  |.  8D45 E4       |LEA     EAX, DWORD PTR SS:[EBP-1C]      ;ebp-1c存放着8                        [ebp-1c]=DF4E5734
  0040134D  |.  0110          |ADD     DWORD PTR DS:[EAX], EDX        ;[ebp-1c]=DF4E572C+8=DF4E5734   =z1    [ebp-1c]=DF9A7254+DF4E5734=BEE8C988   =z2
  0040134F  |.  8B45 E8       |MOV     EAX, DWORD PTR SS:[EBP-18]      ;[ebp-18]=77d395cb                   [ebp-18]=77e69c95 并送到eax
  00401352  |.  0345 E4       |ADD     EAX, DWORD PTR SS:[EBP-1C]       ;eax=77d395cb+DF4E5734=5721ECF7     eax=77e69c95+BEE8C988=36CF661D
  00401355  |.  0345 EC       |ADD     EAX, DWORD PTR SS:[EBP-14]        ;eax=5721ecf7+12e74c=5734d44b       eax=36CF661D+1306dc=36E26CF9
  00401358  |.  8945 E0       |MOV     DWORD PTR SS:[EBP-20], EAX        ;[ebp-20]=5734d44b         =z1'       [ebp-20]=36E26CF9                   =z2'
  0040135B  |.  8D45 F4       |LEA     EAX, DWORD PTR SS:[EBP-C]         
  0040135E  |.  FF00          |INC     DWORD PTR DS:[EAX]                ;22ff6c是一个计数器,计数器加1       计数器再加1,继续第三位跟踪
  00401360  |.^ EB A5         \JMP     SHORT xtfK1.00401307                                                         
  00401362  |>  8B45 E0       MOV     EAX, DWORD PTR SS:[EBP-20]       ; ||
  00401365  |.  894424 08     MOV     DWORD PTR SS:[ESP+8], EAX        ; ||
  00401369  |.  C74424 04 103>MOV     DWORD PTR SS:[ESP+4], xtfK1.0040>; ||%x
  00401371  |.  8D45 B8       LEA     EAX, DWORD PTR SS:[EBP-48]       ; ||
  00401374  |.  890424        MOV     DWORD PTR SS:[ESP], EAX          ; ||
  00401377  |.  E8 44060000   CALL    <JMP.&USER32.wsprintfA>          ; |\wsprintfA        将结果7B52F4A1变成字符串"7b52f4a1"(这个就是最终的真注册码)
  0040137C  |.  C745 F0 00000>MOV     DWORD PTR SS:[EBP-10], 0         ; |        
  00401383  |.  80BD 78FFFFFF>CMP     BYTE PTR SS:[EBP-88], 0          ; |                  ;输入的序列号和0比较
  0040138A  |.  75 0E         JNZ     SHORT xtfK1.0040139A             ; |
  0040138C  |.  C70424 133040>MOV     DWORD PTR SS:[ESP], xtfK1.004030>; |serial 2 short!
  00401393  |.  E8 C8050000   CALL    <JMP.&msvcrt.printf>             ; \printf
  00401398  |.  EB 57         JMP     SHORT xtfK1.004013F1
  0040139A  |>  807D 98 00    CMP     BYTE PTR SS:[EBP-68], 0          ; |
  0040139E  |.  75 0E         JNZ     SHORT xtfK1.004013AE             ; |
  004013A0  |.  C70424 233040>MOV     DWORD PTR SS:[ESP], xtfK1.004030>; |name 2 short!
  004013A7  |.  E8 B4050000   CALL    <JMP.&msvcrt.printf>             ; \printf
  004013AC  |.  EB 43         JMP     SHORT xtfK1.004013F1
  004013AE  |>  C745 F4 00000>MOV     DWORD PTR SS:[EBP-C], 0
  004013B5  |>  8D85 78FFFFFF /LEA     EAX, DWORD PTR SS:[EBP-88]      ; |
  004013BB  |.  890424        |MOV     DWORD PTR SS:[ESP], EAX         ; |          将计算出来的序号和输入的序列号逐位比较,是注册成功,否则失败!
  004013BE  |.  E8 7D050000   |CALL    <JMP.&msvcrt.strlen>            ; \strlen
  004013C3  |.  3945 F4       |CMP     DWORD PTR SS:[EBP-C], EAX
  004013C6  |.  73 29         |JNB     SHORT xtfK1.004013F1
  004013C8  |.  8D45 F8       |LEA     EAX, DWORD PTR SS:[EBP-8]
  004013CB  |.  0345 F4       |ADD     EAX, DWORD PTR SS:[EBP-C]
  004013CE  |.  8D48 C0       |LEA     ECX, DWORD PTR DS:[EAX-40]
  004013D1  |.  8D45 F8       |LEA     EAX, DWORD PTR SS:[EBP-8]
  004013D4  |.  0345 F4       |ADD     EAX, DWORD PTR SS:[EBP-C]
  004013D7  |.  8D50 80       |LEA     EDX, DWORD PTR DS:[EAX-80]
  004013DA  |.  0FB601        |MOVZX   EAX, BYTE PTR DS:[ECX]
  004013DD  |.  3A02          |CMP     AL, BYTE PTR DS:[EDX]
  004013DF      75 02         JNZ     SHORT xtfK1.004013E3
  004013E1  |.  EB 07         |JMP     SHORT xtfK1.004013EA
  004013E3  |>  C745 F0 01000>|MOV     DWORD PTR SS:[EBP-10], 1
  004013EA  |>  8D45 F4       |LEA     EAX, DWORD PTR SS:[EBP-C]
  004013ED  |.  FF00          |INC     DWORD PTR DS:[EAX]
  004013EF  |.^ EB C4         \JMP     SHORT xtfK1.004013B5
  004013F1  |>  837D F0 01    CMP     DWORD PTR SS:[EBP-10], 1
  004013F5      75 02         JNZ     SHORT xtfK1.004013F9
  004013F7  |.  EB 0C         JMP     SHORT xtfK1.00401405
  004013F9  |>  C70424 313040>MOV     DWORD PTR SS:[ESP], xtfK1.004030>; |\ncorect, now make a keygen\n   ;弹出注册成功标志.
  00401400  |.  E8 5B050000   CALL    <JMP.&msvcrt.printf>             ; \printf
  00401405  |>  B8 00000000   MOV     EAX, 0
  0040140A  |.  C9            LEAVE
  0040140B  \.  C3            RET
  
  
--------------------------------------------------------------------------------
【经验总结】
  这个crackme主要的感觉是对堆栈中计算过多,跟踪的时候比较费劲.
  算法:(都是16进制的计算)
  设每位字符的ascii码值为x1,x2,x3,...,xn
  将x1进行左移两位加上自身,再将上面结果左移四位设为x1'
  y1=x1'+12c6cc
  y1'=(y1+77c0aead) xor 32
  z1=(y1'*4)+8
  z1'=y1'+z1+y1
  到此,一个字符的结果计算出来了,但是这些结果并没有带到后面去,
  只是利用运行期间一些变量的变化而已.紧接着是计算第二个字符.
  y2=y1+x2'
  y2'=(y2+y1') xor 32
  z2=(y2'*4)+z1
  z2'=y2'+z2+y2
  直到最后的一个字母算出来的zn'
  将zn'转换格式化为字符即为注册码
  
  所以一组正确的注册码和用户名为:
  name:heminrui
  serial:7b52f4a1
  
     ;12c6cc的地址               ;12e74c
     ;12c6cc+2080=12e74c        = y1           ;12e74c+1f90=1306dc      =y2
  
     ;12e74c+77c0aead=77d395f9               1306dc+77d395cb=77e69ca7
     ;将结果异或77d395f9 xor 32=77d395cb     77e69ca7 xor 32 =77e69c95
     [ebp-18]= 77d395cb        = y1'            [ebp-18]=77e69c95        =y2'
  
     ;edx=DF4E572C                         edx=DF9A7254
     ;ebp-1c存放着8                        [ebp-1c]=DF4E5734
     ;[ebp-1c]=DF4E572C+8=DF4E5734   =z1    [ebp-1c]=DF9A7254+DF4E5734=BEE8C988   =z2
     ;[ebp-18]=77d395cb                   [ebp-18]=77e69c95 并送到eax
     ;eax=77d395cb+DF4E5734=5721ECF7     eax=77e69c95+BEE8C988=36CF661D
     ;eax=5721ecf7+12e74c=5734d44b       eax=36CF661D+1306dc=36E26CF9
     ;[ebp-20]=5734d44b         =z1'       [ebp-20]=36E26CF9                   =z2'
   感觉比较复杂的运行多跟踪几个循环,就比教容易找到规律了.
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年10月12日 19:23:16


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (4)
雪    币: 214
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
学习一下
2006-10-12 22:54
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
3
好精力的说,我现在对 Crackme 提不起劲来,这几天都在搞共享软件,有点收获

刚才跟了一下,难道不高

lgjxj

f0cb2223

大睡去了
2006-10-13 00:14
0
雪    币: 256
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
4
最初由 KAN 发布
好精力的说,我现在对 Crackme 提不起劲来,这几天都在搞共享软件,有点收获
........


一些比较基础的crackme都差不多,确实需要更进一步,
找共享软件是个好方法.
2006-10-14 06:30
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
用OD载入会出错,隐藏OD之后,先运行程序,再选择附加进OD,发现OD的程序领空是ntdll,进入不了xtfk1的程序领空,汗,看来不是入门新手碰的东西了.
2006-11-5 12:44
0
游客
登录 | 注册 方可回帖
返回
//