- Инфраструктура: 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 порядок).
73 lines
5.5 KiB
Java
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);
|
|
}
|
|
} |