吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 21630|回复: 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++] 纯文本查看 复制代码
#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!字样
1.png
2.png
  od加载自己的exe,然后转到dll里面,查找字符串“can't write row 0 in trial version”
  在所有找到的地方下断,然后运行程序
3.png
  程序断在了这里
4.png
  往上边看,如果上边的两个跳转任意一个跳走,就不会触发这个地方,所以这里应该就是关键跳,那么改跳转不就行了么。这当然可以,但是刚才找了N多地方,一个一个的改觉得不大好,
  所以要找关键点
  1007D071  |.  80B8 98090000>cmp byte ptr ds:[eax+0x998],0x0
  这里有一处比较,如果[eax+0x998]不等于0就触发限制。
  所以要找一下哪个地方改写了这个内存地址的值。这里选用内存写入断点
5.png
  操作方法(大牛请无视):鼠标点击那条指令,然后在中间的ds:[00xxxxxx]上按右键,数据窗口跟随
  然后在下边数据窗口的第一个字节处,按右键,断点,内存写入。
  断点下好后,继续运行程序,程序会在这里断下。
6.png
  这里首先给内存地址写入0,过了个call之后又写入1。结合上边的判断,应该始终让这个地址保持为0,所以应该将所有改写这个地址的指令全部修改为0即可。
  这个可以使用查找二进制串,也可以使用查找所有命令来进行操作。我试了一下,所有的改写都是同一个指令,所以,这里使用“查找所有命令”来操作。
  查找结果
7.png
  将这四个指令
  mov byte ptr ds:[ecx+0x998],0x1
  全部改为
  mov byte ptr ds:[ecx+0x998],0x0
  保存到可执行文件。
  重新运行程序
  程序提示发现了buy me
  打开excel文件,果然在25行发现了不同的数据。
8.png
9.png
  把excel文件清空,使用od载入程序,
  查找字符串“Buy me”,同理,全部下断,然后运行
10.png
  程序断下后,把字符串“Buy me”改为其他的字符串,这里我改成“suziha”
11.png
  然后ctrl+f9运行到返回
  下面使用ce(cheatengine)查找字符串“suziha”
12.png
  在od的数据窗口按右键,转到,输入刚才ce找到的地址,并下内存访问断点。然后运行程序
  程序断在了这个位置
13.png
  然后返回到上层(Ctrl+f9)
14.png
  这里没发现什么,继续返回
15.png
  这里上边可以看到有N多跳转,怎么看呢,在段首下断,然后单步看下流程即可
[Asm] 纯文本查看 复制代码
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]
16.png
  经过分析,1007D5D0这个跳转就是关键跳,直接把他改成jmp就可以了,但是注意,程序调用的是宽字节(W结尾)的函数,所对应的多字节(A结尾)的函数也要改,我用上边的那个除法作为特征码进行查找。
  找到这个地方1007B8B1 把他也给改成jmp即可。
17.png

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

查看全部评分

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

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

我也破解完毕了

    完整.jpg

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

免费评分

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

查看全部评分

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

点评

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

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

点评

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

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

   

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

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

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

本版积分规则

返回列表

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

GMT+8, 2024-11-17 10:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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