Add keygen for sony 4x4 codes (16 shifted hexdecimals)
This commit is contained in:
1 parent
b8a8d37e36
commit
96760f66aa
6 files changed
+179
-7
No files matched your search
+2
-2
@@ -23,7 +23,7 @@ gulp.task("pre-coverage", ["coverage-build"], function() {
|
||||
});
|
||||
|
||||
gulp.task('coverage', ['coverage-build', 'pre-coverage'], function() {
|
||||
return gulp.src("coverage-dist/*.spec.js")
|
||||
return gulp.src("coverage-dist/**/*.spec.js")
|
||||
.pipe(jasmine())
|
||||
.pipe(istanbul.writeReports({
|
||||
dir: './coverage',
|
||||
@@ -58,7 +58,7 @@ gulp.task('test-build', function() {
|
||||
});
|
||||
|
||||
gulp.task('test', ['test-build'], function() {
|
||||
return gulp.src("test-dist/*.spec.js")
|
||||
return gulp.src("test-dist/**/*.spec.js")
|
||||
.pipe(jasmine());
|
||||
});
|
||||
|
||||
|
||||
+4
-2
@@ -4,16 +4,18 @@
|
||||
"description": "Password generator for BIOS",
|
||||
"main": "decrypt_bios.js",
|
||||
"dependencies": {
|
||||
"@types/long": "^3.0.32",
|
||||
"@types/jasmine": "^2.8.3",
|
||||
"gulp-jasmine": "^3.0.0",
|
||||
"typescript": "^2.6.2"
|
||||
"typescript": "^2.6.2",
|
||||
"long": "dcodeIO/long.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-webpack-plugin": "^0.1.18",
|
||||
"copy-webpack-plugin": "^4.3.1",
|
||||
"coveralls": "^3.0.0",
|
||||
"gulp": "^3.9.1",
|
||||
"del": "^3.0.0",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-istanbul": "^1.1.3",
|
||||
"gulp-sourcemaps": "^2.6.4",
|
||||
"gulp-tslint": "^8.1.2",
|
||||
|
||||
+3
-1
@@ -1,15 +1,16 @@
|
||||
import { monotonicTime } from "../polyfills/performancePolyfill";
|
||||
import { asusSolver } from "./asus";
|
||||
import { dellHddSolver, dellSolver, hddOldSolver } from "./dell";
|
||||
import { fsi20DecNewSolver, fsi20DecOldSolver, fsiHexSolver } from "./fsi";
|
||||
import { hpMiniSolver } from "./hpmini";
|
||||
import { insydeSolver } from "./insyde";
|
||||
import { monotonicTime } from "../polyfills/performancePolyfill";
|
||||
import {
|
||||
phoenixFsiLSolver, phoenixFsiPSolver, phoenixFsiSolver,
|
||||
phoenixFsiSSolver, phoenixFsiXSolver, phoenixHPCompaqSolver, phoenixSolver
|
||||
} from "./phoenix";
|
||||
import { samsungSolver } from "./samsung";
|
||||
import { sonySolver } from "./sony";
|
||||
import { sony4x4Solver } from "./sony_4x4";
|
||||
import { Solver } from "./utils";
|
||||
|
||||
export type KeygenResult = [Solver, string[], number];
|
||||
@@ -17,6 +18,7 @@ export type KeygenResult = [Solver, string[], number];
|
||||
export const solvers: Solver[] = [
|
||||
asusSolver,
|
||||
sonySolver,
|
||||
sony4x4Solver,
|
||||
samsungSolver,
|
||||
hddOldSolver,
|
||||
dellSolver,
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import * as Long from "long";
|
||||
import { modularPow, sony4x4Keygen, sony4x4Solver } from "./sony_4x4";
|
||||
|
||||
describe("Sony 4x4 BIOS Keygen", () => {
|
||||
it("Sony 4x4 key for 73KR3FP9PVKHK29R is 32799624", () => {
|
||||
expect(sony4x4Keygen("73KR3FP9PVKHK29R")).toEqual("32799624");
|
||||
});
|
||||
it("Sony 4x4 key for 73KR-3FP9-PVKH-K299 is 69423778", () => {
|
||||
expect(sony4x4Keygen("73KR3FP9PVKHK299")).toEqual("69423778");
|
||||
});
|
||||
it("Sony 4x4 key for 9DPK-73KR-8JHX-F3RT is 54746568", () => {
|
||||
expect(sony4x4Keygen("9DPK73KR8JHXF3RT")).toEqual("54746568");
|
||||
});
|
||||
it("Sony 4x4 key for 3RT6-8JV2-6HX8-K7FX is 32969527", () => {
|
||||
expect(sony4x4Keygen("3RT68JV26HX8K7FX")).toEqual("32969527");
|
||||
});
|
||||
it("Sony 4x4 key for K29R-PVKH-3FP9-73KR is 65395983", () => {
|
||||
expect(sony4x4Keygen("K29RPVKH3FP973KR")).toEqual("65395983");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Sony 4x4 BIOS Solver", () => {
|
||||
it("Sony 4x4 key for 73KR-3FP9-PVKH-K29R is 32799624", () => {
|
||||
expect(sony4x4Solver("73KR-3FP9-PVKH-K29R")).toEqual(["32799624"]);
|
||||
});
|
||||
it("Sony 4x4 invalid key 73KR-3FP9-PVKH-K29C", () => {
|
||||
expect(sony4x4Solver("73KR-3FP9-PVKH-K29C")).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("test modularPow", () => {
|
||||
it("4 ^ 13 mod 497 == 445", () => {
|
||||
expect(modularPow(Long.fromInt(4), 13, 497)).toEqual(445);
|
||||
});
|
||||
it("100500 ^ 100500 mod 14 == 8", () => {
|
||||
expect(modularPow(Long.fromInt(100500), 100500, 14)).toEqual(8);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,123 @@
|
||||
// based on dogbert's pwgen-sony-4x4.py
|
||||
/* tslint:disable:no-bitwise */
|
||||
import * as Long from "long";
|
||||
import { makeSolver } from "./utils";
|
||||
|
||||
const otpChars: string = "9DPK7V2F3RT6HX8J";
|
||||
const pwdChars: string = "47592836";
|
||||
const inputRe: RegExp = new RegExp(`^[${otpChars}]{16}\$`);
|
||||
|
||||
function arrayToNumber(arr: number[]): number {
|
||||
// same as python struct.unpack("<I", arr)
|
||||
return (arr[3] << 24 | arr[2] << 16 | arr[1] << 8 | arr[0]) >>> 0;
|
||||
}
|
||||
|
||||
function numberToArray(num: number): number[] {
|
||||
return [num & 0xFF, (num >> 8) & 0xFF, (num >> 16) & 0xFF, (num >> 24) & 0xFF];
|
||||
}
|
||||
|
||||
function decodeHash(hash: string): number[] {
|
||||
let temp: number[] = [];
|
||||
for (let i = 0; i < hash.length; i += 2) {
|
||||
// TODO: check values
|
||||
temp.unshift(otpChars.indexOf(hash[i]) * 16 + otpChars.indexOf(hash[i + 1]));
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
function encodePassword(pwd: number[]): string {
|
||||
let n: number = arrayToNumber(pwd);
|
||||
let result: string = "";
|
||||
for (let i = 0; i < 8; i++) {
|
||||
result += pwdChars.charAt((n >> (21 - i * 3)) & 0x7);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// http://numericalrecipes.blogspot.com/2009/03/modular-multiplicative-inverse.html
|
||||
function extEuclideanAlg(a: Long, b: Long): [Long, Long, Long] {
|
||||
if (b.isZero()) {
|
||||
return [new Long(1), new Long(0), a];
|
||||
} else {
|
||||
let [x, y, gcd] = extEuclideanAlg(b, a.mod(b));
|
||||
return [y, x.sub(y.mul(a.div(b))), gcd];
|
||||
}
|
||||
}
|
||||
|
||||
function modInvEuclid(a: Long, m: Long): Long | undefined {
|
||||
let [x, , gcd] = extEuclideanAlg(a, m);
|
||||
if (gcd.eq(1)) {
|
||||
// hack for javascript modulo operation
|
||||
// https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers
|
||||
const temp = x.mod(m);
|
||||
return temp.gte(0) ? temp : temp.add(m);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method
|
||||
export function modularPow(base: Long, exponent: number, modulus: number): number {
|
||||
let result: Long = new Long(1, 0, true);
|
||||
|
||||
if (modulus === 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
base = base.mod(modulus);
|
||||
|
||||
while (exponent > 0) {
|
||||
if ((exponent & 1) === 1) {
|
||||
result = result.mul(base).mod(modulus);
|
||||
}
|
||||
exponent = exponent >> 1;
|
||||
base = base.mul(base).mod(modulus);
|
||||
}
|
||||
return result.toNumber();
|
||||
}
|
||||
|
||||
function rsaDecrypt(code: number[]): number[] {
|
||||
const low: number = arrayToNumber(code.slice(0, 4));
|
||||
const high: number = arrayToNumber(code.slice(4, 8));
|
||||
const c: Long = Long.fromBits(low, high, true);
|
||||
|
||||
const p: number = 2795287379;
|
||||
const q: number = 3544934711;
|
||||
const e = 41;
|
||||
const phi = (new Long(p - 1, 0, true)).mul(q - 1);
|
||||
const d: Long = modInvEuclid(new Long(e), phi) as Long;
|
||||
|
||||
const dp = d.mod(p - 1);
|
||||
const dq = d.mod(q - 1);
|
||||
const qinv: Long = modInvEuclid(new Long(q), new Long(p)) as Long;
|
||||
|
||||
const m1 = modularPow(c, dp.toNumber(), p);
|
||||
const m2 = modularPow(c, dq.toNumber(), q);
|
||||
let h: Long;
|
||||
|
||||
if (m1 < m2) {
|
||||
h = Long.fromValue(m1 - m2).add(p).mul(qinv).mod(p);
|
||||
} else {
|
||||
h = Long.fromValue(m1 - m2).mul(qinv).mod(p);
|
||||
}
|
||||
const m = h.mul(q).add(m2);
|
||||
return numberToArray(m.low).concat(numberToArray(m.high));
|
||||
}
|
||||
|
||||
export function sony4x4Keygen(hash: string): string {
|
||||
const numHash = decodeHash(hash);
|
||||
const pwd = rsaDecrypt(numHash);
|
||||
return encodePassword(pwd);
|
||||
}
|
||||
|
||||
export let sony4x4Solver = makeSolver({
|
||||
name: "sony4x4",
|
||||
description: "Sony 4x4",
|
||||
examples: ["73KR-3FP9-PVKH-K29R"],
|
||||
cleaner: (input: string) => input.trim().replace(/[-\s]/gi, "").toUpperCase(),
|
||||
inputValidator: (s) => inputRe.test(s),
|
||||
fun: (code: string) => {
|
||||
let res = sony4x4Keygen(code);
|
||||
return res ? [res] : [];
|
||||
}
|
||||
});
|
||||
+9
-2
@@ -7,6 +7,7 @@ export interface SolverDescription {
|
||||
readonly examples?: string[];
|
||||
fun: SolverFunction;
|
||||
inputValidator: Predicate<string>;
|
||||
cleaner?: (val: string) => string;
|
||||
}
|
||||
|
||||
export interface Solver {
|
||||
@@ -75,7 +76,7 @@ function cleanSerial(serial: string): string {
|
||||
export function makeSolver(description: SolverDescription): Solver {
|
||||
|
||||
let solver: any = (code: string) => {
|
||||
let cleanCode = cleanSerial(code);
|
||||
let cleanCode = solver.cleaner(code);
|
||||
if (description.inputValidator(cleanCode)) {
|
||||
return description.fun(cleanCode);
|
||||
} else {
|
||||
@@ -85,7 +86,13 @@ export function makeSolver(description: SolverDescription): Solver {
|
||||
|
||||
solver.biosName = description.name;
|
||||
solver.validator = description.inputValidator;
|
||||
solver.cleaner = cleanSerial;
|
||||
|
||||
if (description.cleaner) {
|
||||
solver.cleaner = description.cleaner;
|
||||
} else {
|
||||
solver.cleaner = cleanSerial;
|
||||
}
|
||||
|
||||
solver.keygen = description.fun;
|
||||
|
||||
if (description.examples) {
|
||||
|
||||
Reference in new issue
Block a user