-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Description
On macOS, when querying memory regions via LLDB and debugserver, the name: attribute is often missing from memory region packets.
Currently, debugserver only provides the type: field (e.g., type:malloc-metadata or type:heap), but this information is not accessible via the Python API (SBMemoryRegionInfo has no GetType() method).
In pwndbg we want to display meaningful memory region names/types for the user (e.g., [heap], [stack], [malloc-metadata]).
But since debugserver does not provide name:, and Python cannot access type:, scripts cannot display human-readable memory page names.
(lldb) script
>>> regions = lldb.process.GetMemoryRegions()
# Example packets where type is present but name is missing
< 87> read packet: $start:100020000;size:4000;permissions:r;dirty-pages:100020000;type:malloc-metadata;#00
< 88> read packet: $start:100024000;size:4000;permissions:rw;dirty-pages:100024000;type:malloc-metadata;#00
>>> region = lldb.SBMemoryRegionInfo()
>>> regions.GetMemoryRegionAtIndex(7, region)
True
>>> region.GetName()
None
Expected behavior
-
Debugserver should implement the
name:attribute in gdb-remote memory region packets. -
Debugserver should implement more memory mapping names, eg:
[shared memory]- (user_tag == 0 && share_mode in (SM_SHARED, SM_TRUESHARED, SM_SHARED_ALIASED))[VM_ALLOCATE]- (user_tag == 0 && share_mode in (SM_PRIVATE, SM_PRIVATE_ALIASED))[Kernel Alloc Once]- (user_tag == VM_MEMORY_OS_ALLOC_ONCE)[stack][heap][malloc-metadata]- or more from XNU VM_* types - https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/vm_statistics.h#L581-L785
-
relevant place in debugserver:
llvm-project/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp
Lines 186 to 225 in c894d3a
std::vector<std::string> MachVMRegion::GetMemoryTypes() const { std::vector<std::string> types; if (m_data.user_tag == VM_MEMORY_STACK) { if (m_data.protection == VM_PROT_NONE) { types.push_back("stack-guard"); } else { types.push_back("stack"); } } if (m_data.user_tag == VM_MEMORY_MALLOC) { if (m_data.protection == VM_PROT_NONE) types.push_back("malloc-guard"); else if (m_data.share_mode == SM_EMPTY) types.push_back("malloc-reserved"); else types.push_back("malloc-metadata"); } if (m_data.user_tag == VM_MEMORY_MALLOC_NANO || m_data.user_tag == VM_MEMORY_MALLOC_TINY || m_data.user_tag == VM_MEMORY_MALLOC_SMALL || m_data.user_tag == VM_MEMORY_MALLOC_LARGE || m_data.user_tag == VM_MEMORY_MALLOC_LARGE_REUSED || m_data.user_tag == VM_MEMORY_MALLOC_LARGE_REUSABLE || m_data.user_tag == VM_MEMORY_MALLOC_HUGE || m_data.user_tag == VM_MEMORY_REALLOC || m_data.user_tag == VM_MEMORY_SBRK || m_data.user_tag == VM_MEMORY_SANITIZER) { types.push_back("heap"); if (m_data.user_tag == VM_MEMORY_MALLOC_TINY) { types.push_back("malloc-tiny"); } if (m_data.user_tag == VM_MEMORY_MALLOC_LARGE) { types.push_back("malloc-large"); } if (m_data.user_tag == VM_MEMORY_MALLOC_SMALL) { types.push_back("malloc-small"); } } return types; }
How it looks like in pwndbg:
In pwndbg we forked lldb, and it looks like this, but our changes are too bad for upstream:
