seemoo-lab / frankenstein

Broadcom and Cypress firmware emulation for fuzzing and further full-stack debugging
Apache License 2.0
433 stars 65 forks source link

qemu-arm segment fault #6

Open lometsj opened 3 years ago

lometsj commented 3 years ago

Hi, i just try to use qemu-arm to run excute.bin like:

qemu-arm excute.bin

and qemu terminated with segment fault is it normal? how can i emulate firmware after patch? i notice that on webui it emulate by using unicorn. im confused about it. how can i run the emulation environment

bolek42 commented 3 years ago

Hi lometsj, what exactly did you try to do? Do you want to run a provided Bluetooth firmware or do you work on your own? More information would be helpful but I'll try to answer your questions:

A .bin file should be a plain memory dump and therefore not executable at all. Executable ELF files, that can be run with qemu-arm should have the memory extension .exe .

If you work on your own, it is quite likely, that you will run into segfaults quite often in the beginning (e.g. due to a missing segment) therefore gdb and your favorite sre tools are your friends. Frankenstein can only assist reverse-engineering but it cannot replace it.

We use unicorn in the web-UI as it can give you deep insights into the execution (code path, including memory access) however this is of course very slow in comparison to plain qemu-arm. This is just another option you have.

if you have further questions feel free to ask. best, Jan

lometsj commented 3 years ago

thanks for response, it was my mistake for posting wrong command.(excute.exe not excute.bin) what i do just follow readme.md build and run qemu-arm

make -C projects/CYW20735B1
qemu-arm projects/CYW20735B1/gen/execute.exe

i had learned a little about reverse and debug with gdb. what i see is qemu-arm crash not inside qemu the excute.exe crash while emulation

Thread 1 "qemu-arm" received signal SIGSEGV, Segmentation fault.
0x00000000084ef062 in code_gen_buffer ()
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x00000000084bad40  →  0x000000000a5f5120  →  0x00000000084bb3f0  →  0x000000380000020c
$rbx   : 0x20a01f
$rcx   : 0x0
$rdx   : 0x00000000084eefc8  →  0xffff00a400000000
$rsp   : 0x00007ffffffed460  →  0x0000000000000200
$rbp   : 0x000000000a522300  →  0x0000000000200330
$rsi   : 0x00000000084ef040  →  0xaa8c0fdb85f05d8b
$rdi   : 0x000000000a522300  →  0x0000000000200330
$rip   : 0x00000000084ef062  →  0x145d8b005d894165
$r8    : 0x00000000084eee48  →  0x0002000400200081
$r9    : 0x2
$r10   : 0x0
$r11   : 0x000000000a611a10  →  0x00000000084eec58  →  0x00000000084eed00  →  0x008c0fdb85f05d8b
$r12   : 0x20a68c
$r13   : 0x20a698
$r14   : 0x00000000084eee40  →  0x000000000020a41c
$r15   : 0x00000000084ef040  →  0xaa8c0fdb85f05d8b
$eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
───────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007ffffffed460│+0x0000: 0x0000000000000200   ← $rsp
0x00007ffffffed468│+0x0008: 0x0000000000000fff
0x00007ffffffed470│+0x0010: 0x000000000a60d000  →  0x00000000084d0858  →  0x00000000084d0900  →  0x168c0fdb85f05d8b
0x00007ffffffed478│+0x0018: 0xfffffffffffff000
0x00007ffffffed480│+0x0020: 0x0000000000001000
0x00007ffffffed488│+0x0028: 0x000000780000007c ("|"?)
0x00007ffffffed490│+0x0030: 0x0000009b00000076 ("v"?)
0x00007ffffffed498│+0x0038: 0x0000000000000000
─────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
    0x84ef056 <code_gen_buffer+176169> mov    DWORD PTR [rbp+0xc], ebx
    0x84ef059 <code_gen_buffer+176172> mov    r12d, DWORD PTR [rbp+0x10]
    0x84ef05d <code_gen_buffer+176176> lea    r13d, [r12+0xc]
 →  0x84ef062 <code_gen_buffer+176181> mov    DWORD PTR gs:[r13+0x0], ebx
    0x84ef067 <code_gen_buffer+176186> mov    ebx, DWORD PTR [rbp+0x14]
    0x84ef06a <code_gen_buffer+176189> lea    r13d, [rbx+0x38]
    0x84ef06e <code_gen_buffer+176193> mov    r13d, DWORD PTR gs:[r13+0x0]
    0x84ef073 <code_gen_buffer+176198> mov    DWORD PTR [rbp+0xc], r13d
    0x84ef077 <code_gen_buffer+176202> lea    r14d, [r12+0x1c]
