文章目录
- 前言
- 1、概述
- 2、安装与使用
- 2.1、源码安装
- 2.1.1、部署系统依赖组件
- 2.1.1.1、部署IDA Pro 7.5 SP3
- 2.1.1.2、部署Python 3.9.13
- 2.1.1.3、部署Go 1.13.1
- 2.1.2、使用源码安装系统
- 2.2、使用方法
- 2.2.1、准备测试程序
- 2.2.2、创建IDA Pro项目
- 2.2.3、使用Go_Parser解析二进制程序
- 3、测试用例
- 4、参考文献
- 总结
前言
本博客的主要内容为Go_Parser的部署、使用与原理分析。本博文内容较长,因为涵盖了Go_Parser的几乎全部内容,从部署的详细过程到如何使用Go_Parser对Go语言编译得到的二进制进行逆向分析,以及对Go_Parser进行逆向分析的原理分析,相信认真读完本博文,各位读者一定会对Go_Parser有更深的了解。以下就是本篇博客的全部内容了。
1、概述
Go_Parser是一个针对Go语言二进制文件的解析工具,灵感来源于golang_loader_assist和jeb-golang-analyzer。它具有多项核心功能:
- 解析firstmoduledata:firstmoduledata是Go语言二进制文件中的一个重要结构,它包含了各种关于模块的信息,如导入表、导出表以及运行时类型信息等。Go_Parser能够自动定位并解析firstmoduledata,从中提取出有用的信息。
- 解析pclntab:pclntab(PC Line Table)是一种用于存储程序计数器(PC)和源代码行号之间映射关系的数据结构。通过解析pclntab,Go_Parser能够恢复函数的符号信息,并提取源码文件列表,有助于理解程序的结构和执行流程。
- 解析strings和string pointers:Go语言中的字符串在二进制文件中以字符串常量的形式存在,而字符串指针则用于指向这些字符串。Go_Parser能够解析二进制文件中的字符串及其指针,有助于分析程序中的字符串使用情况。
- 解析types:在Go语言中,类型信息对于理解程序的数据结构和对象之间的关系至关重要。Go_Parser能够解析二进制文件中的types信息,并为这些类型的各种属性添加有意义的注释或数据引用(dref),帮助逆向分析人员更好地理解程序的数据结构。
- 解析itab:itab(Interface Table)是用于实现Go语言接口的数据结构,在二进制文件中保存了接口类型和实现类型之间的映射关系。通过解析itab,Go_Parser能够理解程序中接口的使用情况,有助于分析程序的设计和实现。
通过以上核心功能,Go_Parser能够帮助逆向分析人员深入理解和解析Go语言的二进制文件,从而更好地进行逆向工程和安全分析。此外Go_Parser工具基于Python语言开发。
2、安装与使用
软件环境 | 硬件环境 | 约束条件 |
---|---|---|
Windows 10专业版 | 使用2个处理器,每个处理器3个内核,共分配6个内核 | 本文所讲解的Go_Parser源代码于2024.05.06下载 |
具体的软件环境可见“2.1、源码安装”章节所示的软件环境 | 内存8GB | 本文所安装的Go_Parser源代码于2023.05.06下载 |
硬盘200GB | 具体的约束条件可见“2.1、源码安装”章节所示的软件版本约束 | |
Go_Parser部署在VMware Pro 17上的Windows 10系统上(主机系统为Windows 11),硬件环境和软件环境也是对应的VMware Pro 17的硬件环境和软件环境 |
2.1、源码安装
2.1.1、部署系统依赖组件
2.1.1.1、部署IDA Pro 7.5 SP3
-
首先来到当前用户的根目录中,创建一个名为“IDAPro7.5”的文件夹:
-
然后来到这里下载IDA Pro 7.5 SP3的免安装压缩包,然后将下载好的免安装压缩包解压刚刚创建的名为“IDAPro7.5”的文件夹中:
-
然后执行下面的程序:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按照如下图所示进行选择:
-
然后按如下图所示进行选择:
-
因为后续需要使用Python 3.9来支持IDA Pro 7.5 SP3,所以我们将该目录中名为“ida75sp3_python39_win”的压缩文件解压到当前目录中并全部替换原有文件:
-
然后启动IDA Pro 7.5 SP3:
-
然后按照如下图所示进行选择:
-
然后按照如下图所示进行选择:
-
然后会出现如下图所示的界面,这就代表IDA Pro 7.5 SP3部署完毕,以后需要使用的时候都按照该步骤启动IDA Pro 7.5 SP3,不再赘述:
2.1.1.2、部署Python 3.9.13
-
首先来到Python官网下载Python 3.9.13的安装文件到本地:
-
然后启动下载后的安装文件,并按照如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
等待安装完成:
-
然后按如下图所示进行选择:
-
然后打开CMD:
-
在打开的命令行窗口中执行
python
命令,会出现如下图所示的内容,这就代表Python 3.9.13部署完毕:
2.1.1.3、部署Go 1.13.1
-
首先来到Go语言官网下载Go 1.13.1的安装文件到本地:
-
然后打开安装文件,并按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后等待安装:
-
然后按如下图所示进行选择:
-
然后打开命令行终端,执行
go version
命令,会打印如下图所示的内容,这代表Go 1.13.1部署完毕:
2.1.2、使用源码安装系统
-
首先来到Go_Parser的官网下载Go_Parser的源代码到本地:
-
然后将下载好的Go_Parser的源代码解压到任意位置,在这里我将其解压到系统的桌面:
-
那么到此时,Go_Parser就已经部署完毕了,因为Go_Parser是以IDA Pro 7.5 SP3的插件的形式使用的,所以不需要额外的安装。只是使用Go_Parser的时候将下载好的Go_Parser的源码当作脚本直接执行即可。关于Go_Parser的具体使用方法,请参考“2.2、使用方法”章节
2.2、使用方法
2.2.1、准备测试程序
- 在系统的桌面创建一个名为“test.go”的文件,并在其中输入如下内容,最后保存后退出即可:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
- 然后在系统桌面打开CMD,并执行如下命令来将上面的源码编译为二进制程序:
> go build -o test
2.2.2、创建IDA Pro项目
-
首先打开在“2.1.1.1、部署IDA Pro 7.5 SP3”章节中部署好的IDA Pro,并将刚刚编译好的二进制程序导入到IDA Pro中:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后就会得到如下图所示的界面,这就是使用IDA Pro对我们的测试文件的初次反汇编的结果。不过由于Go语言有非常多的独有的特点,所以仅仅靠IDA Pro无法解析这些Go语言独有的特点。那么就要利用到本文介绍的Go_Parser插件来对其进行反汇编了,从而得到更精细的反汇编结果:
-
此外,我们还可以查看我们测试文件的
main()
函数对应的反汇编代码:
2.2.3、使用Go_Parser解析二进制程序
-
当我们按照以上步骤做好准备工作后,按照如下图所示加载Go_Parser插件:
-
然后选择在“2.1.2、使用源码安装系统”章节中解压好的Go_Parser的源码目录中的名为“go_parser.py”的文件,并将其打开:
-
然后会出现如下图所示的窗口,提示我们正在使用Go_Parser脚本分析该二进制程序。我们无需对该窗口进行任何操作:
-
当解析成功后,会在输出窗口打印一些提示信息。并且可以发现解析前的汇编代码与解析后的汇编代码确实发生了变化,这说明我们成功在IDA Pro 7.3 SP3中使用Go_Parser插件解析了Go语言编译得到的二进制程序。后续就可以根据解析结果对该二进制程序进行更进一步的分析:
3、测试用例
- 首先在系统的桌面创建一个名为“test.go”的文件,并在其中输入如下内容,最后保存后退出即可:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
- 然后在系统桌面打开CMD,并执行如下命令来将上面的源码编译为二进制程序:
> go build -o test
-
然后打开在“2.1.1.1、部署IDA Pro 7.5 SP3”章节中部署好的IDA Pro,并将刚刚编译好的二进制程序导入到IDA Pro中:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后按如下图所示进行选择:
-
然后就会得到如下图所示的界面,这就是使用IDA Pro对我们的测试文件的初次反汇编的结果。不过由于Go语言有非常多的独有的特点,所以仅仅靠IDA Pro无法解析这些Go语言独有的特点。那么就要利用到本文介绍的Go_Parser插件来对其进行反汇编了,从而得到更精细的反汇编结果:
-
此外,我们还可以查看我们测试文件的
main()
函数对应的反汇编代码:
-
当我们按照以上步骤做好准备工作后,按照如下图所示加载Go_Parser插件:
-
然后选择在“2.1.2、使用源码安装系统”章节中解压好的Go_Parser的源码目录中的名为“go_parser.py”的文件,并将其打开:
-
然后会出现如下图所示的窗口,提示我们正在使用Go_Parser脚本分析该二进制程序。我们无需对该窗口进行任何操作:
-
当解析成功后,会在输出窗口打印一些提示信息。并且可以发现解析前的汇编代码与解析后的汇编代码确实发生了变化,这说明我们成功在IDA Pro 7.3 SP3中使用Go_Parser插件解析了Go语言编译得到的二进制程序:
-
我们着重来看输出窗口中的内容,首先来看如下图红框和红箭头处所示的内容:
根据这个输出,可以发现Go_Parser已经成功地找到了firstmoduledata
对象,并且确认了其魔数为0xfffffffb
。这个结构在Go语言的二进制文件中非常重要,包含了关于模块的各种信息。另外,输出中显示了总共有0x75f
个函数。这表明在二进制文件中存在着相当数量的函数,它们可能是程序的各种组件、功能或者库函数。 -
然后再来看如下图红框和红箭头处所示的内容:
这段输出显示了Go_Parser工具在解析二进制文件时创建了一系列函数,并列出了这些函数的地址。每一行的格式是Create function @ address
,其中address
是函数在内存中的地址。这些函数可能是在二进制文件中定义的各种代码块,例如程序的不同功能模块、库函数或者用户自定义函数等。另外,输出还显示了Go语言的根目录路径为c:\go
,这表明在解析过程中发现了程序所使用的Go语言的根目录路径。 -
然后再来看如下图红框和红箭头处所示的内容:
这条输出表明Go_Parser工具对126个函数指针进行了重命名操作。函数指针是指向函数的指针变量,对其进行重命名可能是为了提高代码的可读性和理解性,或者为了匹配函数的实际名称。通过重命名函数指针,逆向分析人员可以更容易地理解代码中函数指针的作用和含义,从而更好地理解程序结构和行为。 -
然后再来看如下图红框和红箭头处所示的内容:
这段输出显示了Go_Parser工具在解析二进制文件时发现的源文件路径。在这个例子中,发现了一个源文件路径为C:/Users/iie-iisd/Desktop/test.go
。这个路径可能是二进制文件所对应的源代码文件的路径。通过记录源文件路径,可以帮助逆向分析人员将二进制文件中的代码和相应的源代码文件联系起来,进而更好地理解和分析程序的功能和结构。 -
然后再来看如下图红框和红箭头处所示的内容:
这段输出指示了Go语言的版本为1.13.1。这个信息对于逆向分析人员来说可能是有用的,因为不同版本的Go语言可能会有一些语法和行为上的差异。知道程序是使用哪个版本的Go语言编译的,可以帮助分析人员更好地理解代码中的一些特性和行为,以及避免由于版本差异引起的误解。 -
然后再来看如下图红框和红箭头处所示的内容:
这段输出显示了pclntbl的地址为0x4ec3c0
。pclntbl是一种用于存储程序计数器(PC)和源代码行号之间映射关系的数据结构。在Go语言的二进制文件中,pclntbl包含了关于函数的调试信息,例如每个函数的起始地址、指令地址和对应的源代码行号等。知道pclntbl的地址可以帮助逆向分析人员定位到该数据结构在内存中的位置,并且通过解析它,可以获得关于函数调试信息的更多细节,从而更好地理解程序的结构和执行流程。 -
然后再来看如下图红框和红箭头处所示的内容:
这些错误信息表明Go_Parser在解析二进制文件时遇到了一些问题,无法处理某些字符串。具体来说:- 第一个错误指出,在地址
0x56ece0
处的字符串长度为5143
,但无法使用在地址0x417e2c
处的函数中。类似地,第二个错误指出另一个字符串长度为10763
,但无法在另一个函数的上下文中使用。 - 第三个和第四个错误显示了两个较短的字符串,长度分别为
108
。同样,它们也无法在指定的函数中使用。 - 最后一个错误指出了一个长度为
1000000000
的字符串,这是一个非常大的字符串。由于其巨大的长度,可能会导致内存或其他资源方面的问题。
总的来说,这些错误提示了在解析二进制文件时遇到的一些字符串处理问题。这些问题可能会影响到程序的正确解析和理解,因此需要进行进一步的调查和修复。此外,Go_Parser 工具成功地从二进制文件中解析了1316个字符串,并且准备好将它们用于后续的分析过程。这些字符串可能包含了关于程序结构和功能的重要线索,有助于逆向分析人员理解程序的行为和内部机制。
- 第一个错误指出,在地址
-
然后再来看如下图红框和红箭头处所示的内容:
这条输出表明正在构建所有类型。在Go语言中,类型信息对于理解程序的数据结构和对象之间的关系非常重要。因此,在逆向工程中,解析和构建类型信息是一项关键任务。通过构建所有类型,可以建立类型之间的关系,帮助逆向分析人员更好地理解程序的结构和数据流。这些类型信息可能包括基本类型、自定义类型、结构体、接口等。一旦所有类型都被成功构建,逆向分析人员就可以更深入地分析程序的数据结构和对象之间的关系,从而更好地理解程序的功能和行为。 -
然后再来看如下图红框和红箭头处所示的内容:
这段输出提供了有关类型链接(Typelinks)的信息,以及在构建类型过程中发现的一些警告和结果:Typelinks address is 0x4eb680
:这表示类型链接的地址为0x4eb680
。类型链接用于在运行时实现Go语言中的接口。了解类型链接的地址可以帮助逆向分析人员定位到它们在内存中的位置,并进一步分析接口的实现。WARNNING: empty type @ ...
:这些警告表示在构建类型时遇到了一些空类型。这可能是由于二进制文件中存在一些缺失或错误的类型定义导致的。虽然这些警告可能会影响到后续的分析过程,但它们并不会阻止工具的继续运行。Standard types building finished. Total types count: 1175
:这说明标准类型的构建已经完成,共计1175种类型。标准类型包括Go语言中的基本类型(如int、string)和标准库中的一些常见类型。Extra types building done, total count: 1
:这表示额外类型的构建也已完成,共计1种类型。额外类型可能是一些用户自定义的类型或者第三方库中的类型。Start to parse Itab
:这是一个开始解析Itab的提示。Itab是用于实现Go语言接口的数据结构,它保存了接口类型和实现类型之间的映射关系。Itab parsing done, total count: 22
:这表示Itab解析完成,共计找到了22个接口实现。解析Itab可以帮助理解程序中接口的使用情况,有助于分析程序的设计和实现。
综合来看,这段输出提供了关于类型构建和解析过程的一些关键信息,有助于逆向分析人员理解程序的类型系统和接口实现。
-
总而言之,IDA Pro对Go语言编译得到二进制程序的解析效果并不好(因为Go语言有很多独有的特性),而Go_Parser可以帮助我们更好的解析Go语言编译得到二进制程序,且根据以上信息我们可以回到IDA Pro中对测试程序进行后续的分析。不过因为我们主要介绍Go_Parser,故不对IDA Pro中的操作进行过多介绍,感兴趣的读者可以自行查看(其实就是将以上解析结果替换原有的汇编代码,不做过多介绍,若后续有需求再将其更新到该文档中)。
4、参考文献
- Go_Parser:一款针对IDAPro的Galong二进制代码分析工具
- [PYG绿化集成全插件版]IDA Pro 7.5 SP3 (x86, x64, ARM, ARM64, PPC, PPC64, MIPS) + SDK+DOC
- 无符号GoLang逆向经历
- Go二进制文件逆向分析从基础到进阶——综述
- Python Releases for Windows | Python.org
- [原创]GoParser——Yet Another Golang binary parser for IDAPro
- 没有任何安装的文档么? · Issue #3 · 0xjiayu/go_parser
- 【Go】windows下的Go安装与配置,并运行第一个Go程序
- Go语言环境安装及配置
- All releases - The Go Programming Language
- go语言文件逆向认知篇(ida7.6直接绕行)
- Go二进制文件逆向分析从基础到进阶——MetaInfo、函数符号和源码文件路径列表
- Go二进制文件逆向分析从基础到进阶——Tips与实战案例-安全客 - 安全资讯平台
- Go二进制文件逆向分析从基础到进阶——数据类型
- Go二进制文件逆向分析从基础到进阶——itab与strings
总结
以上就是本篇博文的全部内容,可以发现,Go_Parser的部署与使用过程并不复杂,我们本篇博客对其进行了详细的分析。相信读完本篇博客,各位读者一定对Go_Parser有了更深的了解。