Skip to content

Commit 2302dfc

Browse files
committed
Fix stack consistency on protocol notifications
1 parent 3e5b038 commit 2302dfc

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

qiling/os/uefi/utils.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ def execute_protocol_notifications(ql: Qiling, from_hook: bool = False) -> bool:
2929
next_hook = ql.loader.context.heap.alloc(ql.pointersize)
3030

3131
def __notify_next(ql: Qiling):
32+
# discard previous callback's shadow space
33+
ql.reg.arch_sp += (4 * ql.pointersize)
34+
3235
if ql.loader.notify_list:
3336
event_id, notify_func, callback_args = ql.loader.notify_list.pop(0)
3437
ql.log.info(f'Notify event: id = {event_id}, (*{notify_func:#x})({", ".join(f"{a:#x}" for a in callback_args)})')
@@ -42,14 +45,13 @@ def __notify_next(ql: Qiling):
4245
hret.remove()
4346

4447
ql.reg.rax = EFI_SUCCESS
45-
ql.reg.arch_sp += (4 * ql.pointersize)
4648
ql.reg.arch_pc = ql.stack_pop()
4749

4850
hret = ql.hook_address(__notify_next, next_hook)
4951

50-
# functions with more than 4 parameters expect the extra parameters to appear on
51-
# the stack. allocate room for another 4 parameters, in case one of the fucntions
52-
# will need it
52+
# __notify_next unwinds the previous callback shadow space allocated by call_function. however, on its first invocation
53+
# there is no such shadow space. to maintain stack consistency we set here a bogus shadow space that may be discarded
54+
# safely
5355
ql.reg.arch_sp -= (4 * ql.pointersize)
5456

5557
# To avoid having two versions of the code the first notify function will also be called from the __notify_next hook.

0 commit comments

Comments
 (0)