foxjinlin 发表于 2011-3-19 12:08:27

LiteServe 2.81追码、爆破以及出内存注册机(补上易版算法注册机和源码)

本帖最后由 foxjinlin 于 2011-3-24 03:58 编辑

【文章标题】: LiteServe 2.81追码、爆破以及出内存注册机
【文章作者】: foxjinlin
【作者邮箱】: foxjinlin#live.cn(#转@即可,防垃圾邮件群发骚扰)
【软件名称】: LiteServe V2.81
【软件大小】: 1.7MB
【下载地址】: http://www.cmfperception.com/liteserve/pls2_81.exe
【加壳方式】: 无
【保护方式】: 序列号
【编写语言】: Delphi
【使用工具】: PEID,OD,DUP,KeyMake
【操作平台】: Win95/98/2K/ME/XP/2003/Vista/2008/Win7
【软件介绍】: LiteServe 是一个小巧的、全功能的网站架设工具软件包,软件内置有 Web、
            FTP、Telnet 和 EMail 等服务器,您个人或企业都可以很方便地进行设置多种需要
            和多种高要求的服务器平台,适合初学者使用。
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
此软件未注册有试用时间限制,运行程序,弹出“Information”窗口,点“No”,进行试用,程序主窗口出现后,在其“Help”下拉菜单中点“Register/Order...”项进行试注册,输入用户名“foxjinlin”,试验码“987654321”,跳出提示“name and key don't match! try again”

先用PEID探测一下,显示“Borland Delphi 6.0 - 7.0”,没壳就好办事。

破解定位思路:
1、用"MessageBox"等函数,进行消息断点拦截;
2、F12暂停+堆栈窗口中跟随法
3、用字串搜索法
经试验,方法1无效,2和3可行。

试用方法2,跟随进反汇编窗口后,发现这里使用的是“WaitMessage”函数,怪不得用“MessageBox”断不下来,进来之后,发现里面有个很大的向上跳转,看了就吓人,暂时放弃方法2,使用方法3试验,结果发现方法3最好用,因而选择使用方法3。

方法3搜到字串“name and key don't match!\n\ntry again”,再向上看,在代码段首下断。


