调用代码和已编译的dll
https://blog.csdn.net/Qwertyuiop2016/article/details/123417013
编译proto
下载源码
https://github.com/google/protobuf/releases
下载完解压到某个目录
下载cmake-gui
https://cmake.org/download/
安装一直下一步就行了,记得勾选创建桌面快捷方式。不然还要去安装路径找
开始编译
第一个框选择上面下载的源码里cmake文件夹的路径,第二个框是选择编译完的文件存放的路径,随便创建一个目录就行
点击左下的configure,然后第二个框选择你要使用的编辑器,因为我用的是vs2017,就选这个了。第三个框是选择编译的平台:win32、x64、arm、arm64。注意,如果需要给32位的程序使用就需要编译win32的,给64位的程序使用就需要编译x64的,所以最好两个都编译。
其他的选项默认即可,点击Finish
进入这一步点Generate即可, 如果编译成动态链接库dll需要勾选protobuf_BUILD_SHARED_LIBS, 不然就编译成静态链接库lib,编译成lib即可
很短的时间就会完成,接着Open Project就会亮起来,点击就会用vs2017打开源码
vs2017编译
右键protoc,第一个生成就会在之前选择的目录下生成一个Debug文件夹,里面就是需要的东西,当然你也可以编译成release版本的,编译的文件可能会小点。
主要需要的是前三个文件。
proto文件转c
dm.proto
cmd运行protoc --cpp_out=./ dm.proto
protoc就是前面编译的protoc.exe, 然后会生成两个文件dm.pb.h
、dm.pb.cc
编写dll
其他步骤和之前写dll的一样,需要注意下面几个地方
添加源码
将之前下载的源码protobuf-cpp-3.20.0-rc-1\protobuf-3.20.0-rc-1\src
里面的google目录复制到新建的vs2017项目里根目录,然后新建一个lib目录,将libprotobufd.lib
复制到lib里。
右键项目
附加包含目录增加当前项目的根目录(也就是google源码的目录)
将运行库改成多线程调试(/MTd)
(如果编译release版本,需要改成多线程(/MTd)
)
预编译头改成不使用
附加库目录增加lib目录(libprotobufd.lib放的目录)
附加依赖项前面增加libprotobufd.lib;
之后就是添加一下dm.pb.h和dm.pb.cc到项目,然后写个导出的函数
int protoToJson(unsigned char *input, unsigned int inputSize, unsigned char *out) {
bilibili::DmSegMobileReply s;
std::string str(reinterpret_cast<char const*>(input));
if (!s.ParseFromString(str)) {
return -1;
}
std::string output;
google::protobuf::util::MessageToJsonString(s, &output);
unsigned char *out1 = (unsigned char *)output.c_str();
memcpy(out, out1, output.length());
return 0;
}
函数很简单,就从input里读取加密的内容,然后解密成json格式的字符串
python调用
import ctypes
import os
def proto2Json(content):
dll = ctypes.CDLL(os.path.abspath('BILIDM64.dll'))
protoToJson = dll.protoToJson
protoToJson.argtypes=[ctypes.c_char_p, ctypes.c_uint, ctypes.c_char_p]
protoToJson.restype = ctypes.c_int
content_len = len(content)
result = ctypes.create_string_buffer(content_len*3)
print("运行是否成功(0成功):", protoToJson(ctypes.c_char_p(content), ctypes.c_uint(content_len), result))
print("字符串: 结果: %s" % len(result.value.decode()), len(content))
if __name__ == "__main__":
with open('seg.so', 'rb') as f:
content = f.read()
proto2Json(content)
aardio调用
import console;
import web.json;
var dll = raw.loadDll("F:\Code\DLL\Python\BILIDM.dll",,"cdecl" );
var protoToJson = dll.api("protoToJson","int(string str,int len, string str)");
var s = string.load("F:\Code\CPP\proto\seg.so");
var str = raw.buffer(1000000);
console.log("运行是否成功(0成功):", #s, protoToJson(s, #s, str))
var result = raw.tostring(str);
console.dumpTable(web.json.parse(result));
console.log("md5结果: ", #result);
console.pause(true);
这个buffer的长度感觉用加密的长低*3差不多,如果buffer长度不够会报错或者什么也不显示。
折腾这个其实主要是想在aardio解密protobuf内容,因为aardio自带的库只支持proto2。Python的话解密很简单,protoc.exe就支持直接转成python文件,在pip install protobuf
就能解密了