首页
社区
课程
招聘
[原创]海汀菜谱 V1.03 破解笔记[菜谱]
发表于: 2005-11-22 19:17 4583

[原创]海汀菜谱 V1.03 破解笔记[菜谱]

2005-11-22 19:17
4583
海汀菜谱 V1.03 破解笔记

【破解作者】 aCaFeeL

【作者主页】 http://cztool.ys168.com/

【使用工具】 OllyDBG 1.10 & DeDe 3.5

【破解平台】 Win98SE

【软件名称】 海汀菜谱 V1.03

【下载地址】 http://www.ht-soft.com

【软件简介】 “海汀菜谱”软件中一共包含了近两千种菜谱,并且按“菜系”、“用料”、“口味”、“季节”四种分类方法将其分类,使用户可以快速找到合适的菜谱。软件功能强大,界面友好,操作简单方便,不失为厨房的好帮手。

【破解声明】 也不知怎么回事,最近突然爱上了做菜,周末去书城买了一本《天天新口味系列丛书-家常菜》看过之后还不觉过瘾,于是便想到了网络上,到网上一搜索,还真多!嘿嘿,赶紧下了几部下来看,感觉还不错,于是想把它们收藏,于是。。。(声明:只为爱好而破解!愿与我一样还是破解菜鸟的朋友们一起分享!)

【软件限制】 通过对它的使用,发现未注册版本的限制主要是不能使用‘数据库设置’,‘导出菜谱’和‘打印菜谱’功能。

【破解内容】
      用PEid检查,发现没有加壳,是用Delphi编写的;
      用DeDe反编译该程序,在“过程”的"kzhuce"中,发现bitClickbtn事件为注册按钮事件,双击进入后,

。。。。。。
004E642E   8B45E8            mov     eax, [ebp-$18]
004E6431   8B55FC            mov     edx, [ebp-$04]

* Reference to: System.@LStrCmp;
|
004E6434   E8D7E7F1FF      call    00404C10   //注册算法
004E6439   743C            jz      004E6477   //关键跳转,一跳便成功
004E643B   6A01            push    $01

* Reference to: user32.MessageBeep()
|
004E643D   E86214F2FF       call    004078A4
。。。。。。

因此,可在004E642E处,下断点。

    用OllyDBG打开该程序,找到004E642E这处地址后,在此处按F2键下断点,然后按F9键运行到进入程序后,点击“软件注册”对话框中的“生成注册码”,然后随便输入一串数字,如:12345678 后,点击“完成注册”按钮,此时程序中断在了004E642E这处,而EAX中的数据(AscII码)便是:12345678,按F8键运行一步后,则看见有:堆栈 ss:[007AF7CC]=00D44E90, (ASCII "11115116171539121465614291459") 这一行,其中的数据(AscII码)11115116171539121465614291459,这就是真正的注册码!

    如果你感兴趣,还可进入注册算法的关键Call中仔细的研究。

【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!三克油!

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
加油,,,,,,,,,,,
2005-11-22 23:36
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我现在也喜欢做菜了,
可是这个程序好像不能下载了。
有其他地方可以下载吗
2006-1-3 19:29
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
发现bitClickbtn事件为注册按钮事件
为什么?
可以说详细些吗?
2006-1-6 22:26
0
雪    币: 50
活跃值: (145)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
5
学习了谢谢
2006-1-7 18:19
0
雪    币: 243
活跃值: (190)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
6
我也该学学做菜了
2006-1-8 16:48
0
雪    币: 204
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
能不能讲详细一点
2006-1-13 11:01
0
雪    币: 333
活跃值: (116)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
8
【破解详细内容】

    用PEid检查,发现没有加壳,是用Delphi编写的;
    用DeDe反编译该程序,在“过程”页面的单元名"kzhuce"(注:这就是它的注册窗口)中,发现三个事件,分别是FormCreat,BitBtn1Click,BitBtn2Click;进入三个事件中查看后,在BitBtn2Click事件中,看到了与注册成功与否相关的信息(里面有‘注册成功,感谢您使用本软件...’等信息),故BitBtn2Click为注册按钮事件,双击进入后,看到如下代码:
。。。。。。
* Possible String Reference to: '轹垴?七^[?]?
|
004E63A9   68AD654E00             push    $004E65AD

***** TRY
|
004E63AE   64FF30                 push    dword ptr fs:[eax]
004E63B1   648920                 mov     fs:[eax], esp
004E63B4   8D55F0                 lea     edx, [ebp-$10]

* Reference to control et2 : TEdit
|
004E63B7   8B8314030000           mov     eax, [ebx+$0314]

* Reference to: Controls.TControl.GetText(TControl):TCaption;
|
004E63BD   E8FEAFF7FF             call    004613C0                        //得到你输入的假注册码
004E63C2   8B45F0                 mov     eax, [ebp-$10]                  //假注册码丢到 EAX
004E63C5   8D55F4                 lea     edx, [ebp-$0C]

* Reference to: SysUtils.Trim(AnsiString):AnsiString;overload;
|
004E63C8   E85B2CF2FF             call    00409028
004E63CD   837DF400               cmp     dword ptr [ebp-$0C], +$00       //检测是否有字符串输入
004E63D1   7521                   jnz     004E63F4                        //有,则跳
004E63D3   6A01                   push    $01

* Reference to: user32.MessageBeep()
|
004E63D5   E8CA14F2FF             call    004078A4
004E63DA   6A00                   push    $00
004E63DC   668B0DBC654E00         mov     cx, word ptr [$004E65BC]
004E63E3   B202                   mov     dl, $02

* Possible String Reference to: '请输入注册码'
|
004E63E5   B8C8654E00             mov     eax, $004E65C8

|
004E63EA   E8C502F5FF             call    004366B4                       //没有,就显示'请输入注册码'这个对话框提示
004E63EF   E979010000             jmp     004E656D
004E63F4   8D55EC                 lea     edx, [ebp-$14]                 //检测到你有输入字符串后,由 004E63D1 处跳转到这里
004E63F7   A1D8054F00             mov     eax, dword ptr [$004F05D8]
004E63FC   8B00                   mov     eax, [eax]

|
004E63FE   E869670000             call    004ECB6C
004E6403   8B55EC                 mov     edx, [ebp-$14]                 //机器码到EDX
004E6406   8D4DFC                 lea     ecx, [ebp-$04]
004E6409   A1D8054F00             mov     eax, dword ptr [$004F05D8]
004E640E   8B00                   mov     eax, [eax]

|
004E6410   E8B7690000             call    004ECDCC                       //注册算法,可F7键进入//可在此处F2键下断点
004E6415   8D55E4                 lea     edx, [ebp-$1C]

* Reference to control et2 : TEdit
|
004E6418   8B8314030000           mov     eax, [ebx+$0314]

* Reference to: Controls.TControl.GetText(TControl):TCaption;
|
004E641E   E89DAFF7FF             call    004613C0
004E6423   8B45E4                 mov     eax, [ebp-$1C]
004E6426   8D55E8                 lea     edx, [ebp-$18]

* Reference to: SysUtils.Trim(AnsiString):AnsiString;overload;
|
004E6429   E8FA2BF2FF             call    00409028
004E642E   8B45E8                 mov     eax, [ebp-$18]                  //自己输入的假注册码//可在此处F2键下断点
004E6431   8B55FC                 mov     edx, [ebp-$04]                  //程序真正的注册码

* Reference to: System.@LStrCmp;
|
004E6434   E8D7E7F1FF             call    00404C10                        //这里调用字符串的比较函数进行比较了
004E6439   743C                   jz      004E6477                        //比较结果相等,则跳转,一跳便成功
004E643B   6A01                   push    $01

