Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
714fee3
feat(22-01): extend bofdefs.h with psapi.h include and NT/PSAPI sections
TGJLS May 16, 2026
ac9626a
feat(22-01): create PS-BOF directory skeleton with Makefile and 6 stu…
TGJLS May 16, 2026
1b08ec7
feat(22-01): wire PS-BOF into root Makefile SUBDIRS
TGJLS May 16, 2026
c382d55
docs(23): capture phase context
TGJLS May 16, 2026
a72026e
docs(state): record phase 23 context session
TGJLS May 16, 2026
28a11dd
docs(23): research phase — core process BOFs
TGJLS May 16, 2026
989529c
docs(23): plan core process BOFs — 3 plans, 2 waves
TGJLS May 16, 2026
222c45f
docs(23): create phase plan
TGJLS May 16, 2026
e72095e
feat(23-01): create adaptix.h and add 10 declarations to bofdefs.h
TGJLS May 16, 2026
4cb6091
feat(23-01): port list.cc to PS-BOF/list/list.c
TGJLS May 16, 2026
c539ff0
docs(23-01): complete adaptix infrastructure and ps list BOF plan
TGJLS May 16, 2026
6dbe391
chore: merge executor worktree (worktree-agent-a2abba6168963fc09)
TGJLS May 16, 2026
439a9c2
feat(23-02): port kill.cc to PS-BOF/kill/kill.c
TGJLS May 16, 2026
6854976
feat(23-03): implement suspend.c and resume.c BOFs from scratch per D-08
TGJLS May 16, 2026
ffbc193
fix(23-01): use KERNEL32\$lstrlenW for runtime wide string length
TGJLS May 16, 2026
a49cb05
refactor(23-01): replace Kharon-specific BeaconPkg* with standard Bea…
TGJLS May 16, 2026
a7cc868
docs(24): capture phase context
TGJLS May 16, 2026
1d83993
docs(state): record phase 24 context session
TGJLS May 16, 2026
578b8ed
docs(24): plan ps-run BOF — 2 plans, research, PPID+pipe DuplicateHan…
TGJLS May 18, 2026
4b7e530
feat(24-01-T01): add 10 process-creation declarations to bofdefs.h
TGJLS May 18, 2026
e19f2c8
docs(24-01): add SUMMARY.md
TGJLS May 18, 2026
74a7fac
docs(24-02): add SUMMARY.md
TGJLS May 18, 2026
89e3df2
docs(25): capture phase context
TGJLS May 20, 2026
fcfd3b3
docs(state): record phase 25 context session
TGJLS May 20, 2026
ae42e9b
feat(25-01-T01): add toolhelp and NtQueryInformationProcess declarati…
TGJLS May 20, 2026
1a6df57
docs(25-01): add SUMMARY.md and mark phase 25 complete in ROADMAP/STATE
TGJLS May 20, 2026
04afe1d
feat(26-01): create PS-BOF/ps.axs with 6 PS-BOF subcommands
TGJLS May 20, 2026
d9f20a7
feat(26-01): wire PS-BOF/ps.axs into bof-collection.axs
TGJLS May 20, 2026
5198cd8
docs(26-01): complete ps.axs and bof-collection.axs wire-up plan
TGJLS May 20, 2026
04ea22e
chore: merge executor worktree (worktree-agent-a68392e33cfbc7e90)
TGJLS May 20, 2026
54a907f
docs(phase-26): update tracking after wave 1
TGJLS May 20, 2026
6589735
docs(phase-26): reconcile PB-02/PB-03 with D-01 — Process Browser han…
TGJLS May 20, 2026
5ef2db9
fix(26-01): CR-01 use explicit undefined check for exit_code; always …
TGJLS May 20, 2026
a65c47d
fix(26-01): CR-02 cap mod_count to buffer capacity in get_modules
TGJLS May 20, 2026
6669f72
fix(26-01): CR-03 rename Isx64 to IsWow64 to match IsWow64Process sem…
TGJLS May 20, 2026
3ef71dc
fix(26-01): WR-01 document addArgBool dash-retention convention for -…
TGJLS May 20, 2026
0ba4268
fix(26-01): WR-02 declare MSVCRT$memset in bofdefs.h; replace bare me…
TGJLS May 20, 2026
4871213
fix(26-01): WR-03 replace NtQuerySystemInformation probe-then-alloc w…
TGJLS May 20, 2026
96584b7
docs(27): create phase plan
TGJLS May 21, 2026
d6ccd39
docs(27-01): create PS-BOF/README.md
TGJLS May 21, 2026
4d67bca
docs(27-01): add PS-BOF section and Kharon credit to root README.md
TGJLS May 21, 2026
dd009c7
chore: merge executor worktree (worktree-agent-afb119bef3bec2de7)
TGJLS May 21, 2026
02f6d81
docs(phase-27): update tracking after wave 1
TGJLS May 21, 2026
4dfd1c1
docs(phase-27): mark phase complete, update STATE.md
TGJLS May 21, 2026
59643c8
fix(27-01): correct ps grep token description — 'elevation type' → 'e…
TGJLS May 21, 2026
63b2d64
fix(27-01): align ps kill usage in root README with PS-BOF/README.md
TGJLS May 21, 2026
96aba77
docs(28): capture phase context
TGJLS May 21, 2026
0d898e2
docs(state): record phase 28 context session
TGJLS May 21, 2026
ae7c1a2
feat(28-02): add PS-BOF task entries to tasks.yaml
TGJLS May 22, 2026
42617db
feat(28-02): add PS-BOF deploy block and reinstall step to test.yaml
TGJLS May 22, 2026
a0be179
docs(28-02): complete BOF-Collection CI integration plan
TGJLS May 22, 2026
b999d2c
docs(28-01): complete Testing-Kit capture feature plan
TGJLS May 22, 2026
0b99ce0
chore: merge executor worktree (worktree-agent-aed12d60e9776ba03)
TGJLS May 22, 2026
a7f6b47
docs(phase-28): update tracking after wave 1
TGJLS May 22, 2026
6eff23d
docs(phase-28): mark phase complete, update STATE.md
TGJLS May 22, 2026
e41c641
fix(28): WR-01/WR-02 fix fragile wildcard assertions in tasks.yaml
TGJLS May 22, 2026
c31ffd5
fix(28): WR-04 pin Testing-Kit install to specific commit SHA
TGJLS May 22, 2026
2786e06
fix(28): register ps commands for kharon/gopher agents; restore trail…
TGJLS May 22, 2026
501aec6
fix(28): fix STARTUPINFOW cb size for non-PPID ps run; use ping for C…
TGJLS May 22, 2026
6af6a59
fix(ps-run): prevent inherited handle leak from long-running child pr…
TGJLS May 22, 2026
2241923
fix(ps-run): move cmd_buf to heap to prevent BOF stack overflow; bump…
TGJLS May 22, 2026
8540472
fix(ps-bof): fix bof_pack types, buffered list output, grep crash and…
TGJLS May 23, 2026
c349f2e
fix(ps-run): move pipe read buffer to heap to avoid ___chkstk_ms
TGJLS May 23, 2026
113a35f
chore: stop tracking .planning/ — already in .gitignore
TGJLS May 23, 2026
7f9987a
docs(ps-run): replace example usage with full flag reference
TGJLS May 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 38 additions & 8 deletions .github/ci/tasks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,7 @@ tasks:

