qiling icon indicating copy to clipboard operation
qiling copied to clipboard

How to hook some function with hook_address?

Open anaivebird opened this issue 3 years ago • 3 comments

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?

anaivebird avatar Mar 21 '21 19:03 anaivebird

  1. cc @kabeor to have a look at step functionality.
  2. qiling will load and run libc for your program so you don't need to implement them by your own for functions in libc.

wtdcode avatar Mar 22 '21 02:03 wtdcode

@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

kabeor avatar Mar 22 '21 03:03 kabeor

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?

anaivebird avatar Mar 22 '21 05:03 anaivebird

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.

xwings avatar Oct 06 '22 03:10 xwings