004C7F18/.55            push    ebp                        ;此处下断,按三次F9,弹出“Information”窗口,点“No”,进行试用,程序主窗口出现后,在其“Help”下拉菜单中点“Register/Order...”项进行试注册,输入用户名“foxjinlin”,试验码“987654321”,程序断下来
004C7F19|.8BEC          mov   ebp, esp
004C7F1B|.33C9          xor   ecx, ecx
004C7F1D|.51            push    ecx
004C7F1E|.51            push    ecx
004C7F1F|.51            push    ecx
004C7F20|.51            push    ecx
004C7F21|.51            push    ecx
004C7F22|.51            push    ecx
004C7F23|.51            push    ecx
004C7F24|.53            push    ebx
004C7F25|.8BD8          mov   ebx, eax
004C7F27|.33C0          xor   eax, eax
004C7F29|.55            push    ebp
004C7F2A|.68 AE804C00   push    004C80AE
004C7F2F|.64:FF30       push    dword ptr fs:
004C7F32|.64:8920       mov   dword ptr fs:, esp
004C7F35|.8D55 FC       lea   edx, dword ptr       ;取用户名的长度
004C7F38|.8B83 00030000 mov   eax, dword ptr
004C7F3E|.E8 C90DF8FF   call    00448D0C                     
004C7F43|.837D FC 00    cmp   dword ptr , 0         
004C7F47|.0F84 14010000 je      004C8061                      ;用户名为空则跳
004C7F4D|.8D55 F8       lea   edx, dword ptr
004C7F50|.8B83 04030000 mov   eax, dword ptr    
004C7F56|.E8 B10DF8FF   call    00448D0C
004C7F5B|.837D F8 00    cmp   dword ptr , 0          ;到这里时,提示窗口信息为“堆栈 ss:=00B9AC80, (ASCII "987654321")”
004C7F5F|.0F84 FC000000 je      004C8061                      ;注册码为空则跳
004C7F65|.8D55 F0       lea   edx, dword ptr
004C7F68|.8B83 00030000 mov   eax, dword ptr
004C7F6E|.E8 990DF8FF   call    00448D0C
004C7F73|.8B55 F0       mov   edx, dword ptr        ;到这里时,提示窗口信息为“堆栈 ss:=00B831B4, (ASCII "foxjinlin")”
004C7F76|.8D4D F4       lea   ecx, dword ptr
004C7F79|.A1 247D5100   mov   eax, dword ptr
004C7F7E|.8B00          mov   eax, dword ptr
004C7F80|.E8 23FE0000   call    004D7DA8                      ;关键CALL,步入后可以看到程序的注册算法
004C7F85|.8B45 F4       mov   eax, dword ptr       ;把真码放到eax(到这里时信息窗口里出现可疑信息“堆栈 ss:=00B83838, (ASCII "09143932239239132860")”,经试验,“09143932239239132860”正是用户名“foxjinlin”所要追的配套真码),此为爆破点,把改为即可一劳永逸,意思就是让程序认为真码恰好就是输入的试验码
004C7F88|.50            push    eax                           ;此处可用来做内存注册机
004C7F89|.8D55 EC       lea   edx, dword ptr        ;用户名传到edx
004C7F8C|.8B83 04030000 mov   eax, dword ptr       ;把真码放入eax
004C7F92|.E8 750DF8FF   call    00448D0C
004C7F97|.8B55 EC       mov   edx, dword ptr        ;把试验码放入edx
004C7F9A|.58            pop   eax
004C7F9B|.E8 1CD4F3FF   call    004053BC
004C7FA0|.0F85 BB000000 jnz   004C8061                      ;把真码和试验码进行比较,不相同就跳向注册错误提示,相同则向下走,提示注册成功;此为爆破点,nop掉跳转即可,此处修改无技术含量
004C7FA6|.A1 247D5100   mov   eax, dword ptr
004C7FAB|.8B00          mov   eax, dword ptr
004C7FAD|.8B80 88030000 mov   eax, dword ptr
004C7FB3|.33D2          xor   edx, edx
004C7FB5|.E8 6E51F7FF   call    0043D128
004C7FBA|.A1 247D5100   mov   eax, dword ptr
004C7FBF|.8B00          mov   eax, dword ptr
004C7FC1|.C680 72090000>mov   byte ptr , 1
004C7FC8|.8D55 E8       lea   edx, dword ptr
004C7FCB|.8B83 00030000 mov   eax, dword ptr
004C7FD1|.E8 360DF8FF   call    00448D0C
004C7FD6|.8B55 E8       mov   edx, dword ptr
004C7FD9|.A1 247D5100   mov   eax, dword ptr
004C7FDE|.8B00          mov   eax, dword ptr
004C7FE0|.05 74090000   add   eax, 974
004C7FE5|.E8 0ED0F3FF   call    00404FF8
004C7FEA|.A1 247D5100   mov   eax, dword ptr
004C7FEF|.8B00          mov   eax, dword ptr
004C7FF1|.E8 46060100   call    004D863C
004C7FF6|.68 C4804C00   push    004C80C4                         ;liteserve (
004C7FFB|.A1 247D5100   mov   eax, dword ptr
004C8000|.8B00          mov   eax, dword ptr
004C8002|.FFB0 74090000 push    dword ptr
004C8008|.68 D8804C00   push    004C80D8                         ;)
004C800D|.8D45 E4       lea   eax, dword ptr
004C8010|.BA 03000000   mov   edx, 3
004C8015|.E8 1ED3F3FF   call    00405338
004C801A|.8B55 E4       mov   edx, dword ptr
004C801D|.A1 247D5100   mov   eax, dword ptr
004C8022|.8B00          mov   eax, dword ptr
004C8024|.E8 130DF8FF   call    00448D3C
004C8029|.A1 247D5100   mov   eax, dword ptr
004C802E|.8B00          mov   eax, dword ptr
004C8030|.8B80 00030000 mov   eax, dword ptr
004C8036|.BA 03000000   mov   edx, 3
004C803B|.E8 D42DF9FF   call    0045AE14
004C8040|.6A 00         push    0                              ; /Arg1 = 00000000
004C8042|.66:8B0D DC804>mov   cx, word ptr             ; |
004C8049|.B2 02         mov   dl, 2                            ; |
004C804B|.B8 E8804C00   mov   eax, 004C80E8                  ; |liteserve has been successfully registered! =d\n\nthanks!
004C8050|.E8 BB89F7FF   call    00440A10                         ; \liteserv.00440A10
004C8055|.C783 4C020000>mov   dword ptr , 1
004C805F|.EB 15         jmp   short 004C8076                   ;注册成功后就越过注册失败提示
004C8061|>6A 00         push    0                              ; /Arg1 = 00000000
004C8063|.66:8B0D DC804>mov   cx, word ptr             ; |
004C806A|.B2 01         mov   dl, 1                            ; |
004C806C|.B8 28814C00   mov   eax, 004C8128                  ; |name and key don't match!\n\ntry again ;)
004C8071|.E8 9A89F7FF   call    00440A10                         ; \liteserv.00440A10
004C8076|>33C0          xor   eax, eax
004C8078|.5A            pop   edx
004C8079|.59            pop   ecx
004C807A|.59            pop   ecx
004C807B|.64:8910       mov   dword ptr fs:, edx
004C807E|.68 B5804C00   push    004C80B5
004C8083|>8D45 E4       lea   eax, dword ptr
004C8086|.E8 19CFF3FF   call    00404FA4
004C808B|.8D45 E8       lea   eax, dword ptr
004C808E|.BA 03000000   mov   edx, 3
004C8093|.E8 30CFF3FF   call    00404FC8
004C8098|.8D45 F4       lea   eax, dword ptr
004C809B|.E8 04CFF3FF   call    00404FA4
004C80A0|.8D45 F8       lea   eax, dword ptr
004C80A3|.BA 02000000   mov   edx, 2
004C80A8|.E8 1BCFF3FF   call    00404FC8
004C80AD\.C3            retn
004C80AE   .^\E9 79C8F3FF   jmp   0040492C
004C80B3   .^ EB CE         jmp   short 004C8083
004C80B5   .5B            pop   ebx
004C80B6   .8BE5          mov   esp, ebp
004C80B8   .5D            pop   ebp                              ;0012F3E8
004C80B9   .C3            retn


