• 标 题:【原创】制作AUTOcad2002网络版的Flexlm license 时的另类pediy,纯粹是玩,高手略过!
  • 作 者:laoqian
  • 时 间:2004-11-30,16:09
  • 链 接:http://bbs.pediy.com

制作AUTOcad2002中文网络版的Flexlm license 时的另类pediy,纯粹是玩!

软件名称: AUTOcad2002中文网络版
应用平台: Win2000
软件类别: 地球人都知道
软件介绍: 地球人都知道 Flexlm7.1f加密 
破解工具: ollydbg 1.10(Fly修改版) ,w32Dasm_2002828_pll621,UltraEdit10.0,c32asm ,剩余空间查看器,PEditor
破解目的: 1.自动保存“制作无限制使用license文件的关键数据”到指定文件 
           2.练习diy PE
           3.熟悉寄存器的使用,如eax,[eax]....等,顺便说一下心得。

破解过程:

通过这篇文章我们将向你介绍寄存器的使用的一些心得,如eax和[eax]区别,以及使用时方法,其实我也是刚明白
至于如何制作FlexLm的license见|http://bbs.pediy.com/showthread.php?s=&threadid=6562|,当然有些重复的我省略了

一、查找关键的存放位置————准备工作

废话少说,接上回,我们找到了关键地方如下:

代码:
* Referenced by a CALL at Addresses: |:00945490   , :0094C1EA   , :0094C7B0   , :0096383C   , :00971159    |:00985C14    | :0094DB50 55                      push ebp    <====先在这个地方下断 :0094DB51 8BEC                    mov ebpesp :0094DB53 83EC30                  sub esp, 00000030 :0094DB56 C745F08EB94876          mov [ebp-10], 7648B98E   <====这个数在确定l_sg函数上很有用 :0094DB5D C745EC03000000          mov [ebp-14], 00000003 :0094DB64 8B4508                  mov eaxdword ptr [ebp+08] :0094DB67 8B486C                  mov ecxdword ptr [eax+6C] :0094DB6A 8B91D4010000            mov edxdword ptr [ecx+000001D4] :0094DB70 81E200800000            and edx, 00008000 :0094DB76 85D2                    test edxedx :0094DB78 7423                    je 0094DB9D   :0094DB7A 833DC4DAB50000          cmp dword ptr [00B5DAC4], 00000000 :0094DB81 741A                    je 0094DB9D :0094DB83 8B4510                  mov eaxdword ptr [ebp+10] :0094DB86 50                      push eax :0094DB87 8B4D0C                  mov ecxdword ptr [ebp+0C] :0094DB8A 51                      push ecx :0094DB8B 8B5508                  mov edxdword ptr [ebp+08] :0094DB8E 52                      push edx :0094DB8F FF15C4DAB500            call dword ptr [00B5DAC4] <====在这个地方下断,之后就是我们要的! :0094DB95 83C40C                  add esp, 0000000C   <====我们修改这个地方 :0094DB98 E913010000              jmp 0094DCB0


这时执行,中断在0094DB50后,我们下,下面这些数据就是我们计算seed1和seed2的关键!
*************************

输入 d [esp+8]
********

0012F608  00000004
0012F60C  1731E48D     data[0]
0012F610  061711DA     data[1] 

0012F614  A3A37979
0012F618  CC926A64
0012F61C  A1136749
0012F620  F174A41F
0012F624  00000000

输入d [esp]
***********

0131B660  00000066
0131B664  0073001F  
0131B668  AEF0D6A0   job+08
0131B66C  A21343D5   job+0c
0131B670  C156EC2E   job+10 

0131B674  00000000

我们来保存data[0],data[1],job+08,job+0c,job+10这5个数据到文件!
我们不讲为什么是这5个数据(其实我也一知半解),我们只是用它来讲解!
**********
首先我们来看esp和[esp]区别。输入d esp和d [esp]你会看到数据窗口不同,废话!
d esp你会看到一个地址,而他的内容或者说"值"就是"0131B660" !
就是说esp是指向地址"0131B660"
而地址0131B660的值是"00000066", 
d [esp] 显示的就是esp的值作为地址所指向地址0131B660的值!
比如你d 0131B660就和d [esp]是同样的结果.
***********
而我们需要保存的是0012F60C,0012F610,0131B668,0131B66C,0131B670地址的值
对应的就是:
0012F60C ==[esp+8]+4
0012F610 ==[esp+8]+8
0131B668 ==[esp]+8
0131B66C ==[esp]+0c
0131B670 ==[esp]+10


为了容易理解,我们用上面的来表示,当然这是不规范的!

我们的思路:把以上5个地址的内容在此刻(先存储到我们指定的空间),然后写到文件里

二、查找剩余空间:
 推荐:剩余空间查看器:  作者:牛博威
   Email:   advice107@sina.com
 用nbw写的"剩余空间查看器"分析,部分结果如下:
