44#
55
66import os , re
7+ from typing import Any , List , MutableSequence , Optional , Sequence , Tuple
78
9+ from qiling import Qiling
810from qiling .const import *
911from qiling .exception import *
1012
13+ # tuple: range start, range end, permissions mask, range label
14+ MapInfoEntry = Tuple [int , int , int , str ]
1115
1216from unicorn import (
1317 UC_PROT_ALL ,
@@ -23,9 +27,9 @@ class QlMemoryManager:
2327 https://github.com/zeropointdynamics/zelos/blob/master/src/zelos/memory.py
2428 """
2529
26- def __init__ (self , ql ):
30+ def __init__ (self , ql : Qiling ):
2731 self .ql = ql
28- self .map_info = []
32+ self .map_info : MutableSequence [ MapInfoEntry ] = []
2933
3034 bit_stuff = {
3135 64 : (0xFFFFFFFFFFFFFFFF ,),
@@ -59,7 +63,7 @@ def string(self, addr, value=None ,encoding='utf-8'):
5963 self .write (addr , string_bytes )
6064 return None
6165
62- def add_mapinfo (self , mem_s , mem_e , mem_p , mem_info ):
66+ def add_mapinfo (self , mem_s : int , mem_e : int , mem_p : int , mem_info : str ):
6367 tmp_map_info = []
6468 insert_flag = 0
6569 map_info = self .map_info
@@ -97,26 +101,26 @@ def add_mapinfo(self, mem_s, mem_e, mem_p, mem_info):
97101 self .map_info = tmp_map_info
98102
99103
100- def del_mapinfo (self , mem_s , mem_e ):
104+ def del_mapinfo (self , mem_s : int , mem_e : int ):
101105 tmp_map_info = []
102106
103107 for s , e , p , info in self .map_info :
104108 if e <= mem_s :
105- tmp_map_info .append ([ s , e , p , info ] )
109+ tmp_map_info .append (( s , e , p , info ) )
106110 continue
107111
108112 if s >= mem_e :
109- tmp_map_info .append ([ s , e , p , info ] )
113+ tmp_map_info .append (( s , e , p , info ) )
110114 continue
111115
112116 if s < mem_s :
113- tmp_map_info .append ([ s , mem_s , p , info ] )
117+ tmp_map_info .append (( s , mem_s , p , info ) )
114118
115119 if s == mem_s :
116120 pass
117121
118122 if e > mem_e :
119- tmp_map_info .append ([ mem_e , e , p , info ] )
123+ tmp_map_info .append (( mem_e , e , p , info ) )
120124
121125 if e == mem_e :
122126 pass
@@ -144,14 +148,13 @@ def _perms_mapping(ps):
144148 self .ql .log .info ("[+] %08x - %08x - %s %s" % (start , end , _perm , info ))
145149
146150
147- def get_lib_base (self , filename ) :
151+ def get_lib_base (self , filename : str ) -> int :
148152 for s , e , p , info in self .map_info :
149153 if os .path .split (info )[1 ] == filename :
150154 return s
151155 return - 1
152156
153-
154- def align (self , addr , alignment = 0x1000 ):
157+ def align (self , addr : int , alignment : int = 0x1000 ) -> int :
155158 # rounds up to nearest alignment
156159 mask = ((1 << self .ql .archbit ) - 1 ) & - alignment
157160 return (addr + (alignment - 1 )) & mask
@@ -186,7 +189,7 @@ def restore(self, mem_dict):
186189 def read (self , addr : int , size : int ) -> bytearray :
187190 return self .ql .uc .mem_read (addr , size )
188191
189- def read_ptr (self , addr : int , size : int = None ):
192+ def read_ptr (self , addr : int , size : int = None ) -> int :
190193 if not size :
191194 size = self .ql .pointersize
192195
@@ -210,7 +213,7 @@ def write(self, addr: int, data: bytes) -> None:
210213 self .ql .log .error ("addresss write error: " + hex (addr ))
211214 raise
212215
213- def search (self , needle : bytes , begin = None , end = None ):
216+ def search (self , needle : bytes , begin : int = None , end : int = None ):
214217 """
215218 Search for a sequence of bytes in memory. Returns all sequences
216219 that match
@@ -235,7 +238,7 @@ def search(self, needle: bytes, begin= None, end= None):
235238
236239 return addrs
237240
238- def unmap (self , addr , size ) -> None :
241+ def unmap (self , addr : int , size : int ) -> None :
239242 '''
240243 The main function of mem_unmap is to reclaim memory.
241244 This function will reclaim the memory starting with addr and length of size.
@@ -307,9 +310,7 @@ def is_free(self, address, size):
307310 return True
308311
309312
310- def find_free_space (
311- self , size , min_addr = 0 , max_addr = 0 , alignment = 0x10000
312- ):
313+ def find_free_space (self , size , min_addr = 0 , max_addr = 0 , alignment = 0x10000 ):
313314 """
314315 Finds a region of memory that is free, larger than 'size' arg,
315316 and aligned.
@@ -426,7 +427,7 @@ def get_mapped(self):
426427
427428# A Simple Heap Implementation
428429class Chunk ():
429- def __init__ (self , address , size ):
430+ def __init__ (self , address : int , size : int ):
430431 self .inuse = True
431432 self .address = address
432433 self .size = size
@@ -436,9 +437,9 @@ def compare(chunk):
436437 return chunk .size
437438
438439class QlMemoryHeap :
439- def __init__ (self , ql , start_address , end_address ):
440+ def __init__ (self , ql : Qiling , start_address : int , end_address : int ):
440441 self .ql = ql
441- self .chunks = []
442+ self .chunks : List [ Chunk ] = []
442443 self .start_address = start_address
443444 self .end_address = end_address
444445 # unicorn needs 0x1000
@@ -470,7 +471,7 @@ def restore(self, saved_state):
470471 self .current_use = saved_state ['current_use' ]
471472 self .mem_alloc = saved_state ['mem_alloc' ]
472473
473- def alloc (self , size ):
474+ def alloc (self , size : int ):
474475 # Find the heap chunks that best matches size
475476 self .chunks .sort (key = Chunk .compare )
476477 for chunk in self .chunks :
@@ -500,13 +501,13 @@ def alloc(self, size):
500501 #ql.log.debug("heap.alloc addresss: " + hex(chunk.address))
501502 return chunk .address
502503
503- def size (self , addr ) :
504+ def size (self , addr : int ) -> int :
504505 for chunk in self .chunks :
505506 if addr == chunk .address and chunk .inuse :
506507 return chunk .size
507508 return 0
508509
509- def free (self , addr ) :
510+ def free (self , addr : int ) -> bool :
510511 for chunk in self .chunks :
511512 if addr == chunk .address and chunk .inuse :
512513 chunk .inuse = False
@@ -526,7 +527,7 @@ def clear(self):
526527 self .current_alloc = 0
527528 self .current_use = 0
528529
529- def _find (self , addr ) :
530+ def _find (self , addr : int , inuse : bool = None ) -> Optional [ Chunk ] :
530531 for chunk in self .chunks :
531532 if addr == chunk .address :
532533 return chunk
0 commit comments