Hopper Disassembler
Hopper Disassemblerはディスアセンブリ、デコンパイル、制御フローグラフ、スクリプティング機能を提供するmacOSおよびLinux用リバースエンジニアリングツールです。Mach-O、ELF、PE形式のx86、x86_64、ARM、ARM64バイナリをサポートします。
インストール
# macOS - download from hopperapp.com or use Homebrew Cask
brew install --cask hopper-disassembler
# Linux - download .deb or .rpm from hopperapp.com
# Debian/Ubuntu
sudo dpkg -i hopper-v4-*.deb
sudo apt-get install -f
# Launch from command line
Hopper # macOS
hopperv4 # Linux
# Open a binary directly
hopperv4 -e /usr/bin/ls
UI Navigation
Main Views
View shortcuts:
Ctrl+1 Assembly / Disassembly view
Ctrl+2 Hex view
Ctrl+3 Control Flow Graph (CFG)
Ctrl+4 Pseudo-code / Decompiler view
Navigation:
G Go to address or label
N Rename current label/function
; Add comment at current address
Tab Switch between hex and assembly
Space Toggle between linear and graph view
Esc Navigate back
Searching
# Search for strings in the binary
Edit > Find > Search for Strings (Cmd+Shift+F / Ctrl+Shift+F)
# Search for a specific byte pattern
Edit > Find > Search Hex (Cmd+F / Ctrl+F)
Enter hex bytes: 48 8B 05 ?? ?? ?? ??
# Search for an address
Press 'G' and enter: 0x100001234
# Find references to current address
Right-click > References to this address (Ctrl+X)
Disassembly View
# Reading the disassembly
# Address Bytes Instruction
# 100001234: 55 push rbp
# 100001235: 48 89 e5 mov rbp, rsp
# 100001238: 48 83 ec 10 sub rsp, 0x10
# Label functions
Select address > Press 'N' > Enter function name
# Mark data types
Select address > Right-click > Mark as:
- Procedure (P)
- Data (D)
- ASCII String (A)
- Code (C)
- Undefined (U)
Hex View
# Navigate hex view
Ctrl+2 Switch to hex view
Ctrl+G Go to offset
Ctrl+F Find hex pattern
# Edit bytes (requires license)
Select bytes > Right-click > Modify > Assemble Instruction
# Or edit hex directly in hex view
Strings Analysis
# View all strings
Navigate > Strings panel (left sidebar)
# Filter strings
Type in filter box at top of strings panel
# Jump to string reference
Double-click string > shows cross-references
Click reference to jump to code using that string
Cross-References (Xrefs)
# Find all references to a function or address
Right-click on label > References to
Keyboard: Ctrl+X (or Cmd+X on macOS)
# Reference types shown:
# CALL - direct function call
# DATA - data reference (pointer, string)
# JUMP - branch/jump target
# Find what this function calls
Right-click > References from
Procedures and Functions
# List all detected procedures
Navigate > Procedures panel (left sidebar)
# Create a new procedure at cursor
Select address > Modify > Mark as Procedure (P)
# Define procedure boundaries
Right-click > Modify > Set Procedure Boundaries
# View procedure info
Right-click > Procedure Info
# Shows: entry point, size, stack frame, local variables
Control Flow Graph
# View CFG for current function
Ctrl+3 or Space (in disassembly view)
# CFG features:
# - Color-coded blocks (green=taken branch, red=not taken)
# - Zoom in/out with scroll wheel
# - Drag to pan
# - Double-click block to jump to it in disassembly
# Export CFG as image
File > Export CFG as PNG/SVG
Decompiler (Pseudo-code)
# View decompiled pseudo-code
Ctrl+4 or select Pseudo-code tab
# The decompiler generates C-like output:
# int _main(int arg0, char** arg1) {
# var_10 = arg0;
# rax = printf("Hello %s\n", *(arg1 + 0x8));
# return 0;
# }
# Rename variables in decompiler view
Click variable > Press 'N' > Enter meaningful name
# Change variable types
Right-click variable > Set Type
Scripting API (Python)
# Hopper Python scripting (run via Script > Run Script)
# Get the current document
doc = Document
# Get a segment by name
segment = doc.getSegmentByName("__TEXT")
# Iterate over all procedures
for i in range(doc.getProcedureCount()):
proc = doc.getProcedureAtIndex(i)
entry = proc.getEntryPoint()
name = doc.getNameAtAddress(entry)
print(f"0x{entry:x}: {name}")
# Read bytes at address
addr = 0x100001234
byte = doc.readByte(addr)
word = doc.readUInt16LE(addr)
dword = doc.readUInt32LE(addr)
# Set a comment
doc.setCommentAtAddress(0x100001234, "Decryption routine starts here")
# Rename a label
doc.setNameAtAddress(0x100001234, "decrypt_config")
# Get cross-references
refs = doc.getReferencesOfAddress(0x100001234)
for ref in refs:
print(f"Referenced from: 0x{ref:x}")
Scripting API (JavaScript)
// Hopper JavaScript scripting
// Get current document
var doc = Document;
// Iterate through segments
for (var i = 0; i < doc.getSegmentCount(); i++) {
var seg = doc.getSegmentAtIndex(i);
var name = seg.getName();
var start = seg.getStartingAddress();
var size = seg.getLength();
log(name + " @ 0x" + start.toString(16) + " size: " + size);
}
// Find and rename functions matching a pattern
for (var i = 0; i < doc.getProcedureCount(); i++) {
var proc = doc.getProcedureAtIndex(i);
var entry = proc.getEntryPoint();
var name = doc.getNameAtAddress(entry);
if (name.indexOf("sub_") === 0) {
log("Unnamed function at 0x" + entry.toString(16));
}
}
GDB Integration
# Connect Hopper to a GDB remote session
# 1. Start GDB server on target
gdbserver :1234 ./target_binary
# 2. In Hopper: Debug > Connect to Remote GDB Server
# Enter: host:1234
# 3. Set breakpoints in Hopper
# Click the margin next to an instruction
# Or: Debug > Toggle Breakpoint (F2)
# 4. Debug controls
# F5 Continue
# F6 Step Over
# F7 Step Into
# F8 Step Out
File Format Support
Supported formats:
- Mach-O (macOS/iOS binaries, dylibs, frameworks)
- ELF (Linux binaries, shared objects)
- PE/COFF (Windows executables, DLLs)
- Raw binary files
Supported architectures:
- x86 (32-bit)
- x86_64 (64-bit)
- ARM (32-bit)
- ARM64 / AArch64
# Open raw binary with architecture hint
File > Open > Select file > Choose architecture and base address
Exporting
# Export disassembly as text
File > Produce > Assembly File
# Export modified binary (patching)
File > Produce > Executable
# Saves patched binary with your modifications
# Export pseudo-code
File > Produce > Pseudo-code File
# Save Hopper project
File > Save (preserves all labels, comments, types)
# Saves as .hop file