aboutsummaryrefslogtreecommitdiffstats
path: root/fw/gadgets
ModeNameSize
-rw-r--r--GADGET-CLASSES.txt16807logstatsplainblame
-rw-r--r--GADGETS.txt59679logstatsplainblame
-rw-r--r--ONESHOT-GADGETS.md174419logstatsplainblame
-rw-r--r--README.md4153logstatsplainblame
-rw-r--r--arm_mode_sled_sweep.py5784logstatsplainblame
-rw-r--r--build_sweep_pivot.py7137logstatsplainblame
-rw-r--r--gcp_22.0.0.77_code_0x400000.bin28672logstatsplainblame
-rw-r--r--gcp_22.0.0.77_image_0x400000.bin90368logstatsplainblame
-rw-r--r--gcp_code.arm.txt401538logstatsplainblame
-rw-r--r--gcp_code.thumb.txt841494logstatsplainblame
-rw-r--r--ptr_return_store.py6199logstatsplainblame
-rw-r--r--retaddr_reach.py5796logstatsplainblame
-rw-r--r--tlapi_lib.arm.txt59319logstatsplainblame
-rw-r--r--tlapi_lib.thumb.txt120141logstatsplainblame
-rw-r--r--tlapi_lib_0xf00000.bin4096logstatsplainblame

Branch-target hunting material (GCP 22.0.0.77 + tlApi library)

Produced for the control-flow work in FINDING-GCP-FE09-...md Add.89-94.

Binaries (offset == VA - base, so you can disassemble at the right address)

file base VA notes
tlapi_lib_0xf00000.bin 0xf00000 the 4 KB tlApi library page, live dump from the emulator (mapped R-X, dom 7). Code occupies 0xf00101-0xf00790; "$PS1" magic + len 0x590 at +0x10. ARM veneer at 0xf00100, Thumb body from 0xf00114.
gcp_22.0.0.77_code_0x400000.bin 0x400000 GCP code region 0x400000-0x407000 (R-X). 0x400000-0x400100 is SYNTHETIC ZERO PADDING — the real content is unknown (Add.92 observed an ARM store executing at 0x400044, so it is NOT all zero). Body proper starts at 0x400100.
gcp_22.0.0.77_image_0x400000.bin 0x400000 same but the whole image (code+.data+.bss span, to 0x416100).

Disassembly (linear sweep, resynced every instruction so literal pools don't desync)

tlapi_lib.thumb.txt, tlapi_lib.arm.txt, gcp_code.thumb.txt, gcp_code.arm.txt

Gadget catalogues

GADGETS.txt - control-transfer / sp-write / svc sites, per region per mode GADGET-CLASSES.txt - grouped: PC-from-r4, PC-from-mem, SP-from-reg, add-sp+pop-pc, bx/blx r4|r0

Entry state when our planted branch is taken

UNLOAD_TA -> TA_CloseSessionEntryPoint -> gcp_tlApiFree -> gcp_call_once_init -> bx ip r0 = sp = &requestBlock (tlApiFree frame) r1 = r2 = r3 = 0 r4 = ctx pointer (0x41d030) r5 = sp lr = 0x405617 (into tlApiFree) Z=1, V=0 (from movs r3,#0) requestBlock: [sp]=0x22 [sp+4]=2 [sp+8..0x28)=0 [sp+0x38]=ctx ; rest = stale stack NOTE: branching INTO an IT block clears ITSTATE, so e.g. moveq sp,r4 at 0x40371c executes unconditionally as mov sp,r4 (encoding 0xa546 is a plain MOV).

What we are looking for

A gadget that sources PC or SP from memory we can fill:

  • carvable heap: any address >= heapbase+0x7f = 0x41d07f (= ctx+0x4f) -- arbitrary bytes, ~256 CodecToken stamps per byte (descending trailing-byte carve, Add.91)
  • host-written ctx: FE07 puts arg18 at auth[i]+4 and arg10 (8B) at auth[i]+0x10 for 16 slots => ~192 bytes of CHOSEN data at ctx+0x300 + 0x50*i, no lottery needed So the wanted shapes are mov sp,r4 ; add sp,#>=0x300 ; pop {...,pc} or ldr pc,[r4,#imm>=0x50]. Best found so far: 0x0040371c mov sp,r4 ; pop.w {r4,r5,r6,r7,r8,sb,sl,fp,pc} -- pivots to ctx but takes PC from ctx+0x20, which is NOT carve-writable (A=target-0x7f lands in the guard page), so only blob-window values fit there and the only mapped+executable one is 0x00400000. Dead ends: the 61 blx r4 / bx r4 sites (r4=ctx, heap is RW-/XN).

BUILD SENSITIVITY (read this first)

All binaries here are 22.0.0.77 (ta_22-0-0-77_7c426e7f), the build running on our card. Gadget addresses do NOT carry across builds. Measured at the two addresses used above:

build 0x40363a 0x40371c
22.0.0.53/.57/.60 f104 add.w r0,r4,#0x30 a14f adr r1,#0x13c
22.0.0.62/.64 f5b1 cmp.w r1,#0x100 f8cd str.w r0,[sp,#0x79c]
22.0.0.68/.71/.73/.77 46a5 mov sp,r4 46a5 mov sp,r4 ; pop.w {r4-r8,sb,sl,fp,pc}
22.0.4.50 2210 movs r2,#0x10 2010 movs r0,#0x10 ; str r0,[sp,#0x1c]

So the mov sp,r4 ; pop {...,pc} pivot exists only on the .68-.77 line. Note the emulator harness (fuzz_newtas.pick_container) defaults "gcp" to ta_22-0-4-50, which is how one easily ends up disassembling the wrong image -- the same mistake recorded in FINDING Add.49 and Add.55.

CAVEAT on the gadget catalogues

GADGETS.txt, GADGET-CLASSES.txt and the *.txt sweeps decode at EVERY 2-byte offset, so they intentionally include UNINTENDED (misaligned) decodes. Those are valid ROP gadgets -- any halfword is a legal branch target -- but they are not the intended instruction stream. Re-check any candidate with a sequential decode before relying on it. (0x40371c is valid in both senses: bfc r4,#0,#0xb at 0x403636 is 4 bytes, so 0x40363a/0x40371c are genuine instruction boundaries.)