All Projects → aengelke → fadec

aengelke / fadec

Licence: BSD-3-Clause License
A fast and lightweight decoder for x86 and x86-64 and encoder for x86-64.

Programming Languages

c
50402 projects - #5 most used programming language
python
139335 projects - #7 most used programming language
Meson
512 projects

Projects that are alternatives of or similar to fadec

Iced
Blazing fast and correct x86/x64 disassembler, assembler, decoder, encoder for .NET, Rust, Python, JavaScript
Stars: ✭ 1,102 (+2404.55%)
Mutual labels:  encoder, decoder, disassembler, x86
bmod
bmod parses binaries for modification/patching and disassembles machine code sections.
Stars: ✭ 12 (-72.73%)
Mutual labels:  x86-64, disassembler, x86, x86-32
peekaboo
An standalone execution trace library built on DynamoRIO.
Stars: ✭ 17 (-61.36%)
Mutual labels:  x86-64, x86, x86-32
Distorm
Powerful Disassembler Library For x86/AMD64
Stars: ✭ 829 (+1784.09%)
Mutual labels:  x86-64, disassembler, x86
Zydis
Fast and lightweight x86/x86-64 disassembler and code generation library
Stars: ✭ 2,168 (+4827.27%)
Mutual labels:  x86-64, disassembler, x86
Plasma
Plasma is an interactive disassembler for x86/ARM/MIPS. It can generates indented pseudo-code with colored syntax.
Stars: ✭ 2,956 (+6618.18%)
Mutual labels:  x86-64, disassembler, x86
x86-Assembly-Reverse-Engineering
🛠 Knowledge about the topic of x86 assembly & disassembly 🛠
Stars: ✭ 27 (-38.64%)
Mutual labels:  x86-64, x86, x86-32
X64dbg
An open-source x64/x32 debugger for windows.
Stars: ✭ 37,825 (+85865.91%)
Mutual labels:  x86-64, disassembler, x86
Capstone
Capstone disassembly/disassembler framework: Core (Arm, Arm64, BPF, EVM, M68K, M680X, MOS65xx, Mips, PPC, RISCV, Sparc, SystemZ, TMS320C64x, Web Assembly, X86, X86_64, XCore) + bindings.
Stars: ✭ 5,374 (+12113.64%)
Mutual labels:  x86-64, disassembler, x86
Bddisasm
bddisasm is a fast, lightweight, x86/x64 instruction decoder. The project also features a fast, basic, x86/x64 instruction emulator, designed specifically to detect shellcode-like behavior.
Stars: ✭ 540 (+1127.27%)
Mutual labels:  decoder, disassembler, x86
asm2cfg
Python command-line tool and GDB extension to view and save x86, ARM and objdump assembly files as control-flow graph (CFG) pdf files
Stars: ✭ 42 (-4.55%)
Mutual labels:  x86-64, disassembler, x86
Reko
Reko is a binary decompiler.
Stars: ✭ 942 (+2040.91%)
Mutual labels:  x86-64, disassembler, x86
Holodec
Decompiler for x86 and x86-64 ELF binaries
Stars: ✭ 195 (+343.18%)
Mutual labels:  x86-64, disassembler, x86
SDA
SDA is a rich cross-platform tool for reverse engineering that focused firstly on analysis of computer games. I'm trying to create a mix of the Ghidra, Cheat Engine and x64dbg. My tool will combine static and dynamic analysis of programs. Now SDA is being developed.
Stars: ✭ 98 (+122.73%)
Mutual labels:  x86-64, disassembler, x86
Capstone.NET
.NET Core and .NET Framework binding for the Capstone Disassembly Framework
Stars: ✭ 108 (+145.45%)
Mutual labels:  x86-64, disassembler, x86
alpine-php-fpm
Lightweight and optimised PHP-FPM (PHP 7.4, 8.0, 8.1) Docker images with essential extensions on top of latest Alpine Linux.
Stars: ✭ 53 (+20.45%)
Mutual labels:  x86-64, x86
Inflame
User-mode Windows DLL injector written in Assembly language (FASM syntax) with WinAPI.
Stars: ✭ 63 (+43.18%)
Mutual labels:  x86-64, x86
otfed
An OpenType font format encoder & decoder written in OCaml
Stars: ✭ 15 (-65.91%)
Mutual labels:  encoder, decoder
Image deionising auto encoder
Noise removal from images using Convolutional autoencoder
Stars: ✭ 34 (-22.73%)
Mutual labels:  encoder, decoder
pinktrace
Pink's Tracing Library
Stars: ✭ 20 (-54.55%)
Mutual labels:  x86-64, x86

Fadec — Fast Decoder for x86-32 and x86-64 and Encoder for x86-64

Fadec is a fast and lightweight decoder for x86-32 and x86-64. To meet the goal of speed, lookup tables are used to map the opcode the (internal) description of the instruction encoding. This table currently has a size of roughly 24 kiB (for 32/64-bit combined).

Fadec-Enc (or Faenc) is a small, lightweight and easy-to-use encoder, currently for x86-64 only.

Key features

Q: Why not just use any other decoding/encoding library available out there?

