• 标 题:是男人就上120层破解教程
  • 作 者:ohko
  • 时 间:2004-2-02 周一, 下午10:23
  • 链 接:http://bbs.pediy.com

;#########################
;是男人就上120层破解记录
;2004-02-01
;ohko.com@163.com
;http://www.ohko.com
;如果转载请不要删除此信息
;#########################

    今天在网上逛,看到一篇关于这个游戏的文章,突然想起,自己的这个程序还没注册.哎呀,就动手来试试吧.这个游戏早就出来了,
相信大家都玩过了,也可能已经注册了.如果不是自己的注册码就看下去,搞个自己的注册码来注册吧.

;#########################
;程序:是男人就上120层
;工具:Ollydbg (如果没有,网上到处都有,很小的,下载吧.)
;时间:不会超过0.5小时的
;#########################

  打开Ollydbg,载用"是男人就上120层"这个程序.好,载入出,自动停在了程序的入口点上了.
  不要急,现在我们要先下断点.按"CTRL+N".找到"GetDlgItemTextA",按"回车",会弹出窗口的,在每一项上按"F2",每一个都断点.
好,现在断点好了,按"F9"运行程序.游戏运行后,点注册.
用户名: ohko
注册码: 1234567
确定.怎么样,断点对了,拦截在00402FC6处.
就是下面的代码了.
下面就一下一下的按"F8"
00402FC6   > 68 00010000     PUSH    100                           ; /Count = 100 (256.)
00402FCB   . 8D85 FCFDFFFF   LEA     EAXDWORD PTR SS:[EBP-204]   ; |
00402FD1   . 50              PUSH    EAX                           ; |Buffer
00402FD2   . 68 EB030000     PUSH    3EB                           ; |ControlID = 3EB (1003.)
00402FD7   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]     ; |
00402FDA   . 50              PUSH    EAX                           ; |hWnd
00402FDB   . FF15 78F34000   CALL    DWORD PTR DS:[<&USER32.GetDlg>; GetDlgItemTextA  取得用户输入的注册码
00402FE1   . 8D85 FCFDFFFF   LEA     EAXDWORD PTR SS:[EBP-204]
00402FE7   . 50              PUSH    EAX                           ;  [注册码]
;注意这里了00402FE8,下面就是验证注册码的了,要跟进去,按"F7"进入.
00402FE8   . E8 C0010000     CALL    是男人就.004031AD             ;!!!这里就是验证注册码了就.004031AD!!!
00402FED   . 83C4 04         ADD     ESP, 4
00402FF0   . 85C0            TEST    EAXEAX                      ;  测试EAX,就是说注册码是否是正确的
00402FF2   . 0F85 37000000   JNZ     是男人就.0040302F                 ;  是对的就跳,不对不完了,失败框框302F
00402FF8   . 68 00010000     PUSH    100                           ; /Count = 100 (256.)
00402FFD   . 8D85 FCFEFFFF   LEA     EAXDWORD PTR SS:[EBP-104]   ; |
00403003   . 50              PUSH    EAX                           ; |Buffer
00403004   . 6A 04           PUSH    4                             ; |RsrcID = STRING "注册码不煌炅?失?"
00403006   . A1 98D24000     MOV     EAXDWORD PTR DS:[40D298]    ; |
0040300B   . 50              PUSH    EAX                           ; |hInst => 00400000
0040300C   . FF15 BCF34000   CALL    DWORD PTR DS:[<&USER32.LoadSt>; LoadStringA
00403012   . 6A 10           PUSH    10                            ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00403014   . 68 6CC24000     PUSH    是男人就.0040C26CNHAN             ; |Title = "NS-TOWER"
00403019   . 8D85 FCFEFFFF   LEA     EAXDWORD PTR SS:[EBP-104]   ; |
0040301F   . 50              PUSH    EAX                           ; |Text
00403020   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]     ; |
00403023   . 50              PUSH    EAX                           ; |hOwner
00403024   . FF15 B8F34000   CALL    DWORD PTR DS:[<&USER32.Messag>; MessageBoxA
0040302A   . E9 41000000     JMP     是男人就.00403070[<&U
0040302F   > 68 00010000     PUSH    100                           ; /Count = 100 (256.)
00403034   . 8B45 FC         MOV     EAXDWORD PTR SS:[EBP-4]     ; |
00403037   . 83C0 10         ADD     EAX, 10                       ; |
0040303A   . 50              PUSH    EAX                           ; |Buffer
0040303B   . 68 EA030000     PUSH    3EA                           ; |ControlID = 3EA (1002.)
00403040   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]     ; |
00403043   . 50              PUSH    EAX                           ; |hWnd
00403044   . FF15 78F34000   CALL    DWORD PTR DS:[<&USER32.GetDlg>; GetDlgItemTextA
0040304A   . 6A 08           PUSH    8                             ; /Count = 8
0040304C   . 8B45 FC         MOV     EAXDWORD PTR SS:[EBP-4]     ; |
0040304F   . 05 10010000     ADD     EAX, 110                      ; |
00403054   . 50              PUSH    EAX                           ; |Buffer
00403055   . 68 EB030000     PUSH    3EB                           ; |ControlID = 3EB (1003.)
0040305A   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]     ; |
0040305D   . 50              PUSH    EAX                           ; |hWnd
0040305E   . FF15 78F34000   CALL    DWORD PTR DS:[<&USER32.GetDlg>; GetDlgItemTextA
00403064   . 6A 00           PUSH    0                             ; /Result = 0
00403066   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]     ; |
00403069   . 50              PUSH    EAX                           ; |hWnd
0040306A   . FF15 7CF34000   CALL    DWORD PTR DS:[<&USER32.EndDia>; EndDialog



004031AD   $ 55              PUSH    EBP
004031AE   . 8BEC            MOV     EBPESP
004031B0   . 83EC 04         SUB     ESP, 4
004031B3   . 53              PUSH    EBX
004031B4   . 56              PUSH    ESI
004031B5   . 57              PUSH    EDI
004031B6   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]         ;  注册码给[EAX]
004031B9   . 33C9            XOR     ECXECX                          ;  清空ECX
004031BB   . 8A48 07         MOV     CLBYTE PTR DS:[EAX+7]           ;  把注册码的第8个注册码给CL,下面要用于判断的
004031BE   . 85C9            TEST    ECXECX                          ;  测试ECX是否是空
004031C0   . 0F84 07000000   JE      是男人就.004031CD                 ;  如果是空就跳,不是空就继续.也就是说,注册码必须小于8位.
004031C6   . 33C0            XOR     EAXEAX                          ;  清空EAX
004031C8   . E9 45010000     JMP     是男人就.00403312                 ;  弹出[注册失败的框框]
004031CD   > C745 FC 0000000>MOV     DWORD PTR SS:[EBP-4], 0           ;  这个地址放的数据是循环用的,从0到7
004031D4   . E9 03000000     JMP     是男人就.004031DC                 ;  跳
004031D9   > FF45 FC         INC     DWORD PTR SS:[EBP-4]              ;  循环数++
004031DC   > 837D FC 07      CMP     DWORD PTR SS:[EBP-4], 7           ;  循环数与7比较
004031E0   . 0F8D 2B000000   JGE     是男人就.00403211                 ;  循环数>=7就跳
004031E6   . 8B45 FC         MOV     EAXDWORD PTR SS:[EBP-4]         ;  循环数给EAX
004031E9   . 8B4D 08         MOV     ECXDWORD PTR SS:[EBP+8]         ;  注册码地址给ECX
004031EC   . 8A0408          MOV     ALBYTE PTR DS:[EAX+ECX]         ;  循环数+注册码地址里的数据给AL
004031EF   . 50              PUSH    EAX                               ;  EAX进栈
004031F0   . E8 22010000     CALL    是男人就.00403317                 ;  调用子程序,如果是数字就转换成16进制数(31h->1h),如果是字母,就转换成大写.不能是符号
004031F5   . 83C4 04         ADD     ESP, 4
004031F8   . 33C9            XOR     ECXECX                          ;  ECX清空
004031FA   . 8AC8            MOV     CLAL                            ;  AL给CL
004031FC   . 83F9 24         CMP     ECX, 24                           ;  把用一位注册码算出的数据与24"$"比较
004031FF   . 0F8E 07000000   JLE     是男人就.0040320C                 ;  这里说明注册码只能是数字或字母,不然就给你注册失败的框框
00403205   . 33C0            XOR     EAXEAX                          ;  清空EAX
00403207   . E9 06010000     JMP     是男人就.00403312                 ;  弹出[注册失败的框框]
0040320C   > E9 C8FFFFFF     JMP     是男人就.004031D9
00403211   > 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]         ;  注册码地址给EAX
00403214   . 8A40 05         MOV     ALBYTE PTR DS:[EAX+5]           ;  把注册码的第6位给AL
00403217   . 50              PUSH    EAX                               ;  EAX进栈
00403218   . E8 FA000000     CALL    是男人就.00403317                 ;  这个子程序不是很清楚是做什么的,我想是用注册码的第6位来算出个密钥吧,可后面还调用了它,再看看吧.
0040321D   . 83C4 04         ADD     ESP, 4
00403220   . 33DB            XOR     EBXEBX
00403222   . 8AD8            MOV     BLAL                            ;  调用子程序换算出的东东给BL
00403224   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]         ;  注册码地址给EAX
00403227   . 8A40 02         MOV     ALBYTE PTR DS:[EAX+2]           ;  注册码第3位给AL
0040322A   . 50              PUSH    EAX                               ;  EAX进栈
0040322B   . E8 E7000000     CALL    是男人就.00403317                 ;  上面以调用过此子程序了,又来了.就不用跟进去了
00403230   . 83C4 04         ADD     ESP, 4
00403233   . 33C9            XOR     ECXECX
00403235   . 8AC8            MOV     CLAL                            ;  调用子程序换算出的东东给CL
00403237   . BE 24000000     MOV     ESI, 24                           ;  ESI=24
0040323C   . 8D4459 1C       LEA     EAXDWORD PTR DS:[ECX+EBX*2+1C]  ;  哦,这里把换算回的两个数字加起来了,把[ECX+EBX*2+1C]算出的值给EAX
00403240   . 99              CDQ                                       ;  清空EDX,下面要做除法了
00403241   . F7FE            IDIV    ESI                               ;  EAX/ESI(24h),商给EAX,余于给EDX
00403243   . 8BDA            MOV     EBXEDX                          ;  余数给EBX
00403245   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]         ;  注册码地址给EAX
00403248   . 8A00            MOV     ALBYTE PTR DS:[EAX]             ;  注册码第1位给AL
0040324A   . 50              PUSH    EAX                               ;  EAX进栈
0040324B   . E8 C7000000     CALL    是男人就.00403317                 ;  这个子程序又调用了,不用跟了
00403250   . 83C4 04         ADD     ESP, 4
00403253   . 33C9            XOR     ECXECX
00403255   . 8AC8            MOV     CLAL                            ;  转回的东东给CL
00403257   . 3BD9            CMP     EBXECX                          ;  上面数出来的余数和注册码第一位算出的数比较
00403259   . 0F85 AC000000   JNZ     是男人就.0040330B                 ;  哎呀,不得了,如果不相等就跳,跳出失败框框哦
0040325F   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]         ;  注册码地址再次给了EAX
00403262   . 8A40 04         MOV     ALBYTE PTR DS:[EAX+4]           ;  把注册码第5位给AL
00403265   . 50              PUSH    EAX                               ;  EAX进栈
00403266   . E8 AC000000     CALL    是男人就.00403317                 ;  看,是不是,这个子程序又调用了,哈哈,不用跟了
0040326B   . 83C4 04         ADD     ESP, 4
0040326E   . 33DB            XOR     EBXEBX
00403270   . 8AD8            MOV     BLAL                            ;  哎呀,累不累,下面这一段不用看也知道是,和上面一样的嘛,一看就知道
00403272   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]         ;  这下面就简单说说了
00403275   . 8A40 01         MOV     ALBYTE PTR DS:[EAX+1]           ;  注册码第2位
00403278   . 50              PUSH    EAX
00403279   . E8 99000000     CALL    是男人就.00403317
0040327E   . 83C4 04         ADD     ESP, 4
00403281   . 33C9            XOR     ECXECX
00403283   . 8AC8            MOV     CLAL
00403285   . BE 24000000     MOV     ESI, 24
0040328A   . 8D4459 1C       LEA     EAXDWORD PTR DS:[ECX+EBX*2+1C]  ;  做算术(ECX+EBX*2+1C)
0040328E   . 99              CDQ
0040328F   . F7FE            IDIV    ESI                               ;  做除法(EAX/ESI)
00403291   . 8BDA            MOV     EBXEDX
00403293   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]
00403296   . 8A40 06         MOV     ALBYTE PTR DS:[EAX+6]           ;  注册码第7位给AL
00403299   . 50              PUSH    EAX
0040329A   . E8 78000000     CALL    是男人就.00403317                 ;  又调用了这个子程序,不跟
0040329F   . 83C4 04         ADD     ESP, 4
004032A2   . 33C9            XOR     ECXECX
004032A4   . 8AC8            MOV     CLAL
004032A6   . 3BD9            CMP     EBXECX                          ;  和上面一样,比来个比较,上次上第6位和第3位算出的数据与第1位算出的比较,这次就是第5位和第2位算出的数据和第7位算出的数据比较
004032A8   . 0F85 5D000000   JNZ     是男人就.0040330B                 ;  不等就跳,跳到失败框
004032AE   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]         ;  下面又是一样的
004032B1   . 8A40 06         MOV     ALBYTE PTR DS:[EAX+6]           ;  这是第7位给AL
004032B4   . 50              PUSH    EAX
004032B5   . E8 5D000000     CALL    是男人就.00403317                 ;  调
004032BA   . 83C4 04         ADD     ESP, 4
004032BD   . 33DB            XOR     EBXEBX
004032BF   . 8AD8            MOV     BLAL
004032C1   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]
004032C4   . 8A00            MOV     ALBYTE PTR DS:[EAX]             ;  这是第1位给AL
004032C6   . 50              PUSH    EAX
004032C7   . E8 4B000000     CALL    是男人就.00403317                 ;  调
004032CC   . 83C4 04         ADD     ESP, 4
004032CF   . 33C9            XOR     ECXECX
004032D1   . 8AC8            MOV     CLAL
004032D3   . BE 24000000     MOV     ESI, 24
004032D8   . 8D4459 1C       LEA     EAXDWORD PTR DS:[ECX+EBX*2+1C]  ;  再做一次算数
004032DC   . 99              CDQ
004032DD   . F7FE            IDIV    ESI                               ;  再做一次除法
004032DF   . 8BDA            MOV     EBXEDX
004032E1   . 8B45 08         MOV     EAXDWORD PTR SS:[EBP+8]
004032E4   . 8A40 03         MOV     ALBYTE PTR DS:[EAX+3]           ;  第4位给AL,下面去调子程序算
004032E7   . 50              PUSH    EAX
004032E8   . E8 2A000000     CALL    是男人就.00403317                 ;  又调
004032ED   . 83C4 04         ADD     ESP, 4
004032F0   . 33C9            XOR     ECXECX
004032F2   . 8AC8            MOV     CLAL
004032F4   . 3BD9            CMP     EBXECX
004032F6   . 0F85 0F000000   JNZ     是男人就.0040330B                 ;  不等就给你失败框
004032FC   . B8 01000000     MOV     EAX, 1                            ;  EAX=1,就是说注册码验证成功
00403301   . E9 0C000000     JMP     是男人就.00403312                 ;  好了注册码看来是验证完了,准备跳出这个子程序了,回到主程序
00403306   . E9 07000000     JMP     是男人就.00403312
0040330B   > 33C0            XOR     EAXEAX
0040330D   . E9 00000000     JMP     是男人就.00403312
00403312   > 5F              POP     EDI
00403313   . 5E              POP     ESI
00403314   . 5B              POP     EBX
00403315   . C9              LEAVE
00403316   . C3              RETN



00403317  /$ 55              PUSH    EBP
00403318  |. 8BEC            MOV     EBPESP
0040331A  |. 53              PUSH    EBX
0040331B  |. 56              PUSH    ESI
0040331C  |. 57              PUSH    EDI
0040331D  |. 33C0            XOR     EAXEAX
0040331F  |. 8A45 08         MOV     ALBYTE PTR SS:[EBP+8]           ;  调用此子程序时传来的东东给AL,这里是注册码的第6位
00403322  |. 83F8 61         CMP     EAX, 61                           ;  EAX与61"a"比较
00403325  |. 0F8C 0B000000   JL      是男人就.00403336                 ;  小于就跳
0040332B  |. 33C0            XOR     EAXEAX                          ;  清空EAX
0040332D  |. 8A45 08         MOV     ALBYTE PTR SS:[EBP+8]           ;  转来的东东给AL
00403330  |. 83E8 20         SUB     EAX, 20                           ;  EAX-20h
00403333  |. 8845 08         MOV     BYTE PTR SS:[EBP+8], AL           ;  还回去
00403336  |> 33C0            XOR     EAXEAX                          ;  清空EAX
00403338  |. 8A45 08         MOV     ALBYTE PTR SS:[EBP+8]           ;  传来的东东再次给AL
0040333B  |. 83F8 41         CMP     EAX, 41                           ;  EAX与41"A"比较
0040333E  |. 0F8C 0B000000   JL      是男人就.0040334F                 ;  小于就跳
00403344  |. 33C0            XOR     EAXEAX                          ;  清空EAX
00403346  |. 8A45 08         MOV     ALBYTE PTR SS:[EBP+8]           ;  把转来的西西给AL
00403349  |. 83E8 07         SUB     EAX, 7                            ;  EAX-7
0040334C  |. 8845 08         MOV     BYTE PTR SS:[EBP+8], AL           ;  还给转来的东东
0040334F  |> 33C0            XOR     EAXEAX                          ;  再清空EAX
00403351  |. 8A45 08         MOV     ALBYTE PTR SS:[EBP+8]           ;  还是那个传来的东西给AL
00403354  |. 83E8 30         SUB     EAX, 30                           ;  EAX-30"0",也就是把ASCII数字转换成十六进制了.上面已经判断出不是字母,那就一定是数字了
00403357  |. E9 00000000     JMP     是男人就.0040335C                 ;  没什么用,多于的跳转命令,不如删除了
0040335C  |> 5F              POP     EDI
0040335D  |. 5E              POP     ESI
0040335E  |. 5B              POP     EBX
0040335F  |. C9              LEAVE
00403360  . C3              RETN



好了,结束了,算法出来了,就是这样了
([3]+[6]*2+1C) % 24 与 [1]
([2]+[5]*2+1C) % 24 与 [7]
([1]+[7]*2+1C) % 24 与 [4]

if [?]<"a" then jl _NEXT
else [?]-20h
if [?]<"A" then jl _NEXT
else [?]-7h
_NEXT [?]-30h