A Memory Visualiser Tool for iOS Security Research
Happy New Year!🥳
In this post I want to share a recent project of mine — a memory visualiser tool for iOS security researchers.
I’m releasing an early demo version of this tool starting today, so if you’re interested, be sure to go to https://zygosec.com/membuddy.html and try it out.
The tool is
membuddy — a GUI application for macOS that allows you to visualise and track the memory of a target process.
My inspiration for this visualisation tool came from the countless diagrams found in researchers blogs that depict the relationship between structures in memory when describing a vulnerability or exploit strategy.
These diagrams are incredibly useful when trying to understand a complex idea or relationship between multiple data structures in a target process.
I wanted to build something that could generate a similar visual representation of memory, but in real-time and when actually debugging an exploit, or working on general analysis of a running process.
membuddy macOS app connects to a server running on the iOS device (or theoretically another target system).
Once connected to the target, the macOS app will request memory from the server and display it in the GUI. You can browse the process memory in the memory explorer window.
Much like a standard debugger interface, here you can browse the bytes of memory with the ASCII representation to the right. In the screenshot above we are viewing the Mach header of the iOS kernel process.
Clicking on values in the memory dump gives you the option to modify the value, or view nested memory if this value is recognised as a pointer.
Note: Okay – so the current pointer detection isn’t at all smart. It just checks for the presence of the F’s in the upper bits, so be careful trying to read from something that isn’t actually a pointer because you’ll likely panic)
You can also create a new ‘block’ for any memory address.
This adds a visual block view representing this memory area to the canvas on the right-hand side.
Blocks can also be customised in a few ways. This includes, setting a block name (a label to essentially annotate that particular block), setting a structure type (display struct member names alongside the values) and resizing the block.
With the customisations applied to block in the screenshot above, we can see that this block is representing the XNU
proc structure for the kernel process.
We can interact with block data in the same ways we do in the memory viewer — you can modify values and view memory at addresses.
The values displayed on each of the blocks are kept in-sync with the live memory of the target process. Memory is refreshed every 1 second by re-requesting memory from the
Creating a second block that branches from a pointer in the first block adds a visual line connecting the two.
Complex arrangements can be made by creating and connecting multiple blocks in the block canvas.
The blocks can be freely moved around the canvas, and connection lines remain connected to the blocks. This makes the relationship between different memory areas easy to understand.
Connection lines update accordingly when pointers change to point to new memory.
We can demonstrate this by replacing the XNU
ucred structure on an iOS app.
For those who are unfamiliar, an app’s
ucred holds the credentials and sandbox restrictions associated with the process, so replacing this with a more privileged process’
ucred essentially un-sandboxes the app.
The following short video shows how we can use
membuddy to swap out the
The changes in the block connections are reflected in the arrangement of the lines, and the affect this has on the iOS app’s sandbox is apparent thanks to the failure & success alerts displayed when trying to open a connection to a sandbox-protected IOKit user client.
membuddy tool is in a proof-of-concept state right now. There’s plenty of bugs to be fixed, and refinements to be made. However, as I mentioned, if you’re interested in trying it you can download an early version of the beta at https://zygosec.com/membuddy.html.
— Billy Ellis @bellis1000