Skip to content

Commit f390b47

Browse files
committed
Restore old RaiseException hook, add special case for x86
1 parent 4bd7459 commit f390b47

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

qiling/os/windows/dlls/kernel32/errhandlingapi.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,47 @@ def hook_RemoveVectoredExceptionHandler(ql: Qiling, address: int, params):
115115
hook.remove()
116116

117117
return 0
118+
119+
# VOID RaiseException(
120+
# DWORD dwExceptionCode,
121+
# DWORD dwExceptionFlags,
122+
# DWORD nNumberOfArguments,
123+
# CONST ULONG_PTR* lpArguments
124+
# );
125+
@winsdkapi(cc=STDCALL, params={
126+
'dwExceptionCode': DWORD,
127+
'dwExceptionFlags': DWORD,
128+
'nNumberOfArguments': DWORD,
129+
'lpArguments': PVOID
130+
}, passthru=True)
131+
def hook_RaiseException(ql: Qiling, address: int, params):
132+
# On x86_64, RaiseException will call RtlRaiseException,
133+
# which calls the exception dispatcher directly. The native
134+
# exception dispatching code mostly works correctly
135+
# for software exceptions, so we shall simply continue
136+
# through to the native dispatcher in this case.
137+
if ql.arch.type is not QL_ARCH.X86:
138+
return
139+
140+
# On x86, the situation is different. RtlRaiseException
141+
# will call ZwRaiseException, which uses a syscall.
142+
# However, Qiling doesn't really support Windows syscalls
143+
# right now.
144+
# We will treat all exceptions as unhandled exceptions,
145+
# which is better than nothing.
146+
# TODO: Get kernel exception dispatching working properly,
147+
# then first-chance software exceptions, SEH, and C++
148+
# exceptions can work on 32-bit Windows too.
149+
nNumberOfArguments = params['nNumberOfArguments']
150+
lpArguments = params['lpArguments']
151+
152+
handle = ql.os.handle_manager.search("TopLevelExceptionHandler")
153+
154+
if handle is None:
155+
ql.log.warning(f'RaiseException: top level exception handler not found')
156+
return
157+
158+
exception_handler = handle.obj
159+
args = [(PARAM_INTN, ql.mem.read_ptr(lpArguments + i * ql.arch.pointersize)) for i in range(nNumberOfArguments)] if lpArguments else []
160+
161+
ql.os.fcall.call_native(exception_handler, args, None)

0 commit comments

Comments
 (0)