一
实例版本
二
还原过程
// pcHeader holds data used by the pclntab lookups.
type pcHeader struct {
magic uint32 // 0xFFFFFFF0
pad1, pad2 uint8 // 0,0
minLC uint8 // min instruction size
ptrSize uint8 // size of a ptr in bytes
nfunc int // number of functions in the module
nfiles uint // number of entries in the file tab
textStart uintptr // base for function entry PC offsets in this module, equal to moduledata.text
funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
cuOffset uintptr // offset to the cutab variable from pcHeader
filetabOffset uintptr // offset to the filetab variable from pcHeader
pctabOffset uintptr // offset to the pctab variable from pcHeader
pclnOffset uintptr // offset to the pclntab variable from pcHeader
}type moduledata struct {
pcHeader *pcHeader
funcnametab []byte
cutab []uint32
filetab []byte
pctab []byte
pclntable []byte
ftab []functab
findfunctab uintptr
minpc, maxpc uintptrtext, etext uintptr
noptrdata, enoptrdata uintptr
data, edata uintptr
bss, ebss uintptr
noptrbss, enoptrbss uintptr
end, gcdata, gcbss uintptr
types, etypes uintptr
rodata uintptr
gofunc uintptr // go.func.*textsectmap []textsect
typelinks []int32 // offsets from types
itablinks []*itabptab []ptabEntry
pluginpath string
pkghashes []modulehashmodulename string
modulehashes []modulehashhasmain uint8 // 1 if module contains the main function, 0 otherwise
gcdatamask, gcbssmask bitvector
typemap map[typeOff]*_type // offset to *_rtype in previous module
bad bool // module failed to load and should be ignored
next *moduledata
}
type functab struct {
entryoff uint32 // relative to runtime.text
funcoff uint32
}
//src\runtime\symtab.go
type functab struct {
entry uintptr
funcoff uintptr
}type funcInfo struct {
*_func
datap *moduledata
}//src\runtime\runtime2.go
type _func struct {
entry uintptr // start pc
nameoff int32 // function nameargs int32 // in/out args size
deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any.pcsp uint32
pcfile uint32
pcln uint32
npcdata uint32
cuOffset uint32 // runtime.cutab offset of this function's CU
funcID funcID // set for certain special runtime functions
_ [2]byte // pad
nfuncdata uint8 // must be last
}
hex(0x504320 + 0x2c20) = '0x506f40'
hex(0x504320 + 0x2c48) = '0x506f68'
三
输出脚本
import idc
from idc import *
import ida_naltmoduledata_addr = 0x05289C0
pcHeader_addr = idc.get_qword(moduledata_addr)if idc.get_wide_dword(pcHeader_addr) != 0x0FFFFFFF0:
print(idc.get_wide_dword(pcHeader_addr))
print("错误,并不是一个正确的go文件")funcnametable_addr = idc.get_qword(moduledata_addr + 8)
filetab_addr = idc.get_qword(moduledata_addr + 8 + ((8*3) * 2))
pclntable_addr = idc.get_qword(moduledata_addr + 8 + ((8*3) * 4))
pclntable_size = idc.get_qword(moduledata_addr + 8 + ((8*3) * 4) + (8 * 4))
set_name(moduledata_addr, "firstmoduledata")
set_name(funcnametable_addr, "funcnametable")
set_name(filetab_addr, "filetab")
set_name(pclntable_addr, "pclntable")print(pclntable_size)
def readString(addr):
ea = addrres = ''
cur_ea_db = get_db_byte(ea)
while cur_ea_db != 0 and cur_ea_db != 0xff:
res += chr(cur_ea_db)
ea += 1
cur_ea_db = get_db_byte(ea)
return resdef relaxName(name):
# 将函数名称改成ida 支持的字符串
#print(name)
if type(name) != str:
name = name.decode()
name = name.replace('.', '_').replace("<-", '_chan_left_').replace('*', '_ptr_').replace('-', '_').replace(';','').replace('"', '').replace('\\', '')
name = name.replace('(', '').replace(')', '').replace('/', '_').replace(' ', '_').replace(',', 'comma').replace('{','').replace('}', '').replace('[', '').replace(']', '')
return namecur_addr = 0
for i in range(pclntable_size):# 获取函数信息表
cur_addr = pclntable_addr + (i * 8)# 获取函数入口偏移
funcentryOff = get_wide_dword(cur_addr)
funcoff = get_wide_dword(cur_addr + 4)funcInfo_addr = pclntable_addr + funcoff
funcentry_addr = get_wide_dword(funcInfo_addr)
funnameoff = get_wide_dword(funcInfo_addr + 4)
funname_addr = funcnametable_addr + funnameoff
funname = readString(funname_addr)# 真实函数地址
truefuncname = relaxName(funname)
truefuncentry = ida_nalt.get_imagebase() + 0x1000 + funcentryOffprint(hex(truefuncentry), hex(funcoff), hex(funcInfo_addr),hex(funcentry_addr), hex(funnameoff),hex(funname_addr) ,funname)
# 改名
set_name(truefuncentry, truefuncname)#print(hex(cur_addr))
https://github.com/Abyss-emmm/goparse
跳跳糖(http://tttang.com/archive/1422/)
看雪ID:mingyuexc
https://bbs.kanxue.com/user-home-880848.htm
# 往期推荐
3、安卓加固脱壳分享
球分享
球点赞
球在看