Skip to content

Commit 92cd2d4

Browse files
committed
Fix an issue with forwarded symbols, and improve readability
1 parent 15e3c00 commit 92cd2d4

File tree

1 file changed

+39
-30
lines changed

1 file changed

+39
-30
lines changed

qiling/loader/pe.py

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -182,38 +182,47 @@ def resolve_forwarded_exports(self):
182182
target_dll = forwarded_export.target_dll
183183
target_symbol = forwarded_export.target_symbol
184184

185+
if not source_symbol:
186+
# Some DLLs (shlwapi.dll) have a bunch of forwarded
187+
# exports with ordinals but no symbols.
188+
# These are really annoying to deal with, but they are
189+
# used extremely rarely, so we will ignore them.
190+
continue
191+
185192
target_iat = self.import_address_table.get(target_dll)
186193

187-
if target_iat:
188-
# If we have an existing entry in the process IAT for the code
189-
# this entry forwards to, then we will point the symbol there
190-
# rather than the symbol string in the exporter's data section.
191-
forward_ea = target_iat.get(target_symbol)
192-
193-
if forward_ea:
194-
self.import_address_table[source_dll][source_symbol] = forward_ea
195-
self.import_address_table[source_dll][source_ordinal] = forward_ea
196-
197-
# Register the new address as having the source symbol/ordinal.
198-
# This way, hooks on forward source symbols will function
199-
# correctly.
200-
201-
self.import_symbols[forward_ea] = {
202-
'name' : source_symbol,
203-
'ordinal' : source_ordinal,
204-
'dll' : source_dll.split('.')[0]
205-
}
206-
207-
# TODO: With the above code, hooks on functions which are
208-
# forward targets may not work correctly.
209-
# The most correct way to resolve this would be to add
210-
# support for addresses to be associated with multiple symbols.
211-
212-
self.ql.log.debug(f"Forwarding symbol {source_dll}.{source_symbol} to {target_dll}.{target_symbol}: Resolved symbol to ({forward_ea:#x})")
213-
else:
214-
self.ql.log.warning(f"Forwarding symbol {source_dll}.{source_symbol} to {target_dll}.{target_symbol}: Failed to resolve address")
215-
else:
216-
pass # If IAT was not found, it is probably a virtual library.
194+
if not target_iat:
195+
# If IAT was not found, it is probably a virtual library.
196+
continue
197+
198+
# If we have an existing entry in the process IAT for the code
199+
# this entry forwards to, then we will point the symbol there
200+
# rather than the symbol string in the exporter's data section.
201+
forward_ea = target_iat.get(target_symbol)
202+
203+
if not forward_ea:
204+
self.ql.log.warning(f"Forwarding symbol {source_dll}.{source_symbol} to {target_dll}.{target_symbol}: Failed to resolve address")
205+
continue
206+
207+
self.import_address_table[source_dll][source_symbol] = forward_ea
208+
self.import_address_table[source_dll][source_ordinal] = forward_ea
209+
210+
# Register the new address as having the source symbol/ordinal.
211+
# This way, hooks on forward source symbols will function
212+
# correctly.
213+
214+
self.import_symbols[forward_ea] = {
215+
'name' : source_symbol,
216+
'ordinal' : source_ordinal,
217+
'dll' : source_dll.split('.')[0]
218+
}
219+
220+
# TODO: With the above code, hooks on functions which are
221+
# forward targets may not work correctly.
222+
# The most correct way to resolve this would be to add
223+
# support for addresses to be associated with multiple symbols.
224+
225+
self.ql.log.debug(f"Forwarding symbol {source_dll}.{source_symbol} to {target_dll}.{target_symbol}: Resolved symbol to ({forward_ea:#x})")
217226

218227
def load_dll(self, name: str, is_driver: bool = False) -> int:
219228
dll_path, dll_name = self.__get_path_elements(name)

0 commit comments

Comments
 (0)