capstone-engine / capstone

Capstone disassembly/disassembler framework for ARM, ARM64 (ARMv8), Alpha, BPF, Ethereum VM, HPPA, LoongArch, M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86.
http://www.capstone-engine.org
7.59k stars 1.56k forks source link

Failure disassembling 'endbr64' (x86 IBT feature) #1129

Open rupran opened 6 years ago

rupran commented 6 years ago

Intel introduced new instructions for the protection of indirect branches, which make the processor fault if the target of an indirect jump is not an endbr{32,64} instruction. If the processor does not support Indirect Branch Tracking (IBT), the instruction is a nop (see [0], pages 15ff. and 130f.)

The instruction bytes for endbr64 are f3 0f 1e fa, for endbr32 they are f3 0f 1e fb.

The recently released Ubuntu 18.04 already compiles libstdc++.so.6.0.25, libgcc_s.so.1, libtsan.so.0.0.0 and some more with support for these instructions which essentially means every function in the binaries starts with endbr64.

Capstone currently fails when encountering these instructions (it returns an empty list of instructions), making it unusable for disassembly of those libraries. This happens on the master and next branches.

radare commented 6 years ago

This issue has been reported in radare2 as well https://github.com/radare/radare2/issues/10113

aquynh commented 6 years ago

Planning to sync with latest LLVM.

XVilka commented 6 years ago

Any updates on this?

cty12 commented 6 years ago

Is there any (general) documentation on how to add instructions to Capstone by the way? Thx. @aquynh

aquynh commented 6 years ago

i am working on that.

cty12 commented 6 years ago

@aquynh Does syncing the version of llvm fixes RDPKRU and WRPKRU support as well? If so shall I link issue #1076 here?

radare commented 6 years ago

any update?

radare commented 6 years ago

also, soon -next will reach 4 years without being merged into master or released. any plans to do that at some point? some distros take years to update, and this is going too far already

cty12 commented 6 years ago

@radare

At this time, a workaround is to use SKIPDATA mode and simply treat all unrecognized instructions as data bytes, which do not disrupt decoding those instructions to follow.

aquynh commented 6 years ago

a quick fix to make the next branch supports ENDBR64 & ENDBR32 now.

working to sync with LLVM to add more instructions now.

XVilka commented 6 years ago

Any news about this?

aquynh commented 6 years ago

I already fixed it, what news?

rupran commented 6 years ago

I guess a lot of us would like to see the fix (and possibly other ones as well) in a release...

XVilka commented 6 years ago

Then it make sense to close it.

aquynh commented 6 years ago

closed, thanks

disconnect3d commented 6 years ago

@aquynh Any chance to get this to a release version?

It has been few months and it still isn't there... :(

radare commented 6 years ago

months? it’s been 3 years

i completely lost all my faith

On 22 Oct 2018, at 12:01, Disconnect3d notifications@github.com wrote:

@aquynh https://github.com/aquynh Any chance to get this to a release version?

It has been few months and it still isn't there... :(

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aquynh/capstone/issues/1129#issuecomment-431782259, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-llzT2heQnHvpL3-JNQIdTb5KzEiRks5unZdegaJpZM4T0txA.

disconnect3d commented 5 years ago

This is still not fully resolved. While Capstone 4.0 (released yesteday) can decode endbr32 in x86 mode and endbr64 in x64 mode it should be able to decode both instruction in both modes and it can't.

Via the linked pdf:

The ENDBR32 and ENDBR64 instructions will have the same effect as the NOP instruction on Intel 64 processors that do not support CET. On processors supporting CET, these instructions still do not change register state (NOP-like). This allows CET instrumented programs to execute on processors that do not support CET. Even when CET is supported and enabled, these NOP–like instructions do not affect the execution state of the program, do not cause any additional register pressure, and are minimally intrusive from power and performance perspectives.

It is also possible to create a binary that has both those instructions:

#include <stdio.h>

int main() {
    asm("endbr32");
    asm("endbr64");
}

With gcc main.c && objdump -d -Mintel a.out (this also works with -m32):

00000000000005fa <main>:
 5fa:   55                      push   rbp
 5fb:   48 89 e5                mov    rbp,rsp
 5fe:   f3 0f 1e fb             endbr32
 602:   f3 0f 1e fa             endbr64
 606:   b8 00 00 00 00          mov    eax,0x0
 60b:   5d                      pop    rbp
 60c:   c3                      ret
 60d:   0f 1f 00                nop    DWORD PTR [rax]

And a Capstone 4.0 test:

from capstone import *

print('Capstone', __version__)

endbr32 = b'\x90' + b'\xf3\x0f\x1e\xfb' + b'\x90'
endbr64 = b'\x90' + b'\xf3\x0f\x1e\xfa' + b'\x90'

def decode(mode, code):
    md = Cs(CS_ARCH_X86, mode)
    md.detail = True
    for i in md.disasm(code, 0x1000):
        print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
    print('')

print('>>> x86, endbr32')
decode(CS_MODE_32, endbr32)

print('>>> x86, endbr64')
decode(CS_MODE_32, endbr64)

print('>>> x86-64, endbr32')
decode(CS_MODE_64, endbr64)

print('>>> x86-64, endbr32')
decode(CS_MODE_64, endbr64)

Output:

Capstone 4.0.0
>>> x86, endbr32
0x1000: nop
0x1001: endbr32
0x1005: nop

>>> x86, endbr64
0x1000: nop

>>> x86-64, endbr32
0x1000: nop

>>> x86-64, endbr64
0x1000: nop
0x1001: endbr64
0x1005: nop
aquynh commented 5 years ago

just fixed in "master" branch now, please confirm.

$ cstool x32 "f3 0f 1e fa"
 0  f3 0f 1e fa                                      endbr64

$ cstool x64 "f3 0f 1e fa"
 0  f3 0f 1e fa                                      endbr64

$ cstool x32 "f3 0f 1e fb"
 0  f3 0f 1e fb                                      endbr32

$ cstool x64 "f3 0f 1e fb"
 0  f3 0f 1e fb                                      endbr32
disconnect3d commented 5 years ago

Thanks, this is indeed fixed on current master: 472bd43fcf7bb35cf58e2c4e8c9d203310cd5629: image

I have also sent a PR to add info about this fix to the changelog: https://github.com/aquynh/capstone/pull/1331.