angr/pyvex

Possibly incorrect lifting of add instructions on ArchAMD64

Closed this issue · 7 comments

za233 commented

图片
We get an instruction of 4 bytes: add rax,0x1c
图片
But it decodes into 7 bytes by pyvex
图片

Cannot reproduce. Can you post your binary?

In [3]: proj = angr.load_shellcode(b"\x48\x83\xc0\x1c\x48\x8d\x8d\x50\xff\xff\xff", "amd64")

In [4]: proj.factory.block(0).vex.pp()
IRSB {
   t0:Ity_I64 t1:Ity_I64 t2:Ity_I64 t3:Ity_I64 t4:Ity_I64 t5:Ity_I64 t6:Ity_I64

   00 | ------ IMark(0x0, 4, 0) ------
   01 | t2 = GET:I64(rax)
   02 | t0 = Add64(t2,0x000000000000001c)
   03 | PUT(cc_op) = 0x0000000000000004
   04 | PUT(cc_dep1) = t2
   05 | PUT(cc_dep2) = 0x000000000000001c
   06 | PUT(rax) = t0
   07 | ------ IMark(0x4, 7, 0) ------
   08 | t5 = GET:I64(rbp)
   09 | t4 = Add64(t5,0xffffffffffffff50)
   10 | PUT(rcx) = t4
   NEXT: PUT(rip) = 0x000000000000000b; Ijk_Boring
}
za233 commented

Maybe I made a mistake.
This is the binary.
bin.zip

In [8]: block = proj.factory.block(0x40168d)

In [9]: block.vex.pp()
IRSB {
   t0:Ity_I64 t1:Ity_I64 t2:Ity_I64 t3:Ity_I64 t4:Ity_I64 t5:Ity_I64 t6:Ity_I64 t7:Ity_I64 t8:Ity_I64 t9:Ity_I64 t10:Ity_I64 t11:Ity_I64 t12:Ity_I64 t13:Ity_I64 t14:Ity_I64 t15:Ity_I64 t16:Ity_I64

   00 | ------ IMark(0x40168d, 4, 0) ------
   01 | t8 = GET:I64(rbp)
   02 | t7 = Add64(t8,0xffffffffffffff90)
   03 | ------ IMark(0x401691, 4, 0) ------
   04 | t1 = Add64(t7,0x000000000000001c)
   05 | PUT(cc_op) = 0x0000000000000004
   06 | PUT(cc_dep1) = t7
   07 | PUT(cc_dep2) = 0x000000000000001c
   08 | PUT(rax) = t1
   09 | ------ IMark(0x401695, 7, 0) ------
   10 | t9 = Add64(t8,0xffffffffffffff50)
   11 | PUT(rcx) = t9
   12 | ------ IMark(0x40169c, 6, 0) ------
   13 | PUT(r8) = 0x000000000000001c
   14 | ------ IMark(0x4016a2, 3, 0) ------
   15 | PUT(rdx) = t1
   16 | PUT(rip) = 0x00000000004016a5
   17 | ------ IMark(0x4016a5, 5, 0) ------
   18 | t14 = GET:I64(rsp)
   19 | t13 = Sub64(t14,0x0000000000000008)
   20 | PUT(rsp) = t13
   21 | STle(t13) = 0x00000000004016aa
   22 | t15 = Sub64(t13,0x0000000000000080)
   23 | ====== AbiHint(0xt15, 128, 0x0000000000407f00) ======
   NEXT: PUT(rip) = 0x0000000000407f00; Ijk_Call
}

In [10]: block.pp()
0x40168d:       lea     rax, [rbp - 0x70]
0x401691:       add     rax, 0x1c
0x401695:       lea     rcx, [rbp - 0xb0]
0x40169c:       mov     r8d, 0x1c
0x4016a2:       mov     rdx, rax
0x4016a5:       call    0x407f00

Is it possible that your code that runs before the decoding modified the binary code in simulated memory?

FYI You posted two binaries. I used bin, not bin.exe.

za233 commented

There must be something wrong with my code.
thank you very much.

If you have a reference to the block, block.bytes gives you the actual bytes that were lifted.

za233 commented

OK.thanks a lot