Go逆向_解析创建的类型

逆向分析Go语言生成的可执行程序时,会发现创建对象的代码类似下面这样:

Go语言通过调用runtime_newobject函数创建对象,并通过参数描述创建什么对象。在这个样例中,这个参数保存在rax寄存器中,值是地址0x4C4CA0。

我们最想知道的是到底创建的是什么对象,但是从这个地址处的内容并不能直接获得有用的信息:

在Go源码中该参数的类型为 rtype

type rtype struct {
	size       uintptr
	ptrdata    uintptr // number of bytes in the type that can contain pointers
	hash       uint32  // hash of type; avoids computation in hash tables
	tflag      tflag   // extra type information flags
	align      uint8   // alignment of variable with this type
	fieldAlign uint8   // alignment of struct field with this type
	kind       uint8   // enumeration for C
	// function for comparing objects of this type
	// (ptr to object A, ptr to object B) -> ==?
	equal     func(unsafe.Pointer, unsafe.Pointer) bool
	gcdata    *byte   // garbage collection data
	str       nameOff // string form
	ptrToThis typeOff // type for pointer to this type, may be zero
}

其中最重要的成员有两个。

第一个是kind,这个一个枚举值,描述对象的基础类型,比如:Boolean、integers of various lengths、arrays、maps、interfaces,在源码文件中可以找到完整列表。

另一个是nameOff,这个成员指向一个字符串结构,描述要创建的对象的类型。

我们可以在IDA中给rtype对象创建一个结构:

struct go_rtype{
    UINT * size;
    UINT * ptrdata;// number of bytes in the type that can contain pointers
    DWORD hash  // hash of type; avoids computation in hash tables
    BYTE tflag;   // extra type information flags
    BYTE align;// alignment of variable with this type
    BYTE fieldAlign; // alignment of struct field with this type
    BYTE kind;  // enumeration for C
    void *  func;
    BYTE * gcdata;// garbage collection data
    DWORD  nameOff; // string form
    DWORD typeOff; // type for pointer to this type, may be zero
}

在IDA中对runtime_newobject函数的参数应用该结构后的结果如下:

 这里的nameOff成员为0x3A2E。这是相对.rdata段的偏移。我们可以通过16进制编辑器找到nameOff指示的内容。

在我的样例程序中.rdata段的文件偏移为0x9C00:

 所以nameOff成员指示的内容在文件偏移0x9C00+0x3A2E=0xA062E处:

 这是一个字符串结构,包含三字节字符串长度和字符串内容。我们可以看到,这里创建的是md5.digest对象。

一个Go语言程序中可能会创建数百个对象,而且runtime_newobject不是唯一使用rtype结构的函数,比如:runtime.makechan、runtime.makemap。若是人工分析每个rtype结构是很费时的。这里给大家推荐一个python脚本,AlphaGoLang。这个脚本会寻找所有参数中有rtype类型的函数,然后自动解析rtype描述的对象类型,并以注释形式标注出来:

 这将给Go语言程序逆向分析带来很大方便。

欢迎关注我的微博:大雄_RE。专注软件逆向,分享最新的好文章、好工具,追踪行业大佬的研究成果。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值