* Reference to: user32.MessageBeep()
|
004E643D   E86214F2FF             call    004078A4
004E6442   6A00                   push    $00
004E6444   668B0DBC654E00         mov     cx, word ptr [$004E65BC]
004E644B   B202                   mov     dl, $02

* Possible String Reference to: '注册码不正确,请重新输入'
|
004E644D   B8E0654E00             mov     eax, $004E65E0

|
004E6452   E85D02F5FF             call    004366B4                        //不等,就显示'注册码不正确'这个对话框提示

* Reference to control et2 : TEdit
|
004E6457   8B8314030000           mov     eax, [ebx+$0314]
004E645D   33D2                   xor     edx, edx

* Reference to: Controls.TControl.SetText(TControl;TCaption);
|
004E645F   E88CAFF7FF             call    004613F0

* Reference to control et2 : TEdit
|
004E6464   8B8314030000           mov     eax, [ebx+$0314]
004E646A   8B10                   mov     edx, [eax]
004E646C   FF92C4000000           call    dword ptr [edx+$00C4]
004E6472   E9F6000000             jmp     004E656D
004E6477   33C0                   xor     eax, eax                          //比较成功,由 004E6439 处来到这里
004E6479   55                     push    ebp
004E647A   68F4644E00             push    $004E64F4
。。。。。。

    因此,可在004E642E处,下断点。

    用OllyDBG打开该程序,Ctrl+G键打开窗口后,输入地址:004E642E,回车来到此地址后,在此处按F2键下断点,然后按F9键运行到进入程序后,点击“软件注册”对话框中的“生成注册码”,然后随便输入一串假注册码,如:12345678 后,点击“完成注册”按钮,此时程序中断在了004E642E这处,而EAX中的数据(AscII码)便是:12345678,按F8键运行一步后,则看见有:堆栈 ss:[007AF7CC]=00D44E90, (ASCII "11115116171539121465614291459") 这一行,其中的数据(AscII码)11115116171539121465614291459,这就是真正的注册码!

    如果你感兴趣,还可进入注册算法的关键Call中仔细的研究,这里引用 WindayJiang 兄弟对注册算法的分析。

    F7 键进入 004E6410 处的算法 CALL 后,看到:
。。。。。。
004ECDCC   >PUSH EBP
004ECDCD   >MOV EBP,ESP
004ECDCF   >ADD ESP,-18
004ECDD2   >PUSH EBX
004ECDD3   >PUSH ESI
004ECDD4   >PUSH EDI
004ECDD5   >XOR EBX,EBX
004ECDD7   >MOV DWORD PTR SS:[EBP-18],EBX
004ECDDA   >MOV DWORD PTR SS:[EBP-C],EBX
004ECDDD   >MOV DWORD PTR SS:[EBP-10],EBX
004ECDE0   >MOV DWORD PTR SS:[EBP-8],ECX
004ECDE3   >MOV DWORD PTR SS:[EBP-4],EDX
004ECDE6   >MOV EAX,DWORD PTR SS:[EBP-4]
004ECDE9   >CALL 海汀菜谱.00404CB4
004ECDEE   >XOR EAX,EAX
004ECDF0   >PUSH EBP
004ECDF1   >PUSH 海汀菜谱.004ECF1C
004ECDF6   >PUSH DWORD PTR FS:[EAX]
004ECDF9   >MOV DWORD PTR FS:[EAX],ESP
004ECDFC   >MOV EAX,DWORD PTR SS:[EBP-4]
004ECDFF   >CALL 海汀菜谱.00404AC4
004ECE04   >MOV EBX,EAX
004ECE06   >TEST EBX,EBX
004ECE08   >JLE SHORT 海汀菜谱.004ECE7C
004ECE0A   >MOV EDI,1                              ;  开始循环
004ECE0F   > LEA EAX,DWORD PTR SS:[EBP-10]
004ECE12   > PUSH EAX
004ECE13   > MOV ECX,1                             ;  常数1
004ECE18   > MOV EDX,EDI                           ;  第几位
004ECE1A   > MOV EAX,DWORD PTR SS:[EBP-4]          ;  机器码
004ECE1D   > CALL 海汀菜谱.00404D24                ;  MIDSTR功能
004ECE22   > MOV EAX,DWORD PTR SS:[EBP-10]
004ECE25   > MOV EDX,海汀菜谱.004ECF34
004ECE2A   > CALL 海汀菜谱.00404C10                ;  取机器码第N位
004ECE2F   > JB SHORT 海汀菜谱.004ECE6D            ;  CL是机器码第N位的字符值
004ECE31   > MOV EAX,DWORD PTR SS:[EBP-10]
004ECE34   > MOV EDX,海汀菜谱.004ECF40
004ECE39   > CALL 海汀菜谱.00404C10                ;  取机器码第N位
004ECE3E   > JA SHORT 海汀菜谱.004ECE6D
004ECE40   > MOV EAX,DWORD PTR SS:[EBP-10]
004ECE43   > CALL 海汀菜谱.004094CC                ;  转换字符
004ECE48   > MOV ESI,EAX                           ;  AL就是第N位的字符,不过已被转换为数字,像VAL
004ECE4A   > LEA EAX,DWORD PTR DS:[ESI+ESI*2]      ;  *2再加本身
004ECE4D   > ADD EAX,7                             ;  加7
004ECE50   > MOV DWORD PTR SS:[EBP-14],EAX
004ECE53   > FILD DWORD PTR SS:[EBP-14]
004ECE56   > FDIV DWORD PTR DS:[4ECF44]            ;  结果整除2
004ECE5C   > CALL 海汀菜谱.00402C44
004ECE61   > MOV ESI,EAX                           ;  EAX是计算后的结果
004ECE63   > LEA EDX,DWORD PTR SS:[EBP-10]
004ECE66   > MOV EAX,ESI
004ECE68   > CALL 海汀菜谱.00409390
004ECE6D   > LEA EAX,DWORD PTR SS:[EBP-C]
004ECE70   > MOV EDX,DWORD PTR SS:[EBP-10]         ;  待写进的地址
004ECE73   > CALL 海汀菜谱.00404ACC                ;  写到上次结果后面
004ECE78   > INC EDI
004ECE79   > DEC EBX
004ECE7A   > JNZ SHORT 海汀菜谱.004ECE0F           ;  循环
004ECE7C   >MOV EAX,DWORD PTR SS:[EBP-C]           ;  EAX是计算结果
004ECE7F   >CALL 海汀菜谱.00404AC4                 ;  取结果长度
004ECE84   >CMP EAX,3                              ;  比较结果长度是否只有3位
004ECE87   >JLE SHORT 海汀菜谱.004ECEE6            ;  不大于3跳走
004ECE89   >LEA EAX,DWORD PTR SS:[EBP-10]
004ECE8C   >MOV EDX,DWORD PTR SS:[EBP-C]
004ECE8F   >CALL 海汀菜谱.0040489C
004ECE94   >LEA EAX,DWORD PTR SS:[EBP-C]
004ECE97   >PUSH EAX
004ECE98   >MOV EAX,DWORD PTR SS:[EBP-10]
004ECE9B   >CALL 海汀菜谱.00404AC4                 ;  取结果长度
004ECEA0   >MOV ECX,EAX
004ECEA2   >SUB ECX,2                              ;  长度减2
004ECEA5   >MOV EDX,1                              ;  EDX为1
004ECEAA   >MOV EAX,DWORD PTR SS:[EBP-10]          ;  结果
004ECEAD   >CALL 海汀菜谱.00404D24                 ;  上面说过了,MIDSTR功能
004ECEB2   >LEA EAX,DWORD PTR SS:[EBP-C]           ;  STACK的地址就是处理过的结果
004ECEB5   >MOV EDX,海汀菜谱.004ECF50              ;  ASCII "2914"
004ECEBA   >CALL 海汀菜谱.00404ACC                 ;  写入2914
004ECEBF   >LEA EAX,DWORD PTR SS:[EBP-18]
004ECEC2   >PUSH EAX
004ECEC3   >MOV EAX,DWORD PTR SS:[EBP-10]
004ECEC6   >CALL 海汀菜谱.00404AC4                 ;  取未处理的结果长度
004ECECB   >MOV EDX,EAX                            ;  长度放到EDX
004ECECD   >DEC EDX                                ;  减1
004ECECE   >MOV ECX,2                              ;  又是一个参数2
004ECED3   >MOV EAX,DWORD PTR SS:[EBP-10]          ;  未处理的结果
004ECED6   >CALL 海汀菜谱.00404D24                 ;  好烦哦,又来一个MIDSTR
004ECEDB   >MOV EDX,DWORD PTR SS:[EBP-18]          ;  结果到EDX
004ECEDE   >LEA EAX,DWORD PTR SS:[EBP-C]           ;  处理过的结果地址到EAX,记得吧?
004ECEE1   >CALL 海汀菜谱.00404ACC                 ;  写入
004ECEE6   >MOV EAX,DWORD PTR SS:[EBP-8]
004ECEE9   >MOV EDX,DWORD PTR SS:[EBP-C]
004ECEEC   >CALL 海汀菜谱.00404858
004ECEF1   >XOR EAX,EAX
004ECEF3   >POP EDX
004ECEF4   >POP ECX
004ECEF5   >POP ECX
004ECEF6   >MOV DWORD PTR FS:[EAX],EDX
004ECEF9   >PUSH 海汀菜谱.004ECF23
004ECEFE   >LEA EAX,DWORD PTR SS:[EBP-18]
004ECF01   >CALL 海汀菜谱.00404804
004ECF06   >LEA EAX,DWORD PTR SS:[EBP-10]
004ECF09   >MOV EDX,2
004ECF0E   >CALL 海汀菜谱.00404828
004ECF13   >LEA EAX,DWORD PTR SS:[EBP-4]
004ECF16   >CALL 海汀菜谱.00404804
004ECF1B   >RETN
。。。。。。

004ECE87这句如果跳走,就以第一次处理过的做注册码,否则还会做一些处理的。

到这里,算法已经完全弄懂了,我总结一下:
1.机器码的第N位换成数值后,(*2+本身+7)\2=XN,XN再转成字串
2.X1&X2...&XN
3.left(结果,长度-2)&“2914”&right(结果,2)

注册机:
var
  Mcode,Tempchar,PreSN,SN:string;
  Count,Char2Num,Errcode:integer;
begin
  Mcode:=edit1.Text;                                //机器码赋予变量Mcode
  for count:=1 to length(mcode) do                  //开始按机器码长度循环
    begin
      Tempchar:=midstr(mcode,count,1);              //将变量Mcode按循环依次取出一个赋予变量Tempchar
      val(Tempchar,Char2Num,Errcode);               //字符转换为数字
      char2num:=(char2num*$2+$7+char2num) div $2;   //产于运算
      Tempchar:=inttostr(char2num);                 //数字结果又转换回字符
      presn:=presn+tempchar;                        //按循环连接起来
    end;
  if length(presn)>3                                                 //如长度大于3
    then sn:=leftstr(presn,length(presn)-2)+'2914'+rightstr(presn,2) //便取结果前边的(结果长度-2)位数字
                                                                     //加上'2914',再加上结果的最后两位数
    else sn:=presn;                                                  //小于3?好说了!
  edit2.text:=sn;
end;

有关软件的下载地址:

http://www.shareware.cn/pub/12267.html
2006-1-13 13:23
0
游客
登录 | 注册 方可回帖
返回
//