-
Notifications
You must be signed in to change notification settings - Fork 733
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Qiling fails to emulate simple binary with a ubuntu-22.04 root fs #1201
Comments
Hi there.
That said, we'll look into why Qiling did not fail gracefully. |
May this be a direct cause of the preceding syscall failure?
|
That might be the problem. def null_rseq_impl(ql: Qiling, abi: int, length: int, flags: int, sig: int):
# do nothing
pass
ql.os.set_syscall('rseq', null_rseq_impl, QL_INTERCEPT.CALL) Notes:
|
I tried that, though it did not help. Neither combination of return values was successful. |
@LoverOfSadness just use an older version of libc. If you really need the newer version, the easiest way is probably patching the ISA checks in libc |
Ok :-) |
@xwings consider adding an Ubuntu 22.04 LTS machine to the test suite. |
I found a temporary solution, which is to skip this error through hook. hook code: ...
def by_pass_isa_check(ql: Qiling) -> None:
print("by_pass_isa_check():")
ql.arch.regs.rip += 0x15
pass
...
ld_so_base = 0x7ffff7dd5000
ql.hook_address(by_pass_isa_check, ld_so_base+0x2389f) # ld.so base + jz offset Source: IDA Disassembly: |
Glibc2.35 in ubuntu 22.04. I'm not sure whether this offset is appropriate for your version, but the method is the same. |
Some background for this: Emulating a simple References: cc: @wtdcode, in case you want to patch Unicorn to support the mising CPU features (or they are already supported, but that support is not reflected in |
Unicorn has a special hook for cpuid: https://github.com/unicorn-engine/unicorn/blob/6c1cbef6ac505d355033aef1176b684d02e1eb3a/include/unicorn/x86.h#L86 Another solution is that the CPU model might be changed by |
I'll work on enabling a CPU selection. |
any update ..?
|
any update ..? |
Someone actually came out with a workaround. https://cloud.tencent.com/developer/article/2144036 by @yikesoftware i belive. |
can I get the source code and binary for this issue to try it out. |
It's kinda detrimental if qiling can't run the latest binaries from the most popular linux distro on x8664 (for over a year now!). If binaries run just fine when skipping the check, should we just fake a higher cpuid as standard? If the alternative is fixing unicorn then this issue is gonna stay up forever. Am i reading @elicn 's chart correctly that unicorn in fact does not even support baseline, and that's why the test fails? I'm kinda surprised Unicorn doesn't support FPU o_O. |
Trying this but i cannot get any value to work: ql = Qiling(argv, rootfs)
print(f"{ql.uc.ctl_get_cpu_model()=}")
ql.uc.ctl_set_cpu_model(UC_CPU_X86_EPYC_ROME)
not even using the value returned from |
@joleeee, interacting with the Assuming you are using the latest |
Thanks for the explanation! Now i can actually set the cputype/model, but I'm still getting the ISA level error. def run(rootfs, argv):
ql = Qiling(argv, rootfs, cputype=X86_CPU_MODEL.AMD_ATHLON)
print("cpu model", ql.uc.ctl_get_cpu_model())
ql.os.run() I didn't notice until now but is it actually because of a missing syscall?
I hooked the syscall in gdb, right here:
So on this x8664 vm which can run normal binaries, i'm getting a return value from the rseq syscall I tried doing like mentioned above, to no avail. Both with the unsigned and signed version.
|
It seems the rseq syscall is being called from |
Here is a fairly clean workaround for now. No need to set cpumodel. def try_patch_isa(ql: Qiling):
# 00023881 8b8a28030000 mov ecx, dword [rdx+0x328]
# 00023887 89cf mov edi, ecx
# 00023889 4421c7 and edi, r8d {0x0}
# 0002388c 39f9 cmp ecx, edi
# 0002388e 0f85000b0000 jne 0x24394 // from here
# 00023894 488d50f8 lea rdx, [rax-0x8]
# 00023898 4839f0 cmp rax, rsi
# 0002389b 75c3 jne 0x23860
# 0002389d 4c89ce mov rsi, r9 {0x3010102464c457f} // to here
# 000238a0 4c89ff mov rdi, r15
# 000238a3 e8d872ffff call sub_1ab80
pre = bytes.fromhex("8b8a2803000089cf4421c739f9")
ins = bytes.fromhex("0f85000b0000")
skip = bytes.fromhex("488d50f84839f075c3")
def bypass_isa_check(ql: Qiling) -> None:
print("Bypassing ISA Check...")
ql.arch.regs.rip += len(ins) + len(skip)
for start, end, perm, label, img in ql.mem.get_mapinfo():
if label != "ld-linux-x86-64.so.2":
continue
if "x" not in perm:
continue
adrs = ql.mem.search(pre + ins + skip, begin=start, end=end)
for adr in adrs:
ql.hook_address(bypass_isa_check, adr + len(pre))
ql = Qiling(...)
try_patch_isa(ql)
ql.run() |
Indeed, the rseq syscall has nothing to do with this. That should have been resovled by selecting a newer CPU model, but it appears that Unicorn doesn't report compatibility to baseline CPUID features, so the check fails. In the meantime, this is the workaround I am using. No need to hook the address, as this is just a one-time patching oepration: ql = Qiling([r'./some_binary'], fr'{QL_HOME}/examples/rootfs/ubuntu-22.04-x64')
def __patch_cpu_isa_check(ql: Qiling) -> None:
ld_img = ql.loader.get_image_by_name('ld-2.31.so')
if ld_img:
ql.mem.write(ld_img.base + 0x2389f, bytes.fromhex('eb'))
__patch_cpu_isa_check(ql)
ql.run() |
Any updates on this? |
*Describe the bug
When trying to emulate simple binaries on a vanilla ubuntu 22.04 qiling fails gloriously with
unicorn.unicorn.UcError: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)
Sample Code
Expected behavior
The emulations is successful, binary prints "Hi". This works fine on f.e. ubuntu 20.04
Additional context
This is the entire output log, but you should be able to reproduce with the given dockerfile:
The text was updated successfully, but these errors were encountered: