首页
社区
课程
招聘
修正一个CrackMe的破文
发表于: 2011-10-18 22:59 8827

修正一个CrackMe的破文

2011-10-18 22:59
8827
以近比较烦,打发一下时间。做做CM题。结果郁闷了半天,无奈,看答案,看了答案后,发现有答案有错误。我把自己写的东西放到了idb文件里。供大家参考。注意一下SEH的运用,代码解密就行了。呵呵。有些无聊啊:-)

标 题: 奇妙的跳转【原创】
作 者: coldpine
时 间: 2006-09-14 12:44
附 件: sv_keygenme.zip
链 接: http://bbs.pediy.com/showthread.php?threadid=31928
详细信息:

【文章标题】: 奇妙的跳转
【文章作者】: coldpine
【软件名称】: SV_KeygenMe.exe
【下载地址】: b7fK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3y4J5j5h3y4C8L8h3g2K6i4K6u0W2k6r3g2Q4x3V1k6#2M7$3g2J5M7#2)9J5c8Y4y4$3i4K6g2X3M7X3g2$3k6i4u0K6k6i4u0Q4x3V1k6K6N6W2)9#2k6X3E0W2P5h3N6W2L8X3#2W2i4K6u0r3
【编写语言】: masm
【使用工具】: od & calc.exe
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  用od加载,对GetDlgItemTextA函数下断点,并输入
  name:heminrui
  code:1234567890123456(经过跟踪发现要16位序列号)
  00401229   .  6A 28         PUSH    28                               ;
  0040122B   .  68 68344000   PUSH    SV_Keyge.00403468                ;
  00401230   .  68 EB030000   PUSH    3EB                              ;
  00401235   .  FF75 08       PUSH    DWORD PTR SS:[EBP+8]             ;
  00401238   .  E8 0B010000   CALL    <JMP.&user32.GetDlgItemTextA>    ; 获取输入的name
  0040123D   .  6A 28         PUSH    28                               ;
  0040123F   .  68 68304000   PUSH    SV_Keyge.00403068                ;
  00401244   .  68 EC030000   PUSH    3EC                              ;
  00401249   .  FF75 08       PUSH    DWORD PTR SS:[EBP+8]             ;
  0040124C   .  E8 F7000000   CALL    <JMP.&user32.GetDlgItemTextA>    ; 获取输入的code
  00401251   .  68 68304000   PUSH    SV_Keyge.00403068                ;
  00401256   .  E8 53010000   CALL    <JMP.&kernel32.lstrlenA>         ; code代码的长度
  0040125B   .  83F8 10       CMP     EAX, 10                          ;判断是不是16位,如果不是的,就跳出
  0040125E      75 64         JNZ     SHORT SV_Keyge.004012C4
  00401260   .  E8 D3FDFFFF   CALL    SV_Keyge.00401038        ;关键call,计算序列号用的函数
  
  跟进子函数
  功能:取name每位字符的ascii码和code的两位数字进行异或
  ----------------------------------------------------------------------------------------------
  00401038  /$  8D1D 68344000 LEA     EBX, DWORD PTR DS:[403468]       ;用户名地址进ebx
  0040103E  |.  8D35 68304000 LEA     ESI, DWORD PTR DS:[403068]       ;序列号地址进esi
  00401044  |.  8D3D 68324000 LEA     EDI, DWORD PTR DS:[403268]
  0040104A  |.  EB 2A         JMP     SHORT SV_Keyge.00401076
  0040104C  |>  6A 03         /PUSH    3                               ; /n = 3
  0040104E  |.  56            |PUSH    ESI                             ; |String2
  0040104F  |.  68 68364000   |PUSH    SV_Keyge.00403668               ; |String1 = SV_Keyge.00403668
  00401054  |.  E8 4F030000   |CALL    <JMP.&kernel32.lstrcpynA>       ; \lstrcpynA
  00401059  |.  68 68364000   |PUSH    SV_Keyge.00403668               ;取code两位进缓冲区
  0040105E  |.  E8 51030000   |CALL    SV_Keyge.004013B4
  00401063  |.  3203          |XOR     AL, BYTE PTR DS:[EBX]           ;取code前两位和name的第一位的ascii码值异或
  00401065  |.  8807          |MOV     BYTE PTR DS:[EDI], AL           ;保存结果
  00401067  |.  46            |INC     ESI                             
  00401068  |.  46            |INC     ESI               ;code后两位的地址
  00401069  |.  43            |INC     EBX               ;取name后一位的地址
  0040106A  |.  803B 00       |CMP     BYTE PTR DS:[EBX], 0            ;没有取完,就继续取完,取玩的话,再重新取一遍
  0040106D  |.  75 06         |JNZ     SHORT SV_Keyge.00401075
  0040106F  |.  8D1D 68344000 |LEA     EBX, DWORD PTR DS:[403468]
  00401075  |>  47            |INC     EDI
  00401076  |>  803E 00        CMP     BYTE PTR DS:[ESI], 0      ;比较code取完了没有            
  00401079  |.^ 75 D1         \JNZ     SHORT SV_Keyge.0040104C
  0040107B  \.  C3            RET
  
  
  ----------------------------------------------------------------------------------------------------
  
  
  
  00401265   .  8D3D 68324000 LEA     EDI, DWORD PTR DS:[403268]
  0040126B      FFD7          CALL    EDI
  0040126D   .  6A 00         PUSH    0                                ; /Style = MB_OK|MB_APPLMODAL
  0040126F   .  68 3B304000   PUSH    SV_Keyge.0040303B                ; |then  ?
  00401274   .  68 1C304000   PUSH    SV_Keyge.0040301C                ; |try again
  00401279   .  6A 00         PUSH    0                                ; |hOwner = NULL
  0040127B   .  E8 E6000000   CALL    <JMP.&user32.MessageBoxA>        ; \MessageBoxA
  00401280   .  EB 42         JMP     SHORT SV_Keyge.004012C4
  00401282   .  8D3D 68324000 LEA     EDI, DWORD PTR DS:[403268]
  00401288   .  83C7 04       ADD     EDI, 4
  0040128B   .  8B07          MOV     EAX, DWORD PTR DS:[EDI]
  0040128D      3B05 90364000 CMP     EAX, DWORD PTR DS:[403690]
  00401293      75 1C         JNZ     SHORT SV_Keyge.004012B1
  00401295   .  E8 60000000   CALL    SV_Keyge.004012FA
  0040129A   .  68 E9030000   PUSH    3E9                              ; /ControlID = 3E9 (1001.)
  0040129F   .  FF75 08       PUSH    DWORD PTR SS:[EBP+8]             ; |hWnd
  004012A2   .  E8 9B000000   CALL    <JMP.&user32.GetDlgItem>         ; \GetDlgItem
  004012A7   .  6A 00         PUSH    0                                ; /Enable = FALSE
  004012A9   .  50            PUSH    EAX                              ; |hWnd
  004012AA   .  E8 8D000000   CALL    <JMP.&user32.EnableWindow>       ; \EnableWindow
  004012AF   .  EB 13         JMP     SHORT SV_Keyge.004012C4
  004012B1   >  6A 00         PUSH    0                                ; /Style = MB_OK|MB_APPLMODAL
  004012B3   .  68 3B304000   PUSH    SV_Keyge.0040303B                ; |then  ?
  004012B8   .  68 1C304000   PUSH    SV_Keyge.0040301C                ; |try again
  004012BD   .  6A 00         PUSH    0                                ; |hOwner = NULL
  004012BF   .  E8 A2000000   CALL    <JMP.&user32.MessageBoxA>        ; \MessageBoxA
  004012C4   >  FF75 EC       PUSH    DWORD PTR SS:[EBP-14]
  004012C7   .  64:8F05 00000>POP     DWORD PTR FS:[0]
  004012CE   .  EB 0D         JMP     SHORT SV_Keyge.004012DD
  004012D0   >  66:3D EA03    CMP     AX, 3EA
  004012D4   .  75 07         JNZ     SHORT SV_Keyge.004012DD
  004012D6   .  6A 00         PUSH    0                                ; /ExitCode = 0
  004012D8   .  E8 8F000000   CALL    <JMP.&user32.PostQuitMessage>    ; \PostQuitMessage
  004012DD   >  EB 15         JMP     SHORT SV_Keyge.004012F4
  004012DF   >  FF75 14       PUSH    DWORD PTR SS:[EBP+14]            ; /lParam
  004012E2   .  FF75 10       PUSH    DWORD PTR SS:[EBP+10]            ; |wParam
  004012E5   .  FF75 0C       PUSH    DWORD PTR SS:[EBP+C]             ; |Message
  004012E8   .  FF75 08       PUSH    DWORD PTR SS:[EBP+8]             ; |hWnd
  004012EB   .  E8 40000000   CALL    <JMP.&user32.DefWindowProcA>     ; \DefWindowProcA
  004012F0   .  C9            LEAVE
  004012F1   .  C2 1000       RET     10
  004012F4   >  33C0          XOR     EAX, EAX
  004012F6   .  C9            LEAVE
  004012F7   .  C2 1000       RET     10
  
  
