Files

45 lines
2.0 KiB
Java

package mtn3;
import com.eliasmueller.llamamod.exe.ExeImage;
import com.eliasmueller.llamamod.mods.Mod;
import com.eliasmueller.llamamod.mods.ModContext;
import com.eliasmueller.llamamod.mods.ModOption;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
/** Throwaway diagnostics: stale parent-variable access log + local heap consistency check. */
public final class Mtn3DiagMod implements Mod {
static final Path DIR = Path.of("/home/elias/.claude/jobs/90c6eed7/tmp/m3/diag");
public String id() { return "mtn3-diag"; }
public String name() { return "Mountain 3 diagnostics"; }
public String description() { return "Logs stale parent writes and checks the local heap (test only)."; }
public boolean modifiesExecutable() { return true; }
public List<ModOption> options() {
return List.of(ModOption.bool("fix", "Fix", "Redirect stale parent writes to a dummy", false),
ModOption.string("rev", "Rev", "cache buster", "1"));
}
public void apply(ModContext ctx) throws IOException {
ExeImage exe = ctx.exe();
long data = exe.allocateData(8192, "mtn3 diag data");
long cave = exe.nextAllocation();
String fix = ctx.optionBool("fix") ? "1" : "0";
Path bin = DIR.resolve(String.format("cave_%s_%x_%x.bin", fix, cave, data));
Files.writeString(DIR.resolve("addresses.txt"), String.format("CAVE=0x%x DATA=0x%x FIX=%s%n", cave, data, fix));
if (!Files.exists(bin)) {
throw new IOException("assemble " + bin);
}
long at = exe.place(Files.readAllBytes(bin), "mtn3 diag code");
if (at != cave) {
throw new IOException("cave moved " + Long.toHexString(at));
}
exe.hookJmp(0x553770, "8B 44 24 04 8B", cave, "pushParentVarAddr");
exe.hookJmp(0x553a40, "56 8B 74 24 08", cave + 5, "popParentVar");
exe.hookJmp(0x41ada0, "8B 44 24 04 56", cave + 10, "FreeLocalMem");
exe.hookJmp(0x41ae20, "8B 0D 9C 49 58 00", cave + 15, "AllocLocalMem");
}
}