qilingframework / qiling

A True Instrumentable Binary Emulation Framework
https://qiling.io
GNU General Public License v2.0
5.14k stars 744 forks source link

Qdb step over command not working correctly #1321

Open pxqlinux opened 1 year ago

pxqlinux commented 1 year ago

*Describe the bug A clear and concise description of what the bug is.

Sample Code

from qiling import *
from qiling.const import *

# sandbox to emulate the EXE
def my_sandbox(path, rootfs):
    # setup Qiling engine
    ql = Qiling(path, rootfs,
                #verbose=QL_VERBOSE.DEBUG,
                ostype=QL_OS.WINDOWS,
                archtype=QL_ARCH.X86,
                )
    ql.debugger = 'qdb'
    # now emulate the EXE
    ql.run()

if __name__ == "__main__":
    # execute Windows EXE under our rootfs
    my_sandbox([
        "~/qiling/examples/rootfs/x86_windows/test.exe"],
        "~/qiling/examples/rootfs/x86_windows")

I am using qdb to debug the windows pe application. in the code context with: Sample Code

    > 0x004019e6 │ 7404            je         0x4019ec                           
       0x004019e8 │ 85ce            test       esi, ecx                           
       0x004019ea │ 7526            jne        0x401a12                           
       0x004019ec │ e894ffffff      call       0x401985                           
       0x004019f1 │ 8bc8            mov        ecx, eax                           
       0x004019f3 │ 3bcf            cmp        ecx, edi                           
       0x004019f5 │ 7507            jne        0x4019fe                           
       0x004019f7 │ b94fe640bb      mov        ecx, 0xbb40e64f                    
       0x004019fc │ eb0e            jmp        0x401a0c                           
       0x004019fe │ 85ce            test       esi, ecx 

now, zero flag is 1

Expected behavior je in the current line will jump to 0x4019ec expected but the application run until finished

so, i check the code in qiling/debugger/qdb/qdb.py at function do_step_over, the if condition: if prophecy.going: is wrong? maybe if not prophecy.going: ?

ucgJhe commented 1 year ago

Hi, I'll need more context of this for debugging.

  1. are you at the latest dev branch ?
  2. if the branch will be taken, qdb will show a sign at the left side of DISASM window, like the screen shot below

image

or you can provide the test.exe, so I can test it locally for fixing it.

pxqlinux commented 1 year ago

Thanks for answer

  1. i both try latest dev and master branch, the result is same

  2. screen shot: 680927a1d0f31e2da9b3e50753944d3

  3. my test py and exe is test-files.zip

  4. i try to fix the bug: qiling/debugger/qdb/qdb.py at function do_step_over, change if prophecy.going to if not prophecy.going the result is expected

thanks again

ucgJhe commented 1 year ago

Hello, after I change verbose to QL_VERBOSE.DISASM (dump executed instruction) mode, It looks like 0x004819e8 is not supposed to be executed. So the hook which placed by the command step_over is not triggered. if you still think this is a bug and need to be fixed, pls let me know.

pxqlinux commented 1 year ago

Hello ucgJhe, 0x004819e8 not execute is expected,the instruction exec to 0x004819e6 and ZF is 1,so the next instruction will jump to 0x4019ec。 The problem is,the command input to qdb is "s",mean step over to next instruction and hit the temp breakpoint paused, but the simulate exec until the process exit

ucgJhe commented 1 year ago

for qdb command, s is for step in, n for step over. So if you type n on 0x4819e6 the flow will never pause until the program exit , because it simply place a hook on next instruction which is 0x4819e8 and won't be executed. So i think the result is correct. Please correct me if I get you wrong thx.

pxqlinux commented 1 year ago

Sorry for the mistake, the command i type is “n”, not "s". for the step over command, will follow the jump target instruction, and set the temp breakpoint, because the if conditon not right, the breakpoint set to the wrong position, so "n" command run not hit any breakpoint until the program exited.

ucgJhe commented 1 year ago

@pxqlinux I see you point here. The qdb command n should place a temp breakpoint at 0x4019ec since the instruction at 0x4019e6 is NOT a function call, right ? The qdb command is not as same as gdb command semantically. For the qdb command n was used to place a temp breakpoint at the next address ( pc-related : pc+instruction_size@pc ), and the qdb command s is to place a temp breakpoint at the address to be executed. I think the qdb command s is what you want but not n if the assumption above is correct. Any ideas are welcome if you think this can be improved or shouldn't acting like that.