wip crack decoder

This commit is contained in:
Tau
2019-11-06 17:28:29 -05:00
parent 6a8d9a4d28
commit 1d5971b2d5
23 changed files with 464 additions and 307 deletions
+14
View File
@@ -0,0 +1,14 @@
import { RequestCode } from "../defs";
import { AccountLockRequest } from "../request/accountLock";
accountLock.msgCode = 0x0069 as RequestCode;
accountLock.msgLen = 0x0020;
export function accountLock(buf: Buffer): AccountLockRequest {
return {
type: "account_lock_req",
aimeId: buf.readUInt32LE(0x0004),
pcbId: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
field_0018: buf.readUInt16LE(0x0018),
};
}
+13
View File
@@ -0,0 +1,13 @@
import { RequestCode } from "../defs";
import { AccountUnlockRequest } from "../request/accountUnlock";
accountUnlock.msgCode = 0x006f as RequestCode;
accountUnlock.msgLen = 0x0020;
export function accountUnlock(buf: Buffer): AccountUnlockRequest {
return {
type: "account_unlock_req",
aimeId: buf.readUInt32LE(0x0004),
pcbId: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
};
}
+40
View File
@@ -0,0 +1,40 @@
import iconv = require("iconv-lite");
import { RequestCode } from "../defs";
import { CreateProfileRequest } from "../request/createProfile";
createProfile.msgCode = 0x0066 as RequestCode;
createProfile.msgLen = 0x00c0;
export function createProfile(buf: Buffer): CreateProfileRequest {
return {
type: "create_profile_req",
aimeId: buf.readInt32LE(0x0004),
luid: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
name: iconv.decode(
buf.slice(0x001e, buf.indexOf("\0", 0x001e)),
"shift_jis"
),
field_0034: buf.readUInt32LE(0x0034),
field_0040: buf.slice(0x0040, 0x0084),
car_type: buf.readUInt16LE(0x0084),
car_color: buf.readUInt16LE(0x0086),
transmission: buf.readUInt16LE(0x0088) === 0 ? "auto" : "manual",
field_008A: buf.readUInt16LE(0x008a),
field_008C: buf.readUInt16LE(0x008c),
field_0090:
BigInt(buf.readUInt32LE(0x0090)) |
(BigInt(buf.readUInt32LE(0x0094)) << 32n),
field_009C: buf.readUInt16LE(0x009c),
gender: buf.readUInt16LE(0x00a0) === 0 ? "male" : "female",
field_00A2: buf.readUInt16LE(0x00a2),
field_00A4: buf.readUInt16LE(0x00a4),
field_00A6: buf.readUInt16LE(0x00a6),
field_00A8: buf.readUInt16LE(0x00a8),
field_00AA: buf.readUInt16LE(0x00aa),
field_00AC: buf.readUInt16LE(0x00ac),
field_00AE: buf.readUInt16LE(0x00ae),
field_00B0: buf.readUInt16LE(0x00b0),
field_00B2: buf.readUInt8(0x00b2),
};
}
+14
View File
@@ -0,0 +1,14 @@
import { RequestCode } from "../defs";
import { CreateTeamRequest } from "../request/createTeam";
createTeam.msgCode = 0x007b as RequestCode;
createTeam.msgLen = 0x0010;
export function createTeam(buf: Buffer): CreateTeamRequest {
return {
type: "create_team_req",
field_0004: buf.readUInt32LE(0x0004),
field_0008: buf.readUInt32LE(0x0008),
field_000C: buf.readUInt8(0x000c),
};
}
+12
View File
@@ -0,0 +1,12 @@
import { RequestCode } from "../defs";
import { DiscoverProfileRequest } from "../request/discoverProfile";
discoverProfile.msgCode = 0x006b as RequestCode;
discoverProfile.msgLen = 0x0010;
export function discoverProfile(buf: Buffer): DiscoverProfileRequest {
return {
type: "discover_profile_req",
aimeId: buf.readUInt32LE(0x0004),
};
}
+144
View File
@@ -0,0 +1,144 @@
import { Transform } from "stream";
import { accountLock } from "./accountLock";
import { accountUnlock } from "./accountUnlock";
import { createProfile } from "./createProfile";
import { createTeam } from "./createTeam";
import { discoverProfile } from "./discoverProfile";
import { load2on2 } from "./load2on2";
import { loadConfig } from "./loadConfig";
import { loadConfig2 } from "./loadConfig2";
import { loadGeneralReward } from "./loadGeneralReward";
import { loadProfile } from "./loadProfile";
import { loadRewardTable } from "./loadRewardTable";
import { loadServerList } from "./loadServerList";
import { loadStocker } from "./loadStocker";
import { loadTeam } from "./loadTeam";
import { saveExpedition } from "./saveExpedition";
import { saveProfile } from "./saveProfile";
import { saveSettings } from "./saveSettings";
import { saveTopic } from "./saveTopic";
import { updateProvisionalStoreRank } from "./updateProvisionalStoreRank";
import { updateStoryClearNum } from "./updateStoryClearNum";
import { RequestCode } from "../defs";
import { Request } from "../request";
export type ReaderFn = ((buf: Buffer) => Request) & {
msgCode: RequestCode;
msgLen: number;
};
const funcList: ReaderFn[] = [
accountLock,
accountUnlock,
createProfile,
createTeam,
discoverProfile,
load2on2,
loadConfig,
loadConfig2,
loadGeneralReward,
loadProfile,
loadRewardTable,
loadServerList,
loadStocker,
loadTeam,
saveExpedition,
saveProfile,
saveSettings,
saveTopic,
updateProvisionalStoreRank,
updateStoryClearNum,
];
const readerFns = new Map<RequestCode, ReaderFn>();
const msgLengths = new Map<RequestCode, number>();
for (const fn of funcList) {
readerFns.set(fn.msgCode, fn);
msgLengths.set(fn.msgCode, fn.msgLen);
}
function readHeader(buf: Buffer) {
return {
blah: "blah",
};
}
export class Decoder extends Transform {
state: Buffer;
constructor() {
super({
readableObjectMode: true,
writableObjectMode: true,
});
this.state = Buffer.alloc(0);
}
_transform(chunk: Buffer, encoding, callback) {
this.state = Buffer.concat([this.state, chunk]);
// Read header
if (this.state.length < 0x04) {
return callback(null);
}
const magic = this.state.readUInt32LE(0);
if (magic !== 0x01020304) {
return callback(
new Error(
"Invalid magic number, cryptographic processing probably incorrect."
)
);
}
if (this.state.length < 0x30) {
return callback(null);
}
const header = readHeader(this.state);
if (this.state.length < 0x32) {
return callback(null);
}
const msgCode = this.state.readUInt16LE(0x30) as RequestCode;
const msgLen = msgLengths.get(msgCode);
if (msgLen === undefined) {
return callback(
new Error(
`Unknown command code ${msgCode.toString(16)}, cannot continue`
)
);
}
if (this.state.length < 0x30 + msgLen) {
return callback(null);
}
const reqBuf = this.state.slice(0, 0x30 + msgLen);
const payloadBuf = reqBuf.slice(0x30);
console.log("Idz: Req: Raw:", reqBuf.toString("hex"));
console.log("Idz: Req: Header:", header);
const reader = readerFns.get(msgCode);
if (reader === undefined) {
return callback(
new Error(`No reader for command code ${msgCode.toString(16)}`)
);
}
const payload = reader(payloadBuf);
console.log("Idz: Req: Payload:", payload);
return callback(null, payload);
}
}
+14
View File
@@ -0,0 +1,14 @@
import { RequestCode } from "../defs";
import { Load2on2Request } from "../request/load2on2";
load2on2.msgCode = 0x00b0 as RequestCode;
load2on2.msgLen = 0x0010;
export function load2on2(buf: Buffer): Load2on2Request {
return {
type: "load_2on2_req",
field_0002: buf.readUInt16LE(0x0002),
field_0004: buf.readUInt32LE(0x0004),
field_0008: buf.readUInt32LE(0x0008),
};
}
+9
View File
@@ -0,0 +1,9 @@
import { RequestCode } from "../defs";
import { LoadConfigRequest } from "../request/loadConfig";
loadConfig.msgCode = 0x0004 as RequestCode;
loadConfig.msgLen = 0x0050;
export function loadConfig(): LoadConfigRequest {
return { type: "load_config_req" };
}
+9
View File
@@ -0,0 +1,9 @@
import { RequestCode } from "../defs";
import { LoadConfigRequest2 } from "../request/loadConfig2";
loadConfig2.msgCode = 0x00ab as RequestCode;
loadConfig2.msgLen = 0x0010;
export function loadConfig2(): LoadConfigRequest2 {
return { type: "load_config_v2_req" };
}
+12
View File
@@ -0,0 +1,12 @@
import { RequestCode } from "../defs";
import { LoadGeneralRewardRequest } from "../request/loadGeneralReward";
loadGeneralReward.msgCode = 0x009c as RequestCode;
loadGeneralReward.msgLen = 0x0010;
export function loadGeneralReward(buf: Buffer): LoadGeneralRewardRequest {
return {
type: "load_general_reward_req",
field_0004: buf.readUInt32LE(0x0004),
};
}
+13
View File
@@ -0,0 +1,13 @@
import { RequestCode } from "../defs";
import { LoadProfileRequest } from "../request/loadProfile";
loadProfile.msgCode = 0x0067 as RequestCode;
loadProfile.msgLen = 0x0020;
export function loadProfile(buf: Buffer): LoadProfileRequest {
return {
type: "load_profile_req",
aimeId: buf.readUInt32LE(0x0004),
pcbId: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
};
}
+11
View File
@@ -0,0 +1,11 @@
import { RequestCode } from "../defs";
import { LoadRewardTableRequest } from "../request/loadRewardTable";
loadRewardTable.msgCode = 0x0086 as RequestCode;
loadRewardTable.msgLen = 0x0010;
export function loadRewardTable(): LoadRewardTableRequest {
return {
type: "load_reward_table_req",
};
}
+9
View File
@@ -0,0 +1,9 @@
import { RequestCode } from "../defs";
import { LoadServerListRequest } from "../request/loadServerList";
loadServerList.msgCode = 0x0006 as RequestCode;
loadServerList.msgLen = 0x0020;
export function loadServerList(): LoadServerListRequest {
return { type: "load_server_list_req" };
}
+12
View File
@@ -0,0 +1,12 @@
import { RequestCode } from "../defs";
import { LoadStockerRequest } from "../request/loadStocker";
loadStocker.msgCode = 0x00a7 as RequestCode;
loadStocker.msgLen = 0x0010;
export function loadStocker(buf: Buffer): LoadStockerRequest {
return {
type: "load_stocker_req",
field_0004: buf.readUInt32LE(0x0004),
};
}
+13
View File
@@ -0,0 +1,13 @@
import { RequestCode } from "../defs";
import { LoadTeamRequest } from "../request/loadTeam";
loadTeam.msgCode = 0x0077 as RequestCode;
loadTeam.msgLen = 0x0010;
export function loadTeam(buf: Buffer): LoadTeamRequest {
return {
type: "load_team_req",
profileId: buf.readUInt32LE(0x0004),
teamId: buf.readUInt32LE(0x0008),
};
}
+12
View File
@@ -0,0 +1,12 @@
import { RequestCode } from "../defs";
import { SaveExpeditionRequest } from "../request/saveExpedition";
saveExpedition.msgCode = 0x008c as RequestCode;
saveExpedition.msgLen = 0x0010;
export function saveExpedition(buf: Buffer): SaveExpeditionRequest {
return {
type: "save_expedition_req",
field_0004: buf.readUInt32LE(0x0004),
};
}
+12
View File
@@ -0,0 +1,12 @@
import { RequestCode } from "../defs";
import { SaveProfileRequest } from "../request/saveProfile";
saveProfile.msgCode = 0x0068 as RequestCode;
saveProfile.msgLen = 0x0940;
export function saveProfile(buf: Buffer): SaveProfileRequest {
return {
type: "save_profile_req",
// mega TODO
};
}
+19
View File
@@ -0,0 +1,19 @@
import { RequestCode } from "../defs";
import { SaveSettingsRequest } from "../request/saveSettings";
saveSettings.msgCode = 0x00a5 as RequestCode;
saveSettings.msgLen = 0x0020;
export function saveSettings(buf: Buffer): SaveSettingsRequest {
return {
type: "save_settings_req",
field_0002: buf.readUInt16LE(0x0002),
profileId: buf.readUInt32LE(0x0004),
dpoint: buf.readUInt32LE(0x0008),
field_000C: buf.readUInt32LE(0x000c),
field_0010: buf.readUInt8(0x0010),
field_0011: buf.readUInt8(0x0011),
field_0012: buf.readUInt8(0x0012),
field_0013: buf.readUInt8(0x0013),
};
}
+14
View File
@@ -0,0 +1,14 @@
import { RequestCode } from "../defs";
import { SaveTopicRequest } from "../request/saveTopic";
saveTopic.msgCode = 0x009a as RequestCode;
saveTopic.msgLen = 0x0010;
export function saveTopic(buf: Buffer): SaveTopicRequest {
const aimeId = buf.readUInt32LE(0x0004);
return {
type: "save_topic_req",
aimeId: aimeId !== 0xffffffff ? aimeId : undefined,
};
}
@@ -0,0 +1,14 @@
import { RequestCode } from "../defs";
import { UpdateProvisionalStoreRankRequest } from "../request/updateProvisionalStoreRank";
updateProvisionalStoreRank.msgCode = 0x0082 as RequestCode;
updateProvisionalStoreRank.msgLen = 0x0010;
export function updateProvisionalStoreRank(
buf: Buffer
): UpdateProvisionalStoreRankRequest {
return {
type: "update_provisional_store_rank_req",
aimeId: buf.readUInt32LE(0x0004),
};
}
+11
View File
@@ -0,0 +1,11 @@
import { RequestCode } from "../defs";
import { UpdateStoryClearNumRequest } from "../request/updateStoryClearNum";
updateStoryClearNum.msgCode = 0x007f as RequestCode;
updateStoryClearNum.msgLen = 0x0010;
export function updateStoryClearNum(buf: Buffer): UpdateStoryClearNumRequest {
return {
type: "update_story_clear_num_req",
};
}