沈某的第一篇文章
C#调用C++Dll
由于C#的反编译太过容易,所以之前自己客户端里调用的加密Dll被反编译之后,可以很容易的看到一些比较重要的信息,所以这次制作一个C++的Dll,调用C++的加密库Crypto++并且把密钥写在自己的C++Dll中,C#程序直接调用,这样可以把密钥隐藏起来。(但是有什么用呢?反正别人可以直接拷贝走C++Dll,这样不知道密钥只要知道输入输出就能解密,不得不说之前用C#制作这种需要安全性的软件简直就是一个大坑。但是在这里我们先假装它有用吧。)
建立一个C++Dll项目
本文使用的是window10系统下的VS2015,生产环境则是win7 x64的机器。
- 文件->新建->项目 选择VC++模板,选择Win32项目,命名为MyDLL点击确定;
- 点确定,然后直接下一步,选择DLL,附加选项选择空项目,点击确定(可以考虑不勾选安全开发生命周期检测,这样可以直接使用一些类似getchar()之类的函数。)。
- 在右侧解决方案资源管理器中右键头文件,新增头文件“MyDLL.h”;
- 同样的,在源文件中新增源文件“MyDLL.cpp”和“MyDLL.def”;
- 到这里基本上所需要的文件都写好了,接下来会说明这些文件是干嘛的;
编码.h头文件
#pragma once
#include<string>
using namespace std;
extern "C" __declspec(dllexport) int EncryptStr(char* plainText);
extern "C" __declspec(dllexport) int DecryptStr(char* plainText);
在.h头文件中申明需要导出的函数:EncryptStr和DecryptStr。
其中,extern "C"是为了解决命名问题,如果不加的话最后DLL的导出函数名字可能会和自己写的函数名不一致。__declspec(dllexport)是声明导出函数。当然也可以写成这样:
#pragma once
#include<string>
using namespace std;
int EncryptStr(char* plainText);
int DecryptStr(char* plainText);
一会在.def(模块定义文件)中声明导出函数。
具体可以参考这篇博客,讲的比较详细。
这里比较值得注意的一点是我之前直接使用string类型的返回值,结果最后函数传递参数的时候不知道为什么出现了错误,可能是因为我使用了__stdcall关键字。
编码.cpp文件
#include "MyDLL.h"
#pragma comment(lib, "cryptlib.lib" )
#pragma warning( disable : 4996)
#include <aes.h>
#include <Hex.h> // StreamTransformationFilter
#include <modes.h> // CFB_Mode
#include <iostream> // std:cerr
#include <sstream>