Closed 5lipper closed 5 years ago
Reproduced. Should be a bug (or a feature?) in libVEX.
Looks like by writing to lr
, the jumpkind is being set to call. Here's the small case without the lr
write:
In [5]: proj2.factory.block(0x300D14, insn_bytes='20509de524109de568809fe5a7ffffea'.decode('hex')).vex.pp()
IRSB {
t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I32 t5:Ity_I32 t6:Ity_I32 t7:Ity_I32 t8:Ity_I32 t9:Ity_I32 t10:Ity_I32 t11:Ity_I32 t12:Ity_I32 t13:Ity_I32
00 | ------ IMark(0x300d14, 4, 0) ------
01 | t10 = GET:I32(r13)
02 | t9 = Add32(t10,0x00000020)
03 | t2 = LDle:I32(t9)
04 | PUT(r5) = t2
05 | PUT(ip) = 0x00300d18
06 | ------ IMark(0x300d18, 4, 0) ------
07 | t11 = Add32(t10,0x00000024)
08 | t5 = LDle:I32(t11)
09 | PUT(r1) = t5
10 | PUT(ip) = 0x00300d1c
11 | ------ IMark(0x300d1c, 4, 0) ------
12 | t8 = LDle:I32(0x00300d8c)
13 | PUT(r8) = t8
14 | ------ IMark(0x300d20, 4, 0) ------
NEXT: PUT(pc) = 0x00300bc4; Ijk_Boring
}
In [6]: proj2.factory.block(0x300D14, insn_bytes='20509de524109de568809fe5a7ffffea'.decode('hex')).pp()
0x300d14: ldr r5, [sp, #0x20]
0x300d18: ldr r1, [sp, #0x24]
0x300d1c: ldr r8, [pc, #0x68]
0x300d20: b #0x300bc4
But the plot thickens... When adding traceflags to the same statement, VEX prints report that the jump kind is boring not call:
In [9]: proj2.factory.block(0x300D14, insn_bytes='20509de524109de568809fe51ce09de5a7ffffea'.decode('hex'), traceflags=255).vex.pp()
<snip>
IRSB {
t0:I32 t1:I32 t2:I32 t3:I32 t4:I32 t5:I32 t6:I32 t7:I32
t8:I32 t9:I32 t10:I32 t11:I32 t12:I32 t13:I32 t14:I32 t15:I32
t16:I32 t17:I32 t18:I32
------ IMark(0x300d14, 4, 0) ------
t13 = GET:I32(60)
t12 = Add32(t13,0x20:I32)
t2 = LDle:I32(t12)
PUT(28) = t2
PUT(68) = 0x300d18:I32
------ IMark(0x300d18, 4, 0) ------
t14 = Add32(t13,0x24:I32)
t5 = LDle:I32(t14)
PUT(12) = t5
PUT(68) = 0x300d1c:I32
------ IMark(0x300d1c, 4, 0) ------
t8 = LDle:I32(0x300d8c:I32)
PUT(40) = t8
PUT(68) = 0x300d20:I32
------ IMark(0x300d20, 4, 0) ------
t16 = Add32(t13,0x1c:I32)
t11 = LDle:I32(t16)
PUT(64) = t11
------ IMark(0x300d24, 4, 0) ------
PUT(68) = 0x300bc8:I32; exit-Boring
}
IRSB {
t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I32 t5:Ity_I32 t6:Ity_I32 t7:Ity_I32 t8:Ity_I32 t9:Ity_I32 t10:Ity_I32 t11:Ity_I32 t12:Ity_I32 t13:Ity_I32 t14:Ity_I32 t15:Ity_I32 t16:Ity_I32 t17:Ity_I32 t18:Ity_I32
00 | ------ IMark(0x300d14, 4, 0) ------
01 | t13 = GET:I32(r13)
02 | t12 = Add32(t13,0x00000020)
03 | t2 = LDle:I32(t12)
04 | PUT(r5) = t2
05 | PUT(ip) = 0x00300d18
06 | ------ IMark(0x300d18, 4, 0) ------
07 | t14 = Add32(t13,0x00000024)
08 | t5 = LDle:I32(t14)
09 | PUT(r1) = t5
10 | PUT(ip) = 0x00300d1c
11 | ------ IMark(0x300d1c, 4, 0) ------
12 | t8 = LDle:I32(0x00300d8c)
13 | PUT(r8) = t8
14 | PUT(ip) = 0x00300d20
15 | ------ IMark(0x300d20, 4, 0) ------
16 | t16 = Add32(t13,0x0000001c)
17 | t11 = LDle:I32(t16)
18 | PUT(lr) = t11
19 | ------ IMark(0x300d24, 4, 0) ------
NEXT: PUT(pc) = 0x00300bc8; Ijk_Call
}
The top block is from VEX and the bottom from Angr. Notice the JK mismatch.
Upon further digging, I've tracked the bug to Angr in the old angr/lifter.py
ARM post processor: https://github.com/angr/angr/blob/93ba3fac303fdf676b40ce1b7ad4a71b290e5fdb/angr/lifter.py#L274-L299
After the SimEngine merge, I don't believe these post processors exists any more, so the bug may be gone! I haven't confirmed as my checkout is from August....
The engines merge refactored the lifter stuff and moved the postprocessor to pyvex/lift/fixes.py
, lol
This code was ostensably written to fix some bug we found in libvex where an actual call wasn't being marked as a call and everything went to hell. If only we had that testcase lying around so we could write a better postprocessor...
This issue was already fixed
Sometimes simuvex can not detect the correct jumpkind for arm binary. @ltfish @zardus
A small case:
The jumpkind should be Ijk_Boring.
A large case:
This is a oversized basic block, it's not ended with any branching instruction. The correct jumpkind should be Ijk_Boring.