Files
soothe2-re/ImportRtti.java
T
Matiq 25cf786c54 Initial commit: soothe2 RE workspace + roadmap
- Инфраструктура: RTTI-дампы (rtti_dsp/full.json), декомпиляции DSP-классов (decomp_*.txt),
  Ghidra-скрипты (Dump*.java, ImportRtti*.java, Diag.java), depthcurve/curve_fits LUT.
- Поведенческая модель sim_v5.py + sim.py (RMSE ~0.3dB), утилиты (measure, tt_sweep, patchparam,
  sweep, harness_*, verify_sim).
- summary.md + roadmap.md (контракт из manual M1-M12, топология пайплайна из OCR, фазы A-C).
- pipeline_ocr.txt: OCR диаграммы Appendix A (mid/side ручка, trim/mix/bypass порядок).
2026-08-16 18:54:40 +03:00

73 lines
5.5 KiB
Java

import ghidra.app.script.GhidraScript;
import ghidra.program.model.symbol.SymbolTable;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.mem.MemoryBlock;
import java.util.*;
public class ImportRtti extends GhidraScript {
@Override
public void run() throws Exception {
// map: vftable vendor address -> (class name, [func ptrs]) (decimal-addrs form from dump)
// encoded compactly: name|col|vf|func0,func1,... (up to 48)
String[] data = {
"Soothe2AudioProcessor|0x182506ca0|0x1824abf60|0x1813658a0,0x18052c7e0,0x18053846c,0x182504fa0,0x180536f70,0x180536f70,0x180537160,0x180536f60,0x18048db00,0x180481210,0x182505208,0x180536670,0x180536670,0x1804714b0,0x180536660,0x18048db00,0x180481210,0x1825068b0,0x180536cc0,0x180536cc0,0x180537720,0x180536cb0,0x18048db00,0x180481210,0x182504e40,0x180528ba0,0x1804714b0,0x1804714b0,0x1825067d0,0x180536b90,0x180536b90,0x180537930,0x180536b80,0x18048dc80,0x180481210,0x182505680,0x180536c60",
"$SpectralProcessor@M$07$01|0x1825033e0|0x1824abb90|0x18052d390,0x18052cfb0,0x180529550,0x1804714b0,0x180529610,0x18113285a,0x1805295c0,0x180529590,0x180536b60,0x180536b60,0x1805379a0,0x18250e798,0x1804d8db0,0x1804d8db0,0x18250e3f8,0x18052c7b0,0x1804d8db0,0x1804d8db0,0x1825074f0,0x1804714b0,0x18113285a,0x1804714b0,0x1825060e0,0x18113285a,0x18113285a,0x1804d8db0,0x18053fbf0,0x1804d8db0,0x1804d8db0",
"$Soothe2ModuleBase@M$01|0x1825038b0|0x1824ac7a8|0x18052fd40,0x18052cfb0,0x180529550,0x1804714b0,0x18052ce00,0x1804714b0,0x18052cb90,0x18052cbc0,0x180536b60,0x182507120,0x1805367a0,0x18052e540,0x18052ce00,0x18052cbe0,0x18048db00,0x180481210,0x18052ff40,0x180530060,0x18052cfb0",
"$AudioProcessingModule@M$01|0x182503180|0x1824ac638|0x18052d580,0x18052cfb0,0x18052cfa0,0x1804714b0,0x18113285a,0x18113285a,0x18052cbe0,0x180536b60,0x180536b60,0x1825071e8,0x18052cfa0,0x18052cfb0,0x18052cfb0",
"$Soothe2Module@M$01|0x182504e00|0x1824ac210|0x180535ed0,0x18052cfb0,0x180529550,0x1804714b0,0x18052b940,0x180529c60,0x18052bac0,0x18052b9d0,0x18052ba40,0x18052bad0,0x18052d3a0,0x18052b960,0x18052cb90,0x18052cbc0",
"$IIRFilterExtended@M$01|0x182503a58|0x1824ac5d8|0x1805346b0,0x18052cfb0,0x18052cfa0,0x18052fb50,0x18052fb30,0x182506a00,0x18052f820,0x18048db00,0x180481210,0x18052f7d0,0x18052f7c0,0x18052fc70,0x18052f950,0x18053fc00,0x18053fbc0,0x18053fa10",
"$DigitalFilter@M$0BA$01|0x182519b70|0x1824be7a0|0x18058d2b0,0x18052cfb0,0x18052cfa0,0x1804714b0,0x18113285a,0x18113285a,0x18058c850,0x18058c8b0,0x18058c7b0",
"$LowPassFilter@M$0BA$01|0x18251a141|0x1824be990|0x18058d230,0x18052cfb0,0x18052cfa0,0x18058c850,0x18058c8b0,0x18058c7b0",
"Soothe2FilterGraph|0x182518870|0x1824be810|0x180589260,0x18134bc00,0x18058b4d0,0x18058b380,0x18134bbd0,0x18134bbc0,0x18058b2d0,0x18058b290",
"$FilterGraph@M$05$0CAA@|0x1825189b8|0x1824be228|0x18058eb1c,0x18058b010,0x18251ab48,0x18058eab0,0x18160b000,0x1804714b0,0x18058ea70,0x18058ea90,0x18058dfa0,0x18058dfc0,0x18058df40,0x18058df60,0x18058dac0,0x18058daa0",
"Soothe2ModuleDecryptor|0x182504928|0x1824abe68|0x18052d520,0x1813e2a60,0x182505230,0x180536a50,0x180536a50,0x180537680,0x180536a50,0x180536a50,0x180537680",
"$ModuleDecryptor@VSoothe2_DynamicCryptoManager@eden@pace|0x1825043d8|0x1824ab228|0x18052d520,0x18113285a,0x182505008,0x180538490,0x18135c520,0x182506e60,0x180536900,0x180536b60",
};
SymbolTable st = currentProgram.getSymbolTable();
FunctionManager fm = currentProgram.getFunctionManager();
long base = 0x180000000L;
int lab = 0;
int fn = 0;
for (String line : data) {
String[] parts = line.split("\\|");
if (parts.length < 4) continue;
String cls = parts[0];
long col = Long.decode("0x" + parts[2]);
// skip vf slot - parts[2] is vftable
long vf = Long.decode("0x" + parts[2]);
String[] fptr = parts[3].split(",");
// namespace = class name
Namespace ns = st.getNamespace(cls, currentProgram.getGlobalNamespace());
if (ns == null) {
Address aCol = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(col);
ns = st.createClass(null, cls, aCol, SourceType.USER_DEFINED);
lab++;
}
for (String fs : fptr) {
long f = Long.decode("0x" + fs);
Address addr = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(f);
Function existing = fm.getFunctionAt(addr);
if (existing == null) {
fm.createFunction(null, addr, null, SourceType.USER_DEFINED);
fn++;
}
String nm = cls + "_v" + fptr.length + "";
Function fx = fm.getFunctionAt(addr);
if (fx != null && fx.getSymbol() != null
&& fx.getSymbol().getParentNamespace() == currentProgram.getGlobalNamespace()) {
String sname = "v_" + cls;
st.createLabel(addr, sname, ns, SourceType.USER_DEFINED);
lab++;
}
}
}
println("IMPORT_RTTI_NAMESPACES " + lab);
println("IMPORT_RTTI_FUNCTIONS " + fn);
}
}