Add IDA-style asm display mode

This commit is contained in:
√(noham)²
2026-03-03 20:43:02 +01:00
parent 85e8e09249
commit 5e3598d8c4
3 changed files with 92 additions and 11 deletions

View File

@@ -5,10 +5,11 @@ A Hugo shortcode for displaying assembly code blocks with syntax highlighting, h
## Features ## Features
- **Syntax highlighting** for x86 (NASM) and ARM assembly - **Syntax highlighting** for x86 (NASM) and ARM assembly
- **Three display modes:** - **Four display modes:**
- `raw` - Assembly with syntax highlighting only - `raw` - Assembly with syntax highlighting only
- `hex` - Hex bytes + assembly instruction - `hex` - Hex bytes + assembly instruction
- `full` - Address + hex bytes + assembly instruction - `full` - Address + hex bytes + assembly instruction
- `ida` - IDA-style section:address + assembly instruction
- **Capitalization option** for hex bytes and addresses - **Capitalization option** for hex bytes and addresses
- **Dark/light mode** compatible - **Dark/light mode** compatible
@@ -70,11 +71,21 @@ syscall
{{</* /asm */>}} {{</* /asm */>}}
``` ```
### IDA Mode (IDA-style section:address + instruction)
```go-html-template
{{</* asm mode="ida" arch="x86" */>}}
__text:000000010045C182 | mov rdi, [rbp+var_88]
__text:000000010045C189 | call _RuntimeUnlockString
__text:000000010045C18E | mov [rbp+var_88], 0
{{</* /asm */>}}
```
### Parameters ### Parameters
| Parameter | Default | Description | | Parameter | Default | Description |
|--------------|---------|--------------------------------------------------| |--------------|---------|--------------------------------------------------|
| `mode` | `raw` | Display mode: `raw`, `hex`, or `full` | | `mode` | `raw` | Display mode: `raw`, `hex`, `full`, or `ida` |
| `arch` | `x86` | Architecture: `x86` or `arm` | | `arch` | `x86` | Architecture: `x86` or `arm` |
| `capitalize` | `false` | Uppercase hex bytes and addresses when `true` | | `capitalize` | `false` | Uppercase hex bytes and addresses when `true` |

View File

@@ -9,14 +9,16 @@
} }
.asm-hex, .asm-hex,
.asm-full { .asm-full,
.asm-ida {
position: relative; position: relative;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
line-height: 1.6; line-height: 1.6;
} }
.asm-hex pre, .asm-hex pre,
.asm-full pre { .asm-full pre,
.asm-ida pre {
margin: 0; margin: 0;
padding: 1em; padding: 1em;
overflow-x: auto; overflow-x: auto;
@@ -25,7 +27,8 @@
} }
.asm-hex code, .asm-hex code,
.asm-full code { .asm-full code,
.asm-ida code {
display: block; display: block;
background: transparent; background: transparent;
color: inherit; color: inherit;
@@ -56,7 +59,7 @@
color: #569cd6; color: #569cd6;
margin-right: 1.5em; margin-right: 1.5em;
display: inline-block; display: inline-block;
min-width: 20ch; min-width: 15ch;
font-weight: 500; font-weight: 500;
} }
@@ -65,14 +68,31 @@
color: #ce9178; color: #ce9178;
} }
/* IDA-style address styling */
.ida-address {
color: #858585;
margin-right: 0.5em;
display: inline-block;
min-width: 25ch;
user-select: none;
}
.ida-separator {
color: #666;
margin-right: 1em;
user-select: none;
}
/* Ensure highlighted code displays inline */ /* Ensure highlighted code displays inline */
.asm-hex .line, .asm-hex .line,
.asm-full .line { .asm-full .line,
.asm-ida .line {
display: inline; display: inline;
} }
.asm-hex .cl, .asm-hex .cl,
.asm-full .cl { .asm-full .cl,
.asm-ida .cl {
display: inline; display: inline;
} }
@@ -83,15 +103,25 @@
/* Dark mode compatibility */ /* Dark mode compatibility */
.dark .asm-hex pre, .dark .asm-hex pre,
.dark .asm-full pre { .dark .asm-full pre,
.dark .asm-ida pre {
background: var(--hljs-bg) !important; background: var(--hljs-bg) !important;
color: var(--content); color: var(--content);
} }
.dark .ida-address {
color: #858585;
}
.dark .ida-separator {
color: #666;
}
/* Light mode */ /* Light mode */
@media (prefers-color-scheme: light) { @media (prefers-color-scheme: light) {
body:not(.dark) .asm-hex pre, body:not(.dark) .asm-hex pre,
body:not(.dark) .asm-full pre { body:not(.dark) .asm-full pre,
body:not(.dark) .asm-ida pre {
background: var(--hljs-bg) !important; background: var(--hljs-bg) !important;
color: var(--content); color: var(--content);
} }
@@ -107,4 +137,12 @@
body:not(.dark) .instruction { body:not(.dark) .instruction {
color: #a31515; color: #a31515;
} }
body:not(.dark) .ida-address {
color: #666;
}
body:not(.dark) .ida-separator {
color: #999;
}
} }

View File

@@ -1,6 +1,6 @@
{{- /* Assembly code block shortcode - supports multiple display modes */ -}} {{- /* Assembly code block shortcode - supports multiple display modes */ -}}
{{- /* Parameters: {{- /* Parameters:
- mode: "raw" (syntax highlighted), "hex" (hex + asm), "full" (addr + hex + asm) - mode: "raw" (syntax highlighted), "hex" (hex + asm), "full" (addr + hex + asm), "ida" (IDA-style addr + asm)
- arch: "x86" or "arm" (default: "x86") - arch: "x86" or "arm" (default: "x86")
- capitalize: "true" to uppercase hex bytes and addresses (default: "false") - capitalize: "true" to uppercase hex bytes and addresses (default: "false")
*/ -}} */ -}}
@@ -86,5 +86,37 @@
</div> </div>
</div> </div>
{{- else if eq $mode "ida" -}}
{{- /* IDA-style: section:address label | instruction (format: SECTION:ADDR label | INSTRUCTION) */ -}}
<div class="highlight">
<div class="asm-ida">
<pre tabindex="0" class="chroma"><code>{{- range split $content "\n" -}}
{{- if . -}}
<span class="asm-line">
{{- $parts := split . "|" -}}
{{- if ge (len $parts) 2 -}}
{{- /* Extract section:address and optional label */ -}}
{{- $addrPart := index $parts 0 | strings.TrimSpace -}}
{{- /* Extract instruction */ -}}
{{- $instruction := index $parts 1 | strings.TrimSpace -}}
{{- /* Optionally capitalize address */ -}}
{{- if eq $capitalize "true" -}}
{{- $addrPart = upper $addrPart -}}
{{- end -}}
{{- /* Apply syntax highlighting to instruction */ -}}
{{- $lang := cond (eq $arch "arm") "armasm" "nasm" -}}
{{- $highlighted := highlight $instruction $lang "" -}}
{{- /* Strip wrapper divs from highlighted output */ -}}
<span class="ida-address">{{ $addrPart }}</span><span class="ida-separator">|</span>{{ $highlighted | replaceRE "<div class=\"highlight\"><pre[^>]*><code[^>]*>" "" | replaceRE "</code></pre></div>" "" | safeHTML }}
{{- else -}}
{{ . }}
{{- end -}}
</span>
{{- end -}}
{{- end -}}</code></pre>
<button class="copy-code">copy</button>
</div>
</div>
{{- end -}} {{- end -}}
</div> </div>