─────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "qemu-arm", stopped 0x84ef062 in code_gen_buffer (), reason: SIGSEGV
[#1] Id 2, Name: "qemu-arm", stopped 0x7ffffefeb89d in syscall (), reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x84ef062 → code_gen_buffer()
[#1] 0x80ff6f0 → cpu_exec()
[#2] 0x8138cd0 → cpu_loop()
[#3] 0x80bb687 → main()
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  c
Thread 1 "qemu-arm" received signal SIGSEGV, Segmentation fault.
0x00007ffffef1660a in __GI___sigsuspend (set=0x7ffffffed6b8) at ../sysdeps/unix/sysv/linux/sigsuspend.c:26
26      ../sysdeps/unix/sysv/linux/sigsuspend.c: No such file or directory.
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0xfffffffffffffdfe
$rbx   : 0x000000000a5d2b80  →  0x0000000000003fa0 ("?"?)
$rcx   : 0x8
$rdx   : 0x0
$rsp   : 0x00007ffffffed680  →  0x0000000000000000
$rbp   : 0xb
$rsi   : 0x8
$rdi   : 0x00007ffffffed6b8  →  0xfffffffe7ffffbff
$rip   : 0x00007ffffef1660a  →  0x3077fffff0003d48 ("H="?)
$r8    : 0x0
$r9    : 0x0
$r10   : 0x8
$r11   : 0x8
$r12   : 0x00007ffffffed6b8  →  0xfffffffe7ffffbff
$r13   : 0x00007ffffffed6b0  →  0x0000000000000000
$r14   : 0x0
$r15   : 0xa
$eflags: [zero CARRY parity ADJUST SIGN trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
───────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007ffffffed680│+0x0000: 0x0000000000000000   ← $rsp
0x00007ffffffed688│+0x0008: 0x00007ffffffed6b8  →  0xfffffffe7ffffbff
0x00007ffffffed690│+0x0010: 0x000000000000000b
0x00007ffffffed698│+0x0018: 0x000000000813137c  →   call 0x80b9730 <abort@plt>
0x00007ffffffed6a0│+0x0020: 0x0000000000000000
0x00007ffffffed6a8│+0x0028: 0xffffffffffffffff
0x00007ffffffed6b0│+0x0030: 0x0000000000000000   ← $r13
0x00007ffffffed6b8│+0x0038: 0xfffffffe7ffffbff   ← $rdi, $r12
─────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x7ffffef16600 <sigsuspend+64>  mov    r8d, eax
   0x7ffffef16603 <sigsuspend+67>  mov    eax, 0x82
   0x7ffffef16608 <sigsuspend+72>  syscall
 → 0x7ffffef1660a <sigsuspend+74>  cmp    rax, 0xfffffffffffff000
   0x7ffffef16610 <sigsuspend+80>  ja     0x7ffffef16642 <__GI___sigsuspend+130>
   0x7ffffef16612 <sigsuspend+82>  mov    edi, r8d
   0x7ffffef16615 <sigsuspend+85>  mov    DWORD PTR [rsp+0x8], eax
   0x7ffffef16619 <sigsuspend+89>  call   0x7ffffef677c0 <__libc_disable_asynccancel>
   0x7ffffef1661e <sigsuspend+94>  mov    eax, DWORD PTR [rsp+0x8]
─────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "qemu-arm", stopped 0x7ffffef1660a in __GI___sigsuspend (), reason: SIGSEGV
[#1] Id 2, Name: "qemu-arm", stopped 0x7ffffefeb89d in syscall (), reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffffef1660a → __GI___sigsuspend(set=0x7ffffffed6b8)
[#1] 0x813137c → call 0x80b9730 <abort@plt>
[#2] 0x81316f8 → nop DWORD PTR [rax+rax*1+0x0]
[#3] 0x813283c → process_pending_signals()
[#4] 0x8138f48 → cpu_loop()
[#5] 0x80bb687 → main()
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤
bolek42 commented 3 years ago

No worries :D Uhm that's odd.. I've tested the latest commit on freshly installed Ubuntu 20.04 and it seems to work. Can you give more details on your particular setup? E.g. what operating system you are using? The output of readelf -hS projects/CYW20735B1/gen/execute.exe would also be helpful, to verify that the build process works (somewhat) correctly.

In your gdb output are x86 registers (rax, rbx, etc.), so it looks as if you are debugging the qemu process and not the application. This is only helpful if you expect a bug in qemu. You might want to debug the emulated application (e.g. ARM code) instead. This can be done by spawning a gdb server in qemu using :

qemu-arm -g 1337 projects/CYW20735B1/gen/execute.exe

Then you can attach gdb-multiarch to the server. Your plain gdb will most likely not work, as it usually only has support for your native architecture. This is where gdb-multiarch comes in handy as it has support for many architectures.

gdb-multiarch -q -ex "target remote 127.0.0.1:1337" projects/CYW20735B1/gen/execute.exe

Could you provide a gdb output using those commands?

lometsj commented 3 years ago

thanks whatever, i just found out qemu-arm process only crash on wsl. so i tested on ubuntu 20.04 not wsl,and it works fine. it is unusual that a user mode qemu-arm process behaves differently on wsl and a real linux,but i don't want to get the bottom. anyway, thanks for help

RayCxggg commented 1 year ago

@lometsj @bolek42 Hi, I ran into the same issue and I don't know what went wrong. Could you guys help me? After qemu-arm projects/CYW20735B1/gen/execute.exe, QEMU crashes and output:

qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault (core dumped)

With gdb command

gdb-multiarch -q -ex "target remote 127.0.0.1:1337" projects/CYW20735B1/gen/execute.exe

I have the following output

Reading symbols from projects/CYW20735B1/gen/execute.exe...
(No debugging symbols found in projects/CYW20735B1/gen/execute.exe)
Remote debugging using 127.0.0.1:1337
0x0bef7ce4 in _start ()
(gdb) n
Single stepping until exit from function _start,
which has no line number information.

Program received signal SIGSEGV, Segmentation fault.
0x00210006 in _binary_segment_groups_default_Segment_0x200000_bin_start ()
(gdb) n
Single stepping until exit from function _binary_segment_groups_default_Segment_0x200000_bin_start,
which has no line number information.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

The output of readelf -hS projects/CYW20735B1/gen/execute.exe is

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            ARM
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0xbef7ce4
  Start of program headers:          52 (bytes into file)
  Start of section headers:          6698228 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         20
  Size of section headers:           40 (bytes)
  Number of section headers:         25
  Section header string table index: 24

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .Segment_0x0      PROGBITS        00000000 010000 200000 00  WA  0   0  1
  [ 2] .Segment_0x200000 PROGBITS        00200000 210000 050000 00  WA  0   0  1
  [ 3] .Segment_0x270000 PROGBITS        00270000 260000 010000 00  WA  0   0  1
  [ 4] .Segment_0x280000 PROGBITS        00280000 270000 004000 00  WA  0   0  1
  [ 5] .Segment_0x300000 PROGBITS        00300000 280000 008000 00  WA  0   0  1
  [ 6] .Segment_0x310000 PROGBITS        00310000 290000 012000 00  WA  0   0  1
  [ 7] .Segment_0x326000 PROGBITS        00326000 2a6000 00a000 00  WA  0   0  1
  [ 8] .Segment_0x338000 PROGBITS        00338000 2b8000 030000 00  WA  0   0  1
  [ 9] .Segment_0x370000 PROGBITS        00370000 2f0000 010000 00  WA  0   0  1
  [10] .Segment_0x390000 PROGBITS        00390000 300000 008000 00  WA  0   0  1
  [11] .Segment_0x410000 PROGBITS        00410000 310000 004000 00  WA  0   0  1
  [12] .Segment_0x420000 PROGBITS        00420000 320000 004000 00  WA  0   0  1
  [13] .Segment_0x430000 PROGBITS        00430000 330000 004000 00  WA  0   0  1
  [14] .Segment_0x440000 PROGBITS        00440000 340000 004000 00  WA  0   0  1
  [15] .Segment_0x450000 PROGBITS        00450000 350000 004000 00  WA  0   0  1
  [16] .Segment_0x500000 PROGBITS        00500000 360000 100800 00  WA  0   0  1
  [17] .Segment_0x640000 PROGBITS        00640000 470000 000800 00  WA  0   0  1
  [18] .Segment_0x650000 PROGBITS        00650000 480000 000800 00  WA  0   0  1
  [19] .Segment_0xe00000 PROGBITS        e0000000 4b0000 100000 00  WA  0   0  1
  [20] .text             PROGBITS        0beef000 48f000 008d80 00  AX  0   0  8
  [21] .data             PROGBITS        0bef8000 498000 00c348 04 WAX  0   0  4
  [22] .symtab           SYMTAB          00000000 5b0000 04bb40 10     23 790  4
  [23] .strtab           STRTAB          00000000 5fbb40 067837 00      0   0  1
  [24] .shstrtab         STRTAB          00000000 663377 00017a 00      0   0  1

Building environment

Ubuntu 20.04 
qemu-arm version 7.1.92

Highly appreciated!!!

the-moog commented 1 year ago

@RayCxggg Did you get to the bottom of this one. I have the same issue.

RayCxggg commented 1 year ago

@the-moog Yes, I figured it out. It is the qemu-arm version issue. The firmware doesn't work with the latest qemu. Try uninstall qemu and install older version with apt.

the-moog commented 1 year ago

Ahh interesting, thanks. Your issue was 2-3 years ago. Not sure what version to try. What version did you roll back to? Is there a bug open with qemu devs?

RayCxggg commented 1 year ago

@the-moog It is actually not a QEMU bug, but poor compatibility of frankenstein. I believe the working QEMU version should be the latest one when frankenstein was published, which is around 2018 (You should go check the paper). The latest QEMU version is 7.x.x, and the working one should be around 4.x.x.

the-moog commented 1 year ago

Thanks @RayCxggg Thanks for the hint, it may provide clues. I will go take a look at versions about that time. I've actually found the cause, well I think anyway, and made more progress with the current QEMU. It seems there are heavy inter-dependencies on the compiler, linker, newlib, libc, libgcc, application code (including crt and bootstrap) and QEMU. In my case the closest emulated CPU is lacking the CP15 and that is why it's borking. It's a shame QEMU is not more pluggable.... Anyway, I've found it's not just the code I am working with. There are a lot of switches that must be correct during the compilation of the tools and it seems packaged tools, though perhaps fine with common (or more recent) ARMs cores mine, being esoteric (and old), is less well supported without a lot of customization. The original author's have long gone..... Thanks again. Jay