第一次在坛子里发破文,让SQLYogEnt v7.14自己弹出注册码,没有什么技术含量,仅供和我一样的菜鸟分享成功破解的喜悦,高手请飘过。 
 
 
【文章标题】: SQLYogEnt v7.14自爆
【文章作者】: 左手
【作者邮箱】: wxjgeorge@163.com
【作者主页】: www.没有主页.com
【作者QQ号】: 9323166
【软件名称】: SQLYogEnt
【下载地址】: 自己搜索下载
【加壳方式】: Upack 0.39 beta -> Dwing
【保护方式】: 用户名/注册码
【编写语言】: Microsoft Visual C++ 7.0
【使用工具】: PEID,OllyDRX,LordPE,ImportREC
【操作平台】: XP
【软件介绍】: 管理MySQL在一个超级好用的软件
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  原本用过这个软件,感觉真的是很强(在管理MySQL上),当时动手汉化并破解了一次,没有做记录,好像记得是算法是将注册用户名前加一个“01”后进行MD5,取中间8位就是注册码了。
  这两天在www.onegreen.net看到了7.14汉化绿色版,这么好的东西当然要下载了,回来一看,里面带有注册机,自己想再看看注册算法是不是改变了,打算再跟一遍,OD脱壳后载入一看,NND,字符串里面怎么那么多360的网址,KAV,卡巴什么的,怀疑是被人搞过。放弃。到汉化新世纪下载了一下,开始下面的工作:
  1.查壳。
    用PEID查了一下,和在www.onegreen.net下载的一样,也是Upack 0.39 beta -> Dwing
  2.脱壳。
    用OllyDRX载入。
  00401018 S>  BE B0114000               MOV ESI,SQLyogEn.004011B0        //载入停在这
  0040101D     AD                        LODS DWORD PTR DS:[ESI]
  0040101E     50                        PUSH EAX
  0040101F     FF76 34                   PUSH DWORD PTR DS:[ESI+34]       //这里ESP改变为0012FFC0,下断点HR ESP,后直接F9运行。
  00401022     EB 7C                     JMP SHORT SQLyogEn.004010A0
    ESP定律直接就停在了OEP上
  005E2054     6A 60                     PUSH 60                          //到达OEP,查看下面的代码IAT也已经全部还原了
  005E2056     68 A0CF6200               PUSH SQLyogEn.0062CFA0
  005E205B     E8 D04E0000               CALL SQLyogEn.005E6F30
    用LordPE进行dump,并用ImportREC进行修复IAT,得到脱壳后的版本。
  3.破解
    用OllyDRX载入,直接f9运行,输入注册用户名,注册码,注册,结果肯定是蹦个“无效注册码”的窗口了,在OllyDRX中按f12暂停(不要点那个“无效注册码”窗口的“确定”),再查看调用堆栈,
  Call stack of main thr3ad, item 13
   Address=0012F044
   Stack=004E7995
   Procedure / arguments=USER32.MessageBoxW
   Called from=SQLyogEn.004E798F
   Frame=0012F040
  直接双击跟随
  004E7970   /$  51                      PUSH ECX
  004E7971   |.  53                      PUSH EBX
  004E7972   |.  55                      PUSH EBP
  004E7973   |.  FF15 6C056000           CALL DWORD PTR DS:[<&user32.GetFocus>]          ; [GetFocus
  004E7979   |.  8B4C24 18               MOV ECX,DWORD PTR SS:[ESP+18]
  004E797D   |.  8B5424 14               MOV EDX,DWORD PTR SS:[ESP+14]
  004E7981   |.  8B5C24 10               MOV EBX,DWORD PTR SS:[ESP+10]
  004E7985   |.  8BE8                    MOV EBP,EAX
  004E7987   |.  8B4424 1C               MOV EAX,DWORD PTR SS:[ESP+1C]
  004E798B   |.  50                      PUSH EAX                                        ; /Style = MB_OK|MB_ICONQUESTION|MB_DEFBUTTON3|MB_SYSTEMMODAL|MB_NOFOCUS|C90800
  004E798C   |.  51                      PUSH ECX                                        ; |Title = ""
  004E798D   |.  52                      PUSH EDX                                        ; |Text = "x84??xB8\xA1\xB2"
  004E798E   |.  53                      PUSH EBX                                        ; |hOwner = NULL
  004E798F   |.  FF15 CC056000           CALL DWORD PTR DS:[<&user32.MessageBoxW>]       ; \MessageBoxW                     //这里再下断点,重新注册
  F9运行后再点注册,断在刚才下的断点上,Ctrl+F9,执行到返回,再F8返回到上一层函数
  0044299D   |.  50                      PUSH EAX
  0044299E   |.  68 F4806000             PUSH SQLyogEn.006080F4
  004429A3   |.  52                      PUSH EDX                                        ;  ntdll.KiFastSystemCallRet
  004429A4   |.  E8 C74F0A00             CALL SQLyogEn.004E7970                          //这里就是错误对话框了
  004429A9   |.  83C4 10                 ADD ESP,10                                      //返回到这里
  004429AC   |.  EB 0F                   JMP SHORT SQLyogEn.004429BD
  004429AE   |>  8B4424 34               MOV EAX,DWORD PTR SS:[ESP+34]                   ;  Case 2 of switch 004428EC
  004429B2   |.  6A 00                   PUSH 0
  004429B4   |.  50                      PUSH EAX
  004429B5   |.  E8 26260A00             CALL SQLyogEn.004E4FE0
  翻动代码往上面看
  00442908   |.  8BCE                    MOV ECX,ESI                                     ;  Case 417 of switch 004428EC
  0044290A   |.  E8 31FBFFFF             CALL SQLyogEn.00442440                          //关键call
  0044290F   |.  83F8 01                 CMP EAX,1
  00442912   |.  75 6D                   JNZ SHORT SQLyogEn.00442981                     //关键跳
  ……
  00442981   |> \85C0                    TEST EAX,EAX
  00442983   |.  75 38                   JNZ SHORT SQLyogEn.004429BD
  
  我们在00442908下断点后再次注册,断下来后进入0044290A的关键call看看
  00442440   /$  55                      PUSH EBP
  00442441   |.  8BEC                    MOV EBP,ESP
  00442443   |.  83E4 F8                 AND ESP,FFFFFFF8
  00442446   |.  6A FF                   PUSH -1
  00442448   |.  68 E16A5F00             PUSH SQLyogEn.005F6AE1                          ;  SE handler installation
  ……
  0044250C   |.  8B3D C8056000           MOV EDI,DWORD PTR DS:[<&user32.GetWindowTextW>] ;  USER32.GetWindowTextW
  00442512   |.  6A 7F                   PUSH 7F                                         ; /Count = 7F (127.)
  00442514   |.  8D8C24 84020000         LEA ECX,DWORD PTR SS:[ESP+284]                  ; |
  0044251B   |.  51                      PUSH ECX                                        ; |Buffer = 0012F58C
  0044251C   |.  52                      PUSH EDX                                        ; |hWnd = 00000100
  0044251D   |.  C68424 A0040000 02      MOV BYTE PTR SS:[ESP+4A0],2                     ; |
  00442525   |.  FFD7                    CALL EDI                                        ; \GetWindowTextW //获取输入的用户名
  00442527   |.  8B4E 10                 MOV ECX,DWORD PTR DS:[ESI+10]
  0044252A   |.  6A 7F                   PUSH 7F                                         ; /Count = 7F (127.)
  0044252C   |.  8D8424 84010000         LEA EAX,DWORD PTR SS:[ESP+184]                  ; |
  00442533   |.  50                      PUSH EAX                                        ; |Buffer = NULL
  00442534   |.  51                      PUSH ECX                                        ; |hWnd = 0012F58C
  00442535   |.  FFD7                    CALL EDI                                        ; \GetWindowTextW//获取输入的注册码
  
  看了一下,还是将“01”与用户名结合,再通过算法导出真实注册码,因为注册码在内存中出现了,本次主要是让软件自己弹出注册码,算法就不跟了。
  00442658    .  6A 01                   PUSH 1
  0044265A    .  8D4424 70               LEA EAX,DWORD PTR SS:[ESP+70]        //真实注册码地址付给EAX
  0044265E    .  50                      PUSH EAX
  00442660    .  8D4C24 54               LEA ECX,DWORD PTR SS:[ESP+54]
  00442663    >  E8 B8F50F00             CALL SQLyogEn.00541C20
  
  
  在这个地方,EAX保存了真实注册码地址,同时EDX保存了“1用户名”,这样我们可以再找一个MessageBoxA的地址,并跳到一处空代码的地方,patch程序,让软件自己弹出注册码。Let's do it!
  下断点bpx MessageBoxA,到断点列表里面随表挑一个MessageBoxA的断点,双击进去,复制下地址,我这里选了下面这个:
  CALL DWORD PTR DS:[6004F4]    //MessageBoxA函数
  
  找到空地址:
  00614D33       00                      DB 00
  
  修改0044265E处命令为
  JMP 00614D33
  该命令覆盖了原来的两条指令:
  0044265E    .  50                      PUSH EAX
  00442660    .  8D4C24 54               LEA ECX,DWORD PTR SS:[ESP+54]
  
  修改00614D33处指令如下:
  00614D33    > \60                      PUSHAD                                     //保存堆栈
  00614D34    .  6A 00                   PUSH 0                                          ; /Style = MB_OK|MB_APPLMODAL
  00614D36    .  FF7424 40               PUSH DWORD PTR SS:[ESP+40]                      ; |Title = 00000100 ???      //调试到这里的时候发现ESP+40的位置处存放在输入的注册名,直接取用了。
  00614D3A    .  50                      PUSH EAX                                        ; |Text = "937d8047946c179d" //真实注册码
  00614D3B    .  6A 00                   PUSH 0                                          ; |hOwner = NULL
  00614D3D    .  FF15 F4046000           CALL DWORD PTR DS:[<&user32.MessageBoxA>]       ; \MessageBoxA               //调用MessageBoxA
  00614D43    .  61                      POPAD                                      //恢复堆栈
  00614D44    .  50                      PUSH EAX                                   //补全上面的jmp覆盖的两条指令
  00614D45    .  8D4C24 54               LEA ECX,DWORD PTR SS:[ESP+54]              //补全上面的jmp覆盖的两条指令
  00614D49    .^ E9 15D9E2FF             JMP SQLyogEn.00442663                      //跳回去执行软件原有代码。
  
  复制所有修改到可执行文件后破解结束!
  测试能正常弹出用户名对应的密码。
  
  
  
  
  
  
--------------------------------------------------------------------------------
【经验总结】
  对于内存中出现明码注册码的,不用单独制作注册机了,运用软件自己的注册算法,适当的时候调用MessageBox弹出真实注
  册码也是个不错的选择。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
                                                       2009年01月08日 21:36:21

  • 标 题:答复
  • 作 者:wxjgeorge
  • 时 间:2009-01-09 20:50

   刚下班回来,又改了一下,用LordPE添加了一个SetWindowTextA,将原来的代码改动成:
push 注册码地址
push hwnd
call SetWindowTextA
保存了又来看看帖子,呵呵,居然混了个精华!心中狂喜ing!!!