注册成功后的信息保存在其安装目录下的“options.ini”中。

另外,按此文中的两种爆破方法,用任意字符注册,程序会自动把用户名和真码写到此ini文件中,乖乖隆嘀咚,比注册机还酷!
--------------------------------------------------------------------------------

key=09143932239239132860
name=foxjinlin

--------------------------------------------------------------------------------
【经验总结】
经过试验可知,此程序注册机制有2大缺陷:

1、注册码明文比较;
2、注册控制流程有缺陷,只要不跳向注册失败,程序就会把真码写入到注册标识。

--------------------------------------------------------------------------------
最后附上破解补丁和内存注册机(包含编制的方案),算法分析以后再研究。

--------------------------------------------------------------------------------
【版权声明】: 本文原创于PYG论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2011年03月19日 11:59:38

GGLHY 发表于 2011-3-19 12:12:15

前排学习,顶下兄弟了!

foxjinlin 发表于 2011-3-19 12:20:54

GGLHY大侠手好快的说

自己只能座板凳了

GGLHY 发表于 2011-3-19 12:44:38

恩,刚看了下算法,还是很简单的。
依次取用户名20位(不足则重复取用户名直到20为止)每位ASCxor (固定字符串Try BUYING LiteServe)每一位ASC;
xor后的结果转10进制,取10进制的个位
直至20位,就是注册码了

GGLHY 发表于 2011-3-19 12:50:11

GGLHY大侠手好快的说

自己只能座板凳了
foxjinlin 发表于 2011-3-19 12:20 https://www.chinapyg.com/images/common/back.gif


    呵呵,刚好看见你发帖,无意间抢了个沙发

yunfeng 发表于 2011-3-22 22:05:24

回复 4# GGLHY


    兄弟一出手,就把算法搞定了,厉害

GGLHY 发表于 2011-3-23 10:21:50

回复GGLHY


    兄弟一出手,就把算法搞定了,厉害
yunfeng 发表于 2011-3-22 22:05 https://www.chinapyg.com/images/common/back.gif

呵呵,会简单的。向大牛们学习!

foxjinlin 发表于 2011-3-24 02:45:26

本帖最后由 foxjinlin 于 2011-3-24 03:23 编辑

