白盒 SDK 加密 —— Go 语言中直调 C 动态库实现

golang实现依赖注入 golang实现依赖注入 依赖注入是软件工程中经常使用到的一种技术,它提供了一种控制反转的机制,把控制权利交给了调用方。调用方来决定使用哪些参数,哪些对象来进行具体的业务逻辑。 它有几个好处: 1 它让调用方更灵活。 2 大量减少定义类型的代码量 3 增加代码的可用性,因为调用方只需要关注它需要的参数,不需要顾及它不需要的参数了。 什么是依赖注入 依赖注入使用最多的应该是java中的spr... 阅读详情

1.背景

在重构的历史项目中,有一点是语言转换:从 PHP 转至 Goland ,在压缩资源的同时,享受语言实现级别进步带来的性能红利。
在这里插入图片描述

在功能点覆盖上存在白盒 SDK 加密场景,如 流量校验、对端数据传输…等。

  • 原 PHP 实现中是通过扩展方式进行调用:将白盒 SDK 以 .so 文件的形式补充至 php-config --extension-dir,并添加 extension=XXX.so 到 php.ini 配置文件。

  • 现 Goland 实现中,使用直调 C 动态库的方式实现【无成熟的 go-sdk, 存在额外的实现成本】。


2.实现方式

在 Goland 中,也提供了像 Java、Python、C++ …中调用 动态库的原生能力,只是在调度过程实现上存在略微不同。

之前架构设计中提到的 千万级入口服务 —— 框架设计(一:组件模式) 组件也是通过 动态库的方式实现。

  1. Goland 原生动态库构建的时候只要通过 go build -buildmode=plugin -o XX.so 进行 .go 文件到 .so 动态库的状态转换。

  2. C 则需要使用 gcc\g++ gcc/g++ 百科介绍来进行源码文件到 .so 动态库的状态转换。
    在这里插入图片描述


2.1.C 库 .so 文件生成

将目标 C库 的 .a 文件拆解,重新编译 .so 文件。

ar -x XXprotect_sec.a 
g++ -shared *.o -o XXprotect_sec.so

有了 .so 文件之后,还需要有 C 库 的接口文件 .h 文件。.h 文件用来在 Goland 调度过程中进行二次封装调用。


2.2.C 库 .h 文件

在 Goland 中调用 C 库接口,允许存在中间处理环节,即二次封装。而进行的前提是基于 .h 文件提供的 C 库接口。

#pragma once
#ifdef __cplusplus
extern "C" {
#endif

/**
* \brief XX get version function
* \return version string.
*/
typedef const void * (*FN10)(void);
#define XX_VERSION() \
((FN10)gsecfv3[1])()

......

/**
* \brief XX initialize function
* \return return context if successful
*/
typedef void * (*FN11)(const char *, char *, char *);
#define XX_INIT(akey, encrypt_key, decrypt_key) \
((FN11)gsecfv3[2])(akey, encrypt_key, decrypt_key)

2.3.Goland 调用实现

此处聚焦 直调 C 库调用过程,白盒 SDK 加密逻辑及原理 可留言沟通 或 关注后续博文 。

在这里插入图片描述

2.3.1 整体

先整体看:在 package 下方的依赖包引入中,import "C" 必须单起一行,且二次封装的接口务必以注释的方式在其上方编排;下方 Goland 函数中使用时,以 C 库开头直接调用即可。

需要注意的是:

  1. 注释中的 #include .h 行,不仅仅是 C 库的接口,也可以是 C 中的原生包。比如:#include<stdio.h> …
  2. Goland 中调用使用到的 C 库,务必在注释行引入。如果不引入,项目编译时就会报出 could not determine kind of name for C.XX...错误。
  3. C 动态库编译的版本与 Goland 执行版本中的需兼容。否则会报出 :c running gcc failed: exit status 1 //opt/compiler/gcc-8.2/lib64/libstdc++.so.6: undefined reference to... 错误。
package encrypt

/*
   #cgo CFLAGS: -I.
   #cgo LDFLAGS: -L. -lXXprotect_sec -Wl,-rpath,./
   #include "XXlib_v3.h" // C 库接口文件

   const char *XX_version() {
       return XX_VERSION();
   }

   void *XX_init(const char *akey, char *encrypt_key, char *decrypt_key) {
       return  XX_INIT(akey, encrypt_key, decrypt_key);
   }
	......
   int XX_destory(void *context) {
       return XX_DESTORY(context);
   }

*/
import "C" // import “C” 必须单起一行,并且紧跟在注释行之后

import (
	"context"
	"reflect"
	......
	"unsafe"
)

func XXEncrypt(ctx context.Context, tp string, data string, ver string, iv string) (string, error) {
	iv = iv + "\x00"
	// 打印白盒SDK版本号
	log.Println(C.GoString(C.bdswb_version()))
	......
	return "", nil
}
2.3.2 注释块部分

接下来,看到注释块中,前两行标记了当前 C 库调用动态库 的位置及特征。使用的是 #cgo cgo 详细介绍 方式。

在注释主体中,是对 C 库接口的二次封装,类似 Hook 方式,给予开发者适当的操作空间。

需要注意的是:

  1. 动态库在项目编译时,需要在 环境变量中引入。可覆盖、追加变量 LD_LIBRARY_PATH,否则无法从位置路径中获取到 .so 动态库。比如:export LD_LIBRARY_PATH=/root/codes/XXXso/path:$LD_LIBRARY_PATH
  2. 最好是在 ~/.bash_profile 中变更,这样对每次终端都生效,不要忘记重启 source ~/.bash_profile。
2.3.3 逻辑实现部分

在 Goland 实现部分,特地写了 iv = iv + "\x00" 代码行。这里是将 Goland 中的字符串转为 C 中的格式。这种写法是未引用 C 库原生函数的情况下进行。另一种方式是使用原生库,不过需要在 注释部分追加对应的包。

需要注意的是:

  1. 在 Goland 调用的参数部分,格式需要转换为 C 中的样式,会比较常用到 (*C.uchar)(unsafe.Pointer) … 等业务开发中少用到的转换方式。

3.小结

整体下来看,Goland 中直调 C 库 操作是很流程化的。在此前提下,也给予了调用规则适当的灵活性。

在这里插入图片描述

但综上,是不建议初学者使用的。尤其是不充分了解、熟悉 Goland、C 语言特性 及 项目主体逻辑、C 库逻辑 的场景;

  1. 在调用过程调试中,数据格式转换、库函数使用…等语言差异导致的问题容易频发。
  2. C 动态库 对于 Goland 调用主体来讲,完全是黑盒、透明的,出现问题不易排查且是维护盲区。
【golang】使用go语言调用c语言的so动态库 因为要将c语言打包,会需要借助gcc的工具,可以直接网上下载安装,还有go工具,也可以在网上直接下载安装。sudo vim /etc/ld.so.conf 文件,将我们的路径写在该文件下,有的文章提到,编译需要加上-fPIC 参数,应该可以不加。编写完go文件,应该就可以执行了,但是运行的时候会报错。也可以运行成功,具体是什么原因大家可以一起交流一下。编辑好后执行:sudo ldconfig。这个从网上查了一下,需要配置一下。创建mylibrary.c。创建mylibrary.h。2.创建c文件和h文件。 阅读详情

相关推荐

Go语法简略 - 依赖注入

通过对web应用框架背后原理的探索,引入了依赖注入的概念。如果你需要读懂或者写一个框架的话,依赖注入的思想绝对能帮到你。本文记录对依赖注入的探索。 区分依赖和宿主 现在我们把问题简化一下: package main import "fmt" func MethodA(name string, f func(a int, b string)) { fmt.Println("

zddhub的专栏 4804

golang开发之cgo第二节:C提供动态库在go中使用

通过示例和理论整理学习go中调用c的cgo语法

weixin_34858807的博客 1144

iOS应用加固实战:混淆、反调试与自动化防护方案

在移动应用开发领域,代码保护与安全加固是保障应用安全的核心技术。其基本原理是通过对编译后的二进制文件进行变换和加密,使逆向工程工具难以直接分析代码逻辑,从而保护核心算法和业务逻辑不被窃取或篡改。这项技术的核心价值在于显著提升攻击者的分析成本与时间,有效防御静态反编译、动态调试、代码注入等常见攻击手段,尤其适用于金融、游戏、企业应用等对安全性要求较高的场景。具体到iOS平台,由于IPA文件容易被提取和分析,开发者需要结合代码混淆、二进制加密、运行时检测等多种技术,构建分层防御体系。本文将以Obfuscator

weixin_34228387的博客 645

Linux C语言调用C++动态链接库

如果你有一个c++做的动态链接库.so文件,而你只有一些相关类的声明,那么你如何用c调用呢, C++创始人在编写C++的时候,C语言正盛行,他不得不让C++兼容C。C++最大的特性就是封装,继承,多态,重载。而这些特性恰恰是C语言所不具备的。至于多态,核心技术是通过虚函数表实现的,其实也就是指针。而对于重载,与C语言相比,其实就是编译方式不同而已: C++编译方式和C编译方式。对于函数调用,

轻飘飞扬 1万+

iOS应用网络授权验证系统构建指南:从设备绑定到服务端安全

在移动应用开发领域,软件授权与版权保护是保障开发者商业利益的核心技术。其基本原理是通过验证机制确保只有合法用户能在授权设备上使用应用。网络授权验证技术通过将关键验证逻辑置于服务端,有效提升了安全性,防止本地破解。其技术价值在于构建了可控的授权生命周期管理体系,支持灵活的商业模式,如单设备授权、多设备授权与订阅制。典型的应用场景包括独立开发者的付费应用、企业级SaaS服务的移动端以及需要高安全级别的工具类App。本文以iOS平台为例,深入探讨了如何利用Keychain实现稳定的设备指纹绑定,并结合请求签名与S

weixin_33806859的博客 340

使用 ONLYOFFICE API 构建 Java 转换器,在 Word 和 PDF 之间进行转换

随着文档处理需求的增加,格式转换成为了一个重要的需求点。由于PDF格式具有跨平台、不易被篡改的特性,将Word格式(.docx)转换为PDF格式(.pdf)的需求尤为强烈。ONLYOFFICE作为一个强大的办公套件,提供了这样的转换功能,使得用户可以轻松地在Word和PDF之间进行转换。

ONLYOFFICE的官方博客 4567

golang调用c语言动态库和静态库,cgo(二)

golang调用c语言动态库和静态库,cgo(二)

猛犸象 2283

详解电路设计中的RC电路

​ 一、什么是RC电路 RC电路是指由电阻R和电容C组成的电路,它是脉冲产生和整形电路中常用到 的电路。 常见的RC充、放电电路、RC积分电路合RC微分电路接下来详细讲解。 二、RC充、放电电路 RC充、放电电路如下图所示,下面通过充电和放电两个过程来分析此电路。 ​RC充、放电电路图 (1)RC充电电路 RC充电电路图如下图(a)所示 RC充电电路图及充电曲线图 ​由上图分析: 将上图a中开关S置于“1”处,电源E开始通过电阻R对电容C充电,由于刚开始充电时电容两端没有..

IT xiaobai 4万+

golang调用c库,cgo(一)

golang调用c库,cgo(一)

猛犸象 7411

海康威视iSC平台视频流对接:RTSP、HLS、WS三种协议到底该怎么选?

本文深入分析海康威视iSC平台视频流对接中RTSP、HLS和WebSocket三种协议的优缺点,帮助开发者根据实时性、兼容性和网络环境做出最优选择。特别适合综合安防管理平台的Web视频监控系统开发,提升用户体验和系统性能。

weixin_28365523的博客 691

ANSYS二次开发:Python和ANSYS进行交互操作(PyAnsys库,DPF)

🎈ANSYS二次开发:APDL开发入门准备🎈- 🎈ANSYS二次开发:后处理使用APDL命令流解析结果文件🎈 🎈ANSYS二次开发:Python解析ANSYS结果文件(PyAnsys库)🎈 🎈ANSYS二次开发:Python操作ANSYS(PyAnsys库,PyDPF)🎈 文章目录1、简介2、安装2.1 ansys-mapdl-core2.2 pyaedt2.3 ansys-dpf-core2.4 ansys-dpf-post2.5 ansys-mapdl-reader2.6 G...

爱看书的小沐 2万+

golang开发之cgo第一节:go提供动态库在C中使用

通过理论讲解,学习go语言生成动态库给C使用方法,同时提供测试源码练习。

weixin_34858807的博客 1290

大众点评商家及评分数据(2012-2025)

大众点评及商家评分数据库全面覆盖全国范围内多个城市的商户信息,涵盖餐饮、购物、休闲娱乐等多个消费领域,包含商家基础信息、地理坐标、分类体系、经营状态、用户评价、消费水平及服务设施等共计28个字段。

Sunny9qx的博客 2692

cgo调用c动态库实战

这篇从一个需求开始说起。这个需求也很简单,就是需要为某个硬件加密算法封装一个接口,接口的逻辑是传入唯一标识UID,能生成加密后的加密串。你好,我是轩脉刃。这篇从一个需求开始说起。这个需求也很简单,就是需要为某个硬件加密算法封装一个接口,接口的逻辑是传入唯一标识UID,能生成加密后的加密串。但是麻烦的是,这个加密算法是另外一个部门使用C开发的。而Web是Golang开发的。...

轩脉刃的刀光剑影 3482

开放平台实现安全的身份认证与授权原理与实战:使用OAuth 2.0实现授权码模式

作者:禅与计算机程序设计艺术 1.背景介绍 随着互联网应用的飞速发展,各种网站、App、小程序等都将逐渐向用户提供了丰富的功能和服务。在这些应用中,用户通常需要登录才能使用这些服务,这就涉及到用户信息的安全问题。如果用户的信息被泄露或篡改,那么可能造成严重后果。因此,为这些应用提供安全且健壮的身份验

AI天才研究院 492

Python爬虫教程:抓取Android或iOS应用中的数据

随着智能手机的普及,移动应用程序已经成为我们生活中不可或缺的一部分。从社交媒体、在线购物到金融服务和健康管理,几乎所有领域都有相应的手机应用程序(App)服务用户。而这些应用程序通常会存储大量的数据,例如用户行为、产品信息、订单记录等。如果我们能有效地抓取这些数据,可以为数据分析、商业智能、用户行为分析等提供有力支持。本文将重点介绍如何使用Python爬虫技术抓取Android或iOS应用中的数据,尤其是如何从这些应用的后端接口、存储、或网页中提取数据。我们将探讨如何通过反向工程技术访问移动应用中的API接

2201_76125261的博客 800

go语言调用c语言动态库及交叉编译

实现基础:CGO编程 C/C++经过几十年的发展,已经积累了庞大的软件资产,它们很多久经考验而且性能已经足够优化。Go语言必须能够站在C/C++这个巨人的肩膀之上,有了海量的C/C++软件资产兜底之后,我们才可以放心愉快地用Go语言编程。C语言作为一个通用语言,很多库会选择提供一个C兼容的API,然后用其他不同的编程语言实现。Go语言通过自带的一个叫CGO的工具来支持C语言函数调用,同时我们可以用Go语言导出C动态库接口给其它语言使用。 如果有纯Go的解决方法就不要使用CGO;CGO中涉及的C和C++构建问

weixin_43128854的博客 7153

【YOLOv8系列】在Windows上离线搭建YOLOv8运行环境

我们都知道,通过 pip安装YOLOv8是非常方便的,但是有时候网络环境受到限制,比如公司的工作站(无法连接网络)或者机房的教学机器等等,只能通过离线的方式安装YOLOv8;今天就来记录一下离线搭建YOLOv8运行环境的过程。并记录了遇到的问题及解决过程。

AnChenliang_1002的博客 2004

go dll注入 go进程注入

【代码】go dll注入 go进程注入。

friendan的专栏 783

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

golang cgo 动态链接库相互调用

cgo 动态链接库相互调用

u013345780的博客 767

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

golang 学习(10): 使用go语言调用c语言的so动态库

一、前言 最近在学习go,因为需要调用c语言打包成的so动态库里面的方法,避免自己再去造轮子,所以想直接使用golang调用so,但是参考了其他博客大佬写的,我每一步原封不动的写下来,结果都是一堆错误,错误因为没有实时的截图,所以我这里不会展示出具体出现了哪些错误,我将记录下我成功调用的所有步骤。 二、环境 因为要将c语言打包,会需要借助gcc的工具,Wind...

mokwing 1万+

Go中使用动态库C/C++库

最近需要做一些在go中使用动态C++库的工作,经常碰到 示例代码目录结构(假设代码根目录为/home/gdc/cgotest): ----|bin: ----|pkg ----|src --------|main ------------|main.go --------|oidb ------------|hello ----------------|hello.go: --

xiaogugood的专栏 1万+

Go中调用C的动态库与静态库

转:http://ybxu-123.blog.163.com/blog/static/594737702014818113159247/ 最近在学习GO语言,作为一门基于C语言的语言。对于它的语法很快掌握了,其实本人很早就想写一些关于GO的文章了,今天抽空就写一下,费话不说了,直击主题好了。以下代码是在Linux运行的结果,若用GDB调试,最好安装7.1以上版本。   一、Go

xiaoxiaota的专栏 6522

GO程序调用C及C++库的实现方式

一.windows下go调用c函数的实现方法1)直接在go文件中使用package main /* int add(int a,int b){ return a+b; } */ import "C"import ( "fmt" )func main() { fmt.Println("Hello World!") fmt.Println(C.add(2, 1)) } 执行结果:

迷惘宅猪的专栏 1万+

GO调用ffmpeg动态库

package main/*#cgo CFLAGS: -I/usr/local/ffmpeg/include#cgo LDFLAGS: -L/usr/local/ffmpeg/lib -lavformat#include "libavformat/avformat.h"#include "libavcodec/avcodec.h"#include "libavutil/avutil.h"#incl...

evsqiezi 9367

谨慎在多进程中使用Go生成的动态库

之前写过一篇《C语言调用Go生成的动态库中的函数》,实际在OpenSIPS中使用时,却发现程序经常会“陷入”动态库函数的调用。 使用GDB附加到进程,函数调用block时堆栈如下: #0 runtime.futex () at /usr/local/go/src/runtime/sys_linux_amd64.s:520 #1 0x00007f13340e7d16 in runtime.futexsleep (addr=0xfffffffffffffe00, val=0, ns=-1) at /u

kslidong的博客 1659
上一篇: 【HELLO NEW WORLD】一封来自开放自动化时代的邀请函
下一篇: 新服务入驻生产环境 CICD 全流程、自动化脚本教程
魏小言
魏小言 优质创作者: 云计算技术领域 优质创作者: 云计算技术领域 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄11年 1万+粉丝 301原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魏小言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值