一、前言
最近在倒腾东西的时候无意中需要在PC端解密某社交工具的数据库,移动设备中的加密数据库信息,我们也都知道一般采用了免费的SQLCipher进行加密。所以我们想要写个工具解密,需要解决基础问题,在PC上如何用C++进行数据库操作和加解密操作。本文主要来介绍如何用VS2017工具以及C++操作SQLite数据库以及怎么使用加解密数据库,这里为什么要选择VS工具,而不是VC,因为VC的确方便而且也是我之前一直编写C++的工具,但是他的确有很多不足的地方,比如最重要的是没法弄64位的程序,网上说VC也是可以支持的但是需要安装额外的数据包,我觉得太麻烦了,所以选择VS了,而这一次也体会到VS的强大,和AS相比,VS真的太厉害了。以后也都是我编写C/C++必选之利器。
![1183170b7416d5bd44a92b9626fe835c.png](https://i-blog.csdnimg.cn/blog_migrate/82defb2d282b39154e00fd37867ed9ae.jpeg)
二、SQLite数据库操作解析
上面说那么多,下面就来进入本文正题吧,首先我们看看如何借助VS编写我们的第一行SQLite代码,我们的实现效果很简单,只要新建数据库,插入数据然后查询出来就可以了。关于VS2017安装就不多说了,网上都有教程,而且就是傻瓜式的下一步即可。安装好之后我们去SQLite官网下载最新源码,主要包括sqlite3.c,sqlite3.h,sqlite3.def,然后我们新建一个dll工程:
![9dbbbc9377b68f4ebfd9469a92bc5131.png](https://i-blog.csdnimg.cn/blog_migrate/e38bc229e945ae507cb2c059ec3c9c39.jpeg)
这里我们看到有三个项目类型是我们最常见的,第一个就是我们平常用到最多的工程就是DOS中运行的,入口是main函数,大学四年就是一直倒腾这个的,然后就是Windows下的动态库文件dll,这个有点类似于Linux下的共享文件so,我们在编写Android的NDK的时候都知道,可以利用dlopen和dlsym等系统函数,调用so中的函数功能,这个也是可以在代码中调用dll的函数。具体后面会详细介绍。最后一个就是Windows下的静态库,这个类似于Java中的jar包,可以把某些功能打包成lib然后提供给其他项目使用。而dll和lib这两个库类型直接可以转化的,后面会详细介绍。
下面我们就利用sqlite的源码,制作动态库sqlite.dll和静态库sqlite.lib,这个可以只新建一个工程,然后改一下配置就可以自动生成lib文件了。新建dll文件之后,把上面的sqlite3.h和sqlite3.c,sqlite3.def文件拷贝到工程中,注意你的工程名如果是sqlite3,那么工程会默认生成一个sqlite3.cpp入口文件,不过这都没关系,我们删除默认的文件就可以了。然后我们需要设置一下取消预编译头信息,不然报错:
![f0a5f1d3b3e00424050360a5deb5585f.png](https://i-blog.csdnimg.cn/blog_migrate/4fabb5bfaea4d052c3a5e388040f99d1.jpeg)
然后点击生成即可:
![6c1f04eecf1b0dd60c06dc7bdd2ea67f.png](https://i-blog.csdnimg.cn/blog_migrate/ac77db32e96dc06b173ab739aa13ac16.jpeg)
会在控制台中看到生成dll文件:
![975e51e7e6d16a77f6edbdeefa478e7c.png](https://i-blog.csdnimg.cn/blog_migrate/0f528158ec0d4f5977e8e19a634d4922.jpeg)
看到到这里我们就很简单的生成了我们想要的动态链接库文件了,然后我们可以切换成生成lib文件:
![555264744ba96bd1a0d4333dbd464ece.png](https://i-blog.csdnimg.cn/blog_migrate/90083e5ad386a40959853904c90d3dd7.jpeg)
然后在一次点击生成操作:
![3d470d58cfd7b9589b0dc1b63862430b.png](https://i-blog.csdnimg.cn/blog_migrate/958fa191bda372b9dfcc79b4c7977ad2.jpeg)
也是很方便就生成了lib文件了。其实这里还可以借助VS安装之后自带的一些工具通过def文件直接生成lib文件,而def文件之前已经有了用lib命令即可:lib /machine:x86 /def:sqlite3.def /out:sqlite3.lib
![39143d9f4dad2bfb6ec40217997e08a0.png](https://i-blog.csdnimg.cn/blog_migrate/ca734a08e6598e9bfc78b0d72c790efe.jpeg)
然后看看生成的文件:
![9cc9513f9258271730d092289a6b3cef.png](https://i-blog.csdnimg.cn/blog_migrate/e2b86c6e7913d22bb91c8638dac441a5.jpeg)
这里还有一个比较常用的命令就是查看dll文件是32位还是64位的:dumpbin /headers sqlite3.dll
![603f3cebb1ed051784a9abdfe46e6e58.png](https://i-blog.csdnimg.cn/blog_migrate/10c9be71f3adaf7faf15d7187ecc0b8e.jpeg)
好了,到这里我们就看到了如何借助VS生成一个dll文件和lib文件。接下来我们就用我们生成的lib库文件调用看看是否成功,我们只要写一个demo导入sqlite3.lib文件然后操作数据库即可,这里我们就新建一个控制台程序,然后把我们生成的sqlite3.lib和sqlite3.h文件拷贝到我们工程中:
![6cbc2890d4679b62c8d28e87500af05a.png](https://i-blog.csdnimg.cn/blog_migrate/9596f8af9bc0ad990ea436fcc0cc995d.jpeg)
以后一般用第三方库都是这么操作的,会有一个头文件也就是函数的定义,然后就是静态库文件,下面看看操作数据库的代码:
![b1620b86f114f617282a875b0b6b2b45.png](https://i-blog.csdnimg.cn/blog_migrate/f379901d595fc220ca950f2520ffc8d7.jpeg)
这里操作数据库比较简单了,就是打开数据库,然后执行sql语句,最后关闭数据库,这里也可以看到C/C++中使用回调功能都是借助函数指针来进行的。然后运行项目:
![df8bffd6af4cb7bf37f234c48ad369ff.png](https://i-blog.csdnimg.cn/blog_migrate/f011d2c0a6196aca38d513629ced5571.jpeg)
在控制台看到运行结果:
![41eae324ed45a6245adb766e533b88b4.png](https://i-blog.csdnimg.cn/blog_migrate/6884bd825a827e0dd205e3bdf934b573.jpeg)
好了到这里我们就成功的学会了如何借助VS中生成dll和lib库文件,然后在项目中调用。这里全部都是用默认的32位操作的,可以切换成64位来操作。
三、SQLCipher操作解析
上面就介绍了SQLite数据库的操作流程,接下来我们还继续介绍基于这个知识来看看加密数据库SQLCipher项目的使用,这个也是我们最终的目标。我们就来看看把数据库加密即可,这个我们也可以自己去官网去下载SQLCipher下载源码自己编译dll和lib文件,但是我这里没有再去操作了,而是去网上下载了一个别人编译好的dll和def文件,这样我们就可以使用之前说的那个lib命令生成对应的lib库文件了。这里我们介绍两种方式调用,一种是和上面一样的方式直接调用静态库文件lib,还有一个就是利用系统函数调用动态库文件dll,先来看看如何调用静态库文件进行操作:
![9caf9a3928428fb8c1a328a553295a99.png](https://i-blog.csdnimg.cn/blog_migrate/78eafa62384de71936c98c9ac89e47cf.jpeg)
这个不用多说了,用法都很类似,主要需要设置数据库密码。然后运行看效果:
![34a04ee207bc1ce62650a6bf5f6ed0c7.png](https://i-blog.csdnimg.cn/blog_migrate/19dea7e054f47e29cc605062a864fbaa.jpeg)
然后我们把密码修改一下,在去操作数据库:
![f2b61ab4da335518f07a4b202984e733.png](https://i-blog.csdnimg.cn/blog_migrate/c372386df4d73bdb20576cd61f3c8f79.jpeg)
我们把密码改了一下发现提示操作数据库失败了。所以看到操作很简单。下面继续来看看如何调用dll文件:
![450f199b604d3d938cb813a5851baabc.png](https://i-blog.csdnimg.cn/blog_migrate/cd8076deee4a744b162fcd3a175c390e.jpeg)
调用dll文件很简单,和Linux中使用系统函数dlopen和dlsym调用so中的函数一样,这里也是使用系统函数LoadLibrary和GetProcAddress来调用dll中函数功能,所以我们看到在调用之前必须知道dll中导入函数的定义,不然也没法操作的,这里为了操作方便在给每个函数封装了一下,当然这些函数还是需要提前声明,这样在main函数中调用没有问题:
![368f1ade74cc4ba03e9fec6b91588243.png](https://i-blog.csdnimg.cn/blog_migrate/d4c9e8587119f36cc96b3894787fedd7.jpeg)
然后看看调用代码和调用结果:
![c4b019331c47dbad16a7f0995ea2e7ab.png](https://i-blog.csdnimg.cn/blog_migrate/a4e52023ff2dab2ae73bc5746558d80b.jpeg)
看到操作也是成功的。所以到这里我们就成功的调用了dll文件。
四、知识点总结
本文主要介绍了如何用VS工具来操作SQLite数据库,我们学习到的知识点大概如下:
- 第一、学会VS的简单实用
- 第二、学会生成dll库和lib库文件
- 第三、如何在项目中使用dll库和lib库文件
- 第四、SQLite和SQLCipher的基本使用
Windows项目中主要包括编译dll库和lib库,也看到这两个库的区别,dll库是动态库,是项目中编译的时候把函数符号填充进去,运行的时候才被导入进来运行。所以动态库在使用的时候,肯定需要知道导出的函数定义,类似于Android NDK中的共享库so文件。而静态库就是在编译的时候把库中的函数代码都导入项目中了然后运行,类似于Java中的jar包功能。这两个库都有各自的用途,本文就是借助这个例子来给大家演示效果。而且也看到这两个库可以直接转换的,可以通过dll用命令生成def文件,然后在用命令借助def文件生成lib库文件的。然后我们介绍了加密数据库SQLCipher使用lib库文件和dll文件,使用lib库文件很简单,导入头文件,然后在导入库文件即可。而是用dll库文件主要借助系统的函数LoadLibrary和GetProcAddress进行操作。