qiling
qiling copied to clipboard
How to hook some function with hook_address?
I want something like this, but that doesn't work.
def GetStringUTFChars(ql):
ql.log.info('GetStringUTFChars hooked')
# put char array on memory and move pointer to eax(I will try to do myself later)
ret_addr = ql.stack_read(0) # read [esp]
ql.reg.eip = ret_addr # jmp to [esp] which equivalant to ret
ql.hook_address(GetStringUTFChars, 50)
Result is: [=] Executing: 0x56555df5 # jmp [esp] success [=] Executing: 0x56555df5 # but ida pro plugin with qiling not break on step in mode but just running [=] Executing: 0x56555df5 [=] Executing: 0x56555df5 [=] Executing: 0x56555df7 [=] Executing: 0x56555df7 [=] Executing: 0x56555df7 [=] Executing: 0x56555df7 [=] Executing: 0x56555dfa [=] Executing: 0x56555dfa [=] Executing: 0x56555dfa [=] Executing: 0x56555dfa
Problem is : ida pro plugin with qiling not break on step in mode but just running after hook
Another question is that qiling seems not emulate _strlen or _malloc in libc for us. Does that mean I need to implement them myself?
- cc @kabeor to have a look at step functionality.
- qiling will load and run libc for your program so you don't need to implement them by your own for functions in libc.
@anaivebird Hi! Can you show me the complete content of plugin custom script?
You should define ql.hook_address(GetStringUTFChars, 50) in custom_step function
from qiling import *
import struct
# def GetStringUTFChars(ql):
# ql.log.info('GetStringUTFChars hooked')
# # ret_addr = ql.stack_read(0)
# # ret_addr = ql.mem.read(ql.reg.esp, 4)
# # ql.log.info(ret_addr)
# # ql.reg.eip = ret_addr
def force_call_dialog_func(ql):
# get DialogFunc address
lpDialogFunc = ql.unpack32(ql.mem.read(ql.reg.esp - 0x8, 4))
# setup stack for DialogFunc
ql.stack_push(0)
ql.stack_push(1001)
ql.stack_push(273)
ql.stack_push(0)
ql.stack_push(0x0401018)
# force EIP to DialogFunc
ql.reg.eip = lpDialogFunc
class QILING_IDA():
def __init__(self):
pass
def _show_context(self, ql:Qiling):
registers = [ k for k in ql.reg.register_mapping.keys() if type(k) is str ]
for idx in range(0, len(registers), 3):
regs = registers[idx:idx+3]
s = "\t".join(map(lambda v: f"{v:4}: {ql.reg.__getattribute__(v):016x}", regs))
ql.log.info(s)
def custom_prepare(self, ql:Qiling):
ql.stack_push(4) # java native function param
ql.stack_push(3) # java native function param
ql.stack_push(2)
ql.stack_push(1) # Jni_env
ql.mem.map(0//4096*4096, 4096)
ql.mem.write(676, struct.pack("<I",50)) # jni->functions->GetStringUTFChars
# ql.reg.eip = 0x56555C80
# ql.reg.write("EIP", 0x56555C80)
ql.log.info('Context before starting emulation:')
self._show_context(ql)
def custom_continue(self, ql:Qiling):
ql.log.info('custom_continue hook.')
self._show_context(ql)
hook = []
return hook
def custom_step(self, ql:Qiling):
def step_hook(ql, addr, size):
ql.log.info(f"Executing: {hex(addr)}")
if addr == 50:
ql.log.info('GetStringUTFChars hooked')
ret_addr = ql.stack_read(0)
# ret_addr = ql.mem.read(ql.reg.esp, 4)
ql.log.info(ret_addr)
ql.reg.eip = ret_addr
# self._show_context(ql)
# ql.hook_address(GetStringUTFChars, 50)
ql.log.info('custom_step hook')
hook = []
hook.append(ql.hook_code(step_hook))
return hook
def custom_execute_selection(self, ql:Qiling):
ql.log.info('custom execute selection hook')
hook = []
return hook
I seems work just fine after change ql.hook_address(GetStringUTFChars, 50) to if judgement inside step_hook.
For libc problem, I will continue to see later.
Will .so file in android influence emulating libc for qiling?
Will you be able to try the latest version of Qiling and see if you still face same issue. There is lots of rework since 2021. Feel free to open a new issue if you have any similar problem.