Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
- Fix 'DoJit not found!'
  + Yuzu 908+
  + Vita3k 0.1.3.2285+
  + PPSSPP 1.12.3-867+
  + Rpcs3 0.0.20-13234+
- [NS] Tsukihime: names, add 1.0.2
  • Loading branch information
0xDC00 committed Feb 6, 2022
1 parent 4d3f6e9 commit 9061a4f
Show file tree
Hide file tree
Showing 13 changed files with 274 additions and 91 deletions.
102 changes: 91 additions & 11 deletions NS_01001DC01486A000_Tsukihime.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,121 @@
// ==UserScript==
// @name [01001DC01486A000] 月姫 -A piece of blue glass moon-
// @version 0.2.1 - 1.0.1
// @version 0.2.1 - 1.0.1, 1.0.2
// @author [DC]
// @description Yuzu, Tsukihime
// * Aniplex (アニプレックス)
// *
// ==/UserScript==
const gameVer = '1.0.1';
trans.replace(function(s) {
trans.replace(function (s) {
return s
.replace(//g, 'Shiki-Sama')
.replace(//g, 'Akiha-Sama')
.replace(//g, 'Akiha')
.replace(//g, 'Arcueid')
.replace(//g, 'Ciel')
.replace(//g, 'Hisui')
.replace(//g, 'Kohaku')
.replace(//g, 'Vlov')
.replace(//g, 'Vlov Arkhangel')
.replace(//g, 'Arkhangel')
.replace(//g, 'Yumizuka')
.replace(//g, 'Satsuki')
.replace(//g, 'Noel')
.replace(//g, 'Arach')
.replace(//g, 'Mario')
.replace(//g, 'Gallo')
.replace(//g, 'Bestino')
.replace(/ /g, 'Ando')
.replace(//g, 'Yuugo')
.replace(//g, 'Michael')
.replace(//g, 'Roa')
.replace(//g, 'Valdamjong')
.replace(//g, 'Serpent of Akasha')
.replace(//g, 'Mystic Eyes of Death Perception')
.replace(//g, 'Burial Agency')
.replace(//g, 'Seventh holy Scipture')
.replace(//g, 'Ghoul')
.replace(//g, 'Nightkin')
.replace(//g, 'Nightmare')
.replace(//g, 'Dead Apostle')
.replace(//g, 'Successor')
.replace(//g, 'Luminous Body')
.replace(//g, 'Senpai')
.replace(//g, 'Nii-San')
.replace(//g, 'Nee-San')
.replace(//g, 'Shiki')
.replace(//g, 'SHIKI')
.replace(//g, 'Arima')
.replace(//g, 'Miyako')
.replace(//g, 'Keiko')
.replace(//g, 'Fumio')
.replace(//g, 'Kishima')
.replace(//g, 'Kugamine')
.replace(//g, 'Touzaki')
.replace(//g, 'Tsukihime')
.replace(//g, 'Arihiko')
.replace(//g, 'Gransurg')
.replace(//g, 'Blackmore')
.replace(//g, 'Nero')
.replace(//g, 'Chaos')
.replace(//g, 'Saiki')
.replace(//g, 'Goto')
.replace(//g, 'True Ancestor')
.replace(//g, 'Mystic Eyes')
.replace(//g, 'Mystic Eyes of Enchantment')
.replace(//g, 'Mystic Eyes of Whisper')
.replace(//g, 'Burial Agency')
.replace(//g, 'Elesia')
.replace(//g, 'Holy Church')
.replace(//g, 'Mage\'s Association')
.replace(//g, 'Executor')
.replace(//g, 'Keys of Providence')
.replace(//g, 'Magecraft')
.replace(//g, 'Root')
.replace(//g, 'Magus')
.replace(/使/g, 'Magician')
.replace(//g, 'Souya')
.replace(//g, 'Metropolitan Souya High School')
.replace(//g, 'Twenty-seven Dead Apostle Ancestors')
.replace(//g, 'League of the Age of Gods')
.replace(//g, 'Idea Blood')
.replace(//g, 'Seventh Holy Scripture')
.replace(//g, 'Cremation Sacrament')
.replace(//g, 'Iron Plate Effect')
.replace(//g, 'Internment Rite')
.replace(//g, 'Tower of Imprisonment')
.replace(//g, 'Oni Kind')
.replace(//g, 'Crimson Red Vermillion')
.replace(//g, 'Inversion Impulse')
.replace(//g, 'Phantasmal Species')
.replace(//g, 'Synchronization')
.replace(//g, 'Sensei')
.replace(//g, 'Aoko')
.replace(//g, 'Aozaki')
.replace(//g, 'Mystic Eyes Killer')
;
});
//------------------------------------------------
const { setHook } = require('./libyuzu.js');

const mainHandler = handler;

const udp101 = {
0x80ac290: mainHandler
};

setHook({
'1.0.0': {
// TODO
},
'1.0.1': {
0x80ac290: mainHandler
},
'1.0.2': {
// TODO
}
'1.0.1': udp101,
'1.0.2': udp101 // same exe
}[globalThis.gameVer ?? gameVer]);

function handler(regs) {
const address = regs[2].value; // x2

//const pc = this.context.pc;
console.log('onEnter');
console.log(hexdump(address, { header: false, ansi: false, length: 0x50 }));
Expand Down Expand Up @@ -104,7 +184,7 @@ function processBinaryString(address, condition) {
}
}
}

if (s) {
const fromHook = condition === undefined; // hook or delay
if (fromHook) {
Expand All @@ -113,7 +193,7 @@ function processBinaryString(address, condition) {
s = previousString = currentTime - previousTime < 300 ? previousString + '\n' + s : s; // join fast string (choise)
previousTime = currentTime;
} else previousString = s;

trans.send(s);

// detect missed chars
Expand Down
2 changes: 1 addition & 1 deletion NS_0100B5700CDFC000_Amnesia_Later_x_Crowd_V.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const gameVer = '1.0.0';

const { setHook } = require('./libYuzu.js');

const mainHandler = trans.send(handler.bind_(null, 1), '250+'); // x1
const mainHandler = trans.send(handler.bind_(null, 1), '250+'); // join 250ms; x1

setHook({
'1.0.0': {
Expand Down
2 changes: 1 addition & 1 deletion NS_0100DB300B996000_BuddyMissionBOND.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const { setHook } = require('./libYuzu.js');

const encoder = new TextEncoder('shift_jis');
const decoder = new TextDecoder('shift_jis');
const mainHandler = trans.send(handler, 100); // prevent double
const mainHandler = trans.send(handler, 100); // debounce trailing (prevent double)

setHook({
'1.0.0': {
Expand Down
18 changes: 10 additions & 8 deletions NS_0100E94014792000_MAGES_SINceMemories.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ const { setHook } = require('./libYuzu.js');
const { readString } = require('./libPCMAGES.js');

const table = createTable();
const mainHandler = trans.send(handler, '200+'); // line + name => join
const mainHandler = trans.send(handler, '200+'); // join 200ms (line + name)
const directHandler = trans.send(handler);

const base100 = {
0x8048cc8: mainHandler, // line + name => join
0x804f44c: directHandler, // fast trophy
0x804f474: directHandler, // prompt
0x8039dc0: mainHandler // choice
};

setHook({
'1.0.0': {
0x8048cc8: mainHandler, // line + name => join
0x804f44c: directHandler, // fast trophy
0x804f474: directHandler, // prompt
0x8039dc0: mainHandler // choice
},
'1.0.1': this['1.0.0'] // same binary
'1.0.0': base100,
'1.0.1': base100 // same exe
}[globalThis.gameVer ?? gameVer]);

function handler(regs) {
Expand Down
2 changes: 1 addition & 1 deletion PS3_BLJM60347_Dunamis15.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
const { setHook } = require("./libRPCS3.js");

setHook({
0x42c90: trans.send(handler, '200') // all text, leading+trailing 200ms (name text text text..)
0x42c90: trans.send(handler, '200') // join leading+trailing 200ms (all text: name text text text..)
});

function handler(regs) {
Expand Down
2 changes: 1 addition & 1 deletion PSP_ULJM06036 _Princess-Evangile-Portable.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// ==/UserScript==
const { setHook } = require("./libPPSSPP.js");

const mainHandler = trans.send(handler.bind_(null, 2), '200+');
const mainHandler = trans.send(handler.bind_(null, 2), '200+'); // join 200ms

setHook({
0x88506d0: mainHandler, // [0x88506d0(2)...0x088507C0(?)] // name text text (line doubled)
Expand Down
2 changes: 1 addition & 1 deletion PSP_ULJM06119_Dunamis15.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// ==/UserScript==
const { setHook } = require("./libPPSSPP.js");

const mainHandler = trans.send(handler, '100+');
const mainHandler = trans.send(handler, '100+'); // join 100ms

setHook({
0x0891D72C: mainHandler // all
Expand Down
4 changes: 2 additions & 2 deletions PSVita_PCSG00903_New_Game!_The_Challenge_Stage!.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
// @author [DC]
// @description Vita3k
// * MAGES. GAME
// *
// * 5pb.
// ==/UserScript==
const { setHook } = require("./libVita3k.js");

setHook({
// 0x0022b738(2) 0x0022b74c(0)
0x0022b74c: trans.send(handler.bind_(null, 0), '200+') // dialouge + choice + ... => join \n
0x0022b74c: trans.send(handler.bind_(null, 0), '200+') // join 200ms (dialouge + choice + ...; \n); x0
});

function handler(regs, index) {
Expand Down
2 changes: 1 addition & 1 deletion libPCKiriKiriZ.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @name PC KiriKiriZ ENGINES
// @version
// @version textrender.dll (msvc)
// @author [DC]
// @description

Expand Down
69 changes: 54 additions & 15 deletions libPPSSPP.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
// @name PPSSPP JIT Hooker
// @version
// @version 1.12.3-867+
// @author [DC]
// @description TODO: linux
// @description

const __e = Process.enumerateModules()[0];
const DoJitSig1 = '48 89 5C 24 10 48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 E0 F5 FF FF 48 81 EC 20 0B 00 00 48 8B 81 30 2A 00 00';
const DoJitMatch = Memory.scanSync(__e.base, __e.size, DoJitSig1)[0];
if (!DoJitMatch) throw new Error('DoJit not found!');

const DoJitPtr = DoJitMatch.address;
const operations = Object.create(null);
const DoJitPtr = getDoJitAddress();
const buildRegs = createFunction_buildRegs();
const operations = Object.create(null);

// https://github.com/hrydgard/ppsspp/blob/714578a3ad7f9fa670a45281734166077341fa00/Core/MIPS/x86/Jit.cpp#L331
// const u8 *Jit::DoJit(
Expand All @@ -19,8 +14,8 @@ const buildRegs = createFunction_buildRegs();
// )
Interceptor.attach(DoJitPtr, {
onEnter: function (args) {
//const Jit_handle = args[0]; // rcx
this.em_address = args[1].toInt32(); // rdx
//const Jit_handle = args[0]; // rcx | rdi | x0
this.em_address = args[1].toInt32(); // rdx | rsi | x1
},
onLeave: function (entrypoint) {
const em_address = this.em_address;
Expand All @@ -39,22 +34,66 @@ Interceptor.attach(DoJitPtr, {
}
});

function getDoJitAddress() {
if (Process.platform !== 'windows') {
// Unix
// not __ZN8MIPSComp10IRFrontend5DoJitEjRNSt3__16vectorI6IRInstNS1_9allocatorIS3_EEEERjb
const names = [
'_ZN8MIPSComp3Jit5DoJitEjP8JitBlock', // linux x64
'__ZN8MIPSComp3Jit5DoJitEjP8JitBlock', // macOS x64
'_ZN8MIPSComp8Arm64Jit5DoJitEjP8JitBlock', // android arm64
'__ZN8MIPSComp8Arm64Jit5DoJitEjP8JitBlock' // macOS arm64
];
for (const name of names) {
const sym = DebugSymbol.fromName(name);
if (sym.name !== null) {
return sym.address;
}
}
}
else {
// Windows MSVC x64
// TODO: retroarch, DebugSymbol.fromName?
const __e = Process.enumerateModules()[0];
const DoJitSig1 = '48 89 5C 24 10 48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 E0 F5 FF FF 48 81 EC 20 0B 00 00 48 8B 81 30 2A 00 00';
const first = Memory.scanSync(__e.base, __e.size, DoJitSig1)[0];
if (first) return first.address;
}

throw new Error('RegisterBlock not found!')
}

function createFunction_buildRegs() {
let body = '';

// https://github.com/hrydgard/ppsspp/blob/master/Core/MIPS/ARM/ArmRegCache.h
// https://github.com/hrydgard/ppsspp/blob/master/Core/MIPS/ARM64/Arm64RegCache.h
// https://github.com/hrydgard/ppsspp/blob/master/Core/MIPS/x86/RegCache.h
body += 'const base = context.rbx;';
body += 'const regs = context.r14;';

const arch = Process.arch;
if (arch === 'x64') {
body += 'const base = context.rbx;'; // MEMBASEREG
body += 'const regs = context.r14;'; // CTXREG
}
else if (arch === 'arm64') {
body += 'const base = context.x28;';
body += 'const regs = context.x27;';
}
else if (arch === 'arm') {
body += 'const base = context.r11;';
body += 'const regs = context.r10;';
}
else {
throw new Error('CTXREG: ' + arch);
}

// mips: 0->3 (a0->a3)
body += 'const args = [';
for (let i = 0; i < 4; i++) {
// https://github.com/hrydgard/ppsspp/blob/0c40e918c92b897f745abee0d09cf033a1572337/Core/MIPS/MIPS.h#L190
let offset = -0x80 + 0x10 + i * 4;
let offset = -0x80 + 0x10 + i * 4; // skip: zero, at, v0, v1 = 0x10
body += '{';
body += `_vm: regs.add(${offset}).readU32(),`
body += `_vm: regs.add(${offset}).readU32(),`;
body += `get value() { return base.add(this._vm); },`; // host address
body += `set vm(val) { this._vm = val; },`;
body += `get vm() { return this._vm },`;
Expand Down
21 changes: 14 additions & 7 deletions libRPCS3.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
// @name RPCS3 LLVM Hooker
// @version
// @version 0.0.20-13234+ - https://github.com/RPCS3/rpcs3-binaries-win/releases?q=0.0.20&expanded=true
// @author [DC]
// @description TODO: linux
// @description TODO: linux, macM1

const __e = Process.enumerateModules()[0];
const installFunctionPatt1 = '0F86 ???????? 488D?? ?0010000 E8 ???????? 4883C? 68'; // MSVC
if (Process.platform !== 'windows') {
throw 'TODO: ' + Process.platform + ' ' + Process.arch;
}

const installFunctionPatt1 = '0F8? ???????? 488D?? ?00?0000 E8 ???????? 4883C? 68'; // MSVC
let DoJitMatch = Memory.scanSync(__e.base, __e.size, installFunctionPatt1)[0];
if (!DoJitMatch) {
const installFunctionPatt2 = '660F 1F440000 488D?? ?0010000 E8 ???????? 4883C? 68'; // patched
const installFunctionPatt2 = '660F 1F440000 488D?? ?00?0000 E8 ???????? 4883C? 68'; // patched
DoJitMatch = Memory.scanSync(__e.base, __e.size, installFunctionPatt2)[0];
if (!DoJitMatch) throw new Error('DoJit not found!');
}
Expand All @@ -22,11 +26,14 @@ const {_emReg, _jitReg} = (function() {
p = Instruction.parse(p.next); // call 0x00
p = Instruction.parse(p.next); // add r?x, 0x68
const _emReg = p.operands[0].value;
p = Instruction.parse(DoJitPtr.sub(0x16)); // lea rdx, ds:[rax+rcx*2]
const _jitReg = p.operands[0].value;

// nop jbe & je:
const isPPUDebugIfPtr = DoJitPtr.sub(0x21);
let isPPUDebugIfPtr = Memory.scanSync(DoJitPtr.sub(0x40), 0x40, '84C0 ???? 8B')[0]; // je
if (!isPPUDebugIfPtr) throw new Error('DoJit not found 2!');
isPPUDebugIfPtr = isPPUDebugIfPtr.address.add(2);
p = Instruction.parse(isPPUDebugIfPtr.add(0xB)); // lea rdx, ds:[rax+rcx*2]
const _jitReg = p.operands[0].value;

Memory.protect(isPPUDebugIfPtr, 0x40, 'rwx');
DoJitPtr.writeByteArray([0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00]); // 6bytes nop
isPPUDebugIfPtr.writeByteArray([0x66, 0x90]); // 2bytes nop
Expand Down
Loading

0 comments on commit 9061a4f

Please sign in to comment.