iced
Blazing fast and correct x86/x64 disassembler, assembler, decoder, encoder for Rust, .NET, Java, Python, Lua
Top Related Projects
Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
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.
Low-latency machine code generation
Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
Fast and lightweight x86/x86-64 disassembler and code generation library
Quick Overview
Iced is a high-performance x86/x64 disassembler, assembler, and instruction decoder library written in Rust. It provides a fast and accurate way to work with x86 and x64 machine code, making it useful for various applications such as reverse engineering, malware analysis, and code optimization.
Pros
- High performance and efficiency due to its Rust implementation
- Supports both x86 and x64 architectures
- Provides a comprehensive API for disassembly, assembly, and instruction decoding
- Actively maintained and regularly updated
Cons
- Limited to x86 and x64 architectures, not suitable for other CPU architectures
- Steeper learning curve compared to some other disassembly libraries due to Rust's syntax and concepts
- May require additional dependencies or setup for certain features or integrations
Code Examples
- Disassembling a byte sequence:
use iced_x86::{Decoder, DecoderOptions, Formatter, Instruction, NasmFormatter};
let bytes = b"\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x55\x57\x41\x56\x48\x8D\x6C\x24\xC0";
let mut decoder = Decoder::with_ip(64, bytes, 0x1000, DecoderOptions::NONE);
let mut formatter = NasmFormatter::new();
let mut output = String::new();
decoder.iter().for_each(|instruction| {
formatter.format(&instruction, &mut output);
println!("{:016X} {}", instruction.ip(), output);
output.clear();
});
- Encoding an instruction:
use iced_x86::{Code, Instruction, Register};
let mut instruction = Instruction::with_reg_reg(Code::Mov_r64_rm64, Register::RAX, Register::RCX);
let mut bytes = [0u8; 15];
let size = instruction.encode(&mut bytes, 0);
println!("Encoded bytes: {:?}", &bytes[..size]);
- Analyzing instruction properties:
use iced_x86::{Decoder, DecoderOptions, Instruction, Register};
let bytes = b"\x48\x8B\x05\x00\x00\x00\x00";
let mut decoder = Decoder::new(64, bytes, DecoderOptions::NONE);
let instruction = decoder.decode();
println!("Mnemonic: {:?}", instruction.mnemonic());
println!("Operand count: {}", instruction.op_count());
println!("Uses RIP-relative addressing: {}", instruction.is_ip_rel_memory_operand());
println!("Reads from register: {}", instruction.reads_from_reg(Register::RAX));
Getting Started
To use Iced in your Rust project, add the following to your Cargo.toml
:
[dependencies]
iced-x86 = "1.18.0"
Then, in your Rust code, you can import and use Iced like this:
use iced_x86::{Decoder, DecoderOptions, Formatter, Instruction, NasmFormatter};
fn main() {
let bytes = b"\x90\x48\x89\x5C\x24\x10";
let mut decoder = Decoder::new(64, bytes, DecoderOptions::NONE);
let mut formatter = NasmFormatter::new();
decoder.iter().for_each(|instruction| {
let mut output = String::new();
formatter.format(&instruction, &mut output);
println!("{}", output);
});
}
This example demonstrates how to create a decoder, iterate through instructions, and format them using the NASM syntax.
Competitor Comparisons
Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
Pros of Unicorn
- Unicorn is a well-established and widely-used CPU emulator, supporting a wide range of architectures including ARM, MIPS, and x86.
- The project has a large and active community, with regular updates and a wealth of documentation and resources available.
- Unicorn provides a comprehensive API for interacting with the emulator, making it a powerful tool for a variety of use cases.
Cons of Unicorn
- Unicorn is primarily written in C, which may not be the most accessible language for some developers.
- The project's focus on low-level emulation may make it less suitable for certain high-level use cases, where a higher-level abstraction might be more appropriate.
- Unicorn's licensing (GPL v2) may be a concern for some users who require more permissive licensing terms.
Code Comparison
Unicorn:
uc_engine *uc;
uc_err err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err != UC_ERR_OK) {
printf("Failed on uc_open() with error: %u\n", err);
return;
}
uc_mem_map(uc, 0x1000, 0x4000, UC_PROT_ALL);
uc_mem_write(uc, 0x1000, code, sizeof(code));
uc_hook_add(uc, &hook, UC_HOOK_CODE, hook_code, NULL, 1, 0);
uc_emu_start(uc, 0x1000, 0x1010, 0, 0);
Iced:
let mut cpu = Cpu::new(CpuMode::Long64);
cpu.set_instruction_pointer(0x1000);
cpu.write_memory(0x1000, &code);
let mut handler = InstructionHandler::new(&mut cpu);
handler.hook_code(0x1000, 0x1010, |cpu, _addr, _len| {
// Handle instruction
Ok(())
});
cpu.run();
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.
Pros of Capstone
- Multi-architecture support: Covers a wide range of CPU architectures
- Mature and well-established: Used in many production environments
- Extensive language bindings: Supports various programming languages
Cons of Capstone
- Performance: Generally slower than Iced for x86/x64 disassembly
- Memory usage: Typically consumes more memory than Iced
- Less focus on x86/x64: Not as specialized for these architectures
Code Comparison
Iced (Rust):
use iced_x86::{Decoder, Formatter, Instruction, IntelFormatter};
let bytes = b"\x48\x8B\x05\x39\x00\x00\x00";
let mut decoder = Decoder::new(64, bytes, 0);
let mut instruction = Instruction::default();
while decoder.can_decode() {
decoder.decode_out(&mut instruction);
// Process instruction
}
Capstone (C):
#include <capstone/capstone.h>
csh handle;
cs_insn *insn;
size_t count;
if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) == CS_ERR_OK) {
count = cs_disasm(handle, code, code_size, address, 0, &insn);
// Process instructions
cs_free(insn, count);
cs_close(&handle);
}
Both libraries provide disassembly capabilities, but Iced is more focused on x86/x64 performance, while Capstone offers broader architecture support.
Low-latency machine code generation
Pros of asmjit
- Supports multiple architectures (x86, x64, ARM, AArch64)
- More comprehensive JIT compilation capabilities
- Actively maintained with frequent updates
Cons of asmjit
- Steeper learning curve due to more complex API
- Larger codebase, potentially leading to longer compilation times
- Less focused on disassembly compared to iced
Code Comparison
iced (Rust):
use iced_x86::{Decoder, Formatter, Instruction, NasmFormatter};
let bytes = b"\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x55\x57\x41\x56\x48\x8D\x6C\x24\xC0";
let mut decoder = Decoder::with_ip(64, bytes, 0x1000, 0);
let mut instruction = Instruction::default();
asmjit (C++):
#include <asmjit/asmjit.h>
using namespace asmjit;
JitRuntime rt;
CodeHolder code;
code.init(rt.environment());
x86::Assembler a(&code);
a.mov(x86::rax, x86::rcx);
Both libraries offer powerful assembly manipulation capabilities, but they cater to different use cases. iced excels in disassembly and analysis, while asmjit provides more comprehensive JIT compilation features across multiple architectures. The choice between them depends on the specific requirements of your project and your preferred programming language.
Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
Pros of Keystone
- Multi-architecture support (ARM, MIPS, PowerPC, Sparc, SystemZ, XCore, x86)
- Bindings for multiple programming languages (Python, Ruby, Go, etc.)
- Extensive documentation and examples
Cons of Keystone
- Less frequent updates and maintenance
- Larger codebase, potentially more complex to contribute to
- Slower assembly process for large amounts of code
Code Comparison
Keystone (Python):
from keystone import *
ks = Ks(KS_ARCH_X86, KS_MODE_32)
encoding, count = ks.asm("mov eax, 1")
Iced (Rust):
use iced_x86::{Assembler, Code, Register};
let mut asm = Assembler::new(32).unwrap();
asm.mov(Register::EAX, 1).unwrap();
let bytes = asm.assemble(0x1000).unwrap();
Both libraries provide assembler functionality, but Iced focuses specifically on x86/x64 architectures, while Keystone supports multiple architectures. Iced is written in Rust, offering memory safety and performance benefits, whereas Keystone is primarily written in C with bindings for various languages.
Fast and lightweight x86/x86-64 disassembler and code generation library
Pros of Zydis
- Zydis is a lightweight and fast x86/x86-64 disassembler library, which can be useful for a variety of applications such as malware analysis, reverse engineering, and debugging.
- Zydis has a well-documented API and provides a range of features, including instruction decoding, operand extraction, and instruction information retrieval.
- Zydis is actively maintained and has a large community of contributors, ensuring regular updates and improvements.
Cons of Zydis
- Zydis is primarily focused on x86/x86-64 architectures, while Iced supports a wider range of architectures, including ARM, RISC-V, and PowerPC.
- The documentation for Zydis may not be as comprehensive as Iced, which has a more extensive set of examples and tutorials.
- Zydis may have a steeper learning curve for developers who are not familiar with the x86/x86-64 architecture.
Code Comparison
Iced:
var decoder = Decoder.Create(64);
var code = new byte[] { 0x48, 0x89, 0x44, 0x24, 0x08 };
var instruction = decoder.Decode(code, 0);
Console.WriteLine(instruction.Mnemonic); // mov
Zydis:
zydis_decoder_t decoder;
zydis_decoder_init(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
zydis_decoded_instruction_t instruction;
zydis_status_t status = zydis_decoder_decode_buffer(&decoder, (void*)"H\x89D$\x08", 5, &instruction);
printf("%s\n", instruction.mnemonic.str); // mov
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
iced


iced is a blazing fast and correct x86 (16/32/64-bit) instruction decoder, disassembler and assembler.
- ð Supports all Intel and AMD instructions
- ð Correct: All instructions are tested and iced has been tested against other disassemblers/assemblers (xed, gas, objdump, masm, dumpbin, nasm, ndisasm) and fuzzed
- ð Supports .NET, Rust, Python, JavaScript (WebAssembly)
- ð The formatter supports masm, nasm, gas (AT&T), Intel (XED) and there are many options to customize the output
- ð Blazing fast: Decodes >250 MB/s and decode+format >130 MB/s (Rust, see here)
- ð Small decoded instructions, only 40 bytes and the decoder doesn't allocate any memory
- ð Create instructions with code assembler, eg.
asm.mov(eax, edx)
- ð The encoder can be used to re-encode decoded instructions at any address
- ð API to get instruction info, eg. read/written registers, memory and rflags bits; CPUID feature flag, control flow info, etc
- ð License: MIT
Examples
License
MIT
Icon
Logo processor
by Creative Stall from the Noun Project
Top Related Projects
Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
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.
Low-latency machine code generation
Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
Fast and lightweight x86/x86-64 disassembler and code generation library
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot