Skip to content

partial emulation enhance #593

@cq674350529

Description

@cq674350529

Currently, it's often to run partial emulation with saved context. However in many cases, there is no way to get and save the execution context.

If running partial emulation independently, it only supports pure codes without imported function calls, for these lib.so haven't been mapped.

As can be seen, if self.ql.entry_point is set (begin param in ql.run()), the emulation starts from self.ql.entry_point directly. Since the loader (ld.so) is not executed, the related lib.so won't be loaded and mapped.

if self.ql.entry_point is not None:
self.ql.loader.elf_entry = self.ql.entry_point
elif self.ql.loader.elf_entry != self.ql.loader.entry_point:
self.ql.emu_start(self.ql.loader.entry_point, self.ql.loader.elf_entry, self.ql.timeout)
self.ql.enable_lib_patch()
self.run_function_after_load()
self.ql.emu_start(self.ql.loader.elf_entry, self.exit_point, self.ql.timeout, self.ql.count)

A simple example is shown as follows.

int main(int argc, char* argv[])
{
    char* buf[10] = {0};
    memcpy(buf, "hello", strlen("hello"));
    printf("%s\n", buf);
    return 0;
}
.text:004007D0  # int __cdecl main(int argc, const char **argv, const char **envp)
.text:004007D0 addiu   $sp, -0x48
.text:004007D4 sw      $ra, 0x48+var_4($sp)
.text:004007D8 sw      $fp, 0x48+var_8($sp)
.text:004007DC move    $fp, $sp
.text:004007E0 li      $gp, 0x4189A0
.text:004007E8 sw      $gp, 0x48+var_38($sp)
.text:004007EC sw      $a0, 0x48+arg_0($fp)
.text:004007F0 sw      $a1, 0x48+arg_4($fp)
.text:004007F4 sw      $zero, 0x48+var_30($fp)
.text:004007F8 sw      $zero, 0x48+var_2C($fp)
.text:004007FC sw      $zero, 0x48+var_28($fp)
.text:00400800 sw      $zero, 0x48+var_24($fp)
.text:00400804 sw      $zero, 0x48+var_20($fp)
.text:00400808 sw      $zero, 0x48+var_1C($fp)
.text:0040080C sw      $zero, 0x48+var_18($fp)
.text:00400810 sw      $zero, 0x48+var_14($fp)
.text:00400814 sw      $zero, 0x48+var_10($fp)
.text:00400818 sw      $zero, 0x48+var_C($fp)
.text:0040081C li      $a2, 5           # n
.text:00400820 lui     $v0, 0x40
.text:00400824 addiu   $a1, $v0, (aHello - 0x400000)  # "hello"
.text:00400828 addiu   $v0, $fp, 0x48+var_30
.text:0040082C move    $a0, $v0         # dest
.text:00400830 la      $v0, memcpy
.text:00400834 move    $t9, $v0
.text:00400838 jalr    $t9 ; memcpy
.text:0040083C nop

As can be seen, there is no libc.so mapped when calling memcpy().

ipdb> hex(ql.reg.arch_pc)                                                                                            
'0x400838'
ipdb> ql.mem.show_mapinfo()                                                                                          
[+] Start      End        Perm.  Path
[+] 00400000 - 00401000 - r-x    ~/test_mips
[+] 00410000 - 00411000 - rw-   ~/test_mips
[+] 00411000 - 00413000 - rwx    [hook_mem]
[+] 047ba000 - 047d2000 - rwx    ~/sysroot/lib/ld-uClibc.so.0
[+] 7ff0d000 - 7ff3d000 - rwx    [stack]

In summary, when run partial emulation independetly, if no saved_context is restored, it's better to run ld.so to load the necessary lib.so first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions