Skip to content

Commit f6c1ab5

Browse files
committed
Fix unreliable RaiseException code (untested)
1 parent adda4c7 commit f6c1ab5

File tree

3 files changed

+1
-40
lines changed

3 files changed

+1
-40
lines changed

qiling/os/utils.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -184,24 +184,3 @@ def printf(self, format: str, args: MutableSequence, wstring: bool = False) -> i
184184

185185
def update_ellipsis(self, params: MutableMapping, args: Sequence) -> None:
186186
params.update((f'{QlOsUtils.ELLIPSIS_PREF}{i}', a) for i, a in enumerate(args))
187-
188-
def exec_arbitrary(self, start: int, end: int):
189-
old_sp = self.ql.reg.arch_sp
190-
191-
# we read where this hook is supposed to return
192-
ret = self.ql.stack_read(0)
193-
194-
def restore(ql: Qiling):
195-
self.ql.log.debug(f"Executed code from {start:#x} to {end:#x}")
196-
# now we can restore the register to be where we were supposed to
197-
ql.reg.arch_sp = old_sp + ql.pointersize
198-
ql.reg.arch_pc = ret
199-
200-
# we want to execute the code once, not more
201-
hret.remove()
202-
203-
# we have to set an address to restore the registers
204-
hret = self.ql.hook_address(restore, end)
205-
# we want to rewrite the return address to the function
206-
self.ql.stack_write(0, start)
207-

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@ def hook_SetErrorMode(ql: Qiling, address: int, params):
7575
def hook_RaiseException(ql: Qiling, address: int, params):
7676
func_addr = ql.os.handle_manager.search("TopLevelExceptionHandler").obj
7777

78-
# TODO: this implementation won't work most of the time
79-
size = find_size_function(ql, func_addr)
80-
ql.os.exec_arbitrary(func_addr, func_addr + size)
78+
ql.os.fcall.call_native(func_addr, [], None)
8179

8280
return 0
8381

@@ -122,7 +120,6 @@ def exec_standard_into(ql: Qiling, intno: int, user_data):
122120
ql.reg.esi = user_data
123121

124122
addr = params["Handler"]
125-
#size = find_size_function(ql, addr)
126123

127124
# the interrupts 0x2d, 0x3 must be hooked
128125
hook = ql.hook_intno(exec_standard_into, 0x3, user_data=addr)

qiling/os/windows/utils.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,6 @@ def path_leaf(path):
3737
head, tail = ntpath.split(path)
3838
return tail or ntpath.basename(head)
3939

40-
# FIXME: determining a function size by locating 'ret' opcodes in its code is a very unreliable way, to say
41-
# the least. not only that 'ret' instructions may appear more than once in a single function, they not are
42-
# necessarily located at the last function basic block: think of a typical nested loop spaghetty.
43-
#
44-
# also, there is no telling whether a 0xC3 value found in function code is actually a 'ret' instruction, or
45-
# just part of a magic value (e.g. "mov eax, 0xffffffc3").
46-
#
47-
# finally, if this method happens to find the correct function size, by any chance, that would be a pure luck.
48-
def find_size_function(ql: Qiling, func_addr: int):
49-
# We have to retrieve the return address position
50-
code = ql.mem.read(func_addr, 0x100)
51-
return_procedures = [b"\xc3", b"\xc2", b"\xcb", b"\xca"]
52-
min_index = min([code.index(return_value) for return_value in return_procedures if return_value in code])
53-
return min_index
54-
5540

5641
def io_Write(ql: Qiling, in_buffer: bytes):
5742
heap = ql.os.heap

0 commit comments

Comments
 (0)