解决CryptoPP加密库在xp运行的bug

解决CryptoPP加密库在xp运行的bug

现象

使用Qt5.6.3和win10平台编译的程序在xp上运行,报错:无法定位程序输入点memmove_s于动态链接库msvcrt.dll上。

排除过程

这个问题主要是出现的原因是xp上的msvcrt.dll没有提供这个memmove_s这个接口,但是win10上的msvcrt.dll提供了这个接口。但是我搜索了项目代码,并没有显示调用这个接口,所以肯定是其他第三方库调用了这个接口。本项目目前只有一个Cryptopp加密库,所以判断

应该是这个库引入这个接口。

为了验证这个问题,我去该库的源码目录搜索了一下(我是通过源码编译mingw版本的库)。这里有个windows的cmd的小工具,可以快速搜索文本,和Linux的grep类似。

1
findstr memmove_s ./*cpp

结果发现在modes.cpp里面调用这个接口,同时发现在misc.h中已经以内联实现了这个接口。问题来了,编译该库的时候为什么没有提示接口重复定义,或者为什么没有使用cryptopp自己实现的接口。仔细查看misc.h关于该接口实现的代码,发现该库虽然实现了,但是没有开启相关的宏定义,没有把它编译进去,所以默认使用了string_s里面的实现。宏定义如下:

1
#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB)

这里有三个宏影响这个库的是否引入,从字面看CRYPTOPP_WANT_SECURE_LIB是cryptopp自己定义的宏,修改这个宏不会对编译器产生影响。继续搜索这个宏,发现该宏定义在config.h中,解决办法也通过注释给出了,只要打开宏定义就行,默认是注释状态。

1
2
3
4
5
// Define this if you want or need the library's memcpy_s and memmove_s.
// See http://github.com/weidai11/cryptopp/issues/28.
#if !defined(CRYPTOPP_WANT_SECURE_LIB)
# define CRYPTOPP_WANT_SECURE_LIB
#endif

但是这种情况会出现重复实现接口的编译错误,所以为了保证正确引入,在memmove_s的前面直接添加namespace,CryptoPP::memmove_s。这样编译完的库就可以在xp上正确运行。

mingw编译器编译cryptopp

此处采用的是cryptopp820版本,mingw采用Qt5.6.3自带的mingw492。首先搭建mingw编译环境,详情见我另外一篇博客。

1
2
cd cryptopp820
make -j4

该库已经提供了GnuMakefiles,所以在msys2的环境下可以直接编译。

另外一种编译方式如下(不可行):

1
2
3
4
5
cd cryptopp820
rm GnuMakefiles
qmake -project #生成Qt的pro项目文件,修改pro配置,然后执行下列命令
qmake #生成makefiles
make -j4

pro文件修改如下

1
2
3
4
5
6
7
8
TEMPLATE = lib
INCLUDEPATH += .
CONFIG -= qt

win32-g++ {
QMAKE_CXXFLAGS += -msse -msse2 -msse3 -mssse3
LIBS += -lws2_32
}

但是在这种情况下,我无法编译通过,应该是编译参数的问题,明显和GnuMakefiles文件里面的编译参数不一致,这个编译参数是copy网上的,估计那些人也是抄袭的别人的没有验证,所以这种方法不可行。


解决CryptoPP加密库在xp运行的bug
http://yoursite.com/2020/05/29/解决CryptoPP加密库在xp运行的bug/
作者
还在输入
发布于
2020年5月29日
许可协议