Files
luma/Agent/core/env.ts
Ole André Vadla Ravnås 12d5491c22 Sync disasm cache across collab
Identify a process instance by a deterministic identity returned
from the agent (per-OS, with a Process.mainModule + pid fallback)
and stash it on ProcessSession.processInfo. Rekey memory_page
into memory_page_module (module UUID + offset) so cached bytes
survive ASLR, and memory_page_anon (process identity + address)
for JIT / heap regions that only survive within one process
instance. Purge stale anon pages on every fresh attach.

Add updateProcessInfo, updateModuleAnalysis and updateInsight
SessionOps plus a side-channel publish-memory-page op and a
+fetch-memory-page request. The driver write-throughs every
page it fetches; non-drivers pull on miss and persist locally.
Module-analysis rows flow the same way so non-drivers can key
their cache by module UUID. The lab-join snapshot now carries
processInfo and module_analyses too.

Refresh actions on the insight detail view: Reread Bytes drops
the pages overlapping the visible range; Reanalyze Module drops
the module's analysis and pages, re-running r2 on next access.

The macOS detail view now reads the insight live from
insightsBySession via observation; GTK forwards .insightUpdated
into the detail and reschedules a refresh when the resolved
address changes.
2026-05-19 15:16:48 +02:00

121 lines
3.6 KiB
TypeScript

export interface ProcessInfo {
platform: Platform;
arch: Architecture;
pointerSize: number;
mainModule: ModuleInfo;
identity: string;
}
export interface ModuleInfo {
name: string;
path: string;
base: string;
size: number;
}
export function getProcessInfo(): ProcessInfo {
const main = Process.mainModule;
return {
platform: Process.platform,
arch: Process.arch,
pointerSize: Process.pointerSize,
mainModule: {
name: main.name,
path: main.path,
base: main.base.toString(),
size: main.size,
},
identity: computeProcessIdentity(),
};
}
function computeProcessIdentity(): string {
const source = osSpecificIdentitySource() ?? fallbackIdentitySource();
const sum = new Checksum("sha256");
sum.update(source);
return sum.getString().slice(0, 16);
}
function osSpecificIdentitySource(): string | null {
try {
switch (Process.platform) {
case "linux": return linuxIdentitySource();
case "darwin": return darwinIdentitySource();
case "windows": return windowsIdentitySource();
default: return null;
}
} catch (_) {
return null;
}
}
function fallbackIdentitySource(): string {
return `mainbase=${Process.mainModule.base.toString()};pid=${Process.id}`;
}
function linuxIdentitySource(): string {
const bootID = File.readAllText("/proc/sys/kernel/random/boot_id").trim();
const stat = File.readAllText("/proc/self/stat");
const afterComm = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/);
const startTimeJiffies = afterComm[19];
return `boot=${bootID};start=${startTimeJiffies};pid=${Process.id}`;
}
function darwinIdentitySource(): string {
const sysctl: SysctlFunction = new NativeFunction(
Module.getGlobalExportByName("sysctl"),
"int",
["pointer", "uint", "pointer", "pointer", "pointer", "size_t"]
);
return `boot=${darwinBootTime(sysctl)};start=${darwinProcStartTime(sysctl)};pid=${Process.id}`;
}
function darwinBootTime(sysctl: SysctlFunction): string {
const mib = Memory.alloc(8);
mib.writeU32(CTL_KERN); mib.add(4).writeU32(KERN_BOOTTIME);
return readSysctlTimeval(sysctl, mib, 2);
}
function darwinProcStartTime(sysctl: SysctlFunction): string {
const mib = Memory.alloc(16);
mib.writeU32(CTL_KERN);
mib.add(4).writeU32(KERN_PROC);
mib.add(8).writeU32(KERN_PROC_PID);
mib.add(12).writeU32(Process.id);
return readSysctlTimeval(sysctl, mib, 4);
}
function readSysctlTimeval(sysctl: SysctlFunction, mib: NativePointer, mibCount: number): string {
const buf = Memory.alloc(16);
const len = Memory.alloc(Process.pointerSize);
len.writeULong(16);
sysctl(mib, mibCount, buf, len, NULL, 0);
const sec = buf.readS64();
const usec = buf.add(8).readS32();
return `${sec}.${usec}`;
}
type SysctlFunction = NativeFunction<number, [NativePointer, number, NativePointer, NativePointer, NativePointer, number]>;
function windowsIdentitySource(): string {
const getProcessTimes = new NativeFunction(
Module.getGlobalExportByName("GetProcessTimes"),
"int32",
["pointer", "pointer", "pointer", "pointer", "pointer"]
);
const buf = Memory.alloc(32);
getProcessTimes(WINDOWS_CURRENT_PROCESS, buf, buf.add(8), buf.add(16), buf.add(24));
const low = buf.readU32();
const high = buf.add(4).readU32();
return `create=${high}.${low};pid=${Process.id}`;
}
const WINDOWS_CURRENT_PROCESS = ptr(-1);
const CTL_KERN = 1;
const KERN_PROC = 14;
const KERN_BOOTTIME = 21;
const KERN_PROC_PID = 1;
const NULL = ptr(0);