一、实例

在国内很多朋友都觉得golang的逆向分析很难,其实不然,和其他编程语言相比,go语言的函数太多。但是如果go语言不去符号话,则觉得和.net差不多难度(还是未混淆的)。本文就是要解决golang逆向过程中所遇到去符号化问题。

图1是没有去掉符号信息的反汇编,可以看到GOLANG运行时的各函数名 , 第二张图是去掉符号信息的反汇编,GOLANG运行时的函数名都没了(样本准备,最好是在linux下自己编译一个helloworld用于分析对比)。

图1 go语言没有去掉符号信息的反汇编

图2 go语言去掉符号信息的反汇编

二、分析

这里先感谢https://rednaga.io/2016/09/21/reversing_go_binaries_like_a_pro/链接的作者所提供的的脚本和资料(Reversing GO binaries like a pro)。其提供了golang_loader_assist.py脚本可用于还原符号信息。不过该脚本并不能直接用于windows环境下编译的go程序。在golang_loader_assist.py代码中使用了.gopclntab, .gopclntab是一个非常重要的segments 。在windows环境下去符号化编译go程序逆向分析时不包含该segments。如图3所示:

图3  windows环境下去符号化编译go程序无.gopclntab

图4 linux下没有去除符号信息的go。

图4  含有.gopclntab

因此在他人的肩膀上,对于windows环境go语言的去符号化还原,核心就是要确认.gopclntab的位置:

1、首先旅一下golang_loader_assist.py代码的流程,之后再说windows环境下的go符号还原。

先将golang_loader_assist.py中核心代码贴出,如代码1所示:Line 1: def renamer_init():

Line 2:     renamed = 0

Line 3:     gopclntab =idaapi.get_segm_by_name('.gopclntab')

Line 4:     ifgopclntab is not None:

Line 5:         # Skip unimportant header and gotosection size

Line 6:         addr = gopclntab.startEA + 16

Line 7:         size, addr_size = create_pointer(addr)

Line 8:         addr += addr_size

Line 9:         # Unsure if this end is correct

Line 10:         early_end = addr + (size * addr_size *2)

Line 11:         while addr < early_end:

Line 12:             func_offset, addr_size =create_pointer(addr)

Line 13:             name_offset,addr_size = create_pointer(addr + addr_size)

Line 14:             addr += addr_size * 2

Line 15:            func_name_addr = Dword(name_offset +gopclntab.startEA + addr_size)                                                                                       +gopclntab.startEA

Line 16:             func_name =GetString(func_name_addr)

Line 17:             MakeStr(func_name_addr,func_name_addr + len(func_name))

Line 18:             appended = clean_func_name =clean_function_name(func_name)

Line 19:             debug('Going to remap function at0x%x with %s - cleaned up as %s' % (func_offset, func_name, clean_func_name))

Line 20:             ifidaapi.get_func_name(func_offset) is not None:

Line 21:                 if MakeName(func_offset,clean_func_name):

Line 22:                     renamed += 1

Line 23:                 else:

Line 24:                     error('clean_func_nameerror %s' % clean_func_name)

Line 25:     return renamed

代码 1 golang_loader_assist.py中核心代码

如图4所示:.gopclntab的start地址为0813a140,下面为程序单步计算过程。

由line 6可以看到addr = gopclntab.startEA + 16的位置的值是3fcc;

由line 13可知name_offset =3fcc

由line 15可知 name_offset + gopclntab.startEA+ addr_size = 0813a140+3fcc+4=0813e110

Dword(0813e110)=3ffc

func_name_addr=0813e13c

func_name ==(main.main)

图5代码1单步执行结果地址展示

那么如果已知字符串位置,反推.gopclntab是不是也合理呢,答案是一定的。

2、window环境go语言环境去符号化还原:

IDA使用快捷键shif+f12调出字符串窗口搜索runtime或 main一类的关键字,如图6所示:

图6 ida字符串检索结果

随意点开一个字符串,如runtime.memhash_varlen,如图7 所示:

图 7 runtime.memhash_varlen字符串所在地址

runtime.memhash_varlen 的地址是004c1d8c  ,图7中鼠标选择部分是该函数所在的地址,其下方20f6c 为该函数名(runtime.memhash_varlen字符串)相对于.gopclntab的偏移地址。

那么由反推.gopclntab的地址为:004c1d8c-20f6c=004a0e20 如图8 所示:

图8 .gopclntab的地址

心细的朋友可能早就发现, .gopclntab位置是包含特征码的啊!!!!!!FB FF FF FF其实就是这么简单。

三、其它提示

a) 修改IDA的segments 新添加的一定要叫.gopclntab,之后便可以使用idapython(ida的插件)

segment name  .goclntab

start address    (search FB FF FF FF)

end address    (.text segment 的尾部)

b)之后IDA加载golang_loader_assist.py,

i. gopclntab =ida_segment.get_segm_by_name('.gopclntab')

if gopclntab is notNone:

ii.             # Skip unimportant header andgoto section size

iii.             addr = gopclntab.startEA + 8

iv.             size, addr_size =create_pointer(addr)

v.              addr += addr_size  这里 addr = gopclntab.startEA + 8(也有可能是+16)

c) IDA处理go语言的逆向是f5会失效,原因在于每个函数后面都跟随了runtime_morestack或者runtime_morestack_noctxt函数,因此对这两个函数直接字符串化,就可以使用f5了。

d)  runtime_newproc,启动了一个协程,别跟丢。

