Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
static_asm — Montador de cabeçalho único em C++2x em tempo de compilação para codificação de instruções x86/x86-64 | Kitploit
Ferramentas/GitHubGitHub/mahmoudimus/static_asm
Geração de PayloadsAnálise de CódigoExploraçãoEngenharia ReversaShellcodeAnálise de BináriosAprendizado e EducaçãoGeração de ShellcodeTrilhas e Cursos
GitHubmahmoudimus/static_asm

static_asm

Montador de cabeçalho único em C++2x em tempo de compilação para codificação de instruções x86/x86-64

311há 6 mesesRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Ver RepositórioSite

static_asm

CI License

Uma biblioteca C++20 apenas de cabeçalho para codificação de instruções x86/x86-64 em tempo de compilação.

Este projeto é licenciado duplamente sob a Boost Software License 1.0 e a MIT License. Você pode escolher qualquer uma das licenças.

Objetivo

  • Aprender codificação de assembly x86 de forma prática e divertida
  • Gerar instruções assembly em tempo de compilação com total segurança de tipos
  • Criar modelos de shellcode e código JIT sem sobrecarga em tempo de execução

Início Rápido

root@kitploit:~
#include "static_asm.hpp"

using namespace static_asm::x86::registers;
using namespace static_asm::x86::instructions;

// Build machine code at compile time
constexpr auto code = core::assemble(
    mov(rax, 0x12345678),    // mov rax, imm32
    add(rax, rcx),           // add rax, rcx
    xor_(r8, r8),            // xor r8, r8
    call(rax),               // call rax
    ret()                    // ret
);
// code is std::array<uint8_t, N> - fully constexpr!

Exemplos por Categoria

Operações ALU

root@kitploit:~
// Register to register
add(rax, rbx);           // 48 01 D8
sub(ecx, edx);           // 29 D1
and_(r8, r9);            // 4D 21 C8
or_(rsi, rdi);           // 48 09 FE
xor_(eax, eax);          // 31 C0 (common idiom to zero a register)
cmp(rax, rcx);           // 48 39 C8

// Register with immediate
add(rax, 0x10);          // 48 83 C0 10 (sign-extended imm8)
add(rax, 0x10000);       // 48 05 00 00 01 00 (imm32)
sub(ecx, 100);           // 83 E9 64
and_(rdx, 0xFF);         // 48 83 E2 FF

// With memory operands
add(eax, dword_ptr(rbx));              // 03 03
add(rax, qword_ptr(rcx + 0x10));       // 48 03 41 10
sub(dword_ptr(rsp + 0x20), eax);       // 29 44 24 20

Movimentação de Dados

root@kitploit:~
// Register to register
mov(rax, rbx);           // 48 89 D8
mov(eax, ecx);           // 89 C8
mov(r8, r9);             // 4D 89 C8

// Immediate to register
mov(rax, 0x12345678);    // 48 C7 C0 78 56 34 12
mov(eax, 0xDEADBEEF);    // B8 EF BE AD DE

// Memory operations
mov(rax, qword_ptr(rbx));              // 48 8B 03
mov(eax, dword_ptr(rcx + 0x10));       // 8B 41 10
mov(qword_ptr(rsp + 0x8), rax);        // 48 89 44 24 08
mov(dword_ptr(rbp - 0x20), 0x100);     // C7 45 E0 00 01 00 00

// Zero/sign extension
movzx(eax, bl);          // 0F B6 C3 (zero-extend byte to dword)
movzx(rax, bx);          // 48 0F B7 C3 (zero-extend word to qword)
movsx(eax, cl);          // 0F BE C1 (sign-extend byte to dword)
movsx(rax, dx);          // 48 0F BF C2 (sign-extend word to qword)
movsxd(rax, ecx);        // 48 63 C1 (sign-extend dword to qword)

// Load effective address
lea(rax, qword_ptr(rbx + rcx * s4));           // 48 8D 04 8B
lea(rax, qword_ptr(rbx + rcx * s8 + 0x10));    // 48 8D 44 CB 10