恩,刚看了下算法,还是很简单的。
依次取用户名20位(不足则重复取用户名直到20为止)每位ASCxor (固定 ...
GGLHY 发表于 2011-3-19 12:44 https://www.chinapyg.com/images/common/back.gif

GGLHY太猛了,算法分析的速度连富二代们飙车都没法比,呵呵。

算法分析我注解不好,希望能有大侠的这篇算法分析的详细注解,若能有C语言版的算法注册机源码的话,那就求之不得了。

现在有些后悔学易语言了,越来越觉得易语言像个玩具,虽然操作比较便捷,但在高级别的开发应用上就难登大雅之堂,最让我别扭的就是易语言对API函数的调用上,感觉真是婆妈到了极点。

所以,到关键时刻,类C的语言就能独令风骚。

foxjinlin 发表于 2011-3-24 02:48:15

本帖最后由 foxjinlin 于 2011-3-25 12:23 编辑

我补上易语言版的算法注册机吧。

算法分析写注解俺还欠火候,正在请GGLHY帮忙哦,希望各位兄弟不要见怪。

并也放出源码。

注册机预览:


下面是成品算法注册机(把3个附件下回,并放在同一目录下即可解压),易语言静态编译+VC6.0链接,由于加了水波纹特效,所以启动有那么一点慢:



下面是注册机核心算法(还是搞成代码吧):

----------------------------------------------------------------------------------------------------------------
#以下代码可以直接复制到易语言IDE使用:

.子程序 注册算法, 文本型, , 注册机的核心算法部分
    .局部变量 用户名, 文本型
    .局部变量 用户名长度, 整数型
    .局部变量 用户名数组, 文本型, , "0"
    .局部变量 参与字符, 文本型
    .局部变量 参与字符数组, 文本型, , "0"
    .局部变量 注册码, 文本型
    .局部变量 计次, 整数型
      
   ' -----------------------------------------------------------------------------------------------------------------
   ' 把用户名的每位,从左到右依次转换成ASCII字符对应的十六进制,这里去掉了十六进制字符串的空格。原因可能无法说很明白,
   ' 你可以自己写个文本保存,再用UltraEdit打开,以十六进制的方式查看一下,在再OD里跟踪一下就知道了(空格是从来不参与计算的,
   ' 注意这里的语境,是说十六进制中的空格,比方说“foxjinlin”转换成十六进制,就是这样“66 6F 78 6A 69 6E 6C 69 6E ”,参
   ' 与计算的字符就是“666F786A696E6C696E”)。若用户名为中文字符或其它非ASCII字符,则将一个字符拆分成两个字符用(这里我不
   ' 细说了,自己用UltraEdit测试)。
   ' -----------------------------------------------------------------------------------------------------------------
    用户名 = 文本到十六进制无空格 (编辑框1.内容)
    计次 = 1
    用户名长度 = 取文本长度 (用户名) ÷ 2
    .计次循环首 (用户名长度, 计次)
      加入成员 (用户名数组, 取文本左边 (用户名, 2))
      用户名 = 取文本右边 (用户名, (用户名长度 - 计次) × 2)
    .计次循环尾 ()
   ' -----------------------------------------------------------------------------------------------------------------
   ' 若用户名不满20位的(中文字符或其它非ASCII字符,每个算两位),就再从从左到右依次取用户名,直到取满20位为止。
   ' -----------------------------------------------------------------------------------------------------------------
    .如果真 (取数组成员数 (用户名数组) < 20)
      计次 = 1
      .计次循环首 (20 - 取数组成员数 (用户名数组), 计次)
            加入成员 (用户名数组, 用户名数组 [计次])
      .计次循环尾 ()
    .如果真结束
   ' -----------------------------------------------------------------------------------------------------------------
   ' 把“Try BUYING LiteServe”字符串的每位,从左到右依次转换成ASCII字符对应的十六进制数值,同样去掉了十六进制字符串的
   ' 空格,原因不细说了,自己用UltraEdit测试。注意“Try BUYING LiteServe”字符串中的“空格”是参与计算的,ASCII字符“空格”
   ' 转成十六进制就是“20”。
   ' -----------------------------------------------------------------------------------------------------------------
    参与字符 = 文本到十六进制无空格 (“Try BUYING LiteServe”)
    计次 = 1
    .计次循环首 (20, 计次)
      加入成员 (参与字符数组, 取文本左边 (参与字符, 2))
      参与字符 = 取文本右边 (参与字符, (20 - 计次) × 2)
    .计次循环尾 ()
   ' -----------------------------------------------------------------------------------------------------------------
   ' 将转换好的“用户名”和“参与字符”,按对应的位进行异或操作(比方说,用户名的左边第一位异或参与字符的左边第一位)。
   ' 并把每次操作后的结果取出最末位串接起来,就形成了最终的注册码。
   ' -----------------------------------------------------------------------------------------------------------------
    计次 = 1
    .计次循环首 (20, 计次)
      注册码 = 注册码 + 取文本右边 (到文本 (位异或 (到数值 (十六进制转十进制 (用户名数组 [计次])), 到数值 (十六进制转十进制 (参与字符数组 [计次])))), 1)
    .计次循环尾 ()
    返回 (注册码)


#以上代码使用易代码高亮格式工具JS版格式化----------------------------------------------------------------------------------------------------------------

下面是注册机全套源码(把3个附件下回,并放在同一目录下即可解压):

**** Hidden Message *****


背景图片素材(在网上找的,自己拿回家PS处理了下,就现在那样了):




另外背景音乐,比较大,就不上传了,取VERYCD上搜索“林海”,有个专辑叫“琵琶相”,这个背景音乐就是里面的那首“琵琶语”。感觉这曲子很有意境,就用GoldWAVE截取了其高潮部分,做了下增益效果和淡出淡入。

老万 发表于 2011-3-24 06:47:41

学习了,谢谢分享
页: [1] 2
查看完整版本: LiteServe 2.81追码、爆破以及出内存注册机(补上易版算法注册机和源码)