MCPcopy Create free account
hub / github.com/MemNixFS/MemNixFS / resolve_kernel

Function resolve_kernel

src/os/linux/kernel_resolver.cpp:118–334  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

116}
117
118KernelContext resolve_kernel(const PhysicalLayer& phys, const IsfSymbols& isf) {
119 KernelContext ctx{};
120
121 // init_task is OPTIONAL: full DWARF-derived ISFs have it (so we can
122 // derive KASLR shift symbolically); BTF-derived ISFs only carry types,
123 // so we fall back to direct-from-swapper-scan init_task discovery and a
124 // best-effort KASLR shift (=0 unless banner symbol is also present).
125 auto init_task_sym = isf.find_symbol("init_task");
126 const bool have_symbols = (init_task_sym != nullptr);
127 if (!have_symbols) {
128 log::warn("ISF has no `init_task` symbol — running in BTF/types-only "
129 "mode. Process listing will work via direct-map; kernel-VA "
130 "reads (kallsyms, modules, dmesg, DTB walks) will be limited.");
131 }
132
133 warn_if_isf_mismatch(phys, isf);
134
135 u64 task_struct_size = isf.type_size("task_struct");
136 u64 comm_off = isf.field_offset("task_struct", "comm");
137 u64 pid_off = isf.field_offset("task_struct", "pid");
138 u64 tgid_off = isf.field_offset("task_struct", "tgid");
139 u64 tasks_off = isf.field_offset("task_struct", "tasks");
140
141 if (have_symbols)
142 log::debug("init_task VA (pre-KASLR) = {:#x}", init_task_sym->address);
143 log::debug("task_struct: size={:#x} pid@{:#x} comm@{:#x} tasks@{:#x}",
144 task_struct_size, pid_off, comm_off, tasks_off);
145
146 // First try a banner-based shift (robust against task_struct layout drift).
147 auto banner_candidates = banner_candidate_shifts(phys, isf);
148 log::debug("Banner string found at {} location(s)", banner_candidates.size());
149 for (auto& [at, sh] : banner_candidates) {
150 bool aligned_2mb = (sh & 0x1FFFFF) == 0;
151 log::debug(" banner @ PA {:#x} shift={:#x} 2MB-aligned={}", at, sh, aligned_2mb);
152 }
153
154 auto hits = scan_swapper(phys);
155 if (hits.empty()) throw_error("kernel: no swapper signature found");
156
157 const VAddr init_task_sym_addr = have_symbols ? init_task_sym->address : 0;
158
159 for (PAddr comm_pa : hits) {
160 PAddr task_pa = (comm_pa >= comm_off) ? (comm_pa - comm_off) : 0;
161
162 u32 pid = 0;
163 bool ok_pid = phys.read_pod(task_pa + pid_off, pid);
164 u64 next = 0, prev = 0;
165 bool ok_next = phys.read_pod(task_pa + tasks_off + 0, next);
166 bool ok_prev = phys.read_pod(task_pa + tasks_off + 8, prev);
167
168 // dump the comm bytes for sanity
169 char buf[24] = {};
170 phys.read(comm_pa, buf, 16);
171 log::debug("comm bytes @ {:#x}: '{}' (raw: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x})",
172 comm_pa, buf, (u8)buf[0],(u8)buf[1],(u8)buf[2],(u8)buf[3],(u8)buf[4],
173 (u8)buf[5],(u8)buf[6],(u8)buf[7],(u8)buf[8]);
174 log::debug("candidate: comm_pa={:#x} task_pa={:#x} pid={} (ok={}) next={:#x} prev={:#x} (ok={},{})",
175 comm_pa, task_pa, pid, ok_pid, next, prev, ok_next, ok_prev);

Callers 1

createMethod · 0.85

Calls 15

warnFunction · 0.85
warn_if_isf_mismatchFunction · 0.85
debugFunction · 0.85
banner_candidate_shiftsFunction · 0.85
scan_swapperFunction · 0.85
throw_errorFunction · 0.85
kernel_va_to_pa_staticFunction · 0.85
resolve_dtbFunction · 0.85
read_stringFunction · 0.85
find_symbolMethod · 0.80
type_sizeMethod · 0.80
field_offsetMethod · 0.80

Tested by

no test coverage detected