Remove legacy BlackMagic specs
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
# non-blocking-execute Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change inject-and-assemble. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: InjectAndExecuteEx creates remote thread without waiting
|
||||
|
||||
`BlackMagic.InjectAndExecuteEx(IntPtr startAddress, IntPtr parameter)` injects code at `startAddress` into the opened process, creates a remote thread with `parameter`, and returns the thread handle immediately without waiting for the thread to exit.
|
||||
|
||||
#### Scenario: successful non-blocking execution
|
||||
- **WHEN** a process is open and `InjectAndExecuteEx(addr, param)` is called with a valid code address
|
||||
- **THEN** a remote thread is created in the target process and a valid `SafeMemoryHandle` is returned
|
||||
|
||||
#### Scenario: no process open
|
||||
- **WHEN** no process is open and `InjectAndExecuteEx(addr, param)` is called
|
||||
- **THEN** `null` is returned
|
||||
|
||||
### Requirement: InjectAndExecuteEx single-parameter overload
|
||||
|
||||
`BlackMagic.InjectAndExecuteEx(IntPtr startAddress)` calls `InjectAndExecuteEx(startAddress, IntPtr.Zero)`.
|
||||
|
||||
#### Scenario: parameter-less non-blocking execution
|
||||
- **WHEN** `InjectAndExecuteEx(addr)` is called with a valid address
|
||||
- **THEN** the thread is created with parameter `IntPtr.Zero`
|
||||
|
||||
### Requirement: InjectAndExecuteEx from assembly text
|
||||
|
||||
`BlackMagic.InjectAndExecuteEx(string asm)` assembles the text via `AsmBuilder`, allocates remote memory, writes the bytes, calls `InjectAndExecuteEx` on the allocated address, and returns the thread handle.
|
||||
|
||||
#### Scenario: execute assembly text non-blocking
|
||||
- **WHEN** `InjectAndExecuteEx("nop")` is called with a process open
|
||||
- **THEN** the text is assembled to bytes, written to remote memory, a thread is started, and the handle is returned
|
||||
|
||||
#### Scenario: assembly failure
|
||||
- **WHEN** `InjectAndExecuteEx("invalidinstruction")` is called
|
||||
- **THEN** `ArgumentException` is thrown with the assembly error
|
||||
|
||||
### Requirement: InjectAndExecute from assembly text (blocking convenience)
|
||||
|
||||
`BlackMagic.InjectAndExecute(string asm)` assembles the text, allocates remote memory, writes the bytes, calls `Execute` (blocking, 10s timeout), and returns the exit code.
|
||||
|
||||
#### Scenario: execute assembly text blocking
|
||||
- **WHEN** `InjectAndExecute("mov eax, 42\nret")` is called with a process open
|
||||
- **THEN** the text is assembled, injected, executed, and the thread exit code is returned
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
# text-assembler Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change inject-and-assemble. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: AsmBuilder assembles x86 instruction text to byte array
|
||||
|
||||
`AsmBuilder.Assemble(string source)` parses x86 assembly text and returns the corresponding `byte[]` machine code.
|
||||
|
||||
#### Scenario: single instruction
|
||||
- **WHEN** `AsmBuilder.Assemble("nop")` is called
|
||||
- **THEN** the result is `[0x90]`
|
||||
|
||||
#### Scenario: multiple instructions
|
||||
- **WHEN** `AsmBuilder.Assemble("pushad\npopad")` is called
|
||||
- **THEN** the result is `[0x60, 0x61]`
|
||||
|
||||
#### Scenario: instruction with immediate operand
|
||||
- **WHEN** `AsmBuilder.Assemble("mov eax, 1")` is called
|
||||
- **THEN** the result is `[0xB8, 0x01, 0x00, 0x00, 0x00]`
|
||||
|
||||
### Requirement: AsmBuilder supports register operands
|
||||
|
||||
Supported registers: `eax`, `ecx`, `edx`, `ebx`, `esp`, `ebp`, `esi`, `edi` (and 8-bit: `al`, `cl`, `dl`, `bl`, `ah`, `ch`, `dh`, `bh`).
|
||||
|
||||
#### Scenario: register-to-register move
|
||||
- **WHEN** `AsmBuilder.Assemble("mov eax, ecx")` is called
|
||||
- **THEN** the result is `[0x89, 0xC8]` (mov eax, ecx encoding)
|
||||
|
||||
#### Scenario: register encoding
|
||||
- **WHEN** registers are used in instructions
|
||||
- **THEN** each register maps to its correct 3-bit encoding (eax=0, ecx=1, edx=2, ebx=3, esp=4, ebp=5, esi=6, edi=7)
|
||||
|
||||
### Requirement: AsmBuilder supports labels and jumps
|
||||
|
||||
Labels are defined with `@name:` and referenced with `jmp @name` or `je @name`. Forward and backward references are resolved in a second pass.
|
||||
|
||||
#### Scenario: forward jump
|
||||
- **WHEN** `AsmBuilder.Assemble("jmp @skip\nnop\n@skip:\nret")` is called
|
||||
- **THEN** the jump skips exactly over the `nop` (2 bytes) and lands on `ret`
|
||||
|
||||
#### Scenario: backward jump
|
||||
- **WHEN** `AsmBuilder.Assemble("@loop:\nnop\njmp @loop")` is called
|
||||
- **THEN** the jump targets the earlier label correctly
|
||||
|
||||
#### Scenario: multiple labels
|
||||
- **WHEN** multiple labels are used in one source
|
||||
- **THEN** each label resolves to its correct byte offset
|
||||
|
||||
### Requirement: AsmBuilder SetPassLimit controls iteration
|
||||
|
||||
`AsmBuilder.SetPassLimit(int limit)` sets the maximum number of assembly passes for label resolution. Default is 10. If the limit is exceeded before all labels resolve, `InvalidOperationException` is thrown.
|
||||
|
||||
#### Scenario: default pass limit
|
||||
- **WHEN** no `SetPassLimit` is called
|
||||
- **THEN** the assembler uses 10 passes maximum
|
||||
|
||||
#### Scenario: custom pass limit
|
||||
- **WHEN** `SetPassLimit(20)` is called
|
||||
- **THEN** the assembler uses 20 passes maximum
|
||||
|
||||
#### Scenario: pass limit exceeded
|
||||
- **WHEN** forward references cannot resolve within the pass limit
|
||||
- **THEN** `InvalidOperationException` is thrown with label resolution details
|
||||
|
||||
### Requirement: AsmBuilder reports clear errors
|
||||
|
||||
Unknown instructions, missing operands, and invalid register names produce `ArgumentException` with the line number and offending text.
|
||||
|
||||
#### Scenario: unknown instruction
|
||||
- **WHEN** `AsmBuilder.Assemble("xyzw")` is called
|
||||
- **THEN** `ArgumentException` is thrown mentioning line 1 and "xyzw"
|
||||
|
||||
#### Scenario: missing operand
|
||||
- **WHEN** `AsmBuilder.Assemble("mov")` is called (no operands)
|
||||
- **THEN** `ArgumentException` is thrown mentioning missing operand
|
||||
|
||||
### Requirement: AsmBuilder supported instruction set
|
||||
|
||||
The following x86 instructions are supported:
|
||||
- **Data movement**: `mov`, `push`, `pop`, `pushad`, `popad`, `lea`
|
||||
- **Arithmetic**: `add`, `sub`, `inc`, `dec`, `xor`, `and`, `or`, `cmp`, `test`
|
||||
- **Control flow**: `jmp`, `je`, `jne`, `call`, `ret`, `nop`, `hlt`
|
||||
|
||||
#### Scenario: all instructions produce valid bytes
|
||||
- **WHEN** each supported instruction is assembled individually
|
||||
- **THEN** it produces the correct x86 machine code encoding
|
||||
|
||||
Reference in New Issue
Block a user