******************************************
    名称     RVA     OA        尺寸D   可写否
   .text  005e3a27  005e3a27   1497      否
  .rdata  006b6c94  006b6c94    876      否
   .data  0076089c  0076089c  -415900      可
   .rsrc  00771ad8  0070bad8   1320      否
有效剩余空间(字节D)为: 3693 

******************************************
    我们用.rdata段,就说从文件偏移地址006b6c94开始,有876字节可用空间。但是.rdata段为不可写,无法利用这里的空间声明变量。不过不

要紧,用PEditor把这个节区属性改成可写便可以了(方法不罗嗦了,简单)。事实证明,整个文件中.rdata区段最后的剩余空间可以被正确加

载(win2000),这供我们利用足够了!

三、准备winapi函数

我们准备改造注册主程序acad.exe,但是由于acad.exe输入函数表里没有大部分winapi函数,不是他不调用而是反编译后看不到函数名。但是

我们可以用peditor或者LordPE等工具找到winapi函数,再说即使没有我们也可以添加!具体方法我不说了,看雪书里有,找到如下:
 
KERNEL32.CreateFileA 
 
FF1560479E00     call [009e4760] 
*****************
KERNEL32.SetFilePointer

FF15A4489E00     call [009e48a4]
*****************
KERNEL32.WriteFile     

FF15A8489E00     call [009e48a8]
*******************

这里说一下call [009e4760]和call 009e4760不同,[009e4760]是指009e4760的值

四、修改工作


1.变量组织:我们需要用的变量就设在.rdata段006b6c94后面

6b6c96 :    保存号码的文件地址.我们指定在C:\cad.txt里,也可以其他,随便了,不过不要太长!
6b6ca0 :    WriteFile函数的一个参数,数据缓冲区。对我们来说没用。不过不可少!
6b6cac :    文件句柄地址 
6B6CB0 :    我们保存的5个数据的存储地方,每个分配8个字节
6B6CD8 :    一个临时的存放esp指针的地方
6b6ce0 :    我们的修改代码区 


这是文件偏移地址file offset,在使用中要转换,具体参照看雪的书。

2.修改文件,跳转到我们的代码区

:0094DB8F FF15C4DAB500      call dword ptr [00B5DAC4] <====在这个地方下断,之后就是我们要的!
:0094DB95 83C40C            add esp, 0000000C   <====我们修改这个地方,在esp改变前保存他!
:0094DB98 E913010000        jmp 0094DCB0

0094DB95  E946911600         jmp ab6ce0
0094DB95  90                 nop
0094DB96  90                 nop
0094DB97  90                 nop
不足处不上90,下面两句后面补上。
 add esp, 0000000C   
 jmp  0094DCB0

0094DB95跳到我们的代码,我们在.rdata段006b6c96开始我们的工作:

*********************************

00AB6CE0    8925 D86CAB00        mov [AB6CD8], esp <===此时的esp指针保存在AB6CD8
  为什么要保存esp指针呢? 因为是堆栈寄存器,在堆栈操作时要变化比如下面一句pushad,而我们需要的是此刻的esp,
只好保存一下。这里顺便说一下,eax,ebx,edx,ecx是数据寄存器,
而esp,epb,esi,edi是指针及变址寄存器,因为我们在补丁程序时,
不可避免使用寄存器,这时我们最好使用eax,ebx,edx,ecx是数据寄存器,
否则可能会造成堆栈混乱,一点心得。

00AB6CE6    60                   pushad  <===所有的寄存器依次入栈,保持堆栈平衡,后面对应popad
00AB6CE7    A1 D86CAB00          mov eax, [AB6CD8] <===保存在AB6CD8的关键esp指针,这里有我们要的数据!!
00AB6CEC    90                   nop
00AB6CED    36:8B58 08           mov ebx, [eax+8] <===相当于前面[esp+8]的地址,我们传给ebx
00AB6CF1    83C3 04              add ebx,4  <===相当于来到前面[esp+8]+4的地址
00AB6CF4    36:8B0B              mov ecx,[ebx] <===相当于前面[esp+8]+4的地址的值我们传给ecx
00AB6CF7    890D B06CAB00        mov [AB6CB0], ecx  <===相当于前面[esp+8]+4的值保存在AB6CB0
  为什么这么麻烦? 因为“mov [AB6CB0], [ebx]”这汇编命令不存在。