# copy-wildcard-match
- cmdline: "copy C:\\Temp\\fsbof-test\\*.log C:\\Temp\\fsbof-test\\dest\\"
expected: |
C:\Temp\fsbof-test\file1.log
C:\Temp\fsbof-test\file2.log
2 file(s) copied.
expected_regex: "(?s)C:\\\\Temp\\\\fsbof-test\\\\file1\\.log.*C:\\\\Temp\\\\fsbof-test\\\\file2\\.log|C:\\\\Temp\\\\fsbof-test\\\\file2\\.log.*C:\\\\Temp\\\\fsbof-test\\\\file1\\.log"

# copy-wildcard-no-match
- cmdline: "copy C:\\Temp\\fsbof-test\\*.xyz C:\\Temp\\fsbof-test\\dest\\"
Expand Down Expand Up @@ -106,10 +103,7 @@ tasks:

# move-wildcard-match
- cmdline: "move C:\\Temp\\fsbof-test\\*.log C:\\Temp\\fsbof-test\\moved\\"
expected: |
C:\Temp\fsbof-test\file1.log
C:\Temp\fsbof-test\file2.log
2 file(s) moved.
expected_regex: "(?s)C:\\\\Temp\\\\fsbof-test\\\\file1\\.log.*C:\\\\Temp\\\\fsbof-test\\\\file2\\.log|C:\\\\Temp\\\\fsbof-test\\\\file2\\.log.*C:\\\\Temp\\\\fsbof-test\\\\file1\\.log"