--------------------------------------------------------------------------------
【分析总结】
  这个软件我运行了之后通过调试,发现根本没有成功的对话框
  即使code是16位的,仍然一运行就跳到try again对话框上去了.
  但是仔细看了一下代码
  00401265   .  8D3D 68324000 LEA     EDI, DWORD PTR DS:[403268]
  0040126B      FFD7          CALL    EDI
  0040126D   .  6A 00         PUSH    0                                ; /Style = MB_OK|MB_APPLMODAL
  0040126F   .  68 3B304000   PUSH    SV_Keyge.0040303B                ; |then  ?
  00401274   .  68 1C304000   PUSH    SV_Keyge.0040301C                ; |try again
  00401279   .  6A 00         PUSH    0                                ; |hOwner = NULL
  0040127B   .  E8 E6000000   CALL    <JMP.&user32.MessageBoxA>        ; \MessageBoxA
  00401280   .  EB 42         JMP     SHORT SV_Keyge.004012C4
  00401282   .  8D3D 68324000 LEA     EDI, DWORD PTR DS:[403268]
  00401288   .  83C7 04       ADD     EDI, 4
  0040128B   .  8B07          MOV     EAX, DWORD PTR DS:[EDI]
  0040128D      3B05 90364000 CMP     EAX, DWORD PTR DS:[403690]
  00401293      75 1C         JNZ     SHORT SV_Keyge.004012B1
  00401295   .  E8 60000000   CALL    SV_Keyge.004012FA
  0040129A   .  68 E9030000   PUSH    3E9                              ; /ControlID = 3E9 (1001.)
  0040129F   .  FF75 08       PUSH    DWORD PTR SS:[EBP+8]             ; |hWnd
  004012A2   .  E8 9B000000   CALL    <JMP.&user32.GetDlgItem>         ; \GetDlgItem
  004012A7   .  6A 00         PUSH    0                                ; /Enable = FALSE
  004012A9   .  50            PUSH    EAX                              ; |hWnd
  004012AA   .  E8 8D000000   CALL    <JMP.&user32.EnableWindow>       ; \EnableWindow
  004012AF   .  EB 13         JMP     SHORT SV_Keyge.004012C4
  004012B1   >  6A 00         PUSH    0                                ; /Style = MB_OK|MB_APPLMODAL
  004012B3   .  68 3B304000   PUSH    SV_Keyge.0040303B                ; |then  ?
  004012B8   .  68 1C304000   PUSH    SV_Keyge.0040301C                ; |try again
  004012BD   .  6A 00         PUSH    0                                ; |hOwner = NULL
  004012BF   .  E8 A2000000   CALL    <JMP.&user32.MessageBoxA>        ; \MessageBoxA
  发现里面有一个EnableWindow函数,这几天我一直被那几个变灰的按钮搞的头晕,我猜想,是不是
  注册成功就跳转到这个EnableWindow函数上呢?但是查了半天没有看见能跳到EnableWindow这个函数
  上的跳转语句.但是我注意到了这个语句
  00401265   .  8D3D 68324000 LEA     EDI, DWORD PTR DS:[403268]
  0040126B      FFD7          CALL    EDI
  call edi 这个语句应该是调用数据段中的数据,于是我想肯定是通过异或计算出来的结果
  通过call,电脑就把那些数据理解成代码,而且应该是个段间跳转吧!
  于是我通过修改汇编指令:
  首先转到DS:[403268]
  然后修改汇编指令jmp long 401282,看见对应的hex数据变成了E915E0FFFF
  然后单步执行又跳回代码段
  
  00401282   .  8D3D 68324000 LEA     EDI, DWORD PTR DS:[403268]
  00401288   .  83C7 04       ADD     EDI, 4
  0040128B   .  8B07          MOV     EAX, DWORD PTR DS:[EDI]
  0040128D      3B05 90364000 CMP     EAX, DWORD PTR DS:[403690]
  00401293      75 1C         JNZ     SHORT SV_Keyge.004012B1
  
  只是后面有一个比较语句取出计算出来的数据后四个字节
  和DS:[403690]这个地方进行双字(DWORD)比较,我就纳闷了,这个DS:[403690]
  好像在计算序列号的时候并没有出现过,我通过向上查看,终于看见了DS:[403690]出现
  00401218   .  C705 90364000>MOV     DWORD PTR DS:[403690], 0FFFFFF
  00401222   .  C605 68324000>MOV     BYTE PTR DS:[403268], 0
  原来DS:[403690]的内容是00ffffff
  这个说明了通过name和code计算的结果后面的四个字节中应该有00ffffff
  否则的话也跳出那个按钮变灰的函数.
  
  
  好了,弄清楚了算法:就是将name和code两位异或,结果前面刚好能
  组成一个段间跳转语句,后面的四位刚好是00ffffff
  由于按照双字取出,所以实际上要的是ffffff00
  所以最终name和code异或的结果必须是
  E915E0FF  FFFFFF00
   
  
  现在就开始计算正确的序列号:由于计算过程只有一个异或的过程很简单,并且
  异或运行的逆运算也是异或,所以:
  h 的ascii码值是68   xor   e9     =     81
  e 的ascii码值是65   xor   15     =     70
  m 的ascii码值是6D   xor   e0     =     8d
  i 的ascii码值是69   xor   ff     =     96
  n 的ascii码值是6E   xor   ff     =     91
  r 的ascii码值是72   xor   ff     =     8d
  u 的ascii码值是75   xor   ff     =     8a
  i 的ascii码值是69   xor   00     =     69
  组在一起就是code:81708d96918d8a69 由于只是比较数字,所以不分大小写.
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年09月14日 12:41:33

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

  ©2000-2007 PEdiy.com All rights reserved.
By PEDIY

[培训]科锐软件逆向54期预科班、正式班开始火爆招生报名啦!!!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 210
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
先支持,收藏了,明天练练手
2011-10-19 01:33
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢 学习下
2011-10-19 10:59
0
游客
登录 | 注册 方可回帖
返回