Fix Linux module-bounds detection: extend through Wine's anonymous PE mapping
Running the Linux build against a live game showed it stuck forever on "scanning signatures": scanMaps only collected mappings whose file matched eldenring.exe, but this Proton build backs just the 4 KB PE header with the real path and maps the rest of the module (~94 MB of .text/.rdata/.data, where every AOB signature lives) as one anonymous mapping with no path. findModuleBase was handing the scanner the header alone. moduleSpan (the matching logic, now pulled out of scanMaps as a pure function for process_linux_test.go) extends the span through contiguous anonymous mappings that follow the last named one, and stops at the first mapping with its own path so it can't merge in an unrelated module. Confirmed against the live process: all three signatures resolve, PlayerIns confirms, and /deaths reports real numbers end to end. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
66aba2fff2
commit
356df6cbd5
3 files changed
+167
-32
No files matched your search
@@ -89,10 +89,19 @@ Windows, mismas firmas y offsets):
|
||||
(`findProcessID`/`scanMaps`): Proton levanta varios procesos: se
|
||||
recorre `/proc/*/maps` y se toma el pid que tenga mapeado un archivo
|
||||
terminado en `eldenring.exe`. Los mismos mapeos dan la base y el
|
||||
tamaño del módulo para `findModuleBase`: puede venir partido en varios
|
||||
tramos (`.text`/`.rdata`/`.data`), así que se toma el span completo
|
||||
(mínimo inicio, máximo final) — alcanza, porque el escáner ya lee por
|
||||
chunks y saltea los que no puede leer.
|
||||
tamaño del módulo para `findModuleBase` (`moduleSpan`, la parte pura
|
||||
de `scanMaps`, testeada en `process_linux_test.go`) — pero el tamaño
|
||||
real **no** sale de sumar los tramos con ese nombre. Confirmado
|
||||
corriendo contra un Proton real: el loader de PE de Wine sólo mapea
|
||||
con el archivo real la página del header (unos pocos KB); el resto
|
||||
del módulo — `.text`/`.rdata`/`.data`, donde viven las firmas — es UN
|
||||
mapeo anónimo enorme (acá, ~94 MB) pegado justo después, sin ruta.
|
||||
Quedarse con el span de los tramos nombrados solos deja al escáner con
|
||||
el header y nada más: todas las firmas fallan y `resolvePointers` da
|
||||
vueltas para siempre. `moduleSpan` extiende el span a través de
|
||||
mapeos anónimos contiguos que sigan al último tramo nombrado —
|
||||
contiguos y sin ruta nada más, para no comerse por accidente un
|
||||
módulo distinto que justo cargue pegado.
|
||||
- **Leer memoria vía `/proc/<pid>/mem`** (`ReadAt`, sin dependencias
|
||||
externas), no `process_vm_readv(2)` crudo: mismo resultado, sin tener
|
||||
que hacer un syscall a mano con structs `iovec` sin `golang.org/x/sys`.
|
||||
|
||||
Reference in new issue
Block a user