// Exchange
xchg(rax, rbx);          // 48 87 D8

Endereçamento SIB (Scale-Index-Base)

root@kitploit:~
// [base + index*scale]
mov(eax, dword_ptr(rbx + rcx * s1));   // 8B 04 0B
mov(eax, dword_ptr(rbx + rcx * s2));   // 8B 04 4B
mov(eax, dword_ptr(rbx + rcx * s4));   // 8B 04 8B
mov(eax, dword_ptr(rbx + rcx * s8));   // 8B 04 CB

// [base + index*scale + displacement]
mov(rax, qword_ptr(rbx + rcx * s4 + 0x10));     // 48 8B 44 8B 10
mov(rax, qword_ptr(r12 + r13 * s8 + 0x1000));   // 4B 8B 84 EC 00 10 00 00

// Store to SIB address
mov(dword_ptr(rax + rdx * s4), ecx);            // 89 0C 90
mov(qword_ptr(rbx + rsi * s8 + 0x20), rax);     // 48 89 44 F3 20

// LEA with SIB (useful for address calculations)
lea(rax, qword_ptr(rbx + rcx * s4));            // 48 8D 04 8B
lea(rax, qword_ptr(rdi + rsi * s8 + 0x100));    // 48 8D 84 F7 00 01 00 00

Deslocamentos e Rotações

root@kitploit:~
// Shift by 1
shl(eax, 1);             // D1 E0
shr(rax, 1);             // 48 D1 E8
sar(ecx, 1);             // D1 F9

// Shift by immediate
shl(eax, 4);             // C1 E0 04
shr(rax, 8);             // 48 C1 E8 08
sar(rdx, 16);            // 48 C1 FA 10

// Shift by CL register
shl(eax, cl);            // D3 E0
shr(rax, cl);            // 48 D3 E8

// Rotate
rol(eax, 1);             // D1 C0
ror(rax, 8);             // 48 C1 C8 08
rcl(ecx, cl);            // D3 D1
rcr(rdx, 1);             // 48 D1 DA

Multiplicação e Divisão

root@kitploit:~
// Single operand (result in rdx:rax)
mul(rbx);                // 48 F7 E3 (unsigned: rdx:rax = rax * rbx)
imul(rcx);               // 48 F7 E9 (signed: rdx:rax = rax * rcx)
div(rbx);                // 48 F7 F3 (unsigned: rax = rdx:rax / rbx, rdx = remainder)
idiv(rcx);               // 48 F7 F9 (signed division)

// Two-operand IMUL (dest = dest * src)
imul(rax, rbx);          // 48 0F AF C3
imul(ecx, edx);          // 0F AF CA

// Three-operand IMUL (dest = src * imm)
imul(rax, rbx, 10);      // 48 6B C3 0A
imul(ecx, edx, 1000);    // 69 CA E8 03 00 00

Fluxo de Controle

root@kitploit:~
// Unconditional jumps
jmp(0x10);               // EB 10 (short, 8-bit offset)
jmp(0x1000);             // E9 00 10 00 00 (near, 32-bit offset)
jmp(rax);                // FF E0 (indirect)
jmp(here);               // EB FE (jmp $, infinite loop)

// Conditional jumps (8-bit offset)
jz(0x10);                // 74 10
jnz(0x20);               // 75 20
jb(0x08);                // 72 08 (below/carry)
jae(0x08);               // 73 08 (above or equal/no carry)
jl(0x10);                // 7C 10 (less than, signed)
jge(0x10);               // 7D 10 (greater or equal, signed)

// Conditional jumps (32-bit offset for longer branches)
jz_near(0x10000);        // 0F 84 00 00 01 00
jnz_near(0x20000);       // 0F 85 00 00 02 00

// Call and return
call(rax);               // FF D0 (indirect call)
call(0x100);             // E8 00 01 00 00 (relative call)
ret();                   // C3
ret(0x10);               // C2 10 00 (return and pop 16 bytes)