A: I needed to embed a small and fast decoder in a project for a freestanding environment (i.e., no libc). Further, only very few plain encoding libraries are available for x86-64; and most of them are large or make heavy use of external dependencies.

  • Small size: the entire library with a x86-64/32 decoder and a x86-64 encoder uses only 80 kiB; for specific use cases, the size can be reduced even further. The main decode/encode routines are only a few hundreds lines of code.
  • Performance: Fadec is significantly faster than libopcodes or Capstone due to the absence of high-level abstractions and the small lookup table.
  • Zero dependencies: the entire library has no dependencies, even on the standard library, making it suitable for freestanding environments without a full libc or malloc-style memory allocation.
  • Correctness: even corner cases should be handled correctly (if not, that's a bug), e.g., the order of prefixes, immediate sizes of jump instructions, the presence of the lock prefix, or properly handling VEX.W in 32-bit mode.

All components of this library target the Intel 64 implementations of x86. While AMD64 is mostly similar, there are some minor differences (e.g. operand sizes for jump instructions, more instructions, cr8 can be accessed with lock prefix) which are currently not handled.

Decoder Usage

Example

uint8_t buffer[] = {0x49, 0x90};
FdInstr instr;
// Decode from buffer into instr in 64-bit mode.
int ret = fd_decode(buffer, sizeof(buffer), 64, 0, &instr);
// ret<0 indicates an error, ret>0 the number of decoded bytes
// Relevant properties of instructions can now be queried using the FD_* macros.
// Or, we can format the instruction to a string buffer:
char fmtbuf[64];
fd_format(instr, fmtbuf, sizeof(fmtbuf));
// fmtbuf now reads: "xchg r8, rax"

API

The API consists of two functions to decode and format instructions, as well as several accessor macros. A full documentation can be found in fadec.h. Direct access of any structure fields is not recommended.

  • int fd_decode(const uint8_t* buf, size_t len, int mode, uintptr_t address, FdInstr* out_instr)
    • Decode a single instruction. For internal performance reasons, note that:
      • The decoded operand sizes are not always exact. However, the exact size can be reconstructed in all cases.
      • An implicit fwait in FPU instructions is decoded as a separate instruction (matching the opcode layout in machine code). For example, finit is decoded as FD_FWAIT + FD_FINIT
    • Return value: number of bytes used, or a negative value in case of an error.
    • buf/len: buffer containing instruction bytes. At most 15 bytes will be read. If the instruction is longer than len, an error value is returned.
    • mode: architecture mode, either 32 or 64.
    • address: set to 0. (Obsolete use: virtual address of the decoded instruction.)
    • out_instr: Pointer to the instruction buffer, might get written partially in case of an error.
  • void fd_format(const FdInstr* instr, char* buf, size_t len)
    • Format a single instruction to a human-readable format.
    • instr: decoded instruction.
    • buf/len: buffer for formatted instruction string
  • Various accessor macros: see fadec.h.

Encoder Usage

Example

int failed = 0;
uint8_t buf[64];
uint8_t* cur = buf;

// xor eax, eax
failed |= fe_enc64(&cur, FE_XOR32rr, FE_AX, FE_AX);
// movzx ecx, byte ptr [rdi + 1*rax + 0]
failed |= fe_enc64(&cur, FE_MOVZXr32m8, FE_CX, FE_MEM(FE_DI, 1, FE_AX, 0));
// test ecx, ecx
failed |= fe_enc64(&cur, FE_TEST32rr, FE_CX, FE_CX);
// jnz $
// This will be replaced later; FE_JMPL enforces use of longest offset
uint8_t* fwd_jmp = cur;
failed |= fe_enc64(&cur, FE_JNZ|FE_JMPL, (intptr_t) cur);
uint8_t* loop_tgt = cur;
// add rax, rcx
failed |= fe_enc64(&cur, FE_ADD64rr, FE_AX, FE_CX);
// sub ecx, 1
failed |= fe_enc64(&cur, FE_SUB32ri, FE_CX, 1);
// jnz loop_tgt
failed |= fe_enc64(&cur, FE_JNZ, (intptr_t) loop_tgt);
// Update previous jump to jump here. Note that we _must_ specify FE_JMPL too.
failed |= fe_enc64(&fwd_jmp, FE_JNZ|FE_JMPL, (intptr_t) cur);
// ret
failed |= fe_enc64(&cur, FE_RET);
// cur now points to the end of the buffer, failed indicates any failures.

API

The API consists of one function to handle encode requests, as well as some macros. More information can be found in fadec-enc.h. Usage of internals like enum values is not recommended.

  • int fe_enc64(uint8_t** buf, uint64_t mnem, int64_t operands...)
    • Encodes an instruction for x86-64 into *buf.
    • Return value: 0 on success, a negative value in error cases.
    • buf: Pointer to the pointer to the instruction buffer. The pointer (*buf) will be advanced by the number of bytes written. The instruction buffer must have at least 15 bytes left.
    • mnem: Instruction mnemonic to encode combined with extra flags:
      • FE_SEG(segreg): override segment to specified segment register.
      • FE_ADDR32: override address size to 32-bit.
      • FE_JMPL: use longest possible offset encoding, useful when jump target is not known.
    • operands...: Up to 4 instruction operands. The operand kinds must match the requirements of the mnemonic.
      • For register operands, use the register: FE_AX, FE_AH, FE_XMM12.
      • For immediate operands, use the constant: 12, -0xbeef.
      • For memory operands, use: FE_MEM(basereg,scale,indexreg,offset). Use 0 to specify no register. For RIP-relative addressing, the size of the instruction is added automatically.
      • For offset operands, specify the target address.

Known issues

  • The EVEX prefix (AVX-512) is not supported (yet).
  • MPX instructions are not supported.
  • HLE prefixes xacquire/xrelease are not supported by the encoder (yet).
  • Prefixes for indirect jumps and calls are not properly decoded, e.g. notrack, bnd.
  • Low test coverage. (Help needed.)
  • No Python API.

If you find any other issues, please report a bug. Or, even better, send a patch fixing the issue.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].