1010import pickle
1111import secrets
1212import ntpath
13- from typing import TYPE_CHECKING , Any , Dict , MutableMapping , NamedTuple , Optional , Mapping , Sequence , Tuple , Union
13+ from collections import namedtuple
14+ from typing import TYPE_CHECKING , Any , Dict , List , MutableMapping , NamedTuple , Optional , Mapping , Sequence , Tuple , Union
1415
1516from unicorn import UcError
1617from unicorn .x86_const import UC_X86_REG_CR4 , UC_X86_REG_CR8
2930 from logging import Logger
3031 from qiling import Qiling
3132
32- class ForwardedExport :
33- def __init__ (self ,
34- source_dll : str , source_ordinal : str , source_symbol : str ,
35- target_dll : str , target_symbol : str ):
36- self .source_dll = source_dll
37- self .source_ordinal = source_ordinal
38- self .source_symbol = source_symbol
39- self .target_dll = target_dll
40- self .target_symbol = target_symbol
33+ ForwardedExport = namedtuple ('ForwardedExport' , [
34+ 'source_dll' , 'source_ordinal' , 'source_symbol' ,
35+ 'target_dll' , 'target_symbol'
36+ ])
4137
4238
4339class QlPeCacheEntry (NamedTuple ):
@@ -90,14 +86,14 @@ class Process:
9086 libcache : Optional [QlPeCache ]
9187
9288 # maps image base to RVA of its function table
93- function_table_lookup : MutableMapping [int , int ]
89+ function_table_lookup : Dict [int , int ]
9490
9591 # maps image base to its list of function table entries
96- function_tables : MutableMapping [int , list ]
92+ function_tables : MutableMapping [int , List ]
9793
9894 # List of exports which have been forwarded from
9995 # one DLL to another.
100- forwarded_exports : list [ForwardedExport ]
96+ forwarded_exports : List [ForwardedExport ]
10197
10298 def __init__ (self , ql : Qiling ):
10399 self .ql = ql
@@ -128,13 +124,13 @@ def __get_path_elements(self, name: str) -> Tuple[str, str]:
128124
129125 def init_function_tables (self , pe : pefile .PE , image_base : int ):
130126 """Parse function table data for the given PE file.
131- Only works for x64 images.
127+ Only really relevant for non-x86 images.
132128
133129 Args:
134130 pe: the PE image whose function data should be parsed
135131 image_base: the absolute address at which the image was loaded
136132 """
137- if self .ql .arch .type == QL_ARCH .X8664 :
133+ if self .ql .arch .type is not QL_ARCH .X86 :
138134
139135 # Check if the PE file has an exception directory
140136 if hasattr (pe , 'DIRECTORY_ENTRY_EXCEPTION' ):
@@ -144,12 +140,9 @@ def init_function_tables(self, pe: pefile.PE, image_base: int):
144140
145141 self .function_table_lookup [image_base ] = exception_dir .VirtualAddress
146142
147- runtime_function_list = []
143+ runtime_function_list = list ( pe . DIRECTORY_ENTRY_EXCEPTION )
148144
149- for _ , exception_entry in enumerate (pe .DIRECTORY_ENTRY_EXCEPTION , start = 1 ):
150- runtime_function_list .append (exception_entry )
151-
152- if self .function_tables .get (image_base ) is None :
145+ if image_base not in self .function_tables :
153146 self .function_tables [image_base ] = []
154147
155148 self .function_tables [image_base ].extend (runtime_function_list )
@@ -175,17 +168,9 @@ def lookup_function_entry(self, base_addr: int, control_pc: int):
175168
176169 # Initiate a search of the function table for a RUNTIME_FUNCTION
177170 # entry such that the provided PC falls within its start and end range.
178- for i , runtime_function in enumerate (function_table ):
179-
180- # Begin and end addresses exist in the entry as RVAs,
181- # convert them to absolute addresses.
182- begin_addr = base_addr + runtime_function .struct .BeginAddress
183- end_addr = base_addr + runtime_function .struct .EndAddress
184-
185- if begin_addr <= control_pc < end_addr :
186- return i , runtime_function
187-
188- return None , None
171+ return next (((i , rtfunc ) for i , rtfunc in enumerate (function_table )
172+ if rtfunc .struct .BeginAddress <= control_pc - base_addr < rtfunc .struct .EndAddress ),
173+ (None , None ))
189174
190175 def resolve_forwarded_exports (self ):
191176 while self .forwarded_exports :
0 commit comments