@@ -493,6 +493,36 @@ def hook_RtlPcToFileHeader(ql: Qiling, address: int, params):
493493 ql .mem .write_ptr (base_of_image_ptr , base_addr )
494494 return base_addr
495495
496+ def _FindImageBaseAndFunctionTable (ql : Qiling , control_pc : int , image_base_ptr : int ):
497+ """
498+ Helper function to locate a containing image for `control_pc` as well as its
499+ function table, while writing the image base to `image_base_ptr` (if non-zero).
500+ Returns:
501+ (base_addr, function_table_addr)
502+ if no image is found, otherwise
503+ (0, 0)
504+ """
505+ containing_image = ql .loader .find_containing_image (control_pc )
506+
507+ if containing_image :
508+ base_addr = containing_image .base
509+ else :
510+ base_addr = 0
511+
512+ # Write base address to the ImageBase pointer, if provided
513+ if image_base_ptr != 0 :
514+ ql .mem .write_ptr (image_base_ptr , base_addr )
515+
516+ # If we don’t have a valid base, abort now
517+ if base_addr == 0 :
518+ return 0 , 0
519+
520+ # Look up the function-table RVA and compute the absolute address
521+ function_table_rva = ql .loader .function_table_lookup .get (base_addr )
522+ function_table_addr = base_addr + function_table_rva if function_table_rva else 0
523+
524+ return base_addr , function_table_addr
525+
496526# NTSYSAPI PRUNTIME_FUNCTION RtlLookupFunctionEntry(
497527# [in] DWORD64 ControlPc,
498528# [out] PDWORD64 ImageBase,
@@ -518,22 +548,11 @@ def hook_RtlLookupFunctionEntry(ql: Qiling, address: int, params):
518548 if ql .arch .type is QL_ARCH .X86 :
519549 raise QlErrorNotImplemented ("RtlLookupFunctionEntry is not implemented for x86" )
520550
521- containing_image = ql .loader .find_containing_image (control_pc )
522-
523- if containing_image :
524- base_addr = containing_image .base
525- else :
526- base_addr = 0
551+ base_addr , function_table_addr = _FindImageBaseAndFunctionTable (ql , control_pc , image_base_ptr )
527552
553+ # If no function table was found, abort.
554+ if function_table_addr == 0 :
528555 return 0
529-
530- # If we got a valid location to write the image base ptr,
531- # copy it there, and proceed.
532- if image_base_ptr != 0 :
533- ql .mem .write_ptr (image_base_ptr , base_addr )
534-
535- # Get the base address of the function table.
536- function_table_addr = base_addr + ql .loader .function_table_lookup [base_addr ]
537556
538557 # Look up the RUNTIME_FUNCTION entry; we are interested in the index in the table
539558 # so that we can compute the address.
@@ -564,35 +583,17 @@ def hook_RtlLookupFunctionTable(ql: Qiling, address: int, params):
564583 size_of_table_ptr = params ["SizeOfTable" ]
565584
566585 # This function should not be getting called on x86.
567- if ql .arch .type != QL_ARCH .X8664 :
586+ if ql .arch .type is QL_ARCH .X86 :
568587 raise QlErrorNotImplemented ("RtlLookupFunctionTable is not implemented for x86" )
569588
570- containing_image = ql . loader . find_containing_image ( control_pc )
589+ base_addr , function_table_addr = _FindImageBaseAndFunctionTable ( ql , control_pc , image_base_ptr )
571590
572- if containing_image :
573- base_addr = containing_image .base
574- else :
575- base_addr = 0
591+ # If no function table was found, abort.
592+ if function_table_addr == 0 :
593+ ql .mem .write_ptr (size_of_table_ptr , 0 , 4 )
576594
577595 return 0
578596
579- # If we got a valid location to write the image base ptr,
580- # copy it there, and proceed.
581- if image_base_ptr != 0 :
582- ql .mem .write_ptr (image_base_ptr , base_addr )
583-
584- # If image base was 0, we are not going to find a valid function
585- # table anyway, so just return.
586- if base_addr == 0 :
587- return 0
588-
589- # Look up the RVA of the function table.
590- function_table_rva = ql .loader .function_table_lookup [base_addr ]
591-
592- # The caller is expecting a pointer, so convert the RVA
593- # to an absolute address.
594- function_table_addr = int (base_addr + function_table_rva )
595-
596597 # If a valid pointer for the size was provided,
597598 # we want to figure out the size of the table.
598599 if size_of_table_ptr != 0 :
0 commit comments