mirror of
https://dev.lirent.ru/Vatrog/vm-introspection-engine.git
synced 2026-06-18 06:36:37 +03:00
Zero-copy hot path, correctness hardening
gva_ptr: leaf-bounded zero-copy guest reads. gva_sweep redesigned to drive on it — large-page leaves are lent to the callback while 4K runs stay buffered, and the run loop is guarded against wrap at the top of the address space. gva_gpa fetches PTEs zero-copy; optional W32MS_LTO build option folds the per-fetch call boundary (shipped -O2 default unchanged). Correctness: subtract-form bounds check (no add overflow), memcpy decode in place of type-punned wide loads, zero-init PDB name before compare, PCI-hole-crossing range rejection, single-sourced VA_CANON and USER bounds. hot/cold attributes audited across the translation and scan path.
This commit is contained in:
+9
-8
@@ -3,7 +3,7 @@
|
||||
#include "include/memory.h"
|
||||
#include "../include/include.h"
|
||||
|
||||
static void utf8_emit(uint32_t cp, char* dst, size_t size, size_t* need) {
|
||||
static void utf8_emit(uint32_t cp, char* dst, size_t size, size_t* need, size_t* wrote) {
|
||||
uint8_t b[4]; size_t k;
|
||||
if (cp < 0x80) { b[0]=(uint8_t)cp; k=1; }
|
||||
else if (cp < 0x800) { b[0]=0xC0|(uint8_t)(cp>>6); b[1]=0x80|(cp&0x3F); k=2; }
|
||||
@@ -11,12 +11,13 @@ static void utf8_emit(uint32_t cp, char* dst, size_t size, size_t* need) {
|
||||
else { b[0]=0xF0|(uint8_t)(cp>>18); b[1]=0x80|((cp>>12)&0x3F); b[2]=0x80|((cp>>6)&0x3F); b[3]=0x80|(cp&0x3F); k=4; }
|
||||
if (dst && *need + k < size) {
|
||||
for (size_t j = 0; j < k; j++) dst[*need + j] = (char)b[j];
|
||||
*wrote = *need + k; /* end of last full code point */
|
||||
}
|
||||
*need += k;
|
||||
}
|
||||
|
||||
size_t gva_read_text(gva_ctx* ctx, uintptr_t cr3, uintptr_t va, size_t nmemb, char* dst, size_t size) {
|
||||
size_t need = 0;
|
||||
size_t need = 0, wrote = 0;
|
||||
uint16_t stage[256];
|
||||
uint32_t hi = 0;
|
||||
nmemb &= ~(size_t)1;
|
||||
@@ -31,21 +32,21 @@ size_t gva_read_text(gva_ctx* ctx, uintptr_t cr3, uintptr_t va, size_t nmemb, ch
|
||||
uint32_t u = stage[i];
|
||||
if (hi) {
|
||||
if (u >= 0xDC00 && u <= 0xDFFF) {
|
||||
utf8_emit(0x10000u + ((hi - 0xD800u) << 10) + (u - 0xDC00u), dst, size, &need);
|
||||
utf8_emit(0x10000u + ((hi - 0xD800u) << 10) + (u - 0xDC00u), dst, size, &need, &wrote);
|
||||
hi = 0;
|
||||
continue;
|
||||
}
|
||||
utf8_emit(0xFFFD, dst, size, &need);
|
||||
utf8_emit(0xFFFD, dst, size, &need, &wrote);
|
||||
hi = 0;
|
||||
}
|
||||
if (u >= 0xD800 && u <= 0xDBFF) hi = u;
|
||||
else if (u >= 0xDC00 && u <= 0xDFFF) utf8_emit(0xFFFD, dst, size, &need);
|
||||
else utf8_emit(u, dst, size, &need);
|
||||
else if (u >= 0xDC00 && u <= 0xDFFF) utf8_emit(0xFFFD, dst, size, &need, &wrote);
|
||||
else utf8_emit(u, dst, size, &need, &wrote);
|
||||
}
|
||||
va += chunk;
|
||||
nmemb -= chunk;
|
||||
}
|
||||
if (hi) utf8_emit(0xFFFD, dst, size, &need);
|
||||
if (dst && size) dst[need < size ? need : size - 1] = 0;
|
||||
if (hi) utf8_emit(0xFFFD, dst, size, &need, &wrote);
|
||||
if (dst && size) dst[need < size ? need : wrote] = 0;
|
||||
return need;
|
||||
}
|
||||
Reference in New Issue
Block a user