303 lines
8.6 KiB
Python
Executable File
303 lines
8.6 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# coding:utf-8
|
|
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved.
|
|
|
|
import sys,string,re,os
|
|
from ctypes import *
|
|
|
|
DEFINE_SUCCESS=0
|
|
DEFINE_FAIL=1
|
|
|
|
class Sysmbol:
|
|
"""符号表中的符号
|
|
"""
|
|
def __init__(self):
|
|
self.addr=None #符号地址
|
|
self.key_name = None #符号名
|
|
self.class_type=None #符号类型 'a','t','b','d'...
|
|
self.type = None #符号类型 'FUNC','OBJECT','NOTYPE' ...
|
|
self.size = None #符号size,不是都有
|
|
self.section=None #符号落在哪个段
|
|
self.guess_size=None #计算出的符号大小(不准),TBD
|
|
|
|
class _BasicCtrl:
|
|
def __init__(self):
|
|
self.temp_memory = bytearray(4096) # 临时空间,用于计算
|
|
|
|
def uapi_str_to_int(str,num):
|
|
"""字符串转数字
|
|
Args
|
|
str: 字符串
|
|
num: 进制
|
|
return
|
|
int:数值
|
|
"""
|
|
if num!=None:
|
|
return int(str,num)
|
|
match1=re.match(r'\s*0x',str)
|
|
match2=re.match(r'\s*0X',str)
|
|
if match1 or match2:
|
|
return int(str,16)
|
|
else:
|
|
return int(str,10)
|
|
|
|
|
|
def uapi_is_hex_word(word):
|
|
"""判断是否是16进制字符串
|
|
Args
|
|
str: 字符串
|
|
return
|
|
True:是
|
|
False:不是
|
|
"""
|
|
if word is None:
|
|
return False
|
|
for char in word:
|
|
if char not in string.hexdigits:
|
|
return False
|
|
return True
|
|
|
|
_g_ctype_x16_class=[c_byte,c_ubyte,c_short,c_ushort,c_int,c_uint,c_long,c_ulong,c_longlong,c_ulonglong,c_size_t,c_ssize_t]
|
|
_g_ctype_float_class=[c_float,c_double,c_longdouble]
|
|
_g_ctype_char=[c_char,c_bool]
|
|
|
|
def _print_ctypes_obj(var_name,obj,t,fd):
|
|
if type(obj)==int:
|
|
print('%s=0x%x'%(var_name,obj),file=fd)
|
|
return
|
|
if type(obj)==bytes:
|
|
print('%s'%(var_name),obj,file=fd)
|
|
return
|
|
if type(obj)==bool:
|
|
print('%s'%(var_name),obj,file=fd)
|
|
return
|
|
if type(obj)==float:
|
|
print('%s=%f'%(var_name,obj),file=fd)
|
|
return
|
|
|
|
if type(obj) in _g_ctype_x16_class:
|
|
print('%s=0x%x'%(var_name,obj.value),file=fd)
|
|
return
|
|
if type(obj) in _g_ctype_float_class:
|
|
print('%s=%f'%(var_name,obj.value),file=fd)
|
|
return
|
|
if type(obj) in _g_ctype_char:
|
|
print('%s'%(var_name),obj.value,file=fd)
|
|
return
|
|
|
|
if hasattr(obj, '_length_'):
|
|
if hasattr(obj,'value'):
|
|
print('%s='%(var_name),obj.value,file=fd)
|
|
else:
|
|
i=0
|
|
for m in obj:
|
|
prefix="%s[%d]"%(var_name,i)
|
|
_print_ctypes_obj(prefix,m,getattr(obj,'_type_'),fd)
|
|
i=i+1
|
|
return
|
|
if hasattr(obj, '_fields_'):
|
|
for field in obj._fields_:
|
|
name = field[0]
|
|
val = getattr(obj, field[0])
|
|
_print_ctypes_obj(var_name+'.'+name,val,field[1],fd)
|
|
return
|
|
|
|
assert(False)
|
|
|
|
def uapi_print_ctypes_obj(var_name,obj,fd=sys.stdout):
|
|
"""打印ctypes object
|
|
Args
|
|
var_name: 打印名称
|
|
obj: 被打印的obj
|
|
fd: 输出目标
|
|
return
|
|
"""
|
|
print(var_name+'{',file=fd)
|
|
_print_ctypes_obj(' ',obj,type(obj),fd)
|
|
print('}',file=fd)
|
|
|
|
def ctype_member_offset(c_member,c_class):
|
|
"""计算ctype类型的成员相对类的偏移
|
|
Args
|
|
c_member: 成员名字符串
|
|
c_class: ctype类
|
|
fd: 输出目标
|
|
return
|
|
int:偏移
|
|
"""
|
|
list=c_member.split('.')
|
|
obj=c_class.from_buffer(_g_basic_ctrl.temp_memory)
|
|
temp_obj=obj
|
|
for member in list:
|
|
x=getattr(temp_obj,member)
|
|
temp_obj=x
|
|
return addressof(x)-addressof(obj)
|
|
|
|
class _ParseBinItem:
|
|
def __init__(self):
|
|
file_name=None
|
|
start_addr=None
|
|
size = None
|
|
data=None
|
|
|
|
class _ParseMemoryManager:
|
|
def __init__(self):
|
|
self.momory_list=[]
|
|
|
|
def register_memory(self,file_name,start_addr,size):
|
|
with open(file_name,'rb') as fp:
|
|
item = _ParseBinItem()
|
|
data = fp.read()
|
|
item.file_name=file_name
|
|
item.start_addr = start_addr
|
|
item.data=bytearray(data)
|
|
item.size=size
|
|
self.momory_list.append(item)
|
|
def register_bin(bin,start_addr,size):
|
|
item = _ParseBinItem()
|
|
item.file_name=None
|
|
item.start_addr = start_addr
|
|
item.data=bytearray(bin)
|
|
item.size=size
|
|
self.momory_list.append(item)
|
|
|
|
def memory_get(self,addr,size):
|
|
match_item=None
|
|
for item in self.momory_list:
|
|
if addr >= item.start_addr and addr+size < item.start_addr+item.size:
|
|
match_item=item
|
|
break
|
|
if match_item==None:
|
|
return None
|
|
addr=addr-match_item.start_addr
|
|
return match_item.data[addr:addr+size]
|
|
|
|
class _HookFunctions:
|
|
def __init__(self):
|
|
self.get_symbol_info = None
|
|
self.get_u32_symbol_val = None
|
|
self.get_symbol_addr = None
|
|
self.addr_2_function_name = None
|
|
self.addr_in_2_function_name = None
|
|
|
|
def parse_memory_get(addr,size):
|
|
"""获取一段空间
|
|
Args
|
|
addr: 起始地址
|
|
size:大小
|
|
return
|
|
binary:成功返回一段空间
|
|
None:这段空间不存在
|
|
"""
|
|
return _g_parse_memory_manager.memory_get(addr,size)
|
|
|
|
def parse_memory_2_class(addr,class_type,class_size):
|
|
"""将一段空间转换成一个ctype obj
|
|
Args
|
|
addr: 起始地址
|
|
class_type: class 类型
|
|
class_size: class size
|
|
return
|
|
obj:返回一个ctype obj
|
|
None:这段空间不存在
|
|
"""
|
|
bin = parse_memory_get(addr,class_size)
|
|
if bin==None:
|
|
return None
|
|
return class_type.from_buffer(bin)
|
|
|
|
def parse_memory_2_string(addr,max_len):
|
|
obj=parse_memory_2_class(addr,(c_char*max_len),sizeof((c_char*max_len)))
|
|
if obj==None:
|
|
return None
|
|
else:
|
|
return obj.value.decode('utf-8')
|
|
|
|
def parse_memory_register(file_name,start_addr,size):
|
|
"""注册一段内存
|
|
Args
|
|
file_name: 内存来自文件,文件全路径
|
|
start_addr: 内存起始地址
|
|
size: 内存大小
|
|
return
|
|
"""
|
|
_g_parse_memory_manager.register_memory(file_name,start_addr,size)
|
|
|
|
def parse_memory_register_bin(bin,start_addr,size):
|
|
"""注册一段内存
|
|
Args
|
|
bin: 内存一段binary
|
|
start_addr: 内存起始地址
|
|
size: 内存大小
|
|
return
|
|
"""
|
|
_g_parse_memory_manager.register_bin(bin,start_addr,size)
|
|
|
|
def parse_get_symbol_info(name):
|
|
"""获取symbolinfo
|
|
Args
|
|
name: 符号名
|
|
return
|
|
obj:成功,Sysmbol类型的obj
|
|
None:获取失败
|
|
"""
|
|
if _g_hook_functions.get_symbol_info==None:
|
|
assert(False)
|
|
return None
|
|
return _g_hook_functions.get_symbol_info(name)
|
|
|
|
def parse_get_u32_symbol_val(name):
|
|
"""获取值
|
|
Args
|
|
name: 符号名
|
|
return
|
|
int:成功,获取到的值
|
|
None:获取失败
|
|
"""
|
|
if _g_hook_functions.get_u32_symbol_val==None:
|
|
assert(False)
|
|
return None
|
|
return _g_hook_functions.get_u32_symbol_val(name)
|
|
|
|
def parse_get_symbol_addr(name):
|
|
"""获取符号地址
|
|
Args
|
|
name: 符号名
|
|
return
|
|
int:成功,获取到的值
|
|
None:获取失败
|
|
"""
|
|
if _g_hook_functions.get_symbol_addr==None:
|
|
assert(False)
|
|
return None
|
|
return _g_hook_functions.get_symbol_addr(name)
|
|
|
|
def parse_addr_2_function_name(addr):
|
|
if _g_hook_functions.addr_2_function_name==None:
|
|
assert(False)
|
|
return None
|
|
return _g_hook_functions.addr_2_function_name(addr)
|
|
|
|
def parse_addr_in_2_function_name(addr):
|
|
if _g_hook_functions.addr_in_2_function_name==None:
|
|
assert(False)
|
|
return None
|
|
return _g_hook_functions.addr_in_2_function_name(addr)
|
|
|
|
def uapi_register_function(name,function):
|
|
if name=="get_symbol_info":
|
|
_g_hook_functions.get_symbol_info = function
|
|
elif name=="get_u32_symbol_val":
|
|
_g_hook_functions.get_u32_symbol_val = function
|
|
elif name=="get_symbol_addr":
|
|
_g_hook_functions.get_symbol_addr=function
|
|
elif name=="addr_2_function_name":
|
|
_g_hook_functions.addr_2_function_name = function
|
|
elif name=="addr_in_2_function_name":
|
|
_g_hook_functions.addr_in_2_function_name = function
|
|
else:
|
|
assert(False)
|
|
|
|
_g_parse_memory_manager = _ParseMemoryManager()
|
|
_g_basic_ctrl=_BasicCtrl()
|
|
_g_hook_functions =_HookFunctions() |