Reorganize file structure

This commit is contained in:
Slava Bacherikov committed 2018-04-10 14:00:53 +03:00
1 parent f6888b8872
commit b8a8d37e36
24 files changed
+3 -2

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
import { asusKeygen, asusSolver } from "./asus";
// https://pastebin.com/L3c3rySj
describe("Test Asus keygen", () => {
it("Asus password for 2007-02-01 is AA19BALA", () => {
expect(asusKeygen(2007, 2, 1)).toEqual("AA19BALA");
});
it("Asus password for 2017-10-12 is AABABLAL", () => {
expect(asusKeygen(2017, 10, 12)).toEqual("AABABLAL");
});
it("Asus password for 2020-09-15 is LBD9DBA1", () => {
expect(asusKeygen(2020, 9, 15)).toEqual("LBD9DBA1");
});
it("Asus password for 2012-03-29 is AOBOBL2B", () => {
expect(asusKeygen(2012, 3, 29)).toEqual("AOBOBL2B");
});
it("Asus password for 2002-01-02 is ALAA4ABA", () => {
expect(asusKeygen(2002, 1, 2)).toEqual("ALAA4ABA");
});
});
describe("Test Asus solver", () => {
it("Asus password for 2007-02-01 is AA19BALA", () => {
expect(asusSolver("2007-02-01")).toEqual(["AA19BALA"]);
});
it("Asus password for 01-02-2007 is AA19BALA (dmy format)", () => {
expect(asusSolver("01-02-2007")).toEqual(["AA19BALA"]);
});
it("Asus password for 01022007 is AA19BALA (dmy format)", () => {
expect(asusSolver("01022007")).toEqual(["AA19BALA"]);
});
it("41022007 is bad date", () => {
expect(asusSolver("41022007")).toEqual([]);
});
});
+137
View File
@@ -0,0 +1,137 @@
// based on dogbert's pwgen-asus.py
/* tslint:disable:no-bitwise */
import { makeSolver } from "./utils";
function initTable(a1: number = 11, a2: number = 19, a3: number = 6): number[] {
let table: number[] = [];
const zeroCode = "0".charCodeAt(0);
table[0] = a1 + zeroCode;
table[1] = a2 + zeroCode;
table[2] = a3 + zeroCode;
table[3] = "6".charCodeAt(0);
table[4] = "7".charCodeAt(0);
table[5] = "8".charCodeAt(0);
table[6] = "9".charCodeAt(0);
let chksum: number = table.reduce((acc, val) => acc + val, 0);
for (let i = 7; i < 32; i++) {
chksum = (33676 * chksum + 12345) >>> 0;
table[i] = ((chksum >> 16) & 0x7FFF) % 43 + zeroCode;
}
let v3 = a1 * a2;
let v4 = shuffle1((a1 - 1) * (a2 - 1), a3);
return table.map((value) => shuffle2(value - zeroCode, v4, v3));
}
function shuffle1(a1: number, a2: number): number {
let v3 = 2;
for (let i = 0; i < a2; i++) {
let v4 = v3;
let v5 = a1;
while (v5 > 0) {
if (v5 < v4) {
[v5, v4] = [v4, v5];
}
v5 %= v4;
}
if (v4 !== 1) {
v3++;
}
}
return v3;
}
function shuffle2(a1: number, a2: number, a3: number): number {
if (a1 >= a3) {
a1 %= a3;
}
let result = a1;
if (a2 !== 1) {
for (let i = 0; i < a2 - 1; i++) {
result = a1 * result % a3;
}
}
return result;
}
function leftPad(base: string, len: number, fill: string = " ") {
const padding = len - base.length;
for (let i = 0; i < padding; i++) {
base = fill + base;
}
return base;
}
function makeDateRegexp(): [RegExp, RegExp] {
let years: string[] = [];
let months: string[] = [];
let days: string[] = [];
for (let year = 1990; year <= 2100; year++) {
years.push(leftPad(year.toString(), 4, "0"));
}
for (let month = 1; month <= 12; month++) {
months.push(leftPad(month.toString(), 2, "0"));
}
for (let day = 1; day <= 31; day++) {
days.push(leftPad(day.toString(), 2, "0"));
}
let ymdre = new RegExp(`(${years.join("|")})(${months.join("|")})(${days.join("|")})`);
let dmyre = new RegExp(`(${days.join("|")})(${months.join("|")})(${years.join("|")})`);
return [ymdre, dmyre];
}
const asusTable = initTable();
const [ymdRegex, dmyRegex] = makeDateRegexp();
export function asusKeygen(year: number, month: number, day: number): string {
const date = leftPad(year.toString(), 4, "0") +
leftPad(month.toString(), 2, "0") +
leftPad(day.toString(), 2, "0");
let chksum = parseInt(date, 16);
let password: string = "";
for (let i = 0; i < 8; i++) {
chksum = (33676 * chksum + 12345) >>> 0;
let index = (chksum >> 16) & 31;
let pwdChar = asusTable[index] % 36;
if (pwdChar > 9) {
password += String.fromCharCode(pwdChar + "7".charCodeAt(0));
} else {
password += String.fromCharCode(pwdChar + "0".charCodeAt(0));
}
}
return password;
}
export let asusSolver = makeSolver({
name: "asusDate",
description: "ASUS (Using date)",
examples: ["2010-02-03"],
inputValidator: (s) => s.length === 8,
fun: (code) => {
let result: string[] = [];
if (ymdRegex.test(code)) {
let year = parseInt(code.slice(0, 4), 10);
let month = parseInt(code.slice(4, 6), 10);
let day = parseInt(code.slice(6, 8), 10);
result.push(asusKeygen(year, month, day));
}
if (dmyRegex.test(code)) {
let day = parseInt(code.slice(0, 2), 10);
let month = parseInt(code.slice(2, 4), 10);
let year = parseInt(code.slice(4, 8), 10);
result.push(asusKeygen(year, month, day));
}
return result;
}
});
+198
View File
@@ -0,0 +1,198 @@
// OPENSRC-1D3B = S3yJ91q0Gar3O72I
// ABCDEFG-1D3B xvn0qEeftqyrkG52
// NOSOUP4-3A5B zvd97y9h
// 7G9C0G2-6FF1 35c0b0tVb32Z6ivD
//
//
// HDD SN WXH109A14712 ?
import {
calculateSuffix, dellHddSolver, dellSolver, DellTag, hddOldSolver, keygenDell, SuffixType
} from "./dell";
// shortcut for simpler testing
function checkSuffix(serial: string, tag: DellTag, type: SuffixType): number[] {
serial = serial.concat(tag);
let serialArr: number[] = serial.split("").map((c) => c.charCodeAt(0));
return calculateSuffix(serialArr, tag, type);
}
describe("Test calculateSuffix", () => {
it("Check tag suffix for: 1234567-595B", () => {
let suffix = checkSuffix("1234567", DellTag.Tag595B, SuffixType.ServiceTag);
expect(suffix).toEqual([25, 34, 38, 8, 32, 48, 23, 8]);
});
it("Check tag suffix for: 1234567-D35B", () => {
let suffix = checkSuffix("1234567", DellTag.TagD35B, SuffixType.ServiceTag);
expect(suffix).toEqual([25, 34, 38, 8, 32, 48, 23, 8]);
});
it("Check tag suffix for: 1234567-2A7B", () => {
let suffix = checkSuffix("1234567", DellTag.Tag2A7B, SuffixType.ServiceTag);
expect(suffix).toEqual([101, 103, 102, 117, 115, 100, 97, 117]);
});
it("Check tag suffix for: 1234567-A95B", () => {
let suffix = checkSuffix("1234567", DellTag.TagA95B, SuffixType.ServiceTag);
expect(suffix).toEqual([25, 34, 38, 8, 32, 48, 23, 8]);
});
it("Check tag suffix for: 1234567-1D3B", () => {
let suffix = checkSuffix("1234567", DellTag.Tag1D3B, SuffixType.ServiceTag);
expect(suffix).toEqual([65, 78, 57, 72, 97, 56, 80, 72]);
});
it("Check tag suffix for: 1234567-6FF1", () => {
let suffix = checkSuffix("1234567", DellTag.Tag6FF1, SuffixType.ServiceTag);
expect(suffix).toEqual([51, 73, 56, 52, 76, 122, 71, 52]);
});
it("Check tag suffix for: 1234567-1F66", () => {
let suffix = checkSuffix("1234567", DellTag.Tag1F66, SuffixType.ServiceTag);
expect(suffix).toEqual([117, 66, 48, 111, 83, 107, 85, 111]);
});
// HDD
it("Check hdd suffix for: 12345678901-595B", () => {
let suffix = checkSuffix("12345678901", DellTag.Tag595B, SuffixType.HDD);
expect(suffix).toEqual([5, 9, 35, 6, 47, 5, 21, 32]);
});
it("Check hdd suffix for: 12345678901-D35B", () => {
let suffix = checkSuffix("12345678901", DellTag.TagD35B, SuffixType.HDD);
expect(suffix).toEqual([5, 9, 35, 6, 47, 5, 21, 32]);
});
it("Check hdd suffix for: 12345678901-2A7B", () => {
let suffix = checkSuffix("12345678901", DellTag.Tag2A7B, SuffixType.HDD);
expect(suffix).toEqual([48, 51, 113, 98, 107, 48, 99, 115]);
});
it("Check hdd suffix for: 12345678901-A95B", () => {
let suffix = checkSuffix("12345678901", DellTag.TagA95B, SuffixType.HDD);
expect(suffix).toEqual([5, 9, 35, 6, 47, 5, 21, 32]);
});
it("Check hdd suffix for: 12345678901-1D3B", () => {
let suffix = checkSuffix("12345678901", DellTag.Tag1D3B, SuffixType.HDD);
expect(suffix).toEqual([48, 73, 55, 118, 76, 48, 99, 97]);
});
it("Check hdd suffix for: 12345678901-6FF1", () => {
let suffix = checkSuffix("12345678901", DellTag.Tag6FF1, SuffixType.HDD);
expect(suffix).toEqual([48, 112, 75, 86, 101, 48, 77, 76]);
});
it("Check hdd suffix for: 12345678901-1F66", () => {
let suffix = checkSuffix("12345678901", DellTag.Tag1F66, SuffixType.HDD);
expect(suffix).toEqual([48, 114, 79, 71, 55, 48, 49, 83]);
});
});
describe("Test keygenDell", () => {
it("Dell password for: 1234567-595B", () => {
expect(keygenDell("1234567", DellTag.Tag595B, SuffixType.ServiceTag))
.toEqual("46rg65ky");
});
it("Dell password for: 1234567-D35B", () => {
expect(keygenDell("1234567", DellTag.TagD35B, SuffixType.ServiceTag))
.toEqual("5tc8q9re");
});
it("Dell password for: 1234567-2A7B", () => {
expect(keygenDell("1234567", DellTag.Tag2A7B, SuffixType.ServiceTag))
.toEqual("J1KuwWpSUgnDarfi");
});
it("Dell password for: 1234567-A95B", () => {
expect(keygenDell("1234567", DellTag.TagA95B, SuffixType.ServiceTag))
.toEqual("46rg65ky");
});
it("Dell password for: 1234567-1D3B", () => {
expect(keygenDell("1234567", DellTag.Tag1D3B, SuffixType.ServiceTag))
.toEqual("Sn4fkF8bS57NymZl");
});
it("Dell password for: 1234567-1F66", () => {
expect(keygenDell("1234567", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("kIpTBzx0m3s10JDR");
});
it("Dell password for: 1234567-6FF1", () => {
expect(keygenDell("1234567", DellTag.Tag6FF1, SuffixType.ServiceTag))
.toEqual("Rzn1wGe555H5bM2r");
});
it("Dell password for: OPENSRC-1D3B", () => {
expect(keygenDell("OPENSRC", DellTag.Tag1D3B, SuffixType.ServiceTag))
.toEqual("S3yJ91q0Gar3O72I");
});
it("Dell password for: ABCDEFG-1D3B", () => {
expect(keygenDell("ABCDEFG", DellTag.Tag1D3B, SuffixType.ServiceTag))
.toEqual("xvn0qEeftqyrkG52");
});
it("Dell password for: 7G9C0G2-6FF1", () => {
expect(keygenDell("7G9C0G2", DellTag.Tag6FF1, SuffixType.ServiceTag))
.toEqual("35c0b0tVb32Z6ivD");
});
it("Dell password for: DELLSUX-1F66", () => {
expect(keygenDell("DELLSUX", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("qHXaL0ntli6Gu4c0");
});
it("Dell password for: CRPP562-1F66", () => {
expect(keygenDell("CRPP562", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("8i5qLGa9woA919Ys");
});
it("Dell password for: CDG8T32-1F66", () => {
expect(keygenDell("CDG8T32", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("4Ke3y2L3kTP2f6Vo");
});
it("Dell password for: 8M5RQ32-1F66", () => {
expect(keygenDell("8M5RQ32", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("3rlrbaSj46Iw221g");
});
// HDD
it("Dell HDD password for: 1234567890A-595B", () => {
expect(keygenDell("1234567890A", DellTag.Tag595B, SuffixType.HDD))
.toEqual("nyoap4lq");
});
it("Dell HDD password for: 1234567890A-D35B", () => {
expect(keygenDell("1234567890A", DellTag.TagD35B, SuffixType.HDD))
.toEqual("dc14blrd");
});
it("Dell HDD password for: 1234567890A-2A7B", () => {
expect(keygenDell("1234567890A", DellTag.Tag2A7B, SuffixType.HDD))
.toEqual("h6lwdi91qluUyt3u");
});
it("Dell HDD password for: 1234567890A-A95B", () => {
expect(keygenDell("1234567890A", DellTag.TagA95B, SuffixType.HDD))
.toEqual("qr0s6x4n");
});
it("Dell HDD password for: 1234567890A-1D3B", () => {
expect(keygenDell("1234567890A", DellTag.Tag1D3B, SuffixType.HDD))
.toEqual("6JQ1WacHNNR0Taia");
});
it("Dell HDD password for: 1234567890A-1F66", () => {
expect(keygenDell("1234567890A", DellTag.Tag1F66, SuffixType.HDD))
.toEqual("vP0M31x066Z7Rq9p");
});
it("Dell HDD password for: 1234567890A-6FF1", () => {
expect(keygenDell("1234567890A", DellTag.Tag6FF1, SuffixType.HDD))
.toEqual("5enLLpM3Immfb8CK");
});
});
describe("Test Dell BIOS", () => {
it("Dell for 12345678901 is yyyyyhnn", () => {
expect(hddOldSolver("12345678901")).toEqual(["yyyyyhnn"]);
});
it("Dell for 1234567-595B", () => {
expect(dellSolver("1234567-595B")).toEqual(["46rg65ky"]);
});
it("Dell for: 1234567-1F66", () => {
expect(dellSolver("1234567-1f66")).toEqual(["kIpTBzx0m3s10JDR"]);
});
it("Dell HDD for: 1234567890A-595B", () => {
expect(dellHddSolver("1234567890A-595b")).toEqual(["nyoap4lq"]);
});
it("Check bad dell tag", () => {
expect(dellSolver("1234567-BAD1")).toEqual([]);
expect(dellSolver("1234567-TOLONG")).toEqual([]);
expect(dellHddSolver("1234567-SHORT")).toEqual([]);
});
});
+370
View File
@@ -0,0 +1,370 @@
/* tslint:disable:no-bitwise */
import { DellTag } from "./types";
const md5magic = [
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
].map((v) => v | 0);
const md5magic2 = [
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039
].map((v) => v | 0);
const rotationTable = [
[7, 12, 17, 22],
[5, 9, 14, 20],
[4, 11, 16, 23],
[6, 10, 15, 21]
];
const initialData = [
0x67452301 | 0,
0xEFCDAB89 | 0,
0x98BADCFE | 0,
0x10325476 | 0
];
type SumFunction = (a: number, b: number) => number;
type EncFunction = (a: number, b: number, c: number) => number;
interface Encoder {
encode(data: number[]): number[];
}
function rol(x: number, bitsrot: number): number {
// n >>> 0 used to convert signed number to unsigned
// (unsigned(x) >> (32 - bitsrot)) | (unsigned(x) << bitsrot);
return ((x >>> 0) / Math.pow(2, 32 - bitsrot)) | (((x >>> 0) << bitsrot) | 0 );
}
function encF2(num1: number, num2: number, num3: number): number {
return ((num3 ^ num2) & num1) ^ num3;
}
function encF3(num1: number, num2: number, num3: number): number {
return ((num1 ^ num2) & num3) ^ num2;
}
function encF4(num1: number, num2: number, num3: number): number {
return (num2 ^ num1) ^ num3;
}
function encF5(num1: number, num2: number, num3: number): number {
return (num1 | ~num3) ^ num2;
}
function encF1(num1: number, num2: number): number {
return (num1 + num2) | 0;
}
// Negative functions
function encF1N(num1: number, num2: number): number {
return (num1 - num2) | 0;
}
function encF2N(num1: number, num2: number, num3: number): number {
return encF2(num1, num2, ~num3);
}
function encF4N(num1: number, num2: number, num3: number): number {
return encF4(num1, ~num2, num3);
}
function encF5N(num1: number, num2: number, num3: number): number {
return encF5(~num1, num2, num3);
}
class Tag595BEncoder {
protected encBlock: number[];
protected encData: number[];
protected A: number;
protected B: number;
protected C: number;
protected D: number;
protected f1: SumFunction = encF1N;
protected f2: EncFunction = encF2N;
protected f3: EncFunction = encF3;
protected f4: EncFunction = encF4N;
protected f5: EncFunction = encF5N;
protected md5table: number[] = md5magic;
constructor(encBlock: number[]) {
this.encBlock = encBlock;
this.encData = initialData.slice();
this.A = this.encData[0];
this.B = this.encData[1];
this.C = this.encData[2];
this.D = this.encData[3];
}
protected calculate(func: EncFunction, key1: number, key2: number): number {
let temp = func(this.B, this.C, this.D);
return this.A + this.f1(temp, this.md5table[key2] + this.encBlock[key1]) | 0;
}
protected incrementData() {
this.encData[0] += this.A;
this.encData[1] += this.B;
this.encData[2] += this.C;
this.encData[3] += this.D;
this.encData.forEach((val, index) => {
this.encData[index] = val | 0;
});
}
public makeEncode(): void {
let t: number = 0;
for (let i = 0; i < 64; i++) {
switch (i >> 4) {
case 0:
t = this.calculate(this.f2, i & 15, i); // Use half byte
break;
case 1:
t = this.calculate(this.f3, (i * 5 + 1) & 15, i);
break;
case 2:
t = this.calculate(this.f4, (i * 3 + 5) & 15, i);
break;
case 3:
t = this.calculate(this.f5, (i * 7) & 15, i);
break;
}
this.A = this.D;
this.D = this.C;
this.C = this.B;
this.B = rol(t, rotationTable[i >> 4][i & 3]) + this.B | 0;
}
this.incrementData();
}
public result(): number[] {
return this.encData.map((v) => v | 0);
}
public static encode(encBlock: number[]): number[] {
let obj = new this(encBlock);
obj.makeEncode();
return obj.result();
}
}
class TagD35BEncoder extends Tag595BEncoder {
protected f1 = encF1;
protected f2 = encF2;
protected f3 = encF3;
protected f4 = encF4;
protected f5 = encF5;
}
class Tag1D3BEncoder extends Tag595BEncoder {
protected f1 = encF1N;
protected f2 = encF2N;
protected f3 = encF3;
protected f4 = encF4N;
protected f5 = encF5N;
public makeEncode(): void {
for (let j = 0; j < 21; j++) {
this.A |= 0x97;
this.B ^= 0x8;
this.C |= 0x60606161 - j;
this.D ^= 0x50501010 + j;
super.makeEncode();
}
}
}
class Tag1F66Encoder extends Tag595BEncoder {
protected f1 = encF1N;
protected f2 = encF2N;
protected f3 = encF3;
protected f4 = encF4N;
protected f5 = encF5N;
protected md5table = md5magic2;
public makeEncode(): void {
let t: number = 0;
for (let j = 0; j < 17; j++) {
this.A |= 0x100097;
this.B ^= 0xA0008;
this.C |= 0x60606161 - j;
this.D ^= 0x50501010 + j;
for (let i = 0; i < 64; i++) {
switch (i >> 4) {
case 0:
t = this.calculate(this.f2, i & 15, i + 16 | 0);
break;
case 1:
t = this.calculate(this.f3, (i * 5 + 1) & 15, i + 32 | 0);
break;
case 2:
t = this.calculate(this.f4, (i * 3 + 5) & 15, i - 2 * (i & 12) + 12);
break;
case 3:
t = this.calculate(this.f5, (i * 7) & 15, 2 * (i & 3) - (i & 15) + 12);
break;
}
this.A = this.D;
this.D = this.C;
this.C = this.B;
this.B = rol(t, rotationTable[i >> 4][i & 3]) + this.B | 0;
}
this.incrementData();
}
for (let j = 0; j < 21; j++) {
this.A |= 0x97;
this.B ^= 0x8;
this.C |= 0x50501010 - j;
this.D ^= 0x60606161 + j;
for (let i = 0; i < 64; i++) {
switch (i >> 4) {
case 0:
t = this.calculate(this.f4, (i * 3 + 5) & 15, 2 * (i & 3) - i + 44);
break;
case 1:
t = this.calculate(this.f5, (i * 7) & 15, 2 * (i & 3) - i + 76);
break;
case 2:
t = this.calculate(this.f2, i & 15, (i & 15) | 0);
break;
case 3:
t = this.calculate(this.f3, (i * 5 + 1) & 15, i - 32 | 0);
break;
}
let g = (i >> 4) + 2;
this.A = this.D;
this.D = this.C;
this.C = this.B;
this.B = rol(t, rotationTable[g & 3][i & 3]) + this.B | 0;
}
this.incrementData();
}
}
}
class Tag6FF1Encoder extends Tag595BEncoder {
protected f1 = encF1N;
protected f2 = encF2N;
protected f3 = encF3;
protected f4 = encF4N;
protected f5 = encF5N;
protected md5table = md5magic2;
public makeEncode(): void {
let t: number = 0;
for (let j = 0; j < 23; j++) {
this.A |= 0xA08097;
this.B ^= 0xA010908;
this.C |= 0x60606161 - j;
this.D ^= 0x50501010 + j;
for (let i = 0; i < 64; i++) {
let k = (i & 15) - ((i & 12) << 1) + 12;
switch (i >> 4) {
case 0:
t = this.calculate(this.f2, i & 15, i + 32 | 0);
break;
case 1:
t = this.calculate(this.f3, (i * 5 + 1) & 15, (i & 15) | 0);
break;
case 2:
t = this.calculate(this.f4, (i * 3 + 5) & 15, k + 16 | 0);
break;
case 3:
t = this.calculate(this.f5, (i * 7) & 15, k + 48 | 0);
break;
}
this.A = this.D;
this.D = this.C;
this.C = this.B;
this.B = rol(t, rotationTable[i >> 4][i & 3]) + this.B | 0;
}
this.incrementData();
}
for (let j = 0; j < 17; j++) {
this.A |= 0x100097;
this.B ^= 0xA0008;
this.C |= 0x50501010 - j;
this.D ^= 0x60606161 + j;
for (let i = 0; i < 64; i++) {
let k = (i & 15) - ((i & 12) << 1) + 12;
switch (i >> 4) {
case 0:
t = this.calculate(this.f4, ((i & 15) * 3 + 5) & 15, k + 16);
break;
case 1:
t = this.calculate(this.f5, ((i & 3) * 7 + (i & 12) + 4) & 15, (i & 15) + 32);
break;
case 2:
t = this.calculate(this.f2, k & 15, k);
break;
case 3:
t = this.calculate(this.f3, ((i & 15) * 5 + 1) & 15, (i & 15) + 48);
break;
}
let g = (i >> 4) + 2;
this.A = this.D;
this.D = this.C;
this.C = this.B;
this.B = rol(t, rotationTable[g & 3][i & 3]) + this.B | 0;
}
this.incrementData();
}
}
}
const encoders: {readonly [P in DellTag]: Encoder} = {
"595B": Tag595BEncoder,
"2A7B": Tag595BEncoder, // same as 595B
"A95B": Tag595BEncoder, // same as 595B
"1D3B": Tag1D3BEncoder,
"D35B": TagD35BEncoder,
"1F66": Tag1F66Encoder,
"6FF1": Tag6FF1Encoder
};
export function blockEncode(encBlock: number[], tag: DellTag): number[] {
return encoders[tag].encode(encBlock);
}
+240
View File
@@ -0,0 +1,240 @@
/* tslint:disable:no-bitwise */
import { makeSolver } from "../utils";
import { blockEncode } from "./encode";
import { DellTag, SuffixType } from "./types";
export { DellTag, SuffixType};
const scanCodes: string =
"\0\x1B1234567890-=\x08\x09qwertyuiop[]\x0D\xFFasdfghjkl;'`\xFF\\zxcvbnm,./";
const encscans: number[] = [
0x05, 0x10, 0x13, 0x09, 0x32, 0x03, 0x25, 0x11, 0x1F, 0x17, 0x06, 0x15,
0x30, 0x19, 0x26, 0x22, 0x0A, 0x02, 0x2C, 0x2F, 0x16, 0x14, 0x07, 0x18,
0x24, 0x23, 0x31, 0x20, 0x1E, 0x08, 0x2D, 0x21, 0x04, 0x0B, 0x12, 0x2E
];
const extraCharacters: {readonly [P in DellTag]?: string} = {
"2A7B": "012345679abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0",
"1D3B": "0BfIUG1kuPvc8A9Nl5DLZYSno7Ka6HMgqsJWm65yCQR94b21OTp7VFX2z0jihE33d4xtrew0",
"1F66": "0ewr3d4xtUG1ku0BfIp7VFb21OTSno7KDLZYqsJWa6HMgCQR94m65y9Nl5Pvc8AjihE3X2z0",
"6FF1": "08rptBxfbGVMz38IiSoeb360MKcLf4QtBCbWVzmH5wmZUcRR5DZG2xNCEv1nFtzsZB2bw1X0"
};
/*
* Does this really work somewhere ?
* Depends only in first two chars
* Input: 11 symbols
*/
function keygenHddOld(serial: string): string {
let serialArr: number[] = serial.split("").map((c) => c.charCodeAt(0));
// encscans[26], encscans[0xAA % encscans.length]
let ret: number[] = [49, 49, 49, 49, 49];
ret.push(serialArr[1] >> 1);
ret.push((serialArr[1] >> 6) | (serialArr[0] << 2));
ret.push(serialArr[0] >> 3);
// lower bits then 5 are never change
for (let i = 0; i < 8; i++) {
let r = 0xAA;
if (ret[i] & 8) {
r ^= serialArr[1];
}
if (ret[i] & 16) {
r ^= serialArr[0];
}
ret[i] = encscans[r % encscans.length];
}
return ret.map((c) => scanCodes.charAt(c)).join("");
}
export function calculateSuffix(serial: number[], tag: DellTag, type: SuffixType): number[] {
let suffix: number[] = [];
let codesTable: number[];
let arr1: number[];
let arr2: number[];
if (type === SuffixType.ServiceTag) {
arr1 = [1, 2, 3, 4];
arr2 = [4, 3, 2];
} else {
// SuffixType.HDD
arr1 = [1, 10, 9, 8];
arr2 = [8, 9, 10];
}
suffix[0] = serial[arr1[3]];
suffix[1] = (serial[arr1[3]] >> 5) |
(((serial[arr1[2]] >> 5) | (serial[arr1[2]] << 3)) & 0xF1);
suffix[2] = serial[arr1[2]] >> 2;
suffix[3] = (serial[arr1[2]] >> 7) | (serial[arr1[1]] << 1);
suffix[4] = (serial[arr1[1]] >> 4) | (serial[arr1[0]] << 4);
suffix[5] = serial[1] >> 1;
suffix[6] = (serial[1] >> 6) | (serial[0] << 2);
suffix[7] = serial[0] >> 3;
// normalize bytes
suffix.forEach((v, i) => {
suffix[i] = v & 0xFF;
});
let table = extraCharacters[tag];
if (table !== undefined) {
codesTable = table.split("").map((s) => s.charCodeAt(0));
} else {
codesTable = encscans;
}
for (let i = 0; i < 8; i++) {
let r = 0xAA;
if (suffix[i] & 1) {
r ^= serial[arr2[0] ];
}
if (suffix[i] & 2) {
r ^= serial[arr2[1]];
}
if (suffix[i] & 4) {
r ^= serial[arr2[2]];
}
if (suffix[i] & 8) {
r ^= serial[1];
}
if (suffix[i] & 16) {
r ^= serial[0];
}
suffix[i] = codesTable[r % codesTable.length];
}
return suffix;
}
function resultToString(arr: number[], tag: DellTag): string {
let r = arr[0] % 9;
let result = "";
let table = extraCharacters[tag];
for (let i = 0; i < 16; i++) {
if (table !== undefined) {
result += table.charAt(arr[i] % table.length);
} else if (r <= i && result.length < 8) { // 595B, D35B, A95B
result += scanCodes.charAt(encscans[arr[i] % encscans.length]);
}
}
return result;
}
/*
* 7 symbols + 4 symbols ( 595B, D35B, 2A7B, A95B, 1D3B etc...)
* serial -- serial number without tag, 7 symbols for ServiceTag, 11 symbols for HDD
* tag -- tag string
*/
export function keygenDell(serial: string, tag: DellTag, type: SuffixType): string {
let fullSerial: string;
function byteArrayToInt(arr: number[]): number[] {
// convert byte array to 32-bit little-endian int array
// also will convert undefined values to 0
let resultLength = arr.length >> 2; // divide length to 4
let result: number[] = [];
for (let i = 0; i <= resultLength; i++) {
result[i] = arr[i * 4] | (arr[i * 4 + 1] << 8) |
(arr[i * 4 + 2] << 16) | (arr[i * 4 + 3] << 24) | 0;
}
return result;
}
function intArrayToByte(arr: number[]): number[] {
// convert 32-bit little-endian array to byte array
let result: number[] = [];
arr.forEach((num) => {
result.push(num & 0xFF);
result.push((num >> 8) & 0xFF);
result.push((num >> 16) & 0xFF);
result.push((num >> 24) & 0xFF);
});
return result;
}
if (tag === DellTag.TagA95B) {
if (type === SuffixType.ServiceTag) {
fullSerial = serial + DellTag.Tag595B as string;
} else { // HDD
fullSerial = serial.slice(3) + "\0\0\0" + DellTag.Tag595B as string;
}
} else {
fullSerial = serial + tag as string;
}
let fullSerialArray: number[] = [];
// convert string to byte array
for (let i = 0; i < fullSerial.length; i++) {
// Maybe protect against unicode symbols with: charCode & 0xFF ?
fullSerialArray.push(fullSerial.charCodeAt(i));
}
fullSerialArray = fullSerialArray.concat(calculateSuffix(fullSerialArray, tag, type));
const cnt = 23;
// NOTE: after this array might contain undefined values
fullSerialArray[cnt] = 0x80;
let encBlock = byteArrayToInt(fullSerialArray);
// fill empty values with zeros
for (let i = 0; i < 16; i++) {
if (encBlock[i] === undefined) {
encBlock[i] = 0;
}
}
encBlock[14] = cnt << 3;
let decodedBytes = intArrayToByte(blockEncode(encBlock, tag));
return resultToString(decodedBytes, tag);
}
function checkDellTag(tag: string): boolean {
tag = tag.toUpperCase();
for (let tagItem in DellTag) {
if (tag === DellTag[tagItem]) {
return true;
}
}
return false;
}
export let hddOldSolver = makeSolver({
name: "dellHDDOld",
description: "Dell HDD Serial Number (old)",
examples: ["12345678901"],
inputValidator: (s) => s.length === 11,
fun: (s) => [keygenHddOld(s)]
});
export let dellSolver = makeSolver({
name: "dellTag",
description: "Dell from serial number",
examples: ["1234567-595B", "1234567-1D3B"],
inputValidator: (password: string) => {
if (password.length !== 11) {
return false;
} else {
return checkDellTag(password.slice(7, 11));
}
},
fun: (password: string) => {
let suffix = password.slice(7, 11).toUpperCase();
return [keygenDell(password.slice(0, 7), suffix as DellTag, SuffixType.ServiceTag)];
}
});
export let dellHddSolver = makeSolver({
name: "dellHddNew",
description: "Dell from hdd serial number",
examples: ["1234567890A-595B"],
inputValidator: (password: string) => {
if (password.length !== 15) {
return false;
} else {
return checkDellTag(password.slice(11, 15));
}
},
fun: (password: string) => {
let suffix = password.slice(11, 15).toUpperCase();
return [keygenDell(password.slice(0, 11), suffix as DellTag, SuffixType.HDD)];
}
});
+15
View File
@@ -0,0 +1,15 @@
export enum DellTag {
Tag595B = "595B",
TagD35B = "D35B",
Tag2A7B = "2A7B",
TagA95B = "A95B",
Tag1D3B = "1D3B",
Tag6FF1 = "6FF1",
Tag1F66 = "1F66"
}
export const enum SuffixType {
ServiceTag,
HDD
}
+48
View File
@@ -0,0 +1,48 @@
import { fsi20DecNewSolver, fsi20DecOldSolver, fsiHexSolver } from "./fsi";
describe("Test Fujitsu-Siemens 5x4 hexadecimal BIOS", () => {
it("FSI key for 1234-4321-1234-4321-1234 is 35682708", () => {
expect(fsiHexSolver("1234-4321-1234-4321-1234")).toEqual(["35683789"]);
});
it("FSI key for AAAA-BBBB-CCCC-DEAD-BEEF is 64830592", () => {
expect(fsiHexSolver("AAAA-BBBB-CCCC-DEAD-BEEF")).toEqual(["64830592"]);
expect(fsiHexSolver("AAAABBBBCCCCDEADBEEF")).toEqual(["64830592"]);
});
it("FSI key for DEADBEEF is 64830592", () => {
expect(fsiHexSolver("DEADBEEF")).toEqual(["64830592"]);
});
it("test invalid keys", () => {
expect(fsiHexSolver("AAAA-BBBB-CCCC-DEAD-CODE")).toEqual([]);
expect(fsiHexSolver("AAAA-BBBB-CCCC-DEAD-BEEF-12")).toEqual([]);
});
});
describe("Test Fujitsu-Siemens 5x4 decimal new", () => {
it("FSI key for 1234-4321-1234-4321-1234 is 7122790", () => {
expect(fsi20DecNewSolver("1234-4321-1234-4321-1234")).toEqual(["7122790"]);
});
it("FSI key for 7234-4321-1234-4321-1234 is 3122790", () => {
expect(fsi20DecNewSolver("7234-4321-1234-4321-1234")).toEqual(["3122790"]);
});
it("test invalid keys", () => {
expect(fsi20DecNewSolver("1234-4321-1234-4321-1234-1")).toEqual([]);
expect(fsi20DecNewSolver("1234-4321-1234-4321-BEEF")).toEqual([]);
});
});
describe("Test Fujitsu-Siemens 5x4 decimal old", () => {
it("FSI key for 1234-4321-1234-4321-1234 is 10cphf0b", () => {
expect(fsi20DecOldSolver("1234-4321-1234-4321-1234")).toEqual(["10cphf0b"]);
});
it("FSI key for 7234-4321-1234-4321-1234 is 10cphf0b", () => {
expect(fsi20DecOldSolver("7234-4321-1234-4321-1234")).toEqual(["90ldhf0b"]);
});
it("test invalid keys", () => {
expect(fsi20DecOldSolver("1234-4321-1234-4321-1234-1")).toEqual([]);
expect(fsi20DecOldSolver("1234-4321-1234-4321-BEEF")).toEqual([]);
});
});
+147
View File
@@ -0,0 +1,147 @@
import { makeSolver } from "./utils";
/* tslint:disable:no-bitwise */
function generateCRC16Table(): number[] {
let table: number[] = [];
for (let i = 0, crc = 0; i < 256; i++) {
crc = (i << 8);
for (let j = 0; j < 8; j++) {
crc = (crc << 1);
if (crc & 0x10000) {
crc = crc ^ 0x1021;
}
}
table.push(crc & 0xFFFF);
}
return table;
}
const crc16Table = generateCRC16Table();
/* For Fujinsu-Siemens. 8 or 5x4 hexadecimal digits. */
function fsiHexKeygen(serial: string): string {
function hashToString(hash: number) {
const zero = "0".charCodeAt(0);
return [12, 8, 4, 0].reduce((acc, num) => {
let temp = String.fromCharCode(zero + ((hash >> num) % 16) % 10);
return acc + temp;
}, "");
}
function calculateHash(word: string, table: number[]) {
let hash = 0;
for (let i = 0, d = 0; i < word.length; i++) {
d = table[(word.charCodeAt(i) ^ (hash >> 8)) % 256];
hash = ((hash << 8) ^ d) & 0xFFFF ;
}
return hash;
}
if (serial.length === 20) {
serial = serial.slice(12, 20);
}
return hashToString(calculateHash(serial.slice(0, 4), crc16Table)) +
hashToString(calculateHash(serial.slice(4, 8), crc16Table));
}
/* For Fujinsu-Siemens. 5x4 dicimal digits */
function fsi20DecOldKeygen(serial: string): string {
function swap<T>(arr: T[], i1: number, i2: number): void {
const temp = arr[i1];
arr[i1] = arr[i2];
arr[i2] = temp;
}
// opArr - array with that operations do, ar1,ar2 - numbers */
function interleave(opArr: number[], ar1: number[], ar2: number[]) {
let arr = opArr.slice(0); // copy array
arr[ar1[0]] = ((opArr[ar2[0]] >> 4) | (opArr[ar2[3]] << 4)) & 0xFF;
arr[ar1[1]] = ((opArr[ar2[0]] & 0x0F) | (opArr[ar2[3]] & 0xF0));
arr[ar1[2]] = ((opArr[ar2[1]] >> 4) | (opArr[ar2[2]] << 4) & 0xFF);
arr[ar1[3]] = (opArr[ar2[1]] & 0x0F) | (opArr[ar2[2]] & 0xF0);
return arr;
}
function codeToBytes(code: string): number[] {
const numbers = [
parseInt(code.slice(0, 5), 10),
parseInt(code.slice(5, 10), 10),
parseInt(code.slice(10, 15), 10),
parseInt(code.slice(15, 20), 10)
];
let acc = [];
for (let val of numbers) {
acc.push(val % 256);
acc.push(Math.floor(val / 256));
}
return acc;
}
function decryptCode_old(bytes: number[]) {
const xorKey = ":3-v@e4i";
// apply XOR key
bytes.forEach((val, i, arr) => {
arr[i] = val ^ xorKey.charCodeAt(i);
});
// swap two bytes
swap(bytes, 2, 6);
swap(bytes, 3, 7);
bytes = interleave(bytes, [0, 1, 2, 3], [0, 1, 2, 3]);
bytes = interleave(bytes, [4, 5, 6, 7], [6, 7, 4, 5]);
// final rotations
bytes[0] = ((bytes[0] << 3) & 0xFF) | (bytes[0] >> 5);
bytes[1] = ((bytes[1] << 5) & 0xFF) | (bytes[1] >> 3);
bytes[2] = ((bytes[2] << 7) & 0xFF) | (bytes[2] >> 1);
bytes[3] = ((bytes[3] << 4) & 0xFF) | (bytes[3] >> 4);
bytes[5] = ((bytes[5] << 6) & 0xFF) | (bytes[5] >> 2);
bytes[6] = ((bytes[6] << 1) & 0xFF) | (bytes[6] >> 7);
bytes[7] = ((bytes[7] << 2) & 0xFF) | (bytes[7] >> 6);
// len(solution space) = 10 + 26
bytes = bytes.map((b) => b % 36);
return bytes.map((sbyte) => (sbyte > 9 )
? String.fromCharCode("a".charCodeAt(0) + sbyte - 10)
: String.fromCharCode("0".charCodeAt(0) + sbyte)
).join("");
}
return decryptCode_old(codeToBytes(serial));
}
/* For Fujinsu-Siemens. 5x4 dicimal digits. new */
function fsi20DecNewKeygen(serial: string): string {
const fKeys = [
"4798156302", "7201593846", "5412367098", "6587249310",
"9137605284", "3974018625", "8052974163"
];
return [0, 2, 5, 11, 13, 15, 16].map((val, i) => {
let temp = parseInt(serial.charAt(val), 10);
return fKeys[i].charAt(temp);
}).join("");
}
export let fsiHexSolver = makeSolver({
name: "fsiHex",
description: "Fujitsu-Siemens hexdigits",
examples: ["DEADBEEF", "AAAA-BBBB-CCCC-DEAD-BEEF"],
inputValidator: (s) => /^([0-9ABCDEF]{20}|[0-9ABCDEF]{8})$/i.test(s),
fun: (code: string) => [fsiHexKeygen(code)]
});
export let fsi20DecNewSolver = makeSolver({
name: "fsiDecNew",
description: "Fujitsu-Siemens decimal new",
examples: ["1234-4321-1234-4321-1234"],
inputValidator: (s) => /^\d{20}$/i.test(s),
fun: (code: string) => [fsi20DecNewKeygen(code)]
});
export let fsi20DecOldSolver = makeSolver({
name: "fsiDecOld",
description: "Fujitsu-Siemens decimal old",
examples: ["1234-4321-1234-4321-1234"],
inputValidator: (s) => /^\d{20}$/i.test(s),
fun: (code: string) => [fsi20DecOldKeygen(code)]
});
+19
View File
@@ -0,0 +1,19 @@
import { hpMiniSolver } from "./hpmini";
describe("Test HP Mini BIOS", () => {
it("HPMini key for CNU1234ABC is e9l37fvcpe", () => {
expect(hpMiniSolver("CNU1234ABC")).toEqual(["e9l37fvcpe"]);
});
it("HPMini key for CNU1234567 is e9l37fvqgx", () => {
expect(hpMiniSolver("CNU1234567")).toEqual(["e9l37fvqgx"]);
});
it("HPMini key for CNU1234ABX is e9l37fvcp4 or e9l37fvcpr", () => {
expect(hpMiniSolver("CNU1234ABX").sort()).toEqual(["e9l37fvcp4", "e9l37fvcpr"].sort());
});
it("test invalid keys", () => {
expect(hpMiniSolver("CNU12345678")).toEqual([]);
expect(hpMiniSolver("CNU1234")).toEqual([]);
});
});
+44
View File
@@ -0,0 +1,44 @@
/* For HP/Compaq Netbooks. 10 chars */
import { makeSolver } from "./utils";
const table1: {[key: string]: string} = {
"1": "3", "0": "1", "3": "F", "2": "7", "5": "Q", "4": "V",
"7": "X", "6": "G", "9": "O", "8": "U", "a": "C", "c": "E",
"b": "P", "e": "M", "d": "T", "g": "H", "f": "8", "i": "Y",
"h": "Z", "k": "S", "j": "W", "m": "4", "l": "K", "o": "J",
"n": "9", "q": "5", "p": "2", "s": "N", "r": "B", "u": "L",
"t": "A", "w": "D", "v": "6", "y": "I", "x": "4", "z": "0"
};
const table2: {[key: string]: string} = {
"1": "3", "0": "1", "3": "F", "2": "7", "5": "Q", "4": "V",
"7": "X", "6": "G", "9": "O", "8": "U", "a": "C", "c": "E",
"b": "P", "e": "M", "d": "T", "g": "H", "f": "8", "i": "Y",
"h": "Z", "k": "S", "j": "W", "m": "4", "l": "K", "o": "J",
"n": "9", "q": "5", "p": "2", "s": "N", "r": "B", "u": "L",
"t": "A", "w": "D", "v": "6", "y": "I", "x": "R", "z": "0"
};
function hpMiniKeygen(serial: string): string[] {
let password1 = "";
let password2 = "";
serial = serial.toLowerCase();
for (let i = 0; i < serial.length; i++) {
password1 += table1[serial.charAt(i)];
password2 += table2[serial.charAt(i)];
}
if (password1 === password2) {
return [password1.toLowerCase()];
} else {
return [password1.toLowerCase(), password2.toLowerCase()];
}
}
export let hpMiniSolver = makeSolver({
name: "hpMini",
description: "HP/Compaq Mini Netbooks",
examples: ["CNU1234ABC"],
inputValidator: (s) => /^[0-9A-Z]{10}$/i.test(s),
fun: hpMiniKeygen
});
+18
View File
@@ -0,0 +1,18 @@
import { keygen, solvers } from "./";
describe("BIOS keygen", () => {
it("Sony key for 1234567 is 9648669", () => {
let keysList = keygen("1234567");
expect(keysList[0][1]).toEqual(["9648669"]);
});
it("Solvers names should be unique", () => {
let names: {[key: string]: boolean} = {};
solvers.forEach((solver) => {
if (solver.biosName in names) {
throw Error(`${solver.biosName} isn't unique name`);
} else {
names[solver.biosName] = true;
}
});
});
});
+47
View File
@@ -0,0 +1,47 @@
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 { Solver } from "./utils";
export type KeygenResult = [Solver, string[], number];
export const solvers: Solver[] = [
asusSolver,
sonySolver,
samsungSolver,
hddOldSolver,
dellSolver,
dellHddSolver,
fsiHexSolver,
fsi20DecNewSolver,
fsi20DecOldSolver,
hpMiniSolver,
insydeSolver,
phoenixSolver,
phoenixHPCompaqSolver,
phoenixFsiSolver,
phoenixFsiLSolver,
phoenixFsiPSolver,
phoenixFsiSSolver,
phoenixFsiXSolver
];
// NOTE: In future this function can change or even be removed
export function keygen(serial: string): KeygenResult[] {
return solvers
.map((solver): KeygenResult => {
let startTime = monotonicTime();
let passwords = solver(serial);
let calcTime = monotonicTime() - startTime;
return [solver, passwords, calcTime];
}).filter(([_, passwords]) => passwords !== undefined && passwords.length >= 1);
}
+15
View File
@@ -0,0 +1,15 @@
import { insydeSolver } from "./insyde";
describe("Insyde BIOS", () => {
it("Insyde key for 03133610 is 12891236", () => {
expect(insydeSolver("03133610")).toEqual(["12891236"]);
});
it("Insyde key for 12345678 is 03023278", () => {
expect(insydeSolver("12345678")).toEqual(["03023278"]);
});
it("test invalid keys", () => {
expect(insydeSolver("123456789")).toEqual([]);
expect(insydeSolver("1234567")).toEqual([]);
});
});
+33
View File
@@ -0,0 +1,33 @@
/* Maybe need fixing for browsers where numbers is 32-bits */
/* Some Acer, HP laptops. 8 digit */
import { makeSolver } from "./utils";
/* tslint:disable:no-bitwise */
function insydeKeygen(serial: string): string[] {
const salt = "Iou|hj&Z";
let password = "";
let b = 0;
let a = 0;
for (let i = 0; i < 8; i++) {
b = salt.charCodeAt(i) ^ serial.charCodeAt(i);
a = b;
// a = (a * 0x66666667) >> 32;
a = (a * 0x66666667);
a = Math.floor(a / Math.pow(2, 32));
a = (a >> 2) | (a & 0xC0);
if (a & 0x80000000) {
a++;
}
a *= 10;
password += (b - a).toString();
}
return [password];
}
export let insydeSolver = makeSolver({
name: "insydeH2O",
description: "Insyde H2O BIOS (Acer, HP)",
examples: ["03133610"],
inputValidator: (s) => /^\d{8}$/i.test(s),
fun: insydeKeygen
});
+29
View File
@@ -0,0 +1,29 @@
import * as bios from "./phoenix";
describe("Test Phoenix BIOS", () => {
it("check correct passwords", () => {
expect(bios.phoenixSolver.calculateHash("abstoou")).toEqual(12345);
expect(bios.phoenixHPCompaqSolver.calculateHash("vnflm")).toEqual(12345);
expect(bios.phoenixFsiSolver.calculateHash("411113")).toEqual(12345);
expect(bios.phoenixFsiLSolver.calculateHash("362153")).toEqual(12345);
expect(bios.phoenixFsiPSolver.calculateHash("4465237")).toEqual(12345);
expect(bios.phoenixFsiSSolver.calculateHash("71669")).toEqual(12345);
expect(bios.phoenixFsiXSolver.calculateHash("739979")).toEqual(12345);
});
it("find password for hash 12345", () => {
function phoenixValidate(solver: bios.PhoenixSolver, hash: string): number {
let newPassword = solver(hash)[0];
expect(newPassword).not.toBeUndefined();
return solver.calculateHash(newPassword);
}
expect(phoenixValidate(bios.phoenixSolver, "12345")).toEqual(12345);
expect(phoenixValidate(bios.phoenixHPCompaqSolver, "12345")).toEqual(12345);
expect(phoenixValidate(bios.phoenixFsiSolver, "12345")).toEqual(12345);
expect(phoenixValidate(bios.phoenixFsiLSolver, "12345")).toEqual(12345);
expect(phoenixValidate(bios.phoenixFsiPSolver, "12345")).toEqual(12345);
expect(phoenixValidate(bios.phoenixFsiSSolver, "12345")).toEqual(12345);
expect(phoenixValidate(bios.phoenixFsiXSolver, "12345")).toEqual(12345);
});
});
+244
View File
@@ -0,0 +1,244 @@
/* tslint:disable:no-bitwise */
import {
asciiToKeyboardEnc, keyboardEncToAscii, reversedScanCodes, Solver
} from "./utils";
export const enum PhoenixErrors {
BadHash,
NotFound
}
export interface PhoenixInfo {
shift: number;
salt: number;
dictionary: string[];
minLen: number;
maxLen: number;
}
export interface PhoenixBios {
name: string;
description?: string;
shift?: number;
salt?: number;
dictionary?: string[];
minLen?: number;
maxLen?: number;
}
export interface PhoenixSolver extends Solver {
readonly info: PhoenixInfo;
calculateHash(password: string): number;
}
// Without zero
const digitsOnly: string[] = "123456789".split("");
const lettersOnly: string[] = "abcdefghijklmnopqrstuvwxyz".split("");
// const alphaNumeric: string[] = lettersOnly.concat(digitsOnly);
const defaultPhoenix: PhoenixInfo = {
shift: 0,
salt: 0,
dictionary: lettersOnly,
minLen: 3,
maxLen: 7
};
/* The phoenix implementation of the CRC-16 contains a rather severe bug
* quartering the image space of the function: both the first and second MSB
* are always zero regardless of the input.
* For a working implementation, you'd have to change the polynom from 0x2001
* to e.g. 0xA001.
*/
function badCRC16(pwd: number[], salt: number = 0): number {
let hash = salt;
// tslint:disable-next-line:prefer-for-of
for (let c = 0; c < pwd.length; c++) {
hash ^= pwd[c];
for (let i = 8; i--;) {
if (hash & 1) {
hash = (hash >> 1) ^ 0x2001;
} else {
hash = (hash >> 1);
}
}
}
return hash;
}
/*
* Modified version of badCRC16 to speedup bruteForce.
* Returns pasword length if it matches required hash
* or -1 if it isn't matches requiredHash.
*/
function searchBadCRC16(pwd: number[], salt: number, requiredHash: number, minLen: number): number {
minLen--;
let hash = salt;
// tslint:disable-next-line:prefer-for-of
for (let c = 0; c < pwd.length; c++) {
hash ^= pwd[c];
for (let i = 8; i--;) {
if (hash & 1) {
hash = (hash >> 1) ^ 0x2001;
} else {
hash = (hash >> 1);
}
}
if (c >= minLen && hash === requiredHash) {
return c + 1;
}
}
return -1; // not found
}
function generatePhoenixPassword(encodedPwd: number[], characters: string[] = lettersOnly): void {
let rnd = Math.random() * characters.length;
for (let i = 0; i < encodedPwd.length; i++) {
let index = Math.floor(rnd % characters.length);
encodedPwd[i] = reversedScanCodes[characters[index]];
rnd *= encodedPwd.length;
}
}
function bruteForce(hash: number, salt: number = 0, characters: string[] = lettersOnly,
minLen: number = 3, maxLen: number = 7): string | PhoenixErrors {
let encodedPwd: number[] = [];
for (let i = 0; i < maxLen; i++) {
encodedPwd.push(0);
}
if (hash > 0x3FFF) {
return PhoenixErrors.BadHash;
}
let kk = 0;
while (true) {
kk++;
if (kk > 7000000) {
return PhoenixErrors.NotFound;
}
generatePhoenixPassword(encodedPwd, characters);
let found = searchBadCRC16(encodedPwd, salt, hash, minLen);
if (found !== -1) {
return keyboardEncToAscii(encodedPwd.slice(0, found));
}
}
}
function makePhoenixSolver(description?: PhoenixBios): PhoenixSolver {
if (description === void 0) {
description = {} as PhoenixBios;
}
for (let key in defaultPhoenix) {
if ((description as any)[key] === void 0) {
(description as any)[key] = (defaultPhoenix as any)[key];
}
}
const info: PhoenixInfo = {
shift: description.shift as number,
salt: description.salt as number,
dictionary: description.dictionary as string[],
minLen: description.minLen as number,
maxLen: description.maxLen as number
};
let keygen = (code: string) => {
let password = bruteForce(parseInt(code, 10) + info.shift, info.salt,
info.dictionary, info.minLen, info.maxLen);
if (typeof password === "string") {
return [password];
} else {
return [];
}
};
let cleaner = (code: string): string => code.trim().replace(/[-\s]/gi, "");
let validator = (s: string): boolean => /^[0-9]{5}$/i.test(s);
let calculateHash = (password: string): number => {
let pwd = asciiToKeyboardEnc(password);
return badCRC16(pwd, info.salt) - info.shift;
};
let solver: any = (code: string): string[] => {
let cleanCode = cleaner(code);
if (validator(cleanCode)) {
return keygen(cleanCode);
} else {
return [];
}
};
solver.biosName = description.name;
solver.validator = validator;
solver.cleaner = cleaner;
solver.keygen = keygen;
solver.examples = ["12345"];
solver.info = info;
solver.calculateHash = calculateHash;
if (description.description) {
solver.description = description.description;
}
return solver as PhoenixSolver;
}
export let phoenixSolver = makePhoenixSolver({
name: "phoenix",
description: "Generic Phoenix"
});
export let phoenixHPCompaqSolver = makePhoenixSolver({
name: "phoenixHP",
description: "HP/Compaq Phoenix BIOS",
salt: 17232
});
export let phoenixFsiSolver = makePhoenixSolver({
name: "phoenixFSI",
description: "Fujitsu-Siemens Phoenix",
salt: 65,
dictionary: digitsOnly
});
export let phoenixFsiLSolver = makePhoenixSolver({
name: "phoenixFSIModelL",
description: "Fujitsu-Siemens (model L) Phoenix",
shift: 1,
salt: "L".charCodeAt(0),
dictionary: digitsOnly
});
export let phoenixFsiPSolver = makePhoenixSolver({
name: "phoenixFSIModelP",
description: "Fujitsu-Siemens (model P) Phoenix",
shift: 1,
salt: "P".charCodeAt(0),
dictionary: digitsOnly
});
export let phoenixFsiSSolver = makePhoenixSolver({
name: "phoenixFSIModelS",
description: "Fujitsu-Siemens (model S) Phoenix",
shift: 1,
salt: "S".charCodeAt(0),
dictionary: digitsOnly
});
export let phoenixFsiXSolver = makePhoenixSolver({
name: "phoenixFSIModelX",
description: "Fujitsu-Siemens (model X) Phoenix",
shift: 1,
salt: "X".charCodeAt(0),
dictionary: digitsOnly
});
+22
View File
@@ -0,0 +1,22 @@
import { samsungSolver } from "./samsung";
describe("Test Samsung BIOS", () => {
it("Samsung key for 07088120410C0000 is 12345", () => {
expect(samsungSolver("07088120410C0000")).toEqual(["12345"]);
});
it("Samsung key for 07088120410C is 12345", () => {
expect(samsungSolver("07088120410C")).toEqual(["12345"]);
});
it("Samsung key for 1AA9CD4638C0186000 is 5728000", () => {
expect(samsungSolver("1AA9CD4638C0186000")).toEqual(["5728000"]);
});
it("Samsung key for 1AA9CD4638C0186001 is 5728000@", () => {
expect(samsungSolver("1AA9CD4638C0186001")).toEqual(["5728000@"]);
});
it("test invalid keys", () => {
expect(samsungSolver("1AA9CD4638C01860Z0")).toEqual([]);
expect(samsungSolver("1AA9CD4638C01860000")).toEqual([]);
});
});
+79
View File
@@ -0,0 +1,79 @@
/* tslint:disable:no-bitwise */
/* Return password for samsung laptops
* 12 or 18 hexhecimal digits like 07088120410C0000
*/
import { makeSolver } from "./utils";
import { keyboardEncToAscii } from "./utils";
const rotationMatrix1 = [
7, 1, 5, 3, 0, 6, 2, 5, 2, 3, 0, 6, 1, 7, 6, 1, 5, 2, 7, 1, 0, 3, 7,
6, 1, 0, 5, 2, 1, 5, 7, 3, 2, 0, 6
];
const rotationMatrix2 = [
1, 6, 2, 5, 7, 3, 0, 7, 1, 6, 2, 5, 0, 3, 0, 6, 5, 1, 1, 7, 2, 5, 2,
3, 7, 6, 2, 1, 3, 7, 6, 5, 0, 1, 7
];
function keyToAscii(intKeys: number[]): string | undefined {
let out = "";
for (let intKey of intKeys) {
if (intKey === 0) {
return out;
}
if (intKey < 32 || intKey > 127) {
return undefined;
}
out += String.fromCharCode(intKey);
}
return out;
}
function decryptHash(hash: number[], key: number, rotationMatrix: number[]): number[] {
let outhash: number[] = [];
for (let i = 0; i < hash.length; i++) {
const val = ((hash[i] << (rotationMatrix[7 * key + i])) & 0xFF) |
(hash[i] >> (8 - rotationMatrix[7 * key + i]));
outhash.push(val);
}
return outhash;
}
function samsungKeygen(serial: string): string[] {
let hash: number[] = [];
for (let i = 1; i < Math.floor(serial.length / 2); i++) {
let val = parseInt(serial.charAt(2 * i) + serial.charAt(2 * i + 1), 16);
hash.push(val);
}
let key = parseInt(serial.substring(0, 2), 16) % 5;
let calcScanCodePwd = (matrix: number[]) =>
keyboardEncToAscii(decryptHash(hash, key, matrix));
let scanCodePassword = calcScanCodePwd(rotationMatrix1);
if (scanCodePassword === "") {
scanCodePassword = calcScanCodePwd(rotationMatrix2);
}
const asciiPassword1 = keyToAscii(decryptHash(hash, key, rotationMatrix1));
const asciiPassword2 = keyToAscii(decryptHash(hash, key, rotationMatrix2));
// TODO: This might require polyfil
return [scanCodePassword, asciiPassword1, asciiPassword2].
filter((code) => code ? true : false) as string[];
}
export let samsungSolver = makeSolver({
name: "samsung",
description: "Samsung",
examples: ["07088120410C0000"],
inputValidator: (s) => /^[0-9ABCDEF]+$/i.test(s) && (
s.length === 12 || s.length === 14 || s.length === 16 || s.length === 18
),
fun: samsungKeygen
});
+11
View File
@@ -0,0 +1,11 @@
import { sonySolver } from "./sony";
describe("Sony BIOS", () => {
it("Sony key for 1234567 is 9648669", () => {
expect(sonySolver("1234567")).toEqual(["9648669"]);
});
it("test invalid keys", () => {
expect(sonySolver("123456789")).toEqual([]);
expect(sonySolver("123")).toEqual([]);
});
});
+23
View File
@@ -0,0 +1,23 @@
import { makeSolver } from "./utils";
/* Return password for old sony laptops
* password 7 digit number like 1234567
*/
function sonyKeygen(serial: string): string {
const table = "0987654321876543210976543210982109876543109876543221098765436543210987";
let code: string = "";
for (let i = 0; i < serial.length; i++) {
code += table.charAt(parseInt(serial.charAt(i), 10) + 10 * i);
}
return code;
}
export let sonySolver = makeSolver({
name: "sony",
description: "Old Sony",
examples: ["1234567"],
inputValidator: (s) => /^\d{7}$/i.test(s),
fun: (code: string) => {
let res = sonyKeygen(code);
return res ? [res] : [];
}
});
+100
View File
@@ -0,0 +1,100 @@
export type Predicate<T> = (val: T) => boolean;
export type SolverFunction = (val: string) => string[];
export interface SolverDescription {
readonly name: string;
readonly description?: string;
readonly examples?: string[];
fun: SolverFunction;
inputValidator: Predicate<string>;
}
export interface Solver {
(code: string): string[];
readonly biosName: string;
readonly examples?: string[];
readonly description: string;
validator(code: string): boolean;
cleaner(code: string): string;
keygen(code: string): string[];
}
export const keyboardDict: {[key: number]: string} = {
2: "1", 3: "2", 4: "3", 5: "4", 6: "5", 7: "6", 8: "7", 9: "8",
10: "9", 11: "0", 16: "q", 17: "w", 18: "e", 19: "r", 20: "t", 21: "y",
22: "u", 23: "i", 24: "o", 25: "p", 30: "a", 31: "s", 32: "d", 33: "f",
34: "g", 35: "h", 36: "j", 37: "k", 38: "l", 44: "z", 45: "x", 46: "c",
47: "v", 48: "b", 49: "n", 50: "m"
};
// reverse scan code table
function generateReverseKeyDict(): {[key: string]: number} {
let result: {[key: string]: number} = {};
for (let key in keyboardDict) {
if (keyboardDict.hasOwnProperty(key)) {
result[keyboardDict[key]] = parseInt(key, 10);
}
}
return result;
}
export const reversedScanCodes = generateReverseKeyDict();
/* Decode Keyboard code to Ascii symbol */
export function keyboardEncToAscii(inKey: number[]): string {
let out = "";
for (let key of inKey) {
if (key === 0) {
return out;
}
if (key in keyboardDict) {
out += keyboardDict[key];
} else {
return "";
}
}
return out;
}
export function asciiToKeyboardEnc(password: string): number[] {
return password.split("").map((c) => {
let code = reversedScanCodes[c];
if (code === void 0) {
throw new Error("Undefined scan code");
} else {
return code;
}
});
}
function cleanSerial(serial: string): string {
return serial.trim().replace(/-/gi, "");
}
export function makeSolver(description: SolverDescription): Solver {
let solver: any = (code: string) => {
let cleanCode = cleanSerial(code);
if (description.inputValidator(cleanCode)) {
return description.fun(cleanCode);
} else {
return [];
}
};
solver.biosName = description.name;
solver.validator = description.inputValidator;
solver.cleaner = cleanSerial;
solver.keygen = description.fun;
if (description.examples) {
solver.examples = description.examples;
}
if (description.description) {
solver.description = description.description;
}
return solver as Solver;
}