qilingframework / qiling

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

PC(0x0) Unreachable/Invalid memory fetch after running g++ compiled binary. #797

Closed kazimierzfilip closed 3 years ago

kazimierzfilip commented 3 years ago

Hi. I have an issue running binary compiled by g++ compiler. When I compile the same hello-world C program with gcc and g++. The first one runs ok with qiling and the second one does not. Is it connected with issue-377 or am I doing something wrong?

Sample Code

import sys
sys.path.append("..")

from qiling import Qiling

if __name__ == "__main__":
    ql = Qiling(["rootfs/x8664_linux/bin/x8664_hello_cpp"], "rootfs/x8664_linux")
    ql.run()

Compiled binary

#include<stdio.h>

int main(int argc, const char **argv)
{
    printf("Hello, World!\n");

    return 0;
}

Logs

experiments_1  | [=]    brk(input = 0x0)
experiments_1  | [=]    uname(address = 0x80000000d9e0)
experiments_1  | [=]    access(path = 0x7ffff7df6082, mode = 0x0)
experiments_1  | [=]    access(path = 0x7ffff7df8dd0, mode = 0x4)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x7ffff7df6428, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    writev(fd = 0x2, vec = 0x80000000d0e0, vien = 0xa)
experiments_1  | [=]    exit_group(exit_code = 0x7f)
experiments_1  | [x]
experiments_1  | 
experiments_1  | [x]    ah      :        0x0
experiments_1  | [x]    al      :        0xe7
experiments_1  | [x]    ch      :        0x51
experiments_1  | [x]    cl      :        0x60
experiments_1  | [x]    dh      :        0xd6
experiments_1  | [x]    dl      :        0x20
experiments_1  | [x]    bh      :        0x8c
experiments_1  | [x]    bl      :        0xe0
experiments_1  | [x]    ax      :        0xe7
experiments_1  | [x]    cx      :        0x5160
experiments_1  | [x]    dx      :        0xd620
experiments_1  | [x]    bx      :        0x8ce0
experiments_1  | [x]    sp      :        0xd608
experiments_1  | [x]    bp      :        0x0
experiments_1  | [x]    si      :        0xa33
experiments_1  | [x]    di      :        0x5135
experiments_1  | [x]    ip      :        0x0
experiments_1  | [x]    eax     :        0xe7
experiments_1  | [x]    ecx     :        0x55555160
experiments_1  | [x]    edx     :        0xd620
experiments_1  | [x]    ebx     :        0xf7df8ce0
experiments_1  | [x]    esp     :        0xd608
experiments_1  | [x]    ebp     :        0x0
experiments_1  | [x]    esi     :        0xf7df0a33
experiments_1  | [x]    edi     :        0x55555135
experiments_1  | [x]    eip     :        0x0
experiments_1  | [x]    rax     :        0xe7
experiments_1  | [x]    rbx     :        0x7ffff7df8ce0
experiments_1  | [x]    rcx     :        0x555555555160
experiments_1  | [x]    rdx     :        0x80000000d620
experiments_1  | [x]    rsi     :        0x7ffff7df0a33
experiments_1  | [x]    rdi     :        0x555555555135
experiments_1  | [x]    rbp     :        0x0
experiments_1  | [x]    rsp     :        0x80000000d608
experiments_1  | [x]    r8      :        0x5555555551c0
experiments_1  | [x]    r9      :        0x7f
experiments_1  | [x]    r10     :        0x20
experiments_1  | [x]    r11     :        0x0
experiments_1  | [x]    r12     :        0x1
experiments_1  | [x]    r13     :        0x7ffff7ffe960
experiments_1  | [x]    r14     :        0x7ffff7ffe950
experiments_1  | [x]    r15     :        0x7ffff7ffe170
experiments_1  | [x]    rip     :        0x0
experiments_1  | [x]    cr0     :        0x11
experiments_1  | [x]    cr1     :        0x0
experiments_1  | [x]    cr2     :        0x0
experiments_1  | [x]    cr3     :        0x0
experiments_1  | [x]    cr4     :        0x0
experiments_1  | [x]    cr5     :        0x0
experiments_1  | [x]    cr6     :        0x0
experiments_1  | [x]    cr7     :        0x0
experiments_1  | [x]    cr8     :        0x0
experiments_1  | [x]    cr9     :        0x0
experiments_1  | [x]    cr10    :        0x0
experiments_1  | [x]    cr11    :        0x0
experiments_1  | [x]    cr12    :        0x0
experiments_1  | [x]    cr13    :        0x0
experiments_1  | [x]    cr14    :        0x0
experiments_1  | [x]    cr15    :        0x0
experiments_1  | [x]    st0     :        0x0
experiments_1  | [x]    st1     :        0x0
experiments_1  | [x]    st2     :        0x0
experiments_1  | [x]    st3     :        0x0
experiments_1  | [x]    st4     :        0x0
experiments_1  | [x]    st5     :        0x0
experiments_1  | [x]    st6     :        0x0
experiments_1  | [x]    st7     :        0x0
experiments_1  | [x]    ef      :        0x0
experiments_1  | [x]    cs      :        0x1b
experiments_1  | [x]    ss      :        0x28
experiments_1  | [x]    ds      :        0x28
experiments_1  | [x]    es      :        0x28
experiments_1  | [x]    fs      :        0x0
experiments_1  | [x]    gs      :        0x0
experiments_1  | [x]    r8b     :        0xc0
experiments_1  | [x]    r9b     :        0x7f
experiments_1  | [x]    r10b    :        0x20
experiments_1  | [x]    r11b    :        0x0
experiments_1  | [x]    r12b    :        0x1
experiments_1  | [x]    r13b    :        0x60
experiments_1  | [x]    r14b    :        0x50
experiments_1  | [x]    r15b    :        0x70
experiments_1  | [x]    r8w     :        0x51c0
experiments_1  | [x]    r9w     :        0x7f
experiments_1  | [x]    r10w    :        0x20
experiments_1  | [x]    r11w    :        0x0
experiments_1  | [x]    r12w    :        0x1
experiments_1  | [x]    r13w    :        0xe960
experiments_1  | [x]    r14w    :        0xe950
experiments_1  | [x]    r15w    :        0xe170
experiments_1  | [x]    r8d     :        0x555551c0
experiments_1  | [x]    r9d     :        0x7f
experiments_1  | [x]    r10d    :        0x20
experiments_1  | [x]    r11d    :        0x0
experiments_1  | [x]    r12d    :        0x1
experiments_1  | [x]    r13d    :        0xf7ffe960
experiments_1  | [x]    r14d    :        0xf7ffe950
experiments_1  | [x]    r15d    :        0xf7ffe170
experiments_1  | [x]    fsbase  :        0x0
experiments_1  | [x]    gsbase  :        0x6000000
experiments_1  | [x]
experiments_1  | 
experiments_1  | [x]    PC = 0x0
experiments_1  | [=]
experiments_1  | 
experiments_1  | [=]    [+] Start      End        Perm.  Path
experiments_1  | [=]    [+] 00030000 - 00031000 - rwx    [GDT]
experiments_1  | [=]    [+] 06000000 - 07400000 - rwx    [GS]
experiments_1  | [=]    [+] 555555554000 - 555555555000 - r--    /code/qiling/examples/rootfs/x8664_linux/bin/x8664_hello_cpp (/code/qiling/examples/rootfs/x8664_linux/bin/x8664_hello_cpp)
experiments_1  | [=]    [+] 555555555000 - 555555556000 - r-x    /code/qiling/examples/rootfs/x8664_linux/bin/x8664_hello_cpp (/code/qiling/examples/rootfs/x8664_linux/bin/x8664_hello_cpp)
experiments_1  | [=]    [+] 555555556000 - 555555557000 - r--    /code/qiling/examples/rootfs/x8664_linux/bin/x8664_hello_cpp (/code/qiling/examples/rootfs/x8664_linux/bin/x8664_hello_cpp)
experiments_1  | [=]    [+] 555555557000 - 555555559000 - rw-    /code/qiling/examples/rootfs/x8664_linux/bin/x8664_hello_cpp (/code/qiling/examples/rootfs/x8664_linux/bin/x8664_hello_cpp)
experiments_1  | [=]    [+] 555555559000 - 55555555b000 - rwx    [hook_mem]
experiments_1  | [=]    [+] 7ffff7dd5000 - 7ffff7fff000 - rwx    /code/qiling/examples/rootfs/x8664_linux/lib64/ld-linux-x86-64.so.2
experiments_1  | [=]    [+] 7ffffffde000 - 80000000e000 - rwx    [stack]
experiments_1  | [=]    [+] ffffffffff600000 - ffffffffff601000 - rwx    [vsyscall]
experiments_1  | [x]    Error: PC(0x0) Unreachable
experiments_1  | Traceback (most recent call last):
experiments_1  |   File "/code/qiling/examples/hello_x8664_linux_disasm.py", line 45, in <module>
experiments_1  |     ql.run()
experiments_1  |   File "/usr/local/lib/python3.9/site-packages/qiling/core.py", line 724, in run
experiments_1  |     self.os.run()
experiments_1  |   File "/usr/local/lib/python3.9/site-packages/qiling/os/linux/linux.py", line 132, in run
experiments_1  |     self.ql.emu_start(self.ql.loader.elf_entry, self.exit_point, self.ql.timeout, self.ql.count)
experiments_1  |   File "/usr/local/lib/python3.9/site-packages/qiling/core.py", line 865, in emu_start
experiments_1  |     self.uc.emu_start(begin, end, timeout, count)
experiments_1  |   File "/usr/local/lib/python3.9/site-packages/unicorn/unicorn.py", line 318, in emu_start
experiments_1  |     raise UcError(status)
experiments_1  | unicorn.unicorn.UcError: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)

Expected behavior Successful execution.

Logs after running same source file compiled with gcc

experiments_1  | [=]    brk(input = 0x0)
experiments_1  | [=]    uname(address = 0x80000000d9e0)
experiments_1  | [=]    access(path = 0x7ffff7df6082, mode = 0x0)
experiments_1  | [=]    access(path = 0x7ffff7df8dd0, mode = 0x4)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x7ffff7df6428, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    stat(path = 0x80000000d370, buf_ptr = 0x80000000d430)
experiments_1  | [=]    openat(fd = 0xffffff9c, path = 0x80000000d370, flags = 0x80000, mode = 0x0)
experiments_1  | [=]    read(fd = 0x3, buf = 0x80000000d598, len = 0x340)
experiments_1  | [=]    fstat(fd = 0x3, buf_ptr = 0x80000000d430)
experiments_1  | [=]    mmap(addr = 0x0, length = 0x3f0ae0, prot = 0x5, flags = 0x802, fd = 0x3, pgoffset = 0x0)
experiments_1  | [=]    mprotect(start = 0x7fffb7fbd000, len = 0x200000, prot = 0x0)
experiments_1  | [=]    mmap(addr = 0x7fffb81bd000, length = 0x6000, prot = 0x3, flags = 0x812, fd = 0x3, pgoffset = 0x1e7000)
experiments_1  | [=]    mmap(addr = 0x7fffb81c3000, length = 0x3ae0, prot = 0x3, flags = 0x32, fd = 0xffffffff, pgoffset = 0x0)
experiments_1  | [=]    close(fd = 0x3)
experiments_1  | [=]    mmap(addr = 0x0, length = 0x2000, prot = 0x3, flags = 0x22, fd = 0xffffffff, pgoffset = 0x0)
experiments_1  | [=]    arch_prctl(ARCHX = 0x1002, ARCH_SET_FS = 0x7fffb81c7f00)
experiments_1  | [=]    mprotect(start = 0x7fffb81bd000, len = 0x4000, prot = 0x1)
experiments_1  | [=]    mprotect(start = 0x555555557000, len = 0x1000, prot = 0x1)
experiments_1  | [=]    mprotect(start = 0x7ffff7ffc000, len = 0x1000, prot = 0x1)
experiments_1  | [=]    fstat(fd = 0x1, buf_ptr = 0x80000000dc20)
experiments_1  | [=]    brk(input = 0x0)
experiments_1  | [=]    brk(input = 0x55555557c000)
experiments_1  | [=]    write(fd = 0x1, buf = 0x55555555b260, count = 0xe)
experiments_1  | Hello, World!
experiments_1  | [=]    exit_group(exit_code = 0x0)

Qiling version = 1.2.3

wtdcode commented 3 years ago

AFAIK, C++ support is still bad for now.

elicn commented 3 years ago

It requires additional two shared objects in your qiling/examples/rootfs/x8664_linux/lib directory:

  1. libstdc++.so.6
  2. libm.so.6

If you have a Linux installation handy (or WSL, for that matter), you can find them both at /usr/lib/x86_64-linux-gnu @xwings consider adding them to the rootfs repo

kazimierzfilip commented 3 years ago

Thanks a lot! Now both c and c++ programs run fine.