Cannot partially lift basic blocks containing invalid instructions
- Ngôn ngữ chính
- Python
- Star
- 379
- Fork
- 129
- Merge trung bình
- 11 giờ 45 phút
- Pull request đã merge (30 ngày)
- 8
Mô tả
### Description
VEX panics on certain invalid instructions, which results in `lift()` outputting nothing for the entire basic block (not even IR for instructions prior to the invalid one). Ideally, it would return a partial lifted block instead. This breaks angr's handling of self-modifying code containing these instructions (which can be worked around by single-stepping, but that comes with a performance penalty).
### Steps to reproduce the bug
Example:
```
import pyvex, archinfo
# mov word ptr [rip], 0x9090
>>> inst0 = b'\x66\xc7\x05\x00\x00\x00\x00\x90\x90'
# invalid instruction referencing a nonexistent segment register
>>> inst1 = b'\x8c\xf0'
# Lifting the first instruction works
>>> pyvex.lift(inst0, 0, archinfo.ArchAMD64()).pp()
IRSB {
t0:Ity_I64 t1:Ity_I64
00 | ------ IMark(0x0, 9, 0) ------
01 | STle(0x0000000000000009) = 0x9090
NEXT: PUT(rip) = 0x0000000000000009; Ijk_Boring
}
# Appending the invalid instruction results in no output
>>> pyvex.lift(inst0 + inst1, 0, archinfo.ArchAMD64()).pp()
IRSB {
NEXT: PUT(rip) = 0x0000000000000000; Ijk_NoDecode
}
# The failure is due to the panic at https://github.com/angr/vex/blob/c0bace1c7e86a12e4d845139fc246334e7bc402f/priv/guest_x86_toIR.c#L519
>>> print(pyvex.lifting.libvex.LibVEXLifter.get_vex_log())
vex: the `impossible' happened:
segmentGuestRegOffset(amd64)
```
### Environment
_No response_
### Additional context
While VEX's disassembler could be fixed to handle this specific failure gracefully, I worry (though I have not verified) that there may be enough other reachable panics strewn around that it would take a fair amount of effort to fix up all of the error handling. Perhaps an easier, if somewhat hacky solution would be to have `bb_to_IR` update a `lifted_upto` variable in `VexTranslateResult` after every successfully lifted instruction so that pyvex can retry lifting with `max_bytes` to obtain a partial lift.
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Đánh giá
Issue này chưa được đánh giá.