00AB6CFD    83C3 04              add ebx,4  <===相当于来到前面[esp+8]+8的地址
00AB6D00    36:8B0B              mov ecx, [ebx]    <===相当于前面[esp+8]+8的地址的值我们传给ecx
00AB6D03    890D B86CAB00        mov [AB6CB8],ecx  <===相当于前面[esp+8]+8的值保存在AB6CB8
00AB6D09    36:8B18              mov ebx, [eax] <===相当于前面[esp]的地址,我们传给ebx
00AB6D0C    83C3 08              add ebx,8  <===相当于来到前面[esp]+8的地址
00AB6D0F    36:8B0B              mov ecx, [ebx] <===相当于前面[esp]+8的地址的值我们传给ecx
00AB6D12    890D C06CAB00        mov [AB6CC0],ecx  <===同上
00AB6D18    83C3 04              add ebx,4  <===相当于来到前面[esp]+0c的地址
00AB6D1B    36:8B0B              mov ecx, [ebx]
00AB6D1E    890D C86CAB00        mov [AB6CC8],ecx
00AB6D24    83C3 04              add ebx,4  <===相当于来到前面[esp]+10的地址
00AB6D27    36:8B0B              mov ecx, [ebx]
00AB6D2A    890D D06CAB00        mov [AB6CD0],ecx
这里我们看到mov ecx, [ebx]和 mov ecx, ebx是不同,
前者[ebx]是的ebx地址的值给ecx,后者是ebx,相当于ecx=ebx复制!


00AB6D30    90                   nop
00AB6D31    90                   nop
00AB6D32    90                   nop
00AB6D33    90                   nop
00AB6D34    6A 00                push 0
00AB6D36    6A 02                push 2  ;FILE_ATTRIBUTE_HIDDEN,建立文件时使文件属性为隐藏
00AB6D38    6A 04                push 4  ;OPEN_ALWAYS.如果不存在该文件,则建立之
00AB6D3A    6A 00                push 0
00AB6D3C    6A 03                push 3  ;允许其他进程使用文件(为了不发生意外,所以这样设置) 
00AB6D3E    68 000000C0          push C0000000
00AB6D43    68 966CAB00          push 00AB6C96      ; ASCII "C:\cad.txt"指向我们存盘文件 
00AB6D48    FF15 60479E00        call [009e4760]    ; KERNEL32.CreateFileA
00AB6D4E    A3 AC6CAB00          mov  [AB6CAC],eax  ;保存文件句柄留给WriteFile用
00AB6D53    6A 02                push 2  ;FILE_END.设置文件末尾
00AB6D55    6A 00                push 0
00AB6D57    6A 00                push 0  ;设定文件指针为文件末尾
00AB6D59    50                   push eax  ;文件句柄
00AB6D5A    FF15 A4489E00        call [009e48a4]   ; KERNEL32.SetFilePointer
00AB6D60    6A 00                push 0   
00AB6D62    68 A06CAB00          push 00AB6CA0   ;WriteFile函数的一个参数,对我们来说没用,不过不可少!
00AB6D67    6A 28                push 28   ;存储的数据总长度,8x5=40字节
00AB6D69    68 B06CAB00          push 00AB6CB0  ;存储的数据开始地址
00AB6D6E    90                   nop
00AB6D6F    FF35 AC6CAB00        push [AB6CAC]  ;前面保存的文件句柄
这里我们看到push [AB6CAC]和push AB6CAC是不同,前者是的地址的值给入栈,后者是地址,
00AB6D75    FF15 A8489E00        call [009e48a8]    ; KERNEL32.WriteFile
00AB6D7B    61                   popad  <===所有的寄存器依次出栈,保持堆栈平衡
00AB6D7C    83C4 0C              add esp,0C  <===补上
00AB6D7F  - E9 2C6FE9FF          jmp 0094DCB0 <===补上,直接跳去
***********
完工!!
***********
用UltraEdit等工具写acad.exe

这里再说一下pll621的C32asm,绝对是好东东,虽然我习惯用W32dasm,但C32asm的汇编代码查询器,绝对是好,我觉得可以抛弃hiew了,用C3

2asm的汇编代码查询器写汇编,然后再用16进制编辑器如UltraEdit10把代码写到文件里,再结合ollydbg 1.10调试一下,美啊!我以上添加的

代码就是这样的,几乎一次成功(除了改几个跳转的代码)!感谢pll621提供的好东东。

打开acad运行,然后用UltraEdit打开"C:\cad.txt"我们存盘的文件(纪事本打开是乱码)看到如下:

8D E4 31 17 00 00 00 00 DA 11 17 06 00 00 00 00
68 B6 31 01 00 00 00 00 D5 43 13 A2 00 00 00 00
2E EC 56 C1 00 00 00 00 


为什么和前面的不一样?因为存储都是高位在前,低位在后,堆栈!
你只要自己再到着抄一遍

1731E48D     data[0]
0012F610     data[1] ..........略

当然有好事的可以编一段,重新排版,并且直接存为txt文件格式。

五、最后
 
好累啊,其实这是我自己自找麻烦,高手们可以不必看。当时是为了破解cad2004时用的,因为她加了一个猛壳,没法动态调试。
最后也没用上,因为关键点还没找到,哎。虽然已经成功制作了cad2004的license,那是因为autodesk公司太傻!

写出来,如果可以给初学pediy的一点帮助,我就知足了。