mirror of
https://github.com/alfishe/amiga-bootcamp.git
synced 2026-06-13 00:26:28 +00:00
docs(amiga): complete AmigaOS 3.1/3.2 developer reference — 172 files across 17 sections
Comprehensive technical documentation covering: - Hardware: OCS/ECS/AGA custom chip registers, Copper & Blitter deep dives - Boot sequence: cold boot through startup-sequence - Binary format: HUNK executable spec, relocation, debug info - Linking & ABI: .fd files, LVO tables, register calling conventions - Exec kernel: tasks, interrupts, memory, signals, semaphores - AmigaDOS: file I/O, FFS/OFS layout, CLI/Shell scripting - Graphics: planar bitmaps, Copper programming, HAM/EHB modes - Intuition: screens, windows, IDCMP, BOOPSI - Devices: trackdisk, SCSI, serial, timer, audio, keyboard - Libraries: utility, expansion, IFFParse, locale, ARexx - Networking: bsdsocket API, SANA-II, TCP/IP stack comparison - Toolchain: GCC, vasm/vlink, SAS/C, NDK, debugging - Reverse engineering: IDA/Ghidra setup, compiler fingerprints, case studies - CPU & MMU: 68040/060 emulation libs, PMMU, cache management - Driver development: SANA-II, Picasso96/RTG, AHI audio All files include breadcrumb navigation. No local paths or proprietary content.
This commit is contained in:
parent
f07a368bf1
commit
21751c0025
172 changed files with 19701 additions and 0 deletions
137
05_reversing/static/struct_recovery.md
Normal file
137
05_reversing/static/struct_recovery.md
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
[← Home](../../README.md) · [Reverse Engineering](../README.md)
|
||||
|
||||
# Recovering Data Structures
|
||||
|
||||
## Overview
|
||||
|
||||
Amiga executables use OS structures extensively — `ExecBase`, `Node`, `Process`, `IORequest`, etc. This document describes how to recover and annotate these structures in disassembly by matching field access patterns against NDK39 header offsets.
|
||||
|
||||
---
|
||||
|
||||
## The MOVE.L offset(An),Dm Pattern
|
||||
|
||||
Structure field accesses appear as:
|
||||
|
||||
```asm
|
||||
MOVEA.L _DOSBase, A6
|
||||
MOVE.L ($17A,A6), A0 ; SysBase->LibList at offset +0x17A
|
||||
MOVE.L (A0), A1 ; lh_Head
|
||||
```
|
||||
|
||||
The key is the **base register** and **constant offset**. Match the offset against known structure definitions.
|
||||
|
||||
---
|
||||
|
||||
## Common Structures and Key Offsets
|
||||
|
||||
### `struct ExecBase` (at absolute address `$4`)
|
||||
|
||||
| Offset | Field | Type |
|
||||
|---|---|---|
|
||||
| +0 | `LibNode` | `struct Library` |
|
||||
| +0x128 | `TaskReady` | `struct List` |
|
||||
| +0x132 | `TaskWait` | `struct List` |
|
||||
| +0x17A | `LibList` | `struct List` |
|
||||
| +0x182 | `DeviceList` | `struct List` |
|
||||
| +0x21E | `ChipRevBits0` | `UWORD` |
|
||||
| +0x280 | `MemList` | `struct List` |
|
||||
|
||||
### `struct Node` (8 bytes)
|
||||
|
||||
| Offset | Field |
|
||||
|---|---|
|
||||
| +0 | `ln_Succ` (next node) |
|
||||
| +4 | `ln_Pred` (prev node) |
|
||||
| +8 | `ln_Type` (UBYTE) |
|
||||
| +9 | `ln_Pri` (BYTE priority) |
|
||||
| +10 | `ln_Name` (STRPTR) |
|
||||
|
||||
List traversal:
|
||||
```asm
|
||||
MOVEA.L lh_Head, A0 ; first node
|
||||
.loop:
|
||||
TST.L (A0) ; ln_Succ == NULL?
|
||||
BEQ.S .done
|
||||
; process node at A0
|
||||
MOVEA.L (A0), A0 ; A0 = ln_Succ
|
||||
BRA.S .loop
|
||||
```
|
||||
|
||||
### `struct Process` (extends `struct Task`)
|
||||
|
||||
| Offset | Field |
|
||||
|---|---|
|
||||
| +0 | `pr_Task` (struct Task) |
|
||||
| +92 | `pr_MsgPort` |
|
||||
| +128 | `pr_CLI` (BPTR, non-NULL if CLI) |
|
||||
| +172 | `pr_SegList` (BPTR to segment list) |
|
||||
|
||||
Detection in disassembly:
|
||||
```asm
|
||||
MOVE.L ($80,A4), D0 ; pr_CLI at offset +0x80
|
||||
BEQ.S .wb_launch ; NULL = Workbench
|
||||
```
|
||||
|
||||
### `struct IORequest` / `struct IOStdReq`
|
||||
|
||||
| Offset | Field |
|
||||
|---|---|
|
||||
| +0 | `io_Message` (struct Message) |
|
||||
| +20 | `io_Device` |
|
||||
| +24 | `io_Unit` |
|
||||
| +28 | `io_Command` (UWORD) |
|
||||
| +30 | `io_Flags` (UBYTE) |
|
||||
| +32 | `io_Error` (BYTE) |
|
||||
| +36 | `io_Length` (ULONG) |
|
||||
| +40 | `io_Actual` (ULONG) |
|
||||
| +44 | `io_Data` (APTR) |
|
||||
| +48 | `io_Offset` (ULONG) |
|
||||
|
||||
---
|
||||
|
||||
## Annotating Structures in IDA Pro
|
||||
|
||||
### Define a structure type:
|
||||
|
||||
1. `View → Open Subviews → Local Types` → `Insert` → paste C struct definition
|
||||
2. IDA parses the struct and creates a type entry
|
||||
3. Navigate to the base register in disassembly
|
||||
4. Press `T` (structure offset) on any `offset(An)` operand
|
||||
5. Select the struct type → all accesses auto-annotated
|
||||
|
||||
### Import NDK39 headers:
|
||||
|
||||
Use `File → Load file → Parse C header file` → select `exec/execbase.h`, `exec/tasks.h`, etc. from NDK39.
|
||||
|
||||
---
|
||||
|
||||
## Exec Node Traversal Loops
|
||||
|
||||
A recurring pattern: walking the `LibList` or `DeviceList`:
|
||||
|
||||
```asm
|
||||
; Annotated after struct recovery:
|
||||
MOVEA.L SysBase, A6
|
||||
LEA (LibList,A6), A0 ; &SysBase->LibList
|
||||
MOVEA.L (lh_Head,A0), A1 ; first lib node
|
||||
.scan:
|
||||
MOVEA.L (ln_Succ,A1), A2 ; peek next
|
||||
TST.L A2
|
||||
BEQ.S .not_found
|
||||
; compare ln_Name string
|
||||
MOVEA.L (ln_Name,A1), A0
|
||||
JSR ___strcmp
|
||||
TST.L D0
|
||||
BEQ.S .found
|
||||
MOVEA.L A2, A1
|
||||
BRA.S .scan
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `exec/execbase.h`, `exec/tasks.h`, `exec/nodes.h`, `exec/io.h`
|
||||
- `06_exec_os/exec_base.md` — full ExecBase field listing
|
||||
- `06_exec_os/lists_nodes.md` — MinList/List traversal
|
||||
- IDA Pro: Structure subview, Local Types, T hotkey for struct offset
|
||||
Loading…
Add table
Add a link
Reference in a new issue