• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# coding:utf-8
3# Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import sys,string,re,os
17from ctypes import *
18
19DEFINE_SUCCESS=0
20DEFINE_FAIL=1
21
22class Sysmbol:
23    """符号表中的符号
24    """
25    def __init__(self):
26        self.addr=None #符号地址
27        self.key_name = None #符号名
28        self.class_type=None #符号类型 'a','t','b','d'...
29        self.type = None #符号类型 'FUNC','OBJECT','NOTYPE' ...
30        self.size = None #符号size,不是都有
31        self.section=None #符号落在哪个段
32        self.guess_size=None #计算出的符号大小(不准),TBD
33
34class _BasicCtrl:
35    def __init__(self):
36        self.temp_memory = bytearray(4096) # 临时空间,用于计算
37
38def uapi_str_to_int(str,num):
39    """字符串转数字
40    Args
41        str: 字符串
42        num: 进制
43    return
44        int:数值
45    """
46    if num!=None:
47        return int(str,num)
48    match1=re.match(r'\s*0x',str)
49    match2=re.match(r'\s*0X',str)
50    if match1 or match2:
51        return int(str,16)
52    else:
53        return int(str,10)
54
55
56def uapi_is_hex_word(word):
57    """判断是否是16进制字符串
58    Args
59        str: 字符串
60    return
61        True:是
62        False:不是
63    """
64    if word is None:
65        return False
66    for char in word:
67        if char not in string.hexdigits:
68            return False
69    return True
70
71_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]
72_g_ctype_float_class=[c_float,c_double,c_longdouble]
73_g_ctype_char=[c_char,c_bool]
74
75def _print_ctypes_obj(var_name,obj,t,fd):
76    if type(obj)==int:
77        print('%s=0x%x'%(var_name,obj),file=fd)
78        return
79    if type(obj)==bytes:
80        print('%s'%(var_name),obj,file=fd)
81        return
82    if type(obj)==bool:
83        print('%s'%(var_name),obj,file=fd)
84        return
85    if type(obj)==float:
86        print('%s=%f'%(var_name,obj),file=fd)
87        return
88
89    if type(obj) in _g_ctype_x16_class:
90        print('%s=0x%x'%(var_name,obj.value),file=fd)
91        return
92    if type(obj) in _g_ctype_float_class:
93        print('%s=%f'%(var_name,obj.value),file=fd)
94        return
95    if type(obj) in _g_ctype_char:
96        print('%s'%(var_name),obj.value,file=fd)
97        return
98
99    if hasattr(obj, '_length_'):
100        if hasattr(obj,'value'):
101            print('%s='%(var_name),obj.value,file=fd)
102        else:
103            i=0
104            for m in obj:
105                prefix="%s[%d]"%(var_name,i)
106                _print_ctypes_obj(prefix,m,getattr(obj,'_type_'),fd)
107                i=i+1
108        return
109    if hasattr(obj, '_fields_'):
110        for field in obj._fields_:
111            name = field[0]
112            val = getattr(obj, field[0])
113            _print_ctypes_obj(var_name+'.'+name,val,field[1],fd)
114        return
115
116    assert(False)
117
118def uapi_print_ctypes_obj(var_name,obj,fd=sys.stdout):
119    """打印ctypes object
120    Args
121        var_name: 打印名称
122        obj: 被打印的obj
123        fd: 输出目标
124    return
125    """
126    print(var_name+'{',file=fd)
127    _print_ctypes_obj('    ',obj,type(obj),fd)
128    print('}',file=fd)
129
130def ctype_member_offset(c_member,c_class):
131    """计算ctype类型的成员相对类的偏移
132    Args
133        c_member: 成员名字符串
134        c_class: ctype类
135        fd: 输出目标
136    return
137        int:偏移
138    """
139    list=c_member.split('.')
140    obj=c_class.from_buffer(_g_basic_ctrl.temp_memory)
141    temp_obj=obj
142    for member in list:
143        x=getattr(temp_obj,member)
144        temp_obj=x
145    return addressof(x)-addressof(obj)
146
147class _ParseBinItem:
148    def __init__(self):
149        file_name=None
150        start_addr=None
151        size = None
152        data=None
153
154class _ParseMemoryManager:
155    def __init__(self):
156        self.momory_list=[]
157
158    def register_memory(self,file_name,start_addr,size):
159        with open(file_name,'rb') as fp:
160            item = _ParseBinItem()
161            data = fp.read()
162            item.file_name=file_name
163            item.start_addr = start_addr
164            item.data=bytearray(data)
165            item.size=size
166            self.momory_list.append(item)
167    def register_bin(bin,start_addr,size):
168        item = _ParseBinItem()
169        item.file_name=None
170        item.start_addr = start_addr
171        item.data=bytearray(bin)
172        item.size=size
173        self.momory_list.append(item)
174
175    def memory_get(self,addr,size):
176        match_item=None
177        for item in self.momory_list:
178            if addr >= item.start_addr and addr+size < item.start_addr+item.size:
179                match_item=item
180                break
181        if match_item==None:
182            return None
183        addr=addr-match_item.start_addr
184        return match_item.data[addr:addr+size]
185
186class _HookFunctions:
187    def __init__(self):
188        self.get_symbol_info = None
189        self.get_u32_symbol_val = None
190        self.get_symbol_addr = None
191        self.addr_2_function_name = None
192        self.addr_in_2_function_name = None
193
194def parse_memory_get(addr,size):
195    """获取一段空间
196    Args
197        addr: 起始地址
198        size:大小
199    return
200        binary:成功返回一段空间
201        None:这段空间不存在
202    """
203    return _g_parse_memory_manager.memory_get(addr,size)
204
205def parse_memory_2_class(addr,class_type,class_size):
206    """将一段空间转换成一个ctype obj
207    Args
208        addr: 起始地址
209        class_type: class 类型
210        class_size: class size
211    return
212        obj:返回一个ctype obj
213        None:这段空间不存在
214    """
215    bin = parse_memory_get(addr,class_size)
216    if bin==None:
217        return None
218    return class_type.from_buffer(bin)
219
220def parse_memory_2_string(addr,max_len):
221    obj=parse_memory_2_class(addr,(c_char*max_len),sizeof((c_char*max_len)))
222    if obj==None:
223        return None
224    else:
225        return obj.value.decode('utf-8')
226
227def parse_memory_register(file_name,start_addr,size):
228    """注册一段内存
229    Args
230        file_name: 内存来自文件,文件全路径
231        start_addr: 内存起始地址
232        size: 内存大小
233    return
234    """
235    _g_parse_memory_manager.register_memory(file_name,start_addr,size)
236
237def parse_memory_register_bin(bin,start_addr,size):
238    """注册一段内存
239    Args
240        bin: 内存一段binary
241        start_addr: 内存起始地址
242        size: 内存大小
243    return
244    """
245    _g_parse_memory_manager.register_bin(bin,start_addr,size)
246
247def parse_get_symbol_info(name):
248    """获取symbolinfo
249    Args
250        name: 符号名
251    return
252        obj:成功,Sysmbol类型的obj
253        None:获取失败
254    """
255    if _g_hook_functions.get_symbol_info==None:
256        assert(False)
257        return None
258    return _g_hook_functions.get_symbol_info(name)
259
260def parse_get_u32_symbol_val(name):
261    """获取值
262    Args
263        name: 符号名
264    return
265        int:成功,获取到的值
266        None:获取失败
267    """
268    if _g_hook_functions.get_u32_symbol_val==None:
269        assert(False)
270        return None
271    return _g_hook_functions.get_u32_symbol_val(name)
272
273def parse_get_symbol_addr(name):
274    """获取符号地址
275    Args
276        name: 符号名
277    return
278        int:成功,获取到的值
279        None:获取失败
280    """
281    if _g_hook_functions.get_symbol_addr==None:
282        assert(False)
283        return None
284    return _g_hook_functions.get_symbol_addr(name)
285
286def parse_addr_2_function_name(addr):
287    if _g_hook_functions.addr_2_function_name==None:
288        assert(False)
289        return None
290    return _g_hook_functions.addr_2_function_name(addr)
291
292def parse_addr_in_2_function_name(addr):
293    if _g_hook_functions.addr_in_2_function_name==None:
294        assert(False)
295        return None
296    return _g_hook_functions.addr_in_2_function_name(addr)
297
298def uapi_register_function(name,function):
299    if name=="get_symbol_info":
300        _g_hook_functions.get_symbol_info = function
301    elif name=="get_u32_symbol_val":
302        _g_hook_functions.get_u32_symbol_val = function
303    elif name=="get_symbol_addr":
304        _g_hook_functions.get_symbol_addr=function
305    elif name=="addr_2_function_name":
306        _g_hook_functions.addr_2_function_name = function
307    elif name=="addr_in_2_function_name":
308        _g_hook_functions.addr_in_2_function_name = function
309    else:
310        assert(False)
311
312_g_parse_memory_manager = _ParseMemoryManager()
313_g_basic_ctrl=_BasicCtrl()
314_g_hook_functions =_HookFunctions()