吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 22228|回复: 32
上一主题 下一主题
收起左侧

[原创] 一款excel文件解析库的破解记录

[复制链接]
跳转到指定楼层
楼主
苏紫方璇 发表于 2015-8-24 15:57 回帖奖励
本帖最后由 苏紫方璇 于 2015-8-24 16:10 编辑

【文章标题】: 一款excel文件解析库的破解记录
【文章作者】: 苏紫方璇
【软件名称】: LibXl 3.6.2
【下载地址】: 自己搜索下载
【使用工具】: OD,CE,VC
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【转载提示】: 本文原创于吾爱破解论坛的苏紫方璇, 转载请注明作者并保持文章的完整, 谢谢!
--------------------------------------------------------------------------------
  首先介绍一下(抄袭官网)这个库

Direct reading and writing Excel files
  
  LibXL is a library that can read and write Excel files. It doesn't require Microsoft Excel and .NET framework, combines an easy to use and powerful features. Library can be used to
  Generate a new spreadsheet from scratch
  Extract data from an existing spreadsheet
  Edit an existing spreadsheet
  LibXL can help your applications in exporting and extracting data to/from Excel files with minimum effort. Also it can be used as report engine. Library can be used in C, C++, C#, Delphi, Fortran and other languages. Supports Excel 97-2003 binary formats (xls) and Excel 2007-2013 xml formats (xlsx/xlsm). Supports Unicode and 64-bit platforms. There are a wrapper for .NET developers and separate Linux, Mac and iOS editions. See features of the library in demo.xls or demo.xlsx files.

想了解详细的可以去问一下度娘
--------------------------------------------------------------------------------------
  【详细过程】
  由于是分析dll文件,需要一个宿主进程来加载,所以我写了一个程序来加载此dll(代码如下,代码写的很烂,请轻喷{:1_910:})
[C++] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <stdio.h>
#include <conio.h>
#include "include_c/libxl.h"
#include <tchar.h>
 
#pragma comment(lib,"libxl.lib")
 