# move-wildcard-no-match
- cmdline: "move C:\\Temp\\fsbof-test\\*.xyz C:\\Temp\\fsbof-test\\moved\\"
Expand Down Expand Up @@ -173,3 +167,39 @@ tasks:
# pwd-happy-path-step2
- cmdline: "pwd"
expected: "C:\\Temp\\fsbof-test"

# ── PS-BOF ──

# ps-list
- cmdline: "ps list"
expected: "System"

# ps-list-lsass
- cmdline: "ps list"
expected: "lsass.exe"

# ps-run-spawn-ping (CI-02/04/05/06 fixture — ping runs indefinitely on server SKUs)
- cmdline: 'ps run --command "ping -n 999 127.0.0.1"'
expected_regex: "Process started: PID \\d+"
capture:
pid: "Process started: PID (\\d+)"

# ps-run-pipe-whoami (CI-03)
- cmdline: 'ps run --command "cmd.exe /c whoami" --pipe'
expected_regex: "(?i)ci_runner"

# ps-grep (CI-04)
- cmdline: "ps grep {{pid}}"
expected_regex: "(?s)\\[Token\\].*\\[Modules\\].*\\[Cmdline\\].*\\[Threads\\]"

# ps-suspend (CI-05)
- cmdline: "ps suspend {{pid}}"
not_expected: "error"

# ps-resume (CI-06)
- cmdline: "ps resume {{pid}}"
not_expected: "error"

