angr / angr/pyvex

Cannot partially lift basic blocks containing invalid instructions

Đang mở
#425 7 bình luận 0 reaction 1 người được giao Được @ltfish nhận Xem trên GitHub
bug
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á.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.