Skip to content

Instantly share code, notes, and snippets.

@xps3riments
Last active April 5, 2020 11:21
Show Gist options
  • Save xps3riments/3262b2d4ada03f1ea612b5c8c4ddaab4 to your computer and use it in GitHub Desktop.
Save xps3riments/3262b2d4ada03f1ea612b5c8c4ddaab4 to your computer and use it in GitHub Desktop.
<html>
<head> </head>
<body>
<script src="object.keys.js"></script>
<script src="xRegistry.js"></script>
<script>
// Change ip here to reflect you PS3 ip
// Navigate this page in the browser to see the result in the console
// (WORKS ON PS3) Desktop used only to access to the console
console.log(
new XRegistry().load("http://xxx.xxx.xxx.xxx/dev_flash2/etc/xRegistry.sys")
);
// Uncomment for PS3 does not need a url
// alert(
// new XRegistry().load().settings.system.nickname
// );
</script>
</body>
</html>
// https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/keys
if (!Object.keys) {
Object.keys = (function() {
"use strict";
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !{ toString: null }.propertyIsEnumerable("toString"),
dontEnums = [
"toString",
"toLocaleString",
"valueOf",
"hasOwnProperty",
"isPrototypeOf",
"propertyIsEnumerable",
"constructor"
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (
typeof obj !== "object" &&
(typeof obj !== "function" || obj === null)
) {
throw new TypeError("Object.keys called on non-object");
}
var result = [],
prop,
i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
})();
}
// tslint:disable: arrow-parens
// tslint:disable: trailing-comma
// tslint:disable: variable-name
var BinaryReader = /** @class */ (function () {
function BinaryReader(url, pos) {
if (pos === void 0) { pos = 0; }
this.pos = pos;
this.data = this.load(url);
}
BinaryReader.prototype.load = function (url) {
var req = new XMLHttpRequest();
req.open("GET", url, false);
req.overrideMimeType("text/plain; charset=x-user-defined");
req.send(null);
if (req.status !== 200) {
return "";
}
return req.responseText;
};
BinaryReader.prototype.read = function (len) {
var _this = this;
var result = Array.apply(null, Array(len))
.map(Number.prototype.valueOf, 0)
.map(function (_, index) {
// tslint:disable-next-line:no-bitwise
return _this.data.charCodeAt(_this.pos + index) & 0xff;
});
this.pos += len;
return result;
};
BinaryReader.prototype.seek = function (offset) {
this.pos = offset;
};
BinaryReader.prototype.tell = function () {
return this.pos;
};
return BinaryReader;
}());
// tslint:disable-next-line:max-classes-per-file
var XRegistry = /** @class */ (function () {
function XRegistry() {
}
XRegistry.prototype.load = function (ip) {
var _this = this;
if (ip === void 0) { ip = "127.0.0.1"; }
var filenameEntrys = [];
var dataEntrys = [];
var file = new BinaryReader(ip === "127.0.0.1" ? "http://127.0.0.1/dev_flash2/etc/xRegistry.sys" : ip);
if (this._intToHex(file.read(16)) === "bcadadbc0000009000000002bcadadbc") {
var filenameEntry = this._getFileEntry(file, filenameEntrys);
while (filenameEntry) {
filenameEntry = this._getFileEntry(file, filenameEntrys);
}
file.seek(0xfff0);
if (this._isDataMark(file)) {
var dataEntry = this._getDataEntry(file, dataEntrys);
while (dataEntry) {
dataEntry = this._getDataEntry(file, dataEntrys);
}
var r_1 = this._compactFields(filenameEntrys, dataEntrys);
return Object.keys(r_1).reduce(function (acc, key) {
_this._setPathValue(acc, key, r_1[key]);
return acc;
}, {});
}
return null;
}
return null;
};
XRegistry.prototype._compactFields = function (filenameEntrys, dataEntrys) {
var _this = this;
var listObj = {};
var key;
var value;
var filenameEntry;
dataEntrys.forEach(function (dataEntry) {
var i = 0;
var found = false;
while (!found && i < filenameEntrys.length) {
filenameEntry = filenameEntrys[i];
i = i + 1;
var filename = dataEntry.filename, dataValue = dataEntry.dataValue, type = dataEntry.type;
if (filename === filenameEntry.offset - 16) {
found = true;
key = _this._intToChar(filenameEntry.setting);
switch (type) {
case 0:
value = Boolean(dataValue);
break;
case 1:
value = _this._hexToInt(dataValue);
break;
case 2:
value = _this._intToChar(dataValue);
break;
}
listObj[key] = value;
}
}
});
return listObj;
};
XRegistry.prototype._getDataEntry = function (f, list) {
var offset = f.tell();
var flagsHex = this._intToHex(f.read(2));
var flags = parseInt(flagsHex, 16);
var filenameHex = this._intToHex(f.read(2));
var filename = parseInt(filenameHex, 16);
var checksumHex = this._intToHex(f.read(2));
var checksum = parseInt(checksumHex, 16);
var lenHex = this._intToHex(f.read(2));
var len = parseInt(lenHex, 16);
var typeHex = this._intToHex(f.read(1));
var type = parseInt(typeHex, 16);
var dataValue = f.read(len);
this._intToHex(f.read(1));
if (flagsHex !== "aabb" &&
filenameHex !== "ccdd" &&
checksumHex !== "ee00") {
list.push({ offset: offset, flags: flags, filename: filename, checksum: checksum, len: len, type: type, dataValue: dataValue });
return true;
}
else {
return false;
}
};
XRegistry.prototype._getFileEntry = function (f, list) {
var offset = f.tell();
var idHex = this._intToHex(f.read(2));
var id = parseInt(idHex, 16);
var lenHex = this._intToHex(f.read(2));
var len = parseInt(lenHex, 16);
var valueHex = this._intToHex(f.read(1));
var value = parseInt(valueHex, 16);
var setting = f.read(len);
var sep = this._intToHex(f.read(1));
if (sep === "00" && idHex !== "aabb" && lenHex !== "ccdd") {
list.push({ offset: offset, id: id, setting: setting, value: value });
return true;
}
else {
return false;
}
};
XRegistry.prototype._hexToInt = function (bytes) {
return parseInt(bytes
.map(function (byte) {
return byte.toString(16);
})
.join("")
.toLowerCase(), 16);
};
XRegistry.prototype._intToChar = function (bytes) {
return bytes
.map(function (byte) {
return String.fromCharCode(byte);
})
.join("");
};
XRegistry.prototype._intToHex = function (bytes) {
return bytes
.map(function (byte) {
return byte < 16 ? "0" + byte.toString(16) : byte.toString(16);
})
.join("")
.toLowerCase();
};
XRegistry.prototype._isDataMark = function (f) {
return this._intToHex(f.read(2)) === "4d26";
};
XRegistry.prototype._setPathValue = function (obj, path, value) {
if (path.charAt(0) === "/") {
path = path.substring(1);
}
var parts = path.split("/");
var partsLength = parts.length;
parts.forEach(function (part, index) {
if (index + 1 === partsLength) {
obj[part] = value;
return;
}
obj[part] = obj[part] || {};
obj = obj[part];
});
};
return XRegistry;
}());
class BinaryReader {
public data: string;
constructor(url: string, public pos = 0) {
this.data = this.load(url);
}
public load(url: string) {
const req = new XMLHttpRequest();
req.open("GET", url, false);
req.overrideMimeType("text/plain; charset=x-user-defined");
req.send(null);
if (req.status !== 200) {
return "";
}
return req.responseText;
}
public read(len: number): number[] {
const result = Array.apply(null, Array(len))
.map(Number.prototype.valueOf, 0)
.map((_: unknown, index: number) => {
// tslint:disable-next-line:no-bitwise
return this.data.charCodeAt(this.pos + index) & 0xff;
});
this.pos += len;
return result;
}
public seek(offset: number): void {
this.pos = offset;
}
public tell() {
return this.pos;
}
}
interface IXRegistrySettings {
[key: string]: string | number | boolean;
}
interface IFileEntry {
offset: number;
id: number;
setting: number[];
value: number;
}
interface IDataEntry {
offset: number;
flags: number;
filename: number;
checksum: number;
len: number;
type: number;
dataValue: number[];
}
// tslint:disable-next-line:max-classes-per-file
class XRegistry {
public load(ip: string = "127.0.0.1"): IXRegistrySettings | null {
const filenameEntrys: IFileEntry[] = [];
const dataEntrys: IDataEntry[] = [];
const file = new BinaryReader(
ip === "127.0.0.1" ? "http://127.0.0.1/dev_flash2/etc/xRegistry.sys" : ip
);
if (this._intToHex(file.read(16)) === "bcadadbc0000009000000002bcadadbc") {
let filenameEntry = this._getFileEntry(file, filenameEntrys);
while (filenameEntry) {
filenameEntry = this._getFileEntry(file, filenameEntrys);
}
file.seek(0xfff0);
if (this._isDataMark(file)) {
let dataEntry = this._getDataEntry(file, dataEntrys);
while (dataEntry) {
dataEntry = this._getDataEntry(file, dataEntrys);
}
const r = this._compactFields(filenameEntrys, dataEntrys);
return Object.keys(r).reduce((acc, key) => {
this._setPathValue(acc, key, r[key]);
return acc;
}, {});
}
return null;
}
return null;
}
private _compactFields(
filenameEntrys: IFileEntry[],
dataEntrys: IDataEntry[]
) {
const listObj: IXRegistrySettings = {};
let key: string;
let value: string | number | boolean;
let filenameEntry: IFileEntry;
dataEntrys.forEach(dataEntry => {
let i = 0;
let found = false;
while (!found && i < filenameEntrys.length) {
filenameEntry = filenameEntrys[i];
i = i + 1;
const { filename, dataValue, type } = dataEntry;
if (filename === filenameEntry.offset - 16) {
found = true;
key = this._intToChar(filenameEntry.setting);
switch (type) {
case 0:
value = Boolean(dataValue);
break;
case 1:
value = this._hexToInt(dataValue);
break;
case 2:
value = this._intToChar(dataValue);
break;
}
listObj[key] = value;
}
}
});
return listObj;
}
private _getDataEntry(f: BinaryReader, list: IDataEntry[]) {
const offset = f.tell();
const flagsHex = this._intToHex(f.read(2));
const flags = parseInt(flagsHex, 16);
const filenameHex = this._intToHex(f.read(2));
const filename = parseInt(filenameHex, 16);
const checksumHex = this._intToHex(f.read(2));
const checksum = parseInt(checksumHex, 16);
const lenHex = this._intToHex(f.read(2));
const len = parseInt(lenHex, 16);
const typeHex = this._intToHex(f.read(1));
const type = parseInt(typeHex, 16);
const dataValue = f.read(len);
this._intToHex(f.read(1));
if (
flagsHex !== "aabb" &&
filenameHex !== "ccdd" &&
checksumHex !== "ee00"
) {
list.push({ offset, flags, filename, checksum, len, type, dataValue });
return true;
} else {
return false;
}
}
private _getFileEntry(f: BinaryReader, list: IFileEntry[]) {
const offset = f.tell();
const idHex = this._intToHex(f.read(2));
const id = parseInt(idHex, 16);
const lenHex = this._intToHex(f.read(2));
const len = parseInt(lenHex, 16);
const valueHex = this._intToHex(f.read(1));
const value = parseInt(valueHex, 16);
const setting = f.read(len);
const sep = this._intToHex(f.read(1));
if (sep === "00" && idHex !== "aabb" && lenHex !== "ccdd") {
list.push({ offset, id, setting, value });
return true;
} else {
return false;
}
}
private _hexToInt(bytes: number[]) {
return parseInt(
bytes
.map(byte => {
return byte.toString(16);
})
.join("")
.toLowerCase(),
16
);
}
private _intToChar(bytes: number[]) {
return bytes
.map(byte => {
return String.fromCharCode(byte);
})
.join("");
}
private _intToHex(bytes: number[]) {
return bytes
.map(byte => {
return byte < 16 ? "0" + byte.toString(16) : byte.toString(16);
})
.join("")
.toLowerCase();
}
private _isDataMark(f: BinaryReader) {
return this._intToHex(f.read(2)) === "4d26";
}
private _setPathValue(obj: any, path: string, value: unknown) {
if (path.charAt(0) === "/") {
path = path.substring(1);
}
const parts = path.split("/");
const partsLength = parts.length;
parts.forEach((part, index) => {
if (index + 1 === partsLength) {
obj[part] = value;
return;
}
obj[part] = obj[part] || {};
obj = obj[part];
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment