[每周一更]-(第75期):Go相关粗浅的防破解方案

在这里插入图片描述

Go作为编译语言,天然存在跨平台的属性,我们在编译完成后,可以再不暴露源代码的情况下,运行在对应的平台中,但是
还是架不住有逆向工程师的反编译、反汇编的情形;(当然我们写的都不希望被别人偷了,以下内容简单做个攻防介绍,起个引导作用,不到之处,多多留言探讨)

  • 反编码(decompilation)是指将机器代码或二进制代码还原为高级语言源代码的过程。虽然一些工具可以进行反编码,但要注意的是,反编码是一个复杂的任务,成功与否取决于多种因素,包括编译器优化、代码混淆和使用的编程语言。
  • 在Go语言中,由于Go是一种静态编译语言,编译器会将Go代码编译为机器码,而不是保留高级语言结构。这使得从Go二进制文件中还原出与原始Go源代码一样的代码非常困难,甚至几乎是不可能的。

逆向工程(反汇编和反编译)

逆向工程(Reverse Engineering)是指将现有的二进制程序或者系统进行分析,还原出其设计或运行机制的一种技术手段

下面是一些逆向工程的常见技术:

  1. 反汇编技术:通过将二进制程序转化为汇编代码,以还原程序的运行过程和指令执行情况。Go语言提供了反汇编工具,可以通过命令行输入“go tool compile -S可执行文件名”来实现反汇编。
  2. 反编译技术:将已经编译好的程序进行还原,得到其源代码。Go语言的反编译工具是“go tool compile -S 源文件名”,生成的代码需要通过代码分析和修改才能重新编译成可执行程序。
  3. 动态调试技术:通过调试器对程序进行分析,观察程序的运行情况和变量值的变化。Go语言的调试器是“dlv”,可以使用命令行对程序进行单步调试。
  4. 内存分析技术:通过对程序运行时的内存进行分析,以了解程序的行为和数据结构。Go语言的内存分析工具是“pprof”,可以对程序进行CPU、内存和goroutine的分析。

1、破解方案

谈到防破解,首先得知道怎么破解,才能更好的防护;

将Go二进制文件转换为与原始源代码结构相同的高级语言源代码是一项非常困难且不可靠的任务。Go是一种静态编译语言,编译器将Go源代码转换为机器码,优化并去除高级语言结构。因此,反向转换机器码到原始源代码是一个复杂的问题。

虽然有一些工具可以进行反汇编和逆向工程,但这些工具通常无法提供与原始Go源代码结构完全相同的高级语言代码。
这是因为编译器进行了各种优化,同时丢失了一些高级语言结构的信息。

以下是一些可能用到的工具:

IDA Pro: IDA Pro是一款反汇编和逆向工程工具,但它通常只能提供汇编级别的代码,并不能还原为原始的高级语言源代码。

Ghidra: Ghidra是一款开源的逆向工程工具,它提供反汇编和分析二进制文件的功能。与IDA Pro类似,Ghidra也更倾向于提供汇编级别的代码。

汇编代码还原: 逆向工程师可能会尝试还原机器码为汇编代码,但这通常只是一个近似的过程,并不会得到原始的高级语言源代码。

2、防破解方式

防破解一直是个很常见的需求,特别是不能做成服务的、或者需要二进制私部署的场景,Go 的编译特性天然就比脚本类语言更好防逆向,脚本类代码是藏不住的。

当然防破解这个事情主要看投入产出比。Go 在这里的优势主要是省心,同时提高了破解的技术门槛。多数时候,写一个时间戳检查、或者 MAC 比对就很够用了。

举例:比如你可以分离功能逻辑和校验逻辑,校验失败并不会立即触发异常,而是会正常执行功能逻辑,但附加一个随机延迟的取消机制,使得功能完成之前就异常退出。

上述逻辑用 Go 代码写出来大概就是 contextWithCancel 几行代码的事情。这样产生的程序无论静态反编译还是静态调试都会很令人迷惑,静态方面难以定位校验逻辑,动态方面上下文切换缺少规律,实际运行表现又是难以稳定复现的,大幅增加了逆向难度。

除此之外还可以配合 burrowers/garble 之类的自动化混淆工具。

以下是常规的增加破解难度的方式:

  1. 删除调试符号

正常情况,我们go代码,部署完成,如果出现报错和日志等,会有暴露目录内容的风险;

go build -ldflags "-s -w" [<your/package] (go version > 1.7 )
  1. 删除trace文件信息

    放到自己的.bash_profile或.zshrc中即可

     ACTUAL_GOPATH="~/Programming/go"export GOPATH='/tmp/go'export GOROOT_FINAL=$GOPATH[ ! -d $GOPATH ] && ln -s "$ACTUAL_GOPATH" "$GOPATH"[[ ! $PATH =~ $GOPATH ]] && export PATH=$PATH:$GOPATH/bin
    
  • https://github.com/golang/go/issues/13809
  1. 代码混淆:
  • 使用工具对Go代码进行混淆,使代码更难以理解。例如,可以使用诸如gobfuscate等工具。
  1. 静态编译: 使用静态编译将依赖项嵌入到二进制文件中,以减少对外部文件的依赖。这可以增加分析和替换的难度。

  2. 加密关键部分:

  • 使用加密算法:使用加密库对关键代码进行加密。运行时在解密后执行这些代码。
  • 例如,您可以使用Go的crypto包进行加密和解密操作。
  1. 代码分割:
  • 模块化代码:将代码组织成模块,然后使用Go的动态导入或插件系统进行加载。
  • 使用Go的plugin包可以实现动态加载。
  1. 使用硬编码密钥:
    将密钥硬编码:在代码中直接将密钥硬编码,而不是存储在配置文件或其他地方
package mainvar encryptionKey = []byte{0x01, 0x02, 0x03, 0x04, 0x05}
  1. 防调试技术:
    使用防调试技术,防止二进制文件在调试器中运行。这可以增加对抗性,使得破解变得更加困难。
    使用runtime/debug包:通过runtime/debug包的ReadBuildInfo函数检查二进制文件是否被构建,从而检测是否在调试模式下运行。
package mainimport ("fmt""runtime/debug"
)func main() {if info := debug.ReadBuildInfo(); info != nil {fmt.Println("Debug information found:", info)// Take appropriate action if running in debug mode}
}
  1. 使用代码签名: 对二进制文件进行数字签名,以确保它的完整性和来源。这可以防止恶意篡改和替换。

  2. 运行时检测: 在运行时检测二进制文件是否被修改。这可以通过计算文件哈希值等方式来实现。

  3. 虚拟化技术: 使用虚拟化技术将关键代码片段放在虚拟机中执行,增加攻击者分析的难度。

  4. 动态链接库: 将一些关键逻辑放入动态链接库,并在运行时动态加载。这可以减少整个二进制文件的复杂性。

参考

  • 分享一些 Go 在全栈开发中的经验

  • 想成为逆向工程师么?

  • 逆向工程介绍

  • 减小 Go 代码编译后的二进制体积-upx

  • Golang二进制文件混淆保护

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/207590.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker-compose;私有镜像仓库harbor搭建;镜像推送到私有仓库harbor

docker-compose&#xff1b;私有镜像仓库harbor搭建&#xff1b;镜像推送到私有仓库harbor 文章目录 docker-compose&#xff1b;私有镜像仓库harbor搭建&#xff1b;镜像推送到私有仓库harbordocker-compose私有镜像仓库harbor搭建镜像推送到私有仓库harbor docker-compose D…

【代码】基于VMD(变分模态分解)-SSA(麻雀搜索算法优化)-LSTM的光伏功率预测模型(完美复现)matlab代码

程序名称&#xff1a;基于VMD&#xff08;变分模态分解&#xff09;-SSA&#xff08;麻雀搜索算法优化&#xff09;-LSTM的光伏功率预测模型 实现平台&#xff1a;matlab 代码简介&#xff1a;提出了变分模态分解(VMD)和麻雀搜索算法(SSA)与长短期记忆神经网络 (LSTM)相耦合,…

【趣味JavaScript】一文让你读懂JavaScript原型对象与原型链的继承,探秘属性的查找机制! 《重置版》

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起学习和进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&a…

校招笔试-Windows开发工程师客观题合集解析

360公司-2019校招笔试-Windows开发工程师客观题合集 API无法实现进程间数据的相互传递是PostMessage 2.以下代码执行后&#xff0c;it的数据为&#xff08;异常&#xff09; std::list<int> temp; std::list<int>::iterator it temp.begin(); it --it; 3.API…

多线程(初阶五:wait和notify)

目录 一、概念 二、用法 &#xff08;1&#xff09;举个栗子&#xff1a; &#xff08;2&#xff09;wait和notify的使用 1、没有上锁的wait 2、当一个线程被wait&#xff0c;但没有其他线程notify来释放这个wait 3、两个线程&#xff0c;有一个线程wait&#xff0c;有一…

docker安装nacos,实现和mysql容器的通信

1.下载nacos镜像 docker pull nacos/nacos-server2. 启动nacos 启动命令如下&#xff1a; docker run -d -p 8848:8848 --name nacos \ -e JVM_XMS256m \ -e JVM_XMX256m \ -e MODEstandalone \ -e SPRING_DATASOURCE_PLATFORMmysql \ -e MYSQL_SERVICE_HOST192.168.131.223…

C++模板—函数模板、类模板

目录 一、函数模板 1、概念 2、格式 3、实例化 4、模板参数的匹配 二、类模板 1、定义格式 2、实例化 交换两个变量的值&#xff0c;针对不同类型&#xff0c;我们可以使用函数重载实现。 void Swap(double& left, double& right) {double tmp left;left ri…

AI为基,快手新商业图景浮现

监制 | 何玺 排版 | 叶媛 快手新商业图景浮现&#xff01; 11月21日&#xff0c;快手发布了2023年Q3财报。该季度内&#xff0c;快手以超2成营收增长的亮眼业绩&#xff0c;展示出强大的经营韧性。同时其在付费短剧、AI应用等业务上的拓展&#xff0c;则让行业和资本市场看到…

unity学习笔记13

一、常用物理关节 Unity中的物理关节&#xff08;Physics Joints&#xff09;是用于在游戏中模拟和控制物体之间的连接。物理关节允许你在对象之间应用各种约束&#xff0c;例如旋转、移动或固定连接&#xff0c;以模拟真实世界中的物理交互。 物理关节类型&#xff1a; 1.F…

Ubuntu新手使用教程

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

JavaScript类型判断:解密变量真实身份的神奇技巧

文章目录 1. typeof运算符2. instanceof运算符3. Object.prototype.toString4. Array.isArray5. 使用constructor属性6. 使用Symbol.toStringTag7. 使用is类型判断库8. 谨慎使用隐式类型转换结语 &#x1f389;JavaScript类型判断&#xff1a;解密变量真实身份的神奇技巧 ☆* o…

LeetCode105.从前序和中序遍历序列构造二叉树

这道题看完题想了几分钟就想到大概的思路了&#xff0c;但是在写的时候有很多细节没注意出了很多问题&#xff0c;然后写了1个多小时&#xff0c;其实这道题挺简单的。 首先&#xff0c;最基本的知识&#xff0c;先序遍历是根左右&#xff0c;中序遍历是左根右&#xff0c;那么…

Unittest(1):unittest单元测试框架简介setup前置初始化和teardown后置操作

unittest单元测试框架简介 unittest是python内置的单元测试框架&#xff0c;具备编写用例、组 织用例、执行用例、功能&#xff0c;可以结合selenium进行UI自动化测 试&#xff0c;也可以结合appium、requests等模块做其它自动化测试 官方文档&#xff1a;https://docs.pytho…

【ChatGLM3-6B】Docker下部署及微调

【ChatGLM2-6B】小白入门及Docker下部署 注意&#xff1a;Docker基于镜像中网盘上上传的有已经做好的镜像&#xff0c;想要便捷使用的可以直接从Docker基于镜像安装看Docker从0安装前提下载启动访问 Docker基于镜像安装容器打包操作&#xff08;生成镜像时使用的命令&#xff0…

C++11线程以及线程同步

C11中提供的线程类std::thread,基于此类创建一个新的线程相对简单&#xff0c;只需要提供线程函数和线程对象即可 一.命名空间 this_thread C11 添加一个关于线程的命名空间std::this_pthread ,此命名空间中提供四个公共的成员函数&#xff1b; 1.1 get_id() 调用命名空间s…

电商营销场景的RocketMQ实战01-RocketMQ原理

架构图 Broker主从架构与集群模式 RocketMQ原理深入剖析 Broker主从架构原理 HAConnection与HAClient Broker基于raft协议的主从架构 Consumer运行原理 基础知识 001_RocketMQ架构设计与运行流程分析 RocketMQ这一块&#xff0c;非常关键的一个重要的技术&#xff0c;面试的时候…

键盘打字盲打练习系列之指法练习——2

一.欢迎来到我的酒馆 盲打&#xff0c;指法练习&#xff01; 目录 一.欢迎来到我的酒馆二.开始练习 二.开始练习 前面一个章节简单地介绍了基准键位、字母键位和数字符号键位指法&#xff0c;在这个章节详细介绍指法。有了前面的章节的基础练习&#xff0c;相信大家对盲打也有了…

设计模式-结构型模式之适配器设计模式

文章目录 一、结构型设计模式二、适配器模式 一、结构型设计模式 这篇文章我们来讲解下结构型设计模式&#xff0c;结构型设计模式&#xff0c;主要处理类或对象的组合关系&#xff0c;为如何设计类以形成更大的结构提供指南。 结构型设计模式包括&#xff1a;适配器模式&…

Day04:每日一题:2661. 找出叠涂元素

2661. 找出叠涂元素 给你一个下标从 0 开始的整数数组 arr 和一个 m x n 的整数 矩阵 mat 。 arr 和 mat 都包含范围 [1&#xff0c;m * n] 内的 所有 整数。从下标 0 开始遍历 arr 中的每个下标 i &#xff0c;并将包含整数 arr[i] 的 mat 单元格涂色。请你找出 arr 中在 mat…

linux 磁盘管理、分区管理常用命令

文章目录 基础命令挂载新硬盘/分区添加内存交换分区swaplvm分区管理模式 基础命令 查看目录文件大小 du -sh /backup du -sh /backup/* du -sh *查看磁盘挂载信息 df -lhT查看某个目录挂载在哪个分区&#xff0c;以及分区的磁盘使用情况 df [目录] #例如&#xff1a;df /ho…