> For the complete documentation index, see [llms.txt](https://ryukiedev.gitbook.io/wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ryukiedev.gitbook.io/wiki/ni-xiang/25.-jie-mi-bei-jia-mi-de-shu-ju-ku-wen-jian.md).

# 25.解密被加密的数据库文件

## 前言

进来有一个个人项目的灵感，于是找到了有提供类似功能的产品，准备逆向研究一波。拿到了IPA包，也找到了数据库文件。但是在准备看下数据库文件的时候遇到了问题。

***数据库加密了🤷‍♂️***

作为一&#x4E2A;***秃头的***&#x9006;向工程师（并不是），我们怎么能轻言放弃呢？

确定本次逆向目标：

* \[X] 获取数据库密码
* \[X] 清除数据库密码

> 开森～都完成了👌

## 一、 定位数据库SDK

先看看IPA中framework文件夹中有什么吧

![Framework](/files/-MfMF6ElqaAL39oY4lzA)

难道用了 `CoreData` ？我们再进一步分析

### 分析 MachO

我们使用 `Hopper` 进行分析，将 `IPA` 中的可执行文件（`MachO`）丢进 `Hopper`。

![Hopper](/files/-MfMF6En2BEbz-z4DgeX)

哦吼～ 很明显用的 `FMDB`。

## 二、 定位密码函数

查看 `FMDB` 的 `API` 寻找切入点。找到了 `- (BOOL)setKey:(NSString*)key;`，准备 `Hook`。

```
@interface FMDatabase : NSObject {
    /** Set encryption key.

    @param key The key to be used.

    @return `YES` if success, `NO` on error.

    @see http://www.sqlite-encrypt.com/develop-guide.htm

    @warning You need to have purchased the sqlite encryption extensions for this method to work.
    */

    - (BOOL)setKey:(NSString*)key;
}
```

## 三、 寻找Hook目标函数

> 砸壳、重签名这里就不再赘述，不是本文的重点。
>
> > [应用砸壳（一定要有越狱手机）](https://ryukiedev.gitbook.io/wiki/ni-xiang/23.-ying-yong-za-ke)

***下面使用\*\*\*\* ****`Logos`**** ****简单进行**** ****`Hook`****。***

```
@interface FMDatabase : NSObject

@end

%hook FMDatabase
- (void)setKey:(NSString*)key {
    NSLog(@"🔓获取到了数据库密码 %@", key);
    %orig;
}

%end
```

***运行后在应用中触发数据库操作，日志输出：***

```
2021-07-24 12:26:26.561085+0800 xx[16475:3222446] 🔓拦截到了数据库密码 xxxx
```

> 成功拦截到了密码👏

## 四、 移除密码

我们先将数据库文件拷贝出来一份。

使用我的 `小工具-RemoveDataBasePassword` 即可获取无密码的数据库文件了～

获取移除密码的数据库文件。就可以正常打开了

### 4.1 RemoveDataBasePassword 使用说明

[GitHub-RemoveDataBasePassword](https://github.com/RyukieSama/RemoveDataBasePassword)

> 如果有帮助到你，留下一颗小星星吧⭐️～

1. 将你的数据库文件拖进工程
2. 修改 `YourDataBasePassWord` 为密码
3. 修改 `YourDataBaseName` 为你的数据库文件名称
4. 运行程序，模拟器即可
5. 当看到屏幕出现 `Click` 点击屏幕
6. 查看 Log，就可以获取路径
7. Enjoy it!

### 4.2 Navicat 报错

我一直用的 `Navicat` 来查看数据库的，但是打开移除密码的数据库时报错了。

![Navicat](/files/-MfMF6ErRElYL0iNr_JR)

虽然报错了，其实没问题。

![Navicat](/files/-MfMF6EsBRduc0ZX21W8)

双击 main，就可以继续访问数据了。

![Navicat](/files/-MfMF6EttzkiG2ZSRf8H)

## 五、 总结思考

整个研究的过程还是比较顺利的，同时也提醒了自己：

* 如果本地数据库信息比较重要的话，仅仅为数据库添加密码时远远不够的
* 对于懂一些逆向的玩家来说还是很容易就能获取到的
* 感觉也是时候和大家分享一下一些防护手段了
* 欢迎点赞、评论、交流
