bap-ida-python icon indicating copy to clipboard operation
bap-ida-python copied to clipboard

64-bit binaries are loaded as 32-bit

Open fortunac opened this issue 5 years ago • 1 comments

Currently on BAP 1.6.0, opam 2.0.3, and IDA 7.1, given the file assembly compiled with gcc -nostdlib -o foo -foo.S:

.global _start

.text

foo:
    nop
    ret

main:
    lea    -0x98(%rsp), %rsp
    mov    %rdx, (%rsp)
    call   foo
    mov    (%rsp), %rdx
    lea    0x98(%rsp), %rsp
    ret

_start:
    call   main
    mov    $0x0, %rbx
    mov    $0x1, %rax
    int    $0x80

When we grab the BIR representation with bap -dbir foo, we get

00000026: sub main(main_argc, main_argv, main_result)
00000028: main_argc :: in u32 = RDI
00000029: main_argv :: in out u64 = RSI
0000002a: main_result :: out u32 = RAX
0000001a: 
0000001b: RSP := low:64[RSP + 0xFFFFFFFFFFFFFF68]
0000001c: mem := mem with [RSP, el]:u64 <- RDX
0000001d: RSP := RSP - 8
0000001e: mem := mem with [RSP, el]:u64 <- 0x254
0000001f: call @foo with return %00000020

00000020: 
00000021: RDX := mem[RSP, el]:u64
00000022: RSP := low:64[RSP + 0x98]
00000023: v14 := mem[RSP, el]:u64
00000024: RSP := RSP + 8
00000025: return v14

as expected.

However, with the IDA backend, and running the command bap -dbir --loader=ida --rooter=ida symbolizer=ida --brancher=ida foo, all of the registers become 32-bit:

00000045: sub main(main_argc, main_argv, main_result)
0000005c: main_argc :: in u32 = mem[ESP + 4, el]:u32
0000005d: main_argv :: in out u32 = mem[ESP + 8, el]:u32
0000005e: main_result :: out u32 = EAX
0000001d: 
0000001f: EAX := low:32[EAX] - 1
00000025: ESP := low:32[low:32[ESP] + -0x98]
00000027: EAX := low:32[EAX] - 1
0000002d: mem := mem with [ESP, el]:u32 <- EDX
0000002e: ESP := ESP - 4
0000002f: mem := mem with [ESP, el]:u32 <- 0x254
00000030: call @foo with return %00000031

00000031: 
00000033: EAX := low:32[EAX] - 1
00000039: EDX := mem[ESP, el]:u32
0000003b: EAX := low:32[EAX] - 1
00000041: ESP := low:32[low:32[ESP] + 0x98]
00000042: v18 := mem[ESP, el]:u32
00000043: ESP := ESP + 4
00000044: return v18

fortunac avatar Jul 03 '19 15:07 fortunac

From our discussion in gitter, there are two bugs actually,

  1. is_32bit is a function not a field.
  2. is_32bit() is True for x86_64, because it is indeed backward compatible with 32 bit ISA. Therefore, the correct code, should look like this:
size = "r64" if info.is_64bit() else "r32"

ivg avatar Jul 03 '19 15:07 ivg