当前位置: 首页 > 科技观察

开发笔记:如何对【动态链接库】文件进行加密保护?_0

时间:2023-03-21 01:28:40 科技观察

问题描述昨天由于产品需求,需要写一个Windows操作系统下的小工具。这个小工具会调用一个比较重要的DLL动态库文件来完成一些重要的功能。一般来说,最直接的方式是调用Win32API函数动态加载,获取函数地址,释放:LoadLibrary(...);GetProcAddress(...);FreeLibrary(...);然而,由于这个原因,动态库显得更为重要。如果将DLL文件直接放在文件目录下,会增加文件被反编译的风险。也就是说,为了提高DLL文件的安全性,最好不要让用户看到/获取文件;即使获得了文件,用户也不容易破解文件。问题解决分析过程就不多说了,这里直接说目前的处理方法:1、写一个小工具软件,使用AES对称加密算法对DLL文件进行加密,主要是对秘钥进行简单的管理。加密文件liba_enc.png与可执行文件放在一起。此时如果用户获取了动态库,理论上是不可能解锁文件的,因为没有秘钥。然而,道高一尺,魔高十尺。..2、修改应用程序,解密加密后的DLL文件。这个动态库最终必须加载到应用程序的内存空间中才能使用。因此,在加载前需要由用户(即应用程序)解密。.那么,应该在哪里解密呢?用于加载动态库的API函数LoadLibrary()需要文件的路径作为参数。也就是说:必须将一个动态库文件的路径传递给这个函数,这样才能正确加载到内存中。如果是Linux系统,可以解压到/tmp临时文件系统。该文件在动态库使用过程中始终存在;一旦使用结束,它将被立即删除。但是Windows系统中并没有临时文件系统这样的东西。即使有类似的临时文件空间,即使DLL文件的生命周期很短,仍然有暴露给用户的可能。只要用户有机会看到解密后的文件,有办法先dump出来再反编译...3.将加密后的DLL文件解密到内存缓冲区目前能想到的最好的方法即:先将加密后的DLL文件解压到一个空闲的内存缓冲区中(例如:堆空间中malloc的一个空间),然后根据动态库Stream的加载过程从这个缓冲区中读取字节,加载到代码中动态库所属的空间。刚才说了,LoadLibrary(...)函数只能接受文件路径作为参数,我们不能把缓冲区的首地址传给它,所以我们需要使用其他方法来加载。刚好在github上看到这样一个开源的C代码:图中描述的功能正是我需要的,简直就是量身定做:先把DLL文件读入缓冲区;然后从缓冲区加载动态库的内容;只有一个头文件MemoryModule.h和一个C文件:MemoryModule.c,提供的函数也足够简单:HMEMORYMODULEMemoryLoadLibrary(constvoid*,size_t);FARPROCMemoryGetProcAddress(HMEMORYMODULE,LPCSTR);voidMemoryFreeLibrary(HMEMORYMODULE);语义上对应Win32提供的三个函数,唯一不同的是加载函数传入的参数是:缓冲区的地址和长度。经测试证明:此方法效果很好,完美解决了我的问题!4.Linux操作系统呢?因为我目前只有windows平台有这个需求,所以这个方法相当于重写了一套动态库加载函数。那么,如果Linux系统上有类似的需求,有没有类似的:从内存缓冲区加载动态库的实现?我还没有找到类似的代码,如果你知道,请在评论中分享?多谢!