Movimentos Condicionais

root@kitploit:~
// Move if condition is true (no branch penalty!)
cmovz(rax, rbx);         // 48 0F 44 C3 (move if zero)
cmovnz(eax, ecx);        // 0F 45 C1 (move if not zero)
cmovl(rax, rdx);         // 48 0F 4C C2 (move if less, signed)
cmovge(ecx, esi);        // 0F 4D CE (move if greater or equal, signed)
cmovb(rax, rbx);         // 48 0F 42 C3 (move if below, unsigned)
cmovae(edx, edi);        // 0F 43 D7 (move if above or equal, unsigned)

// With memory source
cmovz(rax, qword_ptr(rbx));           // 48 0F 44 03
cmovnz(eax, dword_ptr(rcx + 0x10));   // 0F 45 41 10

Operações com Bits

root@kitploit:~
// Bit test
bt(eax, 5);              // 0F BA E0 05
bt(rax, rbx);            // 48 0F A3 D8

// Bit test and set/reset/complement
bts(eax, 10);            // 0F BA E8 0A (test and set)
btr(rax, rcx);           // 48 0F B3 C8 (test and reset)
btc(edx, 3);             // 0F BA FA 03 (test and complement)

// Bit scan
bsf(eax, ecx);           // 0F BC C1 (scan forward for first 1)
bsr(rax, rbx);           // 48 0F BD C3 (scan reverse for first 1)

// Population count and leading/trailing zeros
popcnt(eax, ecx);        // F3 0F B8 C1
lzcnt(rax, rbx);         // F3 48 0F BD C3
tzcnt(eax, edx);         // F3 0F BC C2

// Byte swap
bswap(eax);              // 0F C8 (reverse byte order)
bswap(rax);              // 48 0F C8

Operações com Strings

root@kitploit:~
// Basic string ops (operate on [rsi] and/or [rdi])
movsb();                 // A4 (move byte [rsi] -> [rdi])
movsw();                 // 66 A5
movsd();                 // A5
movsq();                 // 48 A5

cmpsb();                 // A6 (compare [rsi] with [rdi])
stosb();                 // AA (store al -> [rdi])
lodsb();                 // AC (load [rsi] -> al)
scasb();                 // AE (compare al with [rdi])

// With REP prefix (repeat rcx times)
rep_movsb();             // F3 A4 (memcpy)
rep_movsq();             // F3 48 A5 (fast memcpy, 8 bytes at a time)
rep_stosb();             // F3 AA (memset)
rep_stosq();             // F3 48 AB

// With REPE/REPNE (repeat while equal/not equal)
repe_cmpsb();            // F3 A6 (compare strings until mismatch)
repne_scasb();           // F2 AE (scan for byte in string)

Operações com Pilha

root@kitploit:~
push(rax);               // 50
push(rbx);               // 53
push(r8);                // 41 50
push(0x10);              // 6A 10 (push imm8)
push(0x1000);            // 68 00 10 00 00 (push imm32)

pop(rax);                // 58
pop(rbx);                // 5B
pop(r15);                // 41 5F

Instruções de Sistema

root@kitploit:~
// System calls
syscall_();              // 0F 05 (64-bit syscall)
sysenter();              // 0F 34
sysexit();               // 0F 35

// Interrupts
int3();                  // CC (breakpoint)
int_(0x80);              // CD 80 (Linux 32-bit syscall)
int_(0x21);              // CD 21 (DOS interrupt)

// CPU info
cpuid();                 // 0F A2
rdtsc();                 // 0F 31
rdtscp();                // 0F 01 F9

// Privilege
cli();                   // FA (clear interrupts)
sti();                   // FB (set interrupts)
hlt();                   // F4 (halt)

// Interrupt return
iret();                  // CF (16-bit)
iretd();                 // CF (32-bit)
iretq();                 // 48 CF (64-bit)

Montando Múltiplas Instruções

Use core::assemble() para concatenar arrays de bytes de instruções:

root@kitploit:~
constexpr auto prologue = core::assemble(
    push(rbp),
    mov(rbp, rsp),
    sub(rsp, 0x20)
);

constexpr auto epilogue = core::assemble(
    add(rsp, 0x20),
    pop(rbp),
    ret()
);

// Combine them
constexpr auto full_function = core::assemble(prologue, epilogue);

Instalação

Opção 1: CMake FetchContent (Recomendado)

Adicione ao seu CMakeLists.txt:

root@kitploit:~
include(FetchContent)
FetchContent_Declare(
    static_asm
    GIT_REPOSITORY https://github.com/mahmoudimus/static_asm.git
    GIT_TAG v1.0.0  # ou commit específico
)
FetchContent_MakeAvailable(static_asm)

target_link_libraries(seu_projeto PRIVATE static_asm::static_asm)

Opção 2: CMake add_subdirectory

Clone ou adicione como submodulo git:

root@kitploit:~
git submodule add https://github.com/mahmoudimus/static_asm.git external/static_asm

Então no seu CMakeLists.txt:

root@kitploit:~
add_subdirectory(external/static_asm)
target_link_libraries(seu_projeto PRIVATE static_asm::static_asm)

Quando incluído via add_subdirectory ou FetchContent, apenas o alvo de biblioteca de interface static_asm::static_asm é adicionado ao seu projeto. Testes e exemplos não são compilados a menos que explicitamente habilitados com -DSTATIC_ASM_BUILD_TESTS=ON.

Opção 3: Cabeçalho Único

Baixe static_asm.hpp da página de releases e inclua diretamente:

root@kitploit:~
#include "static_asm.hpp"

Opção 4: Instalação no Sistema

root@kitploit:~
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --install build --prefix /usr/local

Então use find_package:

root@kitploit:~
find_package(static_asm REQUIRED)
target_link_libraries(seu_projeto PRIVATE static_asm::static_asm)

Compilação

root@kitploit:~
# Configurar
cmake -B build -DCMAKE_BUILD_TYPE=Release

# Compilar
cmake --build build

# Executar testes
ctest --test-dir build --output-on-failure

# Compilar com exemplos (apenas Clang, usa assembly inline)
cmake -B build -DCMAKE_BUILD_TYPE=Release -DSTATIC_ASM_BUILD_EXAMPLES=ON

Suporte de plataforma:

  • Linux (GCC 11+, Clang 14+)
  • macOS (Apple Clang, Clang)
  • Windows (MSVC 2022+)

Nota: O recurso de assembly inline core::emit() requer Clang com otimização -O2.

Instruções Suportadas

Suporte a operandos:

  • Todos os registradores de propósito geral de 8/16/32/64 bits (AL-R15)
  • Registradores estendidos (R8-R15, R8D-R15D, R8W-R15W, R8B-R15B)
  • Valores imediatos (8/16/32/64 bits)
  • Operandos de memória com registrador base e deslocamento
  • Endereçamento SIB: [base + index*scale + disp] com fatores de escala 1, 2, 4, 8

Nota: Nenhuma extensão SIMD/AVX ainda.

Desenvolvimento

Configuração do Ambiente

Este projeto usa uv para ferramentas Python (geração de código, amalgamação de cabeçalho único).

root@kitploit:~
# Instalar uv (se ainda não estiver instalado)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Verificar instalação
uv --version

# Todos os scripts Python podem ser executados diretamente com uv (dependências são gerenciadas automaticamente)
uv run scripts/gen_from_x86ref.py --help
uv run scripts/amalgamate.sh

Ferramentas necessárias:

Ferramentas opcionais para desenvolvimento:

FerramentaFinalidadeInstalação
clang-formatFormatação de códigoVia LLVM ou pacote do sistema
clang-tidyAnálise estáticaVia LLVM ou pacote do sistema

Adicionando Novas Instruções

Opção 1: Usar o Gerador de Código

O projeto inclui um gerador que analisa o banco de dados XML do x86reference:

root@kitploit:~
# Mostrar resumo do banco de dados de instruções
uv run scripts/gen_from_x86ref.py

# Mostrar detalhes para uma instrução específica
uv run scripts/gen_from_x86ref.py -i lea
uv run scripts/gen_from_x86ref.py -i imul

# Gerar arquivos de banco de dados de instruções
uv run scripts/gen_from_x86ref.py --generate-db

# Gerar arquivo de teste exaustivo
uv run scripts/gen_from_x86ref.py --generate-tests

Opção 2: Adição Manual

  1. Adicione ao arquivo de banco de dados de instruções (arrays instdb, prefix_db, prefix_0fdb)
  2. Codifique o codificador em encoder.hpp ou estenda um codificador existente
  3. Adicione testes

Técnicas para Criar uma Biblioteca de Cabeçalho Único

Nenhuma ferramenta automática pode converter de forma confiável uma biblioteca C++ arbitrária de múltiplos arquivos em uma versão limpa e apenas de cabeçalho sem alguma preparação manual. As técnicas a seguir ajudam a garantir que sua biblioteca possa ser amalgamada com sucesso em um único arquivo de cabeçalho, permanecendo correta, sustentável e em conformidade com os padrões.

Nota: Este projeto usa quom para amalgamação e clang-tidy com a verificação google-build-using-namespace para automatizar a aplicação dessas regras. O quom também lida parcialmente com a técnica #4 (marcadores inline) através de suas capacidades de processamento.

1. Evite using namespace em arquivos fonte

using namespace no escopo do arquivo em arquivos .cpp é perigoso quando esses arquivos são posteriormente incluídos em um cabeçalho — ele polui o namespace global para toda unidade de tradução que inclui seu cabeçalho.

Padrões recomendados em vez disso:

root@kitploit:~
// Preferido: envolver a implementação no namespace
namespace MyLib {
    Foo::Foo() {
        // ...
    }
}

ou

root@kitploit:~
// Qualificação explícita (mais verbosa, mas muito clara)
MyLib::Foo::Foo() {
    // ...
}

2. Coloque APIs internas/privadas em um namespace aninhado

APIs públicas devem viver no namespace principal. Tudo o que não é destinado a usuários finais deve ser escondido em um namespace aninhado como detail ou impl.

Convenções comuns:

root@kitploit:~
namespace MyLib {
    namespace detail {           // muito usado
        // classes internas, funções, etc.
    }
}

ou

root@kitploit:~
namespace MyLib::impl {          // mais curto, também comum
    // detalhes internos da implementação
}

C++17 e posteriores suportam definições de namespace aninhado inline, que são mais limpas:

root@kitploit:~
namespace MyLib::detail {
    class InternalHelper { /* ... */ };
}

3. Converta dados estáticos de escopo de arquivo para membros de classe static inline

Variáveis static de escopo de arquivo definidas em arquivos .cpp tornam-se problemáticas em um mundo apenas de cabeçalho (definições múltiplas, violações de ODR).

Solução moderna (C++17+):

root@kitploit:~
// Antes (em .cpp)
namespace MyLib {
    static int s_counter = 0;

    int next_id() {
        return ++s_counter;
    }
}
root@kitploit:~
// Depois (seguro para cabeçalho)
namespace MyLib::detail {
    struct Globals {
        static inline int counter = 0;
    };
}

inline int MyLib::next_id() {
    return ++detail::Globals::counter;
}

A variável static inline tem garantia de ter uma única definição mesmo quando incluída múltiplas vezes.

4. Marque funções definidas fora do corpo da classe como inline

Qualquer função, função membro, construtor ou destrutor cujo corpo aparece no cabeçalho (mas não dentro da definição da classe) deve ser marcado como inline para evitar violações da Regra de Definição Única (ODR).

Como muitos scripts de amalgamação são puramente textuais e não analisam a semântica de C++, uma convenção comum é usar uma macro placeholder (ex.: inline_t) durante o desenvolvimento:

root@kitploit:~
// MyLib.h (ou cabeçalho comum)
#define inline_t   /* vazio durante builds normais */

// MyLib.cpp (durante desenvolvimento)
namespace MyLib::detail {
    inline_t void Helper::do_work() {
        // implementação
    }
}

Durante a amalgamação, a ferramenta substitui inline_t por inline:

root@kitploit:~
// Após amalgamação / transformação
inline void MyLib::detail::Helper::do_work() {
    // ...
}

Você pode escolher qualquer nome de macro que preferir (ex.: MYLIB_INLINE, INLINE_IMP, etc.) e configurar seu script de amalgamação de acordo.

Nota: Ferramentas como quom podem automatizar parcialmente isso, entendendo a semântica de inclusão de C++ e lidando corretamente com definições de funções durante a amalgamação, reduzindo a necessidade de marcadores inline manuais em muitos casos.

Resumo — As Quatro Regras Principais

  1. Nunca escreva using namespace … em escopo de namespace/arquivo em arquivos de implementação.
  2. Coloque todos os símbolos internos/não públicos em um namespace aninhado (detail / impl).
  3. Substitua dados static de escopo de arquivo por membros static inline de uma struct/classe.
  4. Marque corpos de funções fora da linha com uma macro de marcador inline (substituída durante a amalgamação).

Seguir essas quatro práticas torna a transição para uma distribuição de cabeçalho único muito mais suave e com muito menos erros — mesmo ao usar ferramentas de amalgamação puramente textuais.

Créditos

  • Godbolt para prototipagem
  • Manual Intel x86-64 manual
  • Defuse.ca para verificar saídas
  • Referência Geek ABC
  • mazegen/x86reference pelo XML do banco de dados de instruções

Agradecimentos

Este projeto é baseado em cx_assembler por Midi12. A biblioteca original forneceu a base para a codificação de assembly x86 em tempo de compilação em C++.

Baixar ferramenta
CategoriaInstruções
ALUADD, ADC, SUB, SBB, AND, OR, XOR, CMP, TEST
UnáriasINC, DEC, NEG, NOT
Multiplicação/DivisãoMUL, IMUL (formas 1/2/3 operandos), DIV, IDIV
Movimentação de DadosMOV, MOVABS, MOVZX, MOVSX, MOVSXD, LEA, XCHG, PUSH, POP
Deslocamento/RotaçãoSHL, SHR, SAL, SAR, ROL, ROR, RCL, RCR
Fluxo de ControleJMP, CALL, RET, RETF
Saltos CondicionaisJZ/JE, JNZ/JNE, JB/JC, JNB/JNC, JBE/JNA, JNBE/JA, JL, JNL, JLE, JNLE, JO, JNO, JS, JNS, JP, JNP (offsets de 8 e 32 bits)
Movimentos CondicionaisCMOVA, CMOVAE, CMOVB, CMOVBE, CMOVE, CMOVG, CMOVGE, CMOVL, CMOVLE, CMOVNE, CMOVNO, CMOVNP, CMOVNS, CMOVO, CMOVP, CMOVS
Operações com BitsBT, BTC, BTR, BTS
Varredura/Contagem de BitsBSF, BSR, POPCNT, LZCNT, TZCNT, BSWAP
Operações com StringsMOVSB/W/D/Q, CMPSB/W/D/Q, LODSB/W/D/Q, STOSB/W/D/Q, SCASB/W/D/Q (com prefixos REP/REPE/REPNE)
SistemaSYSCALL, SYSENTER, SYSEXIT, INT, INT3, IRET/D/Q, CLI, STI, HLT, CPUID, RDTSC, RDTSCP
DiversosNOP, UD2
FerramentaFinalidadeInstalação
uvGerenciador de pacotes/projetos Pythoncurl -LsSf https://astral.sh/uv/install.sh | sh
quomAmalgamação de cabeçalho únicouv tool install quom
CMake 3.19+Sistema de buildcmake.org
Compilador C++20GCC 11+, Clang 14+, MSVC 2022+-