int main()
{
        int i = 0;
        const char *b;
        const TCHAR *c;
        BookHandle book = xlCreateBook();
        if (book)
        {
                if (xlBookLoad(book, _T("example.xls")))
                {
                        SheetHandle sheet = xlBookGetSheet(book, 0);
                        if (sheet)
                        {
                                for (i = 0; i < 350; i++)
                                {
                                        if (xlSheetWriteStr(sheet, i, 0, _T("11111"), 0) == 0)
                                        {
                                                b = xlBookErrorMessage(book);
                                                printf("%d行%d列写入错误:%s\n", i+1,1,b);
                                                break;
                                        }
                                        if (xlSheetWriteStr(sheet, i, 1, _T("222222"), 0) == 0)
                                        {
                                                b = xlBookErrorMessage(book);
                                                printf("%d行%d列写入错误:%s\n", i + 1,2, b);
                                                break;
                                        }
                                        if (xlSheetWriteStr(sheet, i, 2, _T("333333"), 0) == 0)
                                        {
                                                b = xlBookErrorMessage(book);
                                                printf("%d行%d列写入错误:%s\n", i + 1, 3, b);
                                                break;
                                        }
                                        if (xlSheetWriteStr(sheet, i, 3, _T("444444"), 0) == 0)
                                        {
                                                b = xlBookErrorMessage(book);
                                                printf("%d行%d列写入错误:%s\n", i + 1, 4, b);
                                                break;
                                        }
                                        if (xlSheetWriteStr(sheet, i, 4, _T("555555"), 0) == 0)
                                        {
                                                b = xlBookErrorMessage(book);
                                                printf("%d行%d列写入错误:%s\n", i + 1, 5, b);
                                                break;
                                        }
 
                                }
                                 
                        }
 
                        if (xlBookSave(book, _T("example.xlsx"))) printf("\nFile example.xls has been modified.\n");
                        for (i = 0; i < 350; i++)
                        {
                                c = xlSheetReadStr(sheet, i, 0, 0);
                                if (c==NULL)
                                {
                                        b = xlBookErrorMessage(book);
                                        printf("%d行%d列读取错误:%s\n", i + 1, 1, b);
                                        break;
                                }
                                else
                                {
                                        if (_tcscmp(c, _T("11111")) != 0)
                                        {
                                                printf("%d行%d列校验错误:%ws\n", i + 1, 1,c);
                                                break;
                                        }
                                }
                                c = xlSheetReadStr(sheet, i, 1, 0);
                                if (c == NULL)
                                {
                                        b = xlBookErrorMessage(book);
                                        printf("%d行%d列读取错误:%s\n", i + 1, 1, b);
                                        break;
                                }
                                else
                                {
                                        if (_tcscmp(c, _T("222222")) != 0)
                                        {
                                                printf("%d行%d列校验错误:%ws\n", i + 1, 1, c);
                                                break;
                                        }
                                }
                                c = xlSheetReadStr(sheet, i, 2, 0);
                                if (c == NULL)
                                {
                                        b = xlBookErrorMessage(book);
                                        printf("%d行%d列读取错误:%s\n", i + 1, 1, b);
                                        break;
                                }
                                else
                                {
                                        if (_tcscmp(c, _T("333333")) != 0)
                                        {
                                                printf("%d行%d列校验错误:%ws\n", i + 1, 1, c);
                                                break;
                                        }
                                }
                                c = xlSheetReadStr(sheet, i, 3, 0);
                                if (c == NULL)
                                {
                                        b = xlBookErrorMessage(book);
                                        printf("%d行%d列读取错误:%s\n", i + 1, 1, b);
                                        break;
                                }
                                else
                                {
                                        if (_tcscmp(c, _T("444444")) != 0)
                                        {
                                                printf("%d行%d列校验错误:%ws\n", i + 1, 1, c);
                                                break;
                                        }
                                }
                                c = xlSheetReadStr(sheet, i, 4, 0);
                                if (c == NULL)
                                {
                                        b = xlBookErrorMessage(book);
                                        printf("%d行%d列读取错误:%s\n", i + 1, 1, b);
                                        break;
                                }
                                else
                                {
                                        if (_tcscmp(c, _T("555555")) != 0)
                                        {
                                                printf("%d行%d列校验错误:%ws\n", i + 1, 1, c);
                                                break;
                                        }
                                }
 
                        }
                }
                xlBookRelease(book);
        }
 
        printf("\nPress any key to exit...");
        _getch();
 
        return 0;
}


  经过测试未注册版有几个限制
  1、表格的第一行会加上标识,并且无法操作第一行
  2、读写行数有限制
  3、写入时会出现Buy me!字样


  od加载自己的exe,然后转到dll里面,查找字符串“can't write row 0 in trial version”
  在所有找到的地方下断,然后运行程序

  程序断在了这里

  往上边看,如果上边的两个跳转任意一个跳走,就不会触发这个地方,所以这里应该就是关键跳,那么改跳转不就行了么。这当然可以,但是刚才找了N多地方,一个一个的改觉得不大好,
  所以要找关键点
  1007D071  |.  80B8 98090000>cmp byte ptr ds:[eax+0x998],0x0
  这里有一处比较,如果[eax+0x998]不等于0就触发限制。
  所以要找一下哪个地方改写了这个内存地址的值。这里选用内存写入断点

  操作方法(大牛请无视):鼠标点击那条指令,然后在中间的ds:[00xxxxxx]上按右键,数据窗口跟随
  然后在下边数据窗口的第一个字节处,按右键,断点,内存写入。
  断点下好后,继续运行程序,程序会在这里断下。

  这里首先给内存地址写入0,过了个call之后又写入1。结合上边的判断,应该始终让这个地址保持为0,所以应该将所有改写这个地址的指令全部修改为0即可。
  这个可以使用查找二进制串,也可以使用查找所有命令来进行操作。我试了一下,所有的改写都是同一个指令,所以,这里使用“查找所有命令”来操作。
  查找结果

  将这四个指令
  mov byte ptr ds:[ecx+0x998],0x1
  全部改为
  mov byte ptr ds:[ecx+0x998],0x0
  保存到可执行文件。
  重新运行程序
  程序提示发现了buy me
  打开excel文件,果然在25行发现了不同的数据。


  把excel文件清空,使用od载入程序,
  查找字符串“Buy me”,同理,全部下断,然后运行

  程序断下后,把字符串“Buy me”改为其他的字符串,这里我改成“suziha”

  然后ctrl+f9运行到返回
  下面使用ce(cheatengine)查找字符串“suziha”

  在od的数据窗口按右键,转到,输入刚才ce找到的地址,并下内存访问断点。然后运行程序
  程序断在了这个位置

  然后返回到上层(Ctrl+f9)

  这里没发现什么,继续返回

  这里上边可以看到有N多跳转,怎么看呢,在段首下断,然后单步看下流程即可
[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1007D5BB  |. /75 2F         jnz short libxl.1007D5EC
  1007D5BD  |> |E8 35872800   call libxl.10305CF7                     ;  Default case of switch 1007D4AB
  1007D5C2  |. |99            cdq
  1007D5C3  |. |B9 FF7F0000   mov ecx,0x7FFF
  1007D5C8  |. |F7F9          idiv ecx
  1007D5CA  |. |81FA 587F0000 cmp edx,0x7F58
  1007D5D0     |7E 1A         jle short libxl.1007D5EC                ;  跳
  1007D5D2  |. |8B46 20       mov eax,dword ptr ds:[esi+0x20]
  1007D5D5  |. |83B8 100A0000>cmp dword ptr ds:[eax+0xA10],0x8        ;  异常
  1007D5DC  |. |72 1C         jb short libxl.1007D5FA
  1007D5DE  |. |8B88 FC090000 mov ecx,dword ptr ds:[eax+0x9FC]
  1007D5E4  |. |6A 00         push 0x0
  1007D5E6  |. |51            push ecx
  1007D5E7  |. |EB 22         jmp short libxl.1007D60B
  1007D5E9  |> |8B75 08       mov esi,[arg.1]
  1007D5EC  |> \8B4E 20       mov ecx,dword ptr ds:[esi+0x20]
  1007D5EF  |.  6A 00         push 0x0
  1007D5F1  |.  57            push edi                                ;  libxltes.??_C@_1O@HCLCEMEK@?$AA3?$AA3?$AA3?$AA3?$AA3?$AA3?$AA?$AA@?$AAc?$AAt?$AAo?$AAo?$AAl?$AAs?$AA?2?$AAc?$AAr?$AAt?$AA?2?$AAc?$AAr?$AAt?$AAw?$AA3?$AA2?$AA?2?$AAc?$AAo?$AAn?$AAv?$AAe?$AAr?$AAt@AAh@$AAD?$AA?$CC@?$AAy?$AAt@
  1007D5F2  |.  81C1 1C040000 add ecx,0x41C
  1007D5F8  |.  EB 17         jmp short libxl.1007D611                ;  正常
  1007D5FA  |>  8D88 FC090000 lea ecx,dword ptr ds:[eax+0x9FC]
  1007D600  |.  6A 00         push 0x0
  1007D602  |.  51            push ecx
  1007D603  |.  EB 06         jmp short libxl.1007D60B
  1007D605  |>  8B55 14       mov edx,[arg.4]                         ;  libxltes.??_C@_1O@HCLCEMEK@?$AA3?$AA3?$AA3?$AA3?$AA3?$AA3?$AA?$AA@?$AAc?$AAt?$AAo?$AAo?$AAl?$AAs?$AA?2?$AAc?$AAr?$AAt?$AA?2?$AAc?$AAr?$AAt?$AAw?$AA3?$AA2?$AA?2?$AAc?$AAo?$AAn?$AAv?$AAe?$AAr?$AAt@AAh@$AAD?$AA?$CC@?$AAy?$AAt@
  1007D608  |.  6A 00         push 0x0
  1007D60A  |.  52            push edx
  1007D60B  |>  8D88 1C040000 lea ecx,dword ptr ds:[eax+0x41C]
  1007D611  |>  E8 CAEEF9FF   call libxl.1001C4E0                     ;  <<
  1007D616  |.  8B5D 08       mov ebx,[arg.1]
  1007D619  |.  8B8B 04030000 mov ecx,dword ptr ds:[ebx+0x304]
  1007D61F  |.  2B8B 00030000 sub ecx,dword ptr ds:[ebx+0x300]

  经过分析,1007D5D0这个跳转就是关键跳,直接把他改成jmp就可以了,但是注意,程序调用的是宽字节(W结尾)的函数,所对应的多字节(A结尾)的函数也要改,我用上边的那个除法作为特征码进行查找。
  找到这个地方1007B8B1 把他也给改成jmp即可。


  注意:这个我仅仅测试了普通的读写功能,其他功能以及未测试的xlsx文件的读写可能存在不可预料的情况,若出现此类情况,请自行处理。
  另外:我只做了32位_cdecl的dll的破解,若需求64位、.Net以及stdcall的也请自行破解,net我不清楚,其他的应该与此类似(特别是stdcall)。
  最后:以上是本人的一点拙见,如果有什么错误和不足之处,还请各位批评指出,如果各位觉得学到了什么,还请不要吝啬手中的热心和CB,感谢大家的支持。
  源码及破解后的文件(需要例子和资料的请登录官网自行下载) libxltest.7z (1.16 MB, 下载次数: 78)   应@smile1110 的要求,附件云盘链接: http://pan.baidu.com/s/1eQyI1eM 密码: qt4w    (如果失效就请下附件吧)
--------------------------------------------------------------------------------

                                                         吾爱破解论坛
                                                       2015年08月24日


点评

俺也破解了,在地板那个楼层有截图哦  发表于 2015-8-24 16:40

免费评分

参与人数 8威望 +2 吾爱币 +1 热心值 +8 收起 理由
haanzcx + 1 + 1 热心回复!
ninymay + 1 这个Lib对写编程的人很有用,谢谢^^
scblue + 1 谢谢@Thanks!
Hmily + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
吃饭睡觉打豆豆 + 1 你已经是论坛大牛了,干嘛不让我发布~~~
榻榻米 + 1 我很赞同!
枫恋蓝点 + 1 谢谢@Thanks!
三少爷的剑 + 1 楼主威武!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

来自 23#
dxl102586342 发表于 2015-9-10 09:49
@苏紫方璇
本人用的是C++ 编程的
我下载后使用后,发现输出的xls格式文档的文件 第一行输出的是淡红色,并且只有第一行的第一个(A1)能输出, A2之后的都是空的.


前面的 4个  mov byte ptr [ecx+0x998],0x1
还有2个     move byte ptr [esi+0x998],0x1 也是访问该地址!

点评

这个不知道,我这测试的没问题  发表于 2015-9-10 10:32

免费评分

参与人数 1热心值 +1 收起 理由
苏紫方璇 + 1 感谢大牛指正,谢谢

查看全部评分

推荐
 楼主| 苏紫方璇 发表于 2015-8-25 18:00 |楼主
Hmily 发表于 2015-8-25 17:53
我意思普通用户咋使用?不可能也弄个exe来加载?

这回懂了,普通用户还真得弄个exe来加载,不过一般普通用户也用不着这东西,有excel就够了。这个算是编程接口,功能就是不借助excel组件来实现解析xls文件。算是编程用的东西吧。
推荐
smile1110 发表于 2015-8-24 16:38
苏紫方璇 发表于 2015-8-24 16:12
免CB通道
链接: http://pan.baidu.com/s/1eQyI1eM 密码: qt4w

我也破解完毕了

   

最后我发现值得深究的地方 其试用版检测赋值语句在 102bXXXX之中某个地方,然后每次检测都与其一个偏移值比较,若是找到那个地方把其数值赋值为eax数值即可完全注册,也就是该软件本身的正版验证机制原理

免费评分

参与人数 1热心值 +1 收起 理由
苏紫方璇 + 1 热心回复!

查看全部评分

沙发
smile1110 发表于 2015-8-24 16:03
附件要钱 1金币 买不起

点评

4000+的cb你告诉我你买不起,我才不信  发表于 2015-8-24 16:05
3#
smile1110 发表于 2015-8-24 16:12
smile1110 发表于 2015-8-24 16:03
附件要钱 1金币 买不起

俺刚看完这篇文章,也想试试,不过你都领完100金币奖励了!!!!

点评

是50cb不是100cb谢谢,要不你再补我50就凑够100了  发表于 2015-8-24 16:46
4#
 楼主| 苏紫方璇 发表于 2015-8-24 16:12 |楼主
smile1110 发表于 2015-8-24 16:03
附件要钱 1金币 买不起

免CB通道
链接: http://pan.baidu.com/s/1eQyI1eM 密码: qt4w
5#
枫恋蓝点 发表于 2015-8-24 16:25
哇塞,楼主,我看好你哦。可惜我看不明白
7#
 楼主| 苏紫方璇 发表于 2015-8-24 16:44 |楼主
smile1110 发表于 2015-8-24 16:38
我也破解完毕了

   

我一直不知道这个从哪里注册正版,你说的那个地方我看见了,但是没仔细分析过
8#
smile1110 发表于 2015-8-24 16:49
苏紫方璇 发表于 2015-8-24 16:44
我一直不知道这个从哪里注册正版,你说的那个地方我看见了,但是没仔细分析过

俺也想要点金币奖励,这个软件是不是悬赏呢?
9#
smile1110 发表于 2015-8-24 16:54
smile1110 发表于 2015-8-24 16:12
俺刚看完这篇文章,也想试试,不过你都领完100金币奖励了!!!!

大哥,俺也破解了,分俺10金币好吗
10#
soarsoar77 发表于 2015-8-24 17:28
大哥,俺也破解了,分俺10金币好吗
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-19 16:07

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表