Binary Analysis Patterns
Seth HobsonCommunityCreated by Dávid BalatoniDistributed by Seth Hobson
- Skill
- Guidelines
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
Binary Analysis Patterns provides a structured guide to reverse-engineering compiled executables. It covers fundamental assembly idioms, calling conventions across x86-64 and ARM architectures, and common compiler-generated patterns. The skill serves as a reference for recognizing high-level program logic—such as loops, switch statements, and data structure access—within disassembled or decompiled code, while offering practical tips for using tools like Ghidra and IDA Pro.
What it does
- Explains common assembly patterns for control flow, including loops and conditional branches.
- Details data structure recovery for arrays, structs, and linked lists.
- Provides reference material for function prologues, epilogues, and calling conventions.
- Offers guidance on identifying compiler-introduced artifacts and optimization patterns.
- Includes snippets for automating analysis tasks in Ghidra and IDA Pro.
- Outlines a systematic workflow for triaging and analyzing unknown binaries.
When to use it
- When reverse-engineering an unknown executable to determine its functionality.
- When analyzing malware or obfuscated code to understand its internal logic.
- When you need to identify specific assembly idioms or compiler-generated code structures.
- When performing static analysis on binaries using tools like Ghidra, IDA Pro, or Binary Ninja.
Advantages
- Accelerates the process of mapping assembly instructions to high-level source code logic.
- Provides clear, architecture-specific examples for x86-64 and ARM.
- Reduces time spent manually identifying standard function signatures and data structures.
- Offers actionable scripts for automating repetitive analysis tasks.
Usage examples
- “How do I identify a switch statement in assembly code?”
- The skill explains how to recognize jump tables and sequential comparison patterns, providing assembly examples for both.
- “What is the standard function prologue for an x86-64 function?”
- It provides the standard push rbp, mov rbp, rsp sequence and explains how it sets up the stack frame.
- “How can I automate finding dangerous function calls in Ghidra?”
- It provides a Python script example using the Ghidra API to iterate through functions and identify calls to functions like strcpy or sprintf.
- “How do I recognize a linked list traversal in assembly?”
- It shows the assembly pattern for checking a null pointer and looping through memory offsets to access the next node.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/wshobson/binary-analysis-patterns/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip binary-analysis-patterns.zip -d .agents/skills
Documentation by Dávid Balatoni
Binary Analysis Patterns
Comprehensive patterns and techniques for analyzing compiled binaries, understanding assembly code, and reconstructing program logic.
When to Use This Skill
Reverse-engineering an unknown executable to understand its behavior
Analyzing malware or obfuscated binaries with Ghidra / IDA Pro / Binary Ninja
Recognizing common assembly idioms (function prologues, switch tables, vtable dispatch)
Reconstructing high-level control flow from compiled code
Identifying compiler-introduced patterns (stack canaries, PIC trampolines)
Detailed section: Disassembly Fundamentals
Originally a 2047-byte section in this SKILL.md. Moved to references/details.md to fit Codex's 8 KB skill body cap.
Control Flow Patterns
Conditional Branches
; if (a == b)
cmp eax, ebx
jne skip_block
; ... if body ...
skip_block:
; if (a < b) - signed
cmp eax, ebx
jge skip_block ; Jump if greater or equal
; ... if body ...
skip_block:
; if (a < b) - unsigned
cmp eax, ebx
jae skip_block ; Jump if above or equal
; ... if body ...
skip_block:Loop Patterns
; for (int i = 0; i < n; i++)
xor ecx, ecx ; i = 0
loop_start:
cmp ecx, [n] ; i < n
jge loop_end
; ... loop body ...
inc ecx ; i++
jmp loop_start
loop_end:
; while (condition)
jmp loop_check
loop_body:
; ... body ...
loop_check:
cmp eax, ebx
jl loop_body
; do-while
loop_body:
; ... body ...
cmp eax, ebx
jl loop_bodySwitch Statement Patterns
; Jump table pattern
mov eax, [switch_var]
cmp eax, max_case
ja default_case
jmp [jump_table + eax*8]
; Sequential comparison (small switch)
cmp eax, 1
je case_1
cmp eax, 2
je case_2
cmp eax, 3
je case_3
jmp default_caseData Structure Patterns
Array Access
; array[i] - 4-byte elements
mov eax, [rbx + rcx*4] ; rbx=base, rcx=index
; array[i] - 8-byte elements
mov rax, [rbx + rcx*8]
; Multi-dimensional array[i][j]
; arr[i][j] = base + (i * cols + j) * element_size
imul eax, [cols]
add eax, [j]
mov edx, [rbx + rax*4]Structure Access
struct Example {
int a; // offset 0
char b; // offset 4
// padding // offset 5-7
long c; // offset 8
short d; // offset 16
};; Accessing struct fields
mov rdi, [struct_ptr]
mov eax, [rdi] ; s->a (offset 0)
movzx eax, byte [rdi+4] ; s->b (offset 4)
mov rax, [rdi+8] ; s->c (offset 8)
movzx eax, word [rdi+16] ; s->d (offset 16)Linked List Traversal
; while (node != NULL)
list_loop:
test rdi, rdi ; node == NULL?
jz list_done
; ... process node ...
mov rdi, [rdi+8] ; node = node->next (assuming next at offset 8)
jmp list_loop
list_done:Common Code Patterns
String Operations
; strlen pattern
xor ecx, ecx
strlen_loop:
cmp byte [rdi + rcx], 0
je strlen_done
inc ecx
jmp strlen_loop
strlen_done:
; ecx contains length
; strcpy pattern
strcpy_loop:
mov al, [rsi]
mov [rdi], al
test al, al
jz strcpy_done
inc rsi
inc rdi
jmp strcpy_loop
strcpy_done:
; memcpy using rep movsb
mov rdi, dest
mov rsi, src
mov rcx, count
rep movsbArithmetic Patterns
; Multiplication by constant
; x * 3
lea eax, [rax + rax*2]
; x * 5
lea eax, [rax + rax*4]
; x * 10
lea eax, [rax + rax*4] ; x * 5
add eax, eax ; * 2
; Division by power of 2 (signed)
mov eax, [x]
cdq ; Sign extend to EDX:EAX
and edx, 7 ; For divide by 8
add eax, edx ; Adjust for negative
sar eax, 3 ; Arithmetic shift right
; Modulo power of 2
and eax, 7 ; x % 8Bit Manipulation
; Test specific bit
test eax, 0x80 ; Test bit 7
jnz bit_set
; Set bit
or eax, 0x10 ; Set bit 4
; Clear bit
and eax, ~0x10 ; Clear bit 4
; Toggle bit
xor eax, 0x10 ; Toggle bit 4
; Count leading zeros
bsr eax, ecx ; Bit scan reverse
xor eax, 31 ; Convert to leading zeros
; Population count (popcnt)
popcnt eax, ecx ; Count set bitsDecompilation Patterns
Variable Recovery
; Local variable at rbp-8
mov qword [rbp-8], rax ; Store to local
mov rax, [rbp-8] ; Load from local
; Stack-allocated array
lea rax, [rbp-0x40] ; Array starts at rbp-0x40
mov [rax], edx ; array[0] = value
mov [rax+4], ecx ; array[1] = valueFunction Signature Recovery
; Identify parameters by register usage
func:
; rdi used as first param (System V)
mov [rbp-8], rdi ; Save param to local
; rsi used as second param
mov [rbp-16], rsi
; Identify return by RAX at end
mov rax, [result]
retType Recovery
; 1-byte operations suggest char/bool
movzx eax, byte [rdi] ; Zero-extend byte
movsx eax, byte [rdi] ; Sign-extend byte
; 2-byte operations suggest short
movzx eax, word [rdi]
movsx eax, word [rdi]
; 4-byte operations suggest int/float
mov eax, [rdi]
movss xmm0, [rdi] ; Float
; 8-byte operations suggest long/double/pointer
mov rax, [rdi]
movsd xmm0, [rdi] ; DoubleGhidra Analysis Tips
Improving Decompilation
// In Ghidra scripting
// Fix function signature
Function func = getFunctionAt(toAddr(0x401000));
func.setReturnType(IntegerDataType.dataType, SourceType.USER_DEFINED);
// Create structure type
StructureDataType struct = new StructureDataType("MyStruct", 0);
struct.add(IntegerDataType.dataType, "field_a", null);
struct.add(PointerDataType.dataType, "next", null);
// Apply to memory
createData(toAddr(0x601000), struct);Pattern Matching Scripts
# Find all calls to dangerous functions
for func in currentProgram.getFunctionManager().getFunctions(True):
for ref in getReferencesTo(func.getEntryPoint()):
if func.getName() in ["strcpy", "sprintf", "gets"]:
print(f"Dangerous call at {ref.getFromAddress()}")IDA Pro Patterns
IDAPython Analysis
import idaapi
import idautils
import idc
# Find all function calls
def find_calls(func_name):
for func_ea in idautils.Functions():
for head in idautils.Heads(func_ea, idc.find_func_end(func_ea)):
if idc.print_insn_mnem(head) == "call":
target = idc.get_operand_value(head, 0)
if idc.get_func_name(target) == func_name:
print(f"Call to {func_name} at {hex(head)}")
# Rename functions based on strings
def auto_rename():
for s in idautils.Strings():
for xref in idautils.XrefsTo(s.ea):
func = idaapi.get_func(xref.frm)
if func and "sub_" in idc.get_func_name(func.start_ea):
# Use string as hint for naming
passBest Practices
Analysis Workflow
Initial triage: File type, architecture, imports/exports
String analysis: Identify interesting strings, error messages
Function identification: Entry points, exports, cross-references
Control flow mapping: Understand program structure
Data structure recovery: Identify structs, arrays, globals
Algorithm identification: Crypto, hashing, compression
Documentation: Comments, renamed symbols, type definitions
Common Pitfalls
Optimizer artifacts: Code may not match source structure
Inline functions: Functions may be expanded inline
Tail call optimization:
jmpinstead ofcall+retDead code: Unreachable code from optimization
Position-independent code: RIP-relative addressing
Files
- ATTRIBUTION.mdAdded by AutoGineer901 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md7.7 KiB
- references/details.md2.0 KiB
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Python, Needs Node.js
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Dávid Balatoni
- Publisher
- Seth Hobson (Community)
- Distributed by
- Seth Hobson
- Source
- wshobson/agents · plugins/reverse-engineering/skills/binary-analysis-patterns · commit 4bde316
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Dávid Balatoni or Seth Hobson.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download binary-analysis-patterns.zip