# ps-kill (CI-02)
- cmdline: "ps kill {{pid}}"
not_expected: "error"
12 changes: 12 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ jobs:
cp /workspace/FS-BOF/_bin/*.o /tmp/adaptixc2/dist/BOF-Collection/FS-BOF/_bin/
cp /workspace/FS-BOF/fs.axs /tmp/adaptixc2/dist/BOF-Collection/FS-BOF/fs.axs
cp /workspace/Exit-BOF/_bin/*.o /tmp/adaptixc2/dist/BOF-Collection/Exit-BOF/_bin/
mkdir -p /tmp/adaptixc2/dist/BOF-Collection/PS-BOF/_bin
cp /workspace/PS-BOF/_bin/*.o /tmp/adaptixc2/dist/BOF-Collection/PS-BOF/_bin/
cp /workspace/PS-BOF/ps.axs /tmp/adaptixc2/dist/BOF-Collection/PS-BOF/
cp /workspace/bof-collection.axs /tmp/adaptixc2/dist/BOF-Collection/

# ── Build verification ───────────────────────────────────────
echo "=== Build verification ==="
Expand All @@ -273,8 +277,16 @@ jobs:
count=$(ls /tmp/adaptixc2/dist/BOF-Collection/FS-BOF/_bin/*.x64.o | wc -l)
[ "$count" -eq 8 ] && echo "✓ All 8 FS-BOF x64 objects deployed to container" || \
{ echo "✗ Expected 8 FS-BOF x64 objects in container bin, got $count"; exit 1; }
count=$(ls /workspace/PS-BOF/_bin/*.x64.o | wc -l)
[ "$count" -eq 6 ] && echo "✓ All 6 PS-BOF x64 objects compiled" || \
{ echo "✗ Expected 6 PS-BOF x64 objects, got $count"; exit 1; }
count=$(ls /tmp/adaptixc2/dist/BOF-Collection/PS-BOF/_bin/*.x64.o | wc -l)
[ "$count" -eq 6 ] && echo "✓ All 6 PS-BOF x64 objects deployed to container" || \
{ echo "✗ Expected 6 PS-BOF x64 objects in container bin, got $count"; exit 1; }
echo "=== Build verification passed ==="

uv tool install --reinstall "git+https://github.com/TheGr3atJosh/Testing-Kit@c53a47d"

# ── Server startup ───────────────────────────────────────────
echo "Generating required TLS certificate..."
openssl req -x509 -nodes -newkey rsa:2048 \
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SUBDIRS := FS-BOF Exit-BOF
SUBDIRS := FS-BOF Exit-BOF PS-BOF

.PHONY: all $(SUBDIRS) clean docker-build

Expand Down
25 changes: 25 additions & 0 deletions PS-BOF/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
CC64 = x86_64-w64-mingw32-gcc
CC86 = i686-w64-mingw32-gcc
STRIP64 = x86_64-w64-mingw32-strip --strip-unneeded
STRIP86 = i686-w64-mingw32-strip --strip-unneeded
CFLAGS = -I ../_include -I _include -w -Wno-incompatible-pointer-types -Os -DBOF -c

all: bof

bof: clean
@(mkdir _bin 2>/dev/null) && echo 'creating _bin directory' || echo '_bin directory exists'
@($(CC64) $(CFLAGS) list/list.c -o _bin/list.x64.o && $(STRIP64) _bin/list.x64.o) && echo '[+] list x64' || echo '[!] list x64'
@($(CC86) $(CFLAGS) list/list.c -o _bin/list.x32.o && $(STRIP86) _bin/list.x32.o) && echo '[+] list x32' || echo '[!] list x32'
@($(CC64) $(CFLAGS) kill/kill.c -o _bin/kill.x64.o && $(STRIP64) _bin/kill.x64.o) && echo '[+] kill x64' || echo '[!] kill x64'
@($(CC86) $(CFLAGS) kill/kill.c -o _bin/kill.x32.o && $(STRIP86) _bin/kill.x32.o) && echo '[+] kill x32' || echo '[!] kill x32'
@($(CC64) $(CFLAGS) run/run.c -o _bin/run.x64.o && $(STRIP64) _bin/run.x64.o) && echo '[+] run x64' || echo '[!] run x64'
@($(CC86) $(CFLAGS) run/run.c -o _bin/run.x32.o && $(STRIP86) _bin/run.x32.o) && echo '[+] run x32' || echo '[!] run x32'
@($(CC64) $(CFLAGS) grep/grep.c -o _bin/grep.x64.o && $(STRIP64) _bin/grep.x64.o) && echo '[+] grep x64' || echo '[!] grep x64'
@($(CC86) $(CFLAGS) grep/grep.c -o _bin/grep.x32.o && $(STRIP86) _bin/grep.x32.o) && echo '[+] grep x32' || echo '[!] grep x32'
@($(CC64) $(CFLAGS) suspend/suspend.c -o _bin/suspend.x64.o && $(STRIP64) _bin/suspend.x64.o) && echo '[+] suspend x64' || echo '[!] suspend x64'
@($(CC86) $(CFLAGS) suspend/suspend.c -o _bin/suspend.x32.o && $(STRIP86) _bin/suspend.x32.o) && echo '[+] suspend x32' || echo '[!] suspend x32'
@($(CC64) $(CFLAGS) resume/resume.c -o _bin/resume.x64.o && $(STRIP64) _bin/resume.x64.o) && echo '[+] resume x64' || echo '[!] resume x64'
@($(CC86) $(CFLAGS) resume/resume.c -o _bin/resume.x32.o && $(STRIP86) _bin/resume.x32.o) && echo '[+] resume x32' || echo '[!] resume x32'

clean:
@(rm -rf _bin)
60 changes: 60 additions & 0 deletions PS-BOF/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# PS-BOF

Process management operations: ps list, ps kill, ps run, ps grep, ps suspend, ps resume.

## ps list

List all running processes. Output columns: PID, PPID, session ID, owner (domain\user), architecture.

```
ps list
```

## ps kill

Terminate a process by PID. Optional exit code argument (defaults to 1 if omitted).

```
ps kill <PID> [exit_code]
```

## ps run

Launch a new process. Supports default CreateProcess, credential-based launch (WithLogon), and token-based launch (WithToken), with optional PPID spoofing and stdout/stderr pipe capture.

```
ps run --command <cmd> [--pipe] [--ppid <PID>] [--state suspended] [--domain <domain> --username <user> --password <pass>] [--token <handle>]
```

- `--command <cmd>` — Command line to execute (required)
- `--pipe` — Capture stdout/stderr via anonymous pipe
- `--ppid <PID>` — Spoof parent PID
- `--state suspended` — Launch process in suspended state
- `--domain <domain>` — Domain for CreateProcessWithLogon
- `--username <user>` — Username for CreateProcessWithLogon
- `--password <pass>` — Password for CreateProcessWithLogon
- `--token <handle>` — Token handle for CreateProcessWithToken

## ps grep

Inspect a process by PID. Output sections: token (owner, elevated flag, integrity level), modules (name, base address, entry point, size), command line, threads (TIDs).

```
ps grep <PID>
```

## ps suspend

Suspend a process by PID.

```
ps suspend <PID>
```

## ps resume

Resume a suspended process by PID.

```
ps resume <PID>
```
Loading
Loading