e) runtime_makechan,go语言比较特殊的channel。

f) golang_loader_assist.py中涉及到IDApython的版本,如果不能直接使用,可将原python文件中的ida_segment .get_segm_by_name替换成idaapi.get_segm_by_name就可以了。其它地方类似将idat_segment,ida_search,ida_funcs,ida_xref换成idaapi)。

四、总结

在很多论坛里很少看到关于go去符号化还原的文章,也经常听周边的人说go语言逆向有多难,可能是被硕大的golang吓到了吧,其实国外的朋友已经解决了该问题,但是由于使用环境差异造成无法复用。

*本文作者Mworld,转载请注明来自FreeBuf.COM

go语言反汇编linux,Go语言逆向去符号信息还原相关推荐

  1. c语言扫描器,Linux C语言写的超级简单port扫描器

    这个本来曾经也写过的,今天无聊复习下 再写一遍.简单的一塌糊涂,写的不咋地大家见谅哦!有空再加强 嘿嘿! #include #include #include #include #include #i ...

  2. r语言工作路径linux,R语言实用基础知识_工作路径-注释-安装和卸载R包_2019-12-01...

    R语言的实用基础知识有很多,都是我在工作和学习中所整理的,有的是看书整理的,也有的是从网络上的各种博客.各种资源获取的,所以我采用日更的方式进行支持整理和更新,希望能够帮到屏幕前的你! 今天是我日更的 ...

  3. 浅析VS2010反汇编 VS 反汇编方法及常用汇编指令介绍 VS2015使用技巧 调试-反汇编 查看C语言代码对应的汇编代码...

    浅析VS2010反汇编 2015年07月25日 21:53:11 阅读数:4374 第一篇 1. 如何进行反汇编 在调试的环境下,我们可以很方便地通过反汇编窗口查看程序生成的反汇编信息.如下图所示. ...

  4. linux更改语言脚本,Linux shell脚本入门——shell语言脚本【CentOS】

    认识脚本 是使用一种特定的描述性语言,依据一定的格式编写的可执行文件.脚本语言又被称为扩建的语言, 或者动态语言, 是一种编程语言, 用来控制软件应用程序, 脚本通常是以文本 (ASCⅡ) 保存, 只 ...

  5. linux C语言多线程库pthread中条件变量的正确用法逐步详解

    linux C语言多线程库pthread中条件变量的正确用法: 了解pthread常用多线程API和pthread互斥锁,但是对条件变量完全不知道或者不完全了解的人群. 关于条件变量的典型应用,可以参 ...

  6. linux中c语言结构体详解,Linux C语言结构体-学习笔记

    Linux C语言结构体简介 前面学习了c语言的基本语法特性,本节进行更深入的学习. 预处理程序. 编译指令: 预处理, 宏定义, 建立自己的数据类型:结构体,联合体,动态数据结构 c语言表达式工具 ...

  7. 吴章金: 实例解析 Linux C 语言程序之变量类型

    license: "cc-by-nc-nd-4.0" "本文从编译.二进制程序文件和运行角度逐级解析了 Linux C 语言程序中几种变量类型" 吴章金老师&l ...

  8. C语言实现linux环境UDP协议接收发送数据

    C语言实现linux环境UDP协议接收发送数据 说明 上代码 运行结果 说明 闲来无事,写了个C语言的UDP小程序,程序新建了两个线程,分别用来实现UDP数据到发送和接收.需要的直接拿去用. 上代码 ...

  9. 加分项——C语言实现Linux的pwd命令

    加分项--C语言实现Linux的pwd命令 实现要求 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd pwd pw ...

最新文章

  1. OSI七层模型具体解释
  2. (八)整合spring cloud云服务架构 - commonservice-eureka 项目构建过程
  3. 【Python】matplotlib基础:数据可视化
  4. 一夜吸粉200万被封杀,微信都有哪些逆鳞?
  5. linux用unzip解压.zip文件失败解决方案
  6. c语言记录五个数组编程,C语言经典编程之数组
  7. FPGA(8)--频率计检测控制系统
  8. 微信自定义菜单扩容?
  9. (day 29 - 二叉树的先序遍历 )剑指 Offer 34. 二叉树中和为某一值的路径
  10. xshell连接Linxu系统乱码
  11. OKR工作法阅读笔记(第一天)-序言和前言
  12. 洋洋背古诗——寒假版
  13. MIT 6.828 Lab1(从引导扇区开始)
  14. java-IO流-将文件夹以树形结构打印(打印文件夹目录)问题
  15. 计算机键盘输入法基础知识,电脑打字入门基础知识
  16. ubuntu 小新pro14 网卡驱动、键盘、触摸板
  17. 21级pta《查找表》
  18. UVM 代码生成器 easier UVM
  19. EVT, DVT, MVT, PVT常见软件节点是什么意思
  20. java 通联支付接口_通联支付接口.rar

热门文章

  1. 少一份责任,多一份轻松
  2. 基于索引的SQL语句优化之降龙十八掌(转载)!
  3. sklearn机器学习之【学习曲线】
  4. 机器学习的学习曲线和验证曲线
  5. 如何理解进程与线程(超级简单,人人可以看懂)
  6. QML学习十九:ttf字体库使用
  7. 第十三章 SQL命令 CREATE ROLE
  8. mysql_safe my.cnf 配置_mysql my.cnf配置文件详解
  9. BZOJ2085 : [Poi2010]Hamsters
  10. ubuntu 12.04 安装惠普打印机