Update unbacked network for further accuracy#586
Conversation
Track processes better and also stop tracking once it is freed.
There was a problem hiding this comment.
Code Review
This pull request refactors several Windows unbacked memory signatures to optimize API checks using frozensets, handle VirtualAllocEx separately, and track memory deallocations via NtFreeVirtualMemory and VirtualFree. However, two key issues were identified: first, VirtualAllocEx incorrectly treats the hProcess handle as a PID, which will lead to tracking failures; second, there is significant code duplication across the five signature classes, which should be resolved by extracting the shared memory-tracking logic into a common base class.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if api == "VirtualAllocEx": | ||
| base_address = self.get_argument(call, "lpAddress") | ||
| region_size = self.get_argument(call, "dwSize") | ||
| target_pid = self.get_argument(call, "hProcess") | ||
| if base_address and region_size and target_pid: | ||
| try: | ||
| base_val = int(base_address, 16) if isinstance(base_address, str) else int(base_address) | ||
| size_val = int(region_size, 16) if isinstance(region_size, str) else int(region_size) | ||
| t_pid = int(target_pid, 16) if isinstance(target_pid, str) else int(target_pid) | ||
| if t_pid not in self.unbacked_ranges: | ||
| self.unbacked_ranges[t_pid] = [] | ||
| self.unbacked_ranges[t_pid].append((base_val, base_val + size_val)) | ||
| except (ValueError, TypeError): | ||
| pass | ||
| return |
There was a problem hiding this comment.
Correctness Issue: hProcess is a Process Handle, Not a PID
In Windows, the hProcess argument passed to VirtualAllocEx is a process handle (e.g., 0x7c), not the actual Process ID (PID) of the target process. Treating hProcess directly as a PID (t_pid) is a bug:
- The allocated memory range will be stored under the handle value (e.g.,
124) instead of the actual target PID (e.g.,4096). - When the target process later executes a network or DNS API, the signature will look up its actual PID and fail to find the unbacked memory range, resulting in a false negative.
To properly track remote allocations via VirtualAllocEx, you need to maintain a mapping of process handles to PIDs by intercepting handle-creation APIs (such as OpenProcess, NtOpenProcess, or CreateProcessInternalW). If handle-to-PID mapping is not implemented, VirtualAllocEx cannot be reliably tracked for remote processes.
Track processes better and also stop tracking once it is freed.