Files
SDD 01923ecb69 dwt/tcpip: map the socket API and fetch a file over TFTP into RAM
The firmware's tftp_open hangs in its resolver from the rdebug process, so
the payload speaks RFC 783 over the firmware socket API: socket(2,2,0),
sendto(RRQ), recvfrom(DATA)/ACK into a malloc'd buffer, close. Verified
live: 600 B fetched from 192.168.99.1 into the malloc buffer, server RRQ
logged, and rdebug peek matches probe.bin byte-for-byte.

Notes: dwt/notes/TCPIP.md (function table, ABI, limits) and the
loader/transport hand-off in dwt/notes/LOADER_CROSS.md.
2026-10-18 15:24:34 +03:00

219 lines
9.6 KiB
Plaintext

GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:10:29 2026
(c) Copyright 1985, 1987, Texas Instruments Inc.
PAGE 1
0001 ; tftp_fetch.asm -- fetch a file over TFTP into a mallo
0002 ; firmware's own client (dwt_tftp.c in ROM).
0003 ;
0004 ; Linked at bit 01870000h (byte 0x30E000) and executed
0005 ; call. The payload follows the firmware's stack-argum
0006 ;
0007 ; MOVE A14,-*SP,1 ; reserve the slo
0008 ; MOVE argN,*A14+,1 ; last argument f
0009 ; MOVE arg0,*A14+,1 ; first argument
0010 ; CALLA target
0011 ;
0012 ; We point A14 at a fixed argument area and restore SP/
0013 ; entry values after every call, so a payload bug canno
0014 ; stack. a9 and a11 are callee-saved by tftp_open/tftp
0015 ; hold the fd and the current write pointer across call
0016 ;
0017 ; Firmware entry points (bit addresses; Ghidra = bit >>
0018 ; malloc 3F701230h (Ghidra 07EE0246) malloc(by
0019 ; tftp_open 3F5EBC40h (Ghidra 07EBD788) tftp_open
0020 ; tftp_read 3F5ED230h (Ghidra 07EBDA46) tftp_read
0021 ; tftp_close 3F5EC860h (Ghidra 07EBD90C) tftp_clos
0022 ;
0023 ; tftp_read returns the DATA payload length, and 0 once
0024 ; has been consumed. tftp_close sends TFTP ERROR 3 if
0025 ; a full 512 bytes, so the loop must read until it gets
0026 ;
0027 ; Evidence cells (32-bit, bit addresses; peeked over rd
0028 ; 01871000 stage (1 malloc, 2 open, 3 reading, 4 cl
0029 ; 01871020 fd
0030 ; 01871040 buffer pointer (returned by malloc; a BIT
0031 ; 01871060 total bytes fetched
0032 ; 01871080 last tftp_read return
0033 ; 018710A0 marker: 05A5A5A5h when the fetch complete
0034 ; 018710C0 tftp_close return scratch
0035 ; 01871200 entry SP
0036 ; 01871220 entry A14
0037 ;
0038 ; The fetched bytes are at [01871040] and are compared
0039 ; The marker cells are deliberately above 01870AD0 (the
0040 ; writing them into the code was the first, silent fail
0041
0042 00000000 .text
0043 00000000 _start:
0044 00000000 0550 setf 16, 0, 0
0045 00000010 0740 setf 32, 0, 1
0046 00000020 098F mmtm sp, a0,a1,a2,a3,a4,a5,a6,a7
00000030 FF00
0047 00000040 078F move sp, @01871200h, 1 ; entry SP
00000050 01871200
0048 00000070 078E move a14, @01871220h, 1 ; entry A14
00000080 01871220
0049
0050 000000A0 09E0 movi 1, a0, L
000000B0 00000001
0051 000000D0 0780 move a0, @01871000h, 1 ; stage = 1
000000E0 01871000
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:10:29 2026
(c) Copyright 1985, 1987, Texas Instruments Inc.
PAGE 2
0052
0053 ; ---- buf = malloc(010000h) -------------------------
0054 00000100 A3CF move a14, -*sp, 1
0055 00000110 09EE movi 01878000h, a14, L ; argument area
00000120 01878000
0056 00000140 09E0 movi 010000h, a0, L ; 65536 bytes
00000150 00010000
0057 00000170 920E move a0, *a14+, 1
0058 00000180 0D5F calla 3F701230h ; malloc
00000190 3F701230
0059 000001B0 07AF move @01871200h, sp, 1
000001C0 01871200
0060 000001E0 07AE move @01871220h, a14, 1
000001F0 01871220
0061 00000210 0550 setf 16, 0, 0
0062 00000220 0740 setf 32, 0, 1
0063 00000230 0788 move a8, @01871040h, 1 ; buffer pointer (bit address)
00000240 01871040
0064 00000260 4D0B move a8, a11
0065 00000270 4D08 move a8, a8
0066 00000280 CA6A jreq fail
0067
0068 00000290 09E0 movi 2, a0, L
000002A0 00000002
0069 000002C0 0780 move a0, @01871000h, 1 ; stage = 2
000002D0 01871000
0070
0071 ; ---- fd = tftp_open("192.168.99.1", "dwt/tcpip/probe
0072 000002F0 09EE movi 01878000h, a14, L ; argument area
00000300 01878000
0073 00000320 09E0 movi FNAME, a0, L
00000330 00000A60'
0074 00000350 920E move a0, *a14+, 1 ; arg1 = filename
0075 00000360 09E0 movi HOST, a0, L
00000370 000009F0'
0076 00000390 920E move a0, *a14+, 1 ; arg0 = host
0077 000003A0 0D5F calla 3F5EBC40h ; tftp_open
000003B0 3F5EBC40
0078 000003D0 07AF move @01871200h, sp, 1
000003E0 01871200
0079 00000400 07AE move @01871220h, a14, 1
00000410 01871220
0080 00000430 0550 setf 16, 0, 0
0081 00000440 0740 setf 32, 0, 1
0082 00000450 0788 move a8, @01871020h, 1 ; fd
00000460 01871020
0083 00000480 4D09 move a8, a9
0084 00000490 4D08 move a8, a8
0085 000004A0 C448 jrlt fail
0086
0087 ; ---- while ((n = tftp_read(fd, p, 010000h)) > 0) p +
0088 000004B0 09E0 movi 3, a0, L
000004C0 00000003
0089 000004E0 0780 move a0, @01871000h, 1 ; stage = 3
000004F0 01871000
0090 00000510 read_loop:
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:10:29 2026
(c) Copyright 1985, 1987, Texas Instruments Inc.
PAGE 3
0091 00000510 09EE movi 01878000h, a14, L
00000520 01878000
0092 00000540 09E0 movi 010000h, a0, L
00000550 00010000
0093 00000570 920E move a0, *a14+, 1 ; arg2 = bufsize
0094 00000580 936E move a11, *a14+, 1 ; arg1 = buffer
0095 00000590 932E move a9, *a14+, 1 ; arg0 = fd
0096 000005A0 0D5F calla 3F5ED230h ; tftp_read
000005B0 3F5ED230
0097 000005D0 07AF move @01871200h, sp, 1
000005E0 01871200
0098 00000600 07AE move @01871220h, a14, 1
00000610 01871220
0099 00000630 0550 setf 16, 0, 0
0100 00000640 0740 setf 32, 0, 1
0101 00000650 0788 move a8, @01871080h, 1 ; last return
00000660 01871080
0102 00000680 4D08 move a8, a8
0103 00000690 C609 jrle close_it
0104 000006A0 410B add a8, a11 ; advance the write pointer
0105 000006B0 07A1 move @01871060h, a1, 1
000006C0 01871060
0106 000006E0 4101 add a8, a1
0107 000006F0 0781 move a1, @01871060h, 1 ; total += n
00000700 01871060
0108 00000720 C0DE jruc read_loop
0109
0110 00000730 close_it:
0111 00000730 09E0 movi 4, a0, L
00000740 00000004
0112 00000760 0780 move a0, @01871000h, 1 ; stage = 4
00000770 01871000
0113 00000790 09EE movi 01878000h, a14, L
000007A0 01878000
0114 000007C0 932E move a9, *a14+, 1 ; arg0 = fd
0115 000007D0 0D5F calla 3F5EC860h ; tftp_close
000007E0 3F5EC860
0116 00000800 07AF move @01871200h, sp, 1
00000810 01871200
0117 00000830 07AE move @01871220h, a14, 1
00000840 01871220
0118 00000860 0550 setf 16, 0, 0
0119 00000870 0740 setf 32, 0, 1
0120 00000880 0788 move a8, @018710C0h, 1
00000890 018710C0
0121 000008B0 09E0 movi 05A5A5A5h, a0, L
000008C0 05A5A5A5
0122 000008E0 0780 move a0, @018710A0h, 1 ; DONE marker
000008F0 018710A0
0123 00000910 4508 sub a8, a8 ; return 0
0124 00000920 C009 jruc epilogue
0125
0126 00000930 fail:
0127 00000930 09E0 movi 0FFh, a0, L
00000940 000000FF
0128 00000960 0780 move a0, @01871000h, 1
GSP COFF Assembler, Version 2.00, 87.300 Sun Oct 18 15:10:29 2026
(c) Copyright 1985, 1987, Texas Instruments Inc.
PAGE 4
00000970 01871000
0129 00000990 09E8 movi 0FFFFFFFFh, a8, L
000009A0 FFFFFFFF
0130 000009C0 epilogue:
0131 000009C0 09AF mmfm sp, a0,a1,a2,a3,a4,a5,a6,a7
000009D0 00FF
0132 000009E0 0960 rets
0133
0134 000009F0 HOST:
0135 000009F0 3931 .word 03931h ; "192.168.99.1"
0136 00000A00 2E32 .word 02E32h
0137 00000A10 3631 .word 03631h
0138 00000A20 2E38 .word 02E38h
0139 00000A30 3939 .word 03939h
0140 00000A40 312E .word 0312Eh
0141 00000A50 0000 .word 00000h
0142 00000A60 FNAME:
0143 00000A60 7764 .word 07764h ; "dwt/tcpip/probe.bin"
0144 00000A70 2F74 .word 02F74h
0145 00000A80 6374 .word 06374h
0146 00000A90 6970 .word 06970h
0147 00000AA0 2F70 .word 02F70h
0148 00000AB0 7270 .word 07270h
0149 00000AC0 626F .word 0626Fh
0150 00000AD0 2E65 .word 02E65h
0151 00000AE0 6962 .word 06962h
0152 00000AF0 006E .word 0006Eh
0153 .end
No Errors, No Warnings