Skip to content

Commit b895748

Browse files
committed
Make requested changes in PE loader
1 parent 4ea1a0a commit b895748

File tree

1 file changed

+16
-31
lines changed

1 file changed

+16
-31
lines changed

qiling/loader/pe.py

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
import pickle
1111
import secrets
1212
import 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

1516
from unicorn import UcError
1617
from unicorn.x86_const import UC_X86_REG_CR4, UC_X86_REG_CR8
@@ -29,15 +30,10 @@
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

4339
class 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

Comments
 (0)