Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
skip to main content
research-article

In the Land of MMUs: Multiarchitecture OS-Agnostic Virtual Memory Forensics

Published: 09 July 2022 Publication History

Abstract

The first step required to perform any analysis of a physical memory image is the reconstruction of the virtual address spaces, which allows translating virtual addresses to their corresponding physical offsets. However, this phase is often overlooked, and the challenges related to it are rarely discussed in the literature. Practical tools solve the problem by using a set of custom heuristics tailored on a very small number of well-known operating systems (OSs) running on few architectures.
In this article, we look for the first time at all the different ways the virtual to physical translation can be operated in 10 different CPU architectures. In each case, we study the inviolable constraints imposed by the memory management unit that can be used to build signatures to recover the required data structures from memory without any knowledge about the running OS. We build a proof-of-concept tool to experiment with the extraction of virtual address spaces showing the challenges of performing an OS-agnostic virtual to physical address translation in real-world scenarios. We conduct experiments on a large set of 26 different OSs and a use case on a real hardware device. Finally, we show a possible usage of our technique to retrieve information about user space processes running on an unknown OS without any knowledge of its internals.
Appendices

A POWER ISA (64-bit)

The Power architecture is a RISC architecture introduced by IBM in the early 1990s. Starting from the original POWER ISA, many architectural variants have been developed over the past 30 years, including variants for gaming consoles. However, only two of those architectures are still currently developed and supported: PowerPC, already described in Section 5.1, and Power ISA.

A.1 MMU Internals

Power ISA is a server-class 64-bit bi-endian architecture focused on para-virtualization: a hypervisor OS manages all resources of the system, including MMU registers and in-memory tables, partitioning them between the para-virtualized machines (called logical partitions (LPARs)). An OS running inside an LPAR needs specific support for this environment to interface with the hypervisor. CPUs based on the latest Power ISA revision [41], like the IBM POWER9 family, use the PTCR register to point to an in-memory hypervisor-reserved table called the partition table, which contains pointers to relevant memory management structures of the hypervisor and every LPAR running on the system. Each entry of this table points to one of two different types of structures automatically used by the MMU to translate virtual addresses of the LPAR (or the hypervisor): an inverted page table (along with an optional segment table used instead of the segment registers) or the root of the radix tree of the kernel (with a related process table containing roots of process radix trees).
The inverted page resolution mode works in the same way as for PowerPC (without BAT registers) with, in addition, the support for 64-bit VASs and multiple page sizes. In this mode, all LPARs share the hash table with the hypervisor calling it to fill the hash table and the segment registers (the optional segment table is filled directly by the OS).
In radix tree mode, the translation of a virtual address to a physical one goes through a double translation: a radix tree, allocated by the guest OS, translates the virtual address to a pseudo-physical address. Then, a radix tree associated with the LPAR and maintained by the hypervisor translates the pseudo-physical address to a real physical one. Radix trees have a predefined number of levels, page sizes, and table entry format that permits to distinguish between directory and page tables.

A.2 Analysis

On a Power ISA machine, we can perform a physical memory dump in two different ways: a dump of the entire machine memory or a dump of a single LPAR. In the first case, we can recover the value contained in the PTCR register using code analysis or parsing for the partition table using rules derived from the ISA. If an LPAR or the hypervisor uses the radix tree MMU or the hash table with the segment table, it is possible to recover the entire V2P address mapping starting from the partition table. Instead, if they use the hash table MMU mode with the segment registers set, we can only reconstruct the segmented to physical translation, in the same ways as we described for PowerPC.
Finally, if we work with an LPAR memory dump, we can recover the structure of the guest radix trees, but if the LPAR uses the hash table mode, we cannot recover any information about the V2P address translation because the hash table resides in the hypervisor memory.

A.3 Limitations

We decided to not include Power ISA in Section 3 for four reasons. First of all, this architecture is strongly oriented to virtualization and the MMU operating modes are structured with this perspective, opening the problem of the privilege level to whom the memory dump is taken, which influences, in turn, the features recoverability. Second, QEMU does not support the emulation of a complete Power machine running an LPAR—making it impossible to test the reconstruction techniques in the case of a hypervisor memory dump. Third, Miasm does not support Power ISA, making it impossible to perform the code analysis phase. Last but not least, the only OS we could find that runs in hypervisor mode is Linux, and this lack of test cases would not allow to have any statistical significance on the obtained results.

B Structure Signatures and Validation Rules

Table 7.
AArch64 (64-bit) Long MMU Mode
ObjectTypeRule
PTL0/PTL1/PTL2/PTL3 entrySize(Entry) = 8 bytes
Empty PTL0/PTL1/PTL2/PTL3 entryEntry[0] = 0
PTL3 reserved entry 4/16/64-Kib granuleEntry[0] = 1 \(\wedge\) Entry[1] = 0
PTL3 entry 4/64-KiB granuleEntry[0,1] = 1 \(\wedge\) Entry[SH] \(\ne\) 1
PTL3 entry 16-KiB granuleEntry[0,1] = 1 \(\wedge\) Entry[SH] \(\ne\) 1 \(\wedge\) Entry[12,13] = 0
Block PTL2 entry 4-KiB granuleEntry[0] = 1 \(\wedge\) Entry[1] = 1 \(\wedge\) Entry[12 \(\ldots\) 15] = 0 \(\wedge\) Entry[SH] \(\ne\) 1 \(\wedge\) Entry[17 \(\ldots\) 20] = 0
Block PTL2 entry 16-KiB granuleEntry[0] = 1 \(\wedge\) Entry[1] = 1 \(\wedge\) Entry[12 \(\ldots\) 15] = 0 \(\wedge\) Entry[SH] \(\ne\) 1 \(\wedge\) Entry[17 \(\ldots\) 24] = 0
Block PTL2 entry 64-KiB granuleEntry[0] = 1 \(\wedge\) Entry[1] = 1 \(\wedge\) Entry[12 \(\ldots\) 15] = 0 \(\wedge\) Entry[SH] \(\ne\) 1 \(\wedge\) Entry[17 \(\ldots\) 28] = 0
Block PTL1 entry 4-KiB granuleEntry[0] = 1 \(\wedge\) Entry[1] = 1 \(\wedge\) Entry[12 \(\ldots\) 15] = 0 \(\wedge\) Entry[SH] \(\ne\) 1 \(\wedge\) Entry[17 \(\ldots\) 29] = 0
PTL0/PTL1/PTL2 pointer 4-KiB granuleEntry[0,1] = 1 \(\wedge\) Entry[Address] \(\in\) RAM
PTL0/PTL1/PTL2 pointer 16-KiB granuleEntry[0,1] = 1 \(\wedge\) Entry[12,13] = 0 \(\wedge\) Entry[Address] \(\in\) RAM
PTL0/PTL1/PTL2 pointer 64-KiB granuleEntry[0,1] = 1 \(\wedge\) Entry[12 \(\ldots\) 15] = 0 \(\wedge\) Entry[Address] \(\in\) RAM
Kernel radix tree \(\exists\) DataPage \(|\) ReadOpcode(ESR_EL1, FAR_EL1, ELR_EL1) \(\in\) DataPage \(\wedge\) \(\exists\) DataPage \(|\) WriteOpcode(TTBR0_EL1, TCR_EL1) \(\in\) DataPage \(\wedge\) \(\exists\) DataPage \(|\) ExecOpcode(ERET) \(\in\) DataPage
Kernel radix tree \({^{{1}}}\) \(\exists\) Entry \(\in\) {Tables of RadixT} \(|\) Entry[AP[0,1]] = 0 \(\Rightarrow\) RadixT \(\in\) {Accepted Kernel radix trees}
User radix tree \(\exists\) DataPage \(|\) ExecOpcode(RET) \(\in\) DataPage \(\wedge\) \(\exists\) DataPage \(|\) ExecOpcode(BLR) \(\in\) DataPage
User radix tree \({^{{2}}}\) \(\exists\) Entry \(\in\) {Tables of RadixT} \(|\) Entry[AP[1]] = 1 \(\Rightarrow\) RadixT \(\in\) {Accepted User radix trees}
PTL0/PTL1/PTL2/PTL3Address(Table) alignment and Size(Table) compatible with TCR_EL1 fields. See documentation by ARM Holdings [40] for more details.
TCR_EL1TCR_EL1[6, 35, 59 \(\dots\) 63] = 0
Table 7. Structure Signatures (○) and Validation Rules (●) for Each MMU Mode Implemented in MMUShell
Size(X) = The size of the object X.
Object[W,X,Y \(\ldots\) Z] = Bit W,X and all the bits in [Y,Z] of Object.
Object[NAME] = Field ‘NAME’ of Object. See documentation for the exact location of the field in the object.
RAM = Physical address used to access to a system memory location (no MMIO, ROMs, device memory etc.).
ReadOpcode(X,Y), WriteOpcode(X,Y) = Physical address of an opcode that reads/writes on register X or Y.
ExecOpcode(X) = Physical address of X opcode.
Address(X) = Physical address of the object X.
REGISTER[W,X,Y \(\ldots\) Z] = Bits of the value contained in REGISTER.
\(^1\) i.e., It exists at least a page writable in kernel mode and not writable in user mode.
\(^2\) i.e., It exists at least a page readable or writable in user mode.
Note: See ISA’s documentation [34, 39, 40, 42, 65] for more details.
AMD64 (64-bit) Four-Level MMU Mode
ObjectTypeRule
IDT entrySize(IDTEntry) = 16 bytes
IDT entryAddress(IDT) % 4 = 0
Empty IDT entryIDTEntry[P] = 0
Used IDT entryIDTEntry[P] = 1 \(\wedge\) IDTEntry[35 \(\ldots\) 39,44,95:127] = 0 \(\wedge\) IDTEntry[TYPE] \(\in\) {14,15} \(\wedge\) IDTEntry[DPL] \(\in\) {0,3}
IDT tableAddress(IDT) % 8 = 0 \(\wedge\) Size(IDT) = 4,096 bytes
IDT table \(\forall\) i \(\in\) {0 \(\ldots 8,10\ldots 14,16\ldots\) 19} IDT[i][P] = 1 \(\wedge\) IDT[i][47 \(\ldots\) 64] = 1
IDT table \({^{{1}}}\) IDT[3][DPL] = 3 \(\wedge\) IDT[0,2,6,7,8,10 \(\ldots\) 14][DPL] = 0
PT/PD/PDPT/PML4 entrySize(Entry) = 8 bytes
Empty PT/PD/PDPT/PML4 entryEntry[P] = 0
PT entryEntry[P] = 1 \(\wedge\) Entry[MAXPHYADDR:51] = 0
PD 2-MiB entryEntry[P] = 1 \(\wedge\) Entry[MAXPHYADDR:51] = 0 \(\wedge\) Entry[7] = 1
PDPT 1-GiB entryEntry[P] = 1 \(\wedge\) Entry[MAXPHYADDR:51] = 0 \(\wedge\) Entry[7] = 1 \(\wedge\) Entry[21:29] = 0
PT/PD/PDPT pointerEntry[P] = 1 \(\wedge\) Entry[MAXPHYADDR:51] = 0 \(\wedge\) Entry[7] = 0 \(\wedge\) Entry[Address] \(\ll\) 12 \(\in\) RAM
PD/PT/PDPT/PML4Address(Table) % 4,096 = 0 \(\wedge\) Size(Table) = 4,096 bytes
Radix tree \(\forall\) InterruptHandler \(\in\) {Found IDT} Resolve(RadixTree, InterruptHandler[Address]) = True
IDT[X][Y] = Field Y of the record X in the interrupt table.
MAXPHYADDR = See documentation from Intel [42] for more details.
Resolve(R,V) = Resolve virtual address V using radix tree R returning True for success and False otherwise.
\(^1\) The DPL field of IDT entries defines the minimum CPU privilege mode (0 for kernel mode, 3 for user mode) that is allowed to execute the code pointed by the entry. We force the DPL field of some entries to be 0 because the entries are associated with interrupts that can be managed only by the kernel (NMI, invalid opcode, double fault, etc.). Instead, we force the code pointed by the entry associated with breakpoint exception to have DPL \(=\) 3 because, in general, a user space process is allowed to debug other user space processes.
ARM (32-bit) Short MMU Mode
ObjectTypeRule
PTL1/PTL2 entrySize(Entry) = 4 bytes
Empty PTL1/PTL2 entryEntry[0,1] = 0
Small PTL2 page entryEntry[1] = 1 \(\wedge\) (Entry[TEX] \(\ne\) 1 \(\vee\) Entry[B] = 1 \(\vee\) Entry[C] = 0)
Large PTL2 page entryEntry[0] = 1 \(\wedge\) Entry[1] = 0 \(\wedge\) Entry[6 \(\ldots\) 8] = 0 \(\wedge\) (Entry[TEX] \(\ne\) 1 \(\vee\) Entry[B] = 1 \(\vee\) Entry[C] = 0)
Large PTL2 page entries groupif \(\exists\) LPEntry in Table \(\Rightarrow\) \(\exists\) LPEntryj \(|\) Address(LPEntryj+1) = Address(LPEntryj+ 4) \(\wedge\) Address(LPEntry0) % 16 = 0) j \(\in\) {0 \(\ldots\) 15}
Section PTL1 entryEntry[1] = 1 \(\wedge\) Entry[9,18] = 0 \(\wedge\) (Entry[TEX] \(\ne\) 1 \(\vee\) Entry[B] = 1 \(\vee\) Entry[C] = 0)
Supersection PTL1 entryEntry[1,18] = 1 \(\wedge\) Entry[9] = 0 \(\wedge\) (Entry[TEX] \(\ne\) 1 \(\vee\) Entry[B] = 1 \(\vee\) Entry[C] = 0)
Supersection PTL1 entries groupif \(\exists\) SSEntry in Table \(\Rightarrow\) \(\exists\) SSEntryj \(|\) Address(SSEntryj+1) = Address(SSEntryj+ 4) \(\wedge\) Address(SSEntry0) % 16 = 0) j \(\in\) {0 \(\ldots\) 15}
PTL2 pointer entryEntry[0] = 1 \(\wedge\) Entry[1] = 0 \(\wedge\) Entry[9] = 0
PTL1 tableAddress(Table) alignment and Size(Table) compatible with TTBCR fields. See documentation by Intel [42] for more details.
PTL2 tableAddress(Table) % 1,024 = 0 \(\wedge\) Size(Table) = 1,024 bytes
Kernel radix tree \(\exists\) DataPage \(|\) ReadOpcodes(DFSR, IFSR) \(\in\) DataPage \(\wedge\) \(\exists\) DataPage \(|\) WriteOpcodes(TTBR0, TTBCR) \(\in\) DataPage
Kernel radix tree \({^{{1}}}\) \(\exists\) Entry \(\in\) {Tables of RadixT} \(|\) Entry[PNX] = 0 \(\Rightarrow\) RadixT \(\in\) {Accepted Kernel radix trees}
User radix tree \({^{{1}}}\) \(\exists\) Entry \(\in\) {Tables of RadixT} \(|\) Entry[NX] = 0 \(\Rightarrow\) RadixT \(\in\) {Accepted User radix trees}
User radix tree \({^{{2}}}\) \(\exists\) Entry \(\in\) {Tables of RadixT} \(|\) Entry[AP[1]] = 1 \(\Rightarrow\) RadixT \(\in\) {Accepted User radix trees}
TTBCRTTBCR[3] = 1 \(\wedge\) TTBCR[6, 31] = 0
\(^1\) It exist at least a table entry executable (i.e., it exist at least a page that contains code).
\(^2\) It exist at least a table entry writable (i.e., it exist at least a page that contains data).
MIPS32 (32-bit) TLB and Radix Tree MMU Modes
ObjectTypeRule
ConfigConfig[4 \(\ldots\) 6] = 0 \(\wedge\) Config[31] = 1
Config5Config5[1,12,14 \(\ldots\) 26] = 0
PageGrainPageGrain[5 \(\ldots 7,13\ldots\) 25] = 0
PageMaskPageMask[0 \(\ldots 10,29\ldots\) 31] = 0
PWCtlPWCtl[8 \(\ldots\) 30] = 0
PWFieldPWField[30 \(\ldots\) 31] = 0 \(\wedge\) (if Config[10 \(\ldots\) 12] \(\ge\) 2 \(\Rightarrow\) \(\forall\) i \(\in\) {GDI, UDI, MDI, PTI}PWField[i] < 12)
PWSizePWSize[30 \(\ldots\) 31] = 0 \(\wedge\) (if Config[10 \(\ldots\) 12] \(\ge\) 2 \(\Rightarrow\) PWSize[PTW] \(\ne\) 1)
WiredWired[0 \(\ldots\) 15] < Wired[16 \(\ldots\) 31]
PowerPC (32-bit) SDR1+BAT MMU Mode
ObjectTypeRule
Hash table entrySize(Entry) = 8 bytes
Empty hash table entryEntry[V] = 0
Used hash table entryEntry[V] = 1 \(\wedge\) Entry[RPN] \(\ll\) 12 \(\in\) RAM \(\wedge\) (Entry[R] = 1 \(\vee\) Entry[C] = 0)
Hash table entries groupHT[i][j] \(\ne\) HT[i][k] i \(\in\) {0 \(\ldots\) Size(HT)/64 - 1} j,k \(\in\) {0 \(\ldots\) 7} \(\wedge\) j \(\ne\) k
Hash tableAddress(HT) % 16 = 0 \(\wedge\) Size(HT) \(\in\) {64Kib 128Kib 256KiB 512KiB 1MiB 2MiB 4Mib 8MiB 16MiB 32MiB}
Hash table \(\forall\) Entry \(\in\) HT \(|\) Entry[V] = 1 \(\Rightarrow\) Address(Entry)[16 \(\ldots\) 31] = Address(HT)[25 \(\ldots\) 31] \(\mathbin \Vert\) Hash(Entry[VSID][10 \(\ldots\) 18] \(\oplus\) Entry[API]) \(\wedge\) (1 \(\ll\) (Log(Size(HT) - 16) -1) \(\vee\) (Address(HT) \(\gg\) 16)[0 \(\ldots\) 8]
Hash table \({^{{1}}}\) \(\exists\) Entry \(\in\) HT \(|\) Entry[V] = 1
Hash table \({^{{2}}}\) \(\exists\) Entry1 and Entry2 \(\in\) HT \(|\) Entry1[V] = Entry2[V] = 1 \(\wedge\) Entry1[VSID] \(\ne\) Entry2[VSID]
Hash table \({^{{3}}}\) \(\exists\) Entry1 and Entry2 \(\in\) HT Entry1[V] = Entry2[V] = 1 \(\wedge\) Entry1[RPN] \(\ne\) Entry2[RPN]
Parsed hash tables \({^{{4}}}\) \(\forall\) j \(\in\) {Parsed HTs} \(| H_{j} = H(\text{HT}_{j}) = -\sum P(\text{RPN}_{i}) \log _2 P(\text{RPN}_{i})\) ; \(H_{\text{max}}\) = Max( \(H_j\) ); if \(H_j \gt 0.8 H_{\text{max}}\) \(\Rightarrow\) j \(\in\) {Accepted HTs}
HT[X][Y] = Field Y of the record X in the hash table.
\(^1\) It exists at least one not empty entry in the table.
\(^2\) It exists entries associated with at least two different segments.
\(^3\) The hash table maps for at least two different physical pages.
\(^4\) The kernel, spreading data among a wide range of physical pages in RAM, increases the entropy of the distribution of the physical addresses of the pages in the real hash table. We filter the set of hash table candidates, discarding tables that have entropy less than 80% of the maximum entropy in the set.
RISC-V SV32 and SV48 MMU Modes
ObjectTypeRule
PTL0/PTL1 entry (SV32)Size(Entry) = 4 bytes
PTL0/PTL1/PTL2 entry (SV48)Size(Entry) = 8 bytes
Empty PTL0/PTL1(/PTL2) entryEntry[V] = 0
PTL0 entry (SV32)Entry[V] = 1
PTL0 entry (SV39)Entry[V] = 1 \(\wedge\) Entry[54,63] = 0
PTL1 4-MiB entry (SV32)Entry[V] = 1 \(\wedge\) Entry[10:19] = 0
PTL1 2-MiB entry (SV39)Entry[V] = 1 \(\wedge\) Entry[54,63] = 0 \(\wedge\) Entry[10:18] = 0
PTL2 1-GiB entry (SV39)Entry[V] = 1 \(\wedge\) Entry[54,63] = 0 \(\wedge\) Entry[10:28] = 0
PTL0 pointer (SV32)Entry[V] = 1 \(\wedge\) Entry[R,W,X,D,A,U] = 0 \(\wedge\) Entry[Address] \(\ll\) 12 \(\in\) RAM
PTL0/PTL1 pointer (SV39)Entry[V] = 1 \(\wedge\) Entry[R,W,X,D,A,U] = 0 \(\wedge\) Entry[54,63] = 0 \(\wedge\) Entry[Address] \(\ll\) 12 \(\in\) RAM
PTL0/PTL1(/PTL2)Address(Table) % 4,096 = 0 \(\wedge\) Size(Table) = 4,096 bytes
Intel x86 IA32 and PAE MMU Modes
ObjectTypeRule
IDT entrySize(IDTEntry) = 8 bytes
Empty IDT entryIDTEntry[P] = 0
Used IDT entryIDTEntry[P] = 1 \(\wedge\) IDTEntry[32:39,44] = 0 \(\wedge\) IDTEntry[42] = 1 \(\wedge\) IDTEntry[DPL] \(\in\) {0,3}
IDTAddress(IDT) % 4 = 0 \(\wedge\) Size(IDT) = 2,048 bytes
IDTIDT[0 \(\ldots 8,10\ldots\) 14][P] = 1
IDT \({^{{1}}}\) IDT[0,2,6 \(\ldots 8,10\ldots\) 14][DPL] = 0 \(\wedge\) IDT[3][DPL] = 3
PT/PD entry (IA32)Size(Entry) = 4 bytes
PT/PD/PDPT entry (PAE)Size(Entry) = 8 bytes
Empty PT/PD(/PDPT) entryEntry[P] = 0
PT entry (IA32)Entry[P] = 1
PT entry (PAE)Entry[P] = 1 \(\wedge\) Entry[MAXPHYADDR:62] = 0 \(\wedge\) Entry[7] = 0
PD 4-MiB entry (IA32)Entry[P] = 1 \(\wedge\) Entry[7] = 1 \(\wedge\) Entry[MAXPHYADDR \(\ldots\) 19, 21] = 0
PD 2-MiB entry (PAE)Entry[P] = 1 \(\wedge\) Entry[MAXPHYADDR:62] = 0 \(\wedge\) Entry[7] = 1 \(\wedge\) Entry[13:20] = 0
PT pointer (IA32)Entry[P] = 1 \(\wedge\) Entry[7] = 0 \(\wedge\) Entry[Address] \(\ll\) 12 \(\in\) RAM
PT pointer (PAE)Entry[P] = 1 \(\wedge\) Entry[MAXPHYADDR:62] = 0 \(\wedge\) Entry[7] = 0 \(\wedge\) newline Entry[Address] \(\ll\) 12 \(\in\) RAM
PD pointer (PAE)Entry[P] = 1 \(\wedge\) Entry[MAXPHYADDR:62] = 0 \(\wedge\) Entry[7] = 0 \(\wedge\) newline Entry[1,2,5,6,8,63] = 0 \(\wedge\) Entry[Address] \(\ll\) 12 \(\in\) RAM
PD/PTAddress(Table) % 4,096 = 0 \(\wedge\) Size(Table) = 4,096 bytes
PDPT (PAE)Address(Table) % 32 = 0 \(\wedge\) Size(Table) = 32 bytes
Radix tree \(\forall\) InterruptHandler \(\in\) {Found IDT} Resolve(RadixTree, Address(InterruptHandler))
\(^1\) See note 1 of AMD64 architecture.

References

[1]
Ali Reza Arasteh and Mourad Debbabi. 2007. Forensic memory analysis: From stack and code to execution history. Digital Investigation 4 (2007), 114–125.
[3]
Buildroot Association. 2022. Home Page. Retrieved April 2, 2022 from https://buildroot.org/.
[4]
Apple Inc. 2022. Darwin OS. Retrieved April 2, 2022 from https://github.com/apple/darwin-xnu.
[5]
[6]
Genode Labs. 2022. Home Page. Retrieved April 2, 2022 from https://genode.org/.
[7]
Haiku Inc. 2022. Home Page. Retrieved April 2, 2022 from https://www.haiku-os.org/.
[8]
HelenOS Community. 2022. Home Page. Retrieved April 2, 2022 from http://www.helenos.org/.
[9]
VU University. 2022. MINIX3 OS. Retrieved April 2, 2022 from https://www.minix3.org/.
[10]
MorphOS Development Team. 2022. Home Page. Retrieved April 2, 2022 from https://www.morphos-team.net/.
[11]
BlackBerry Ltd. 2022. Blackberry QNX. Retrieved April 2, 2022 from https://www.qnx.com.
[12]
RaspberryPI Foundation. 2022. Home Page. Retrieved April 2, 2022 from https://www.raspberrypi.org/.
[13]
rCore Developers. 2022. rCore. Retrieved April 2, 2022 from https://github.com/rcore-os/rCore.
[14]
ReactOS Team and Contributors. 2022. Home Page. Retrieved April 2, 2022 from https://reactos.org/.
[15]
Redox Developers. 2022. Home Page. Retrieved April 2, 2022 from https://www.redox-os.org/.
[16]
RISC OS Open Ltd. 2022. Home Page. Retrieved April 2, 2022 from https://www.riscosopen.org.
[17]
ETH Zurich. 2022. The Barrelfish Operating System. Retrieved April 2, 2022 from http://www.barrelfish.org/.
[18]
Trend Micro. 2022. TLSH—Trend Micro Locality Sensitive Hash. Retrieved April 2, 2022 from https://github.com/trendmicro/tlsh.
[19]
Wind River Systems. 2022. VxWorks. Retrieved April 2, 2022 from https://www.windriver.com/products/vxworks/.
[20]
Massachusetts Institute of Technology. 2022. XV6. Retrieved April 2, 2022 from https://github.com/mit-pdos/xv6-riscv.
[21]
Jeffrey Burt. 2020. Alibaba on the bleeding edge of RISC-V with XT910. The Next Platform. Retrieved April 2, 2022 from https://www.nextplatform.com/2020/08/21/alibaba-on-the-bleeding-edge-of-risc-v-with-xt910/.
[22]
Andrew Case, Ryan D. Maggio, Modhuparna Manna, and Golden G. Richard III. 2020. Memory analysis of macOS page queues. Forensic Science International: Digital Investigation 33 (2020), 301004.
[23]
Michael Cohen. 2014. Rekall Memory Forensic Framework. Retrieved April 2, 2022 from http://www.rekall-forensic.com/.
[24]
9Front Community. 2022. 9Front OS. Retrieved April 2, 2022 from http://9front.org/.
[25]
Emanuele Cozzi, Mariano Graziano, Yanick Fratantonio, and Davide Balzarotti. 2018. Understanding Linux malware. In Proceedings of the 2018 IEEE Symposium on Security and Privacy (SP’18). IEEE, Los Alamitos, CA, 161–175.
[26]
Anthony Cozzie, Frank Stratton, Hui Xue, and Samuel T. King. 2008. Digging for data structures. In Proceedings of the 8th USENIX Conference on Operating Systems Design and Implementation (OSDI’08). 255–266.
[27]
Brendan Dolan-Gavitt, Tim Leek, Michael Zhivich, Jonathon Giffin, and Wenke Lee. 2011. Virtuoso: Narrowing the semantic gap in virtual machine introspection. In Proceedings of the 2011 IEEE Symposium on Security and Privacy (SP’11). IEEE, Los Alamitos, CA, 297–312.
[28]
Brendan Dolan-Gavitt, Abhinav Srivastava, Patrick Traynor, and Jonathon Giffin. 2009. Robust signatures for kernel data structures. In Proceedings of the 16th ACM Conference on Computer and Communications Security (CCS’09). ACM, New York, NY, 566–577.
[29]
OmniOS Community Edition. 2022. Home Page. Retrieved April 2, 2022 from https://omniosce.org/.
[30]
QEMU.2022. Home Page. Retrieved April 2, 2022 from https://www.qemu.org/.
[31]
Fabrice Desclaux.2022. Miasm. Retrieved April 2, 2022 from https://github.com/cea-sec/miasm.
[32]
Radare2 Community.2022. Home Page. Retrieved April 2, 2022 from https://rada.re/n/.
[33]
Qian Feng, Aravind Prakash, Heng Yin, and Zhiqiang Lin. 2014. Mace: High-coverage and robust memory analysis for commodity operating systems. In Proceedings of the 30th Annual Computer Security Applications Conference. ACM, New York, NY, 196–205.
[34]
FreeScale. 2005. Programming Environments Manual for 32-Bit Implementations of the PowerPC Architecture. FreeScale.
[35]
Yangchun Fu and Zhiqiang Lin. 2012. Space traveling across VM: Automatically bridging the semantic gap in virtual machine introspection via online kernel data redirection. In Proceedings of the IEEE Symposium on Security and Privacy (SP’12). IEEE, Los Alamitos, CA, 586–600.
[36]
Mariano Graziano, Andrea Lanzi, and Davide Balzarotti. 2013. Hypervisor memory forensics. In Research in Attacks, Intrusions, and Defenses, Salvatore J. Stolfo, Angelos Stavrou, and Charles V. Wright (Eds.). Springer, Berlin, Germany, 21–40.
[37]
Yufei Gu, Yangchun Fu, Aravind Prakash, Zhiqiang Lin, and Heng Yin. 2014. Multi-aspect, robust, and memory exclusive guest OS fingerprinting. IEEE Transactions on Cloud Computing 2, 4 (2014), 380–394.
[38]
Craig Heffner. 2022. ReFirmLabs/Binwalk. Retrieved April 2, 2022 from https://github.com/ReFirmLabs/binwalk.
[39]
ARM Holdings. 2018. ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition. ARM Holdings.
[40]
ARM Holdings. 2020. ARM Architecture Reference Manual, ARMv8, for ARMv8-A Architecture Profile. ARM Holdings.
[41]
IBM. 2017. Power ISA. Version 3.0B. IBM.
[42]
Intel. 2020. Intel 64 and IA-32 Architectures—Software Developer’s Manual—Volume 3 (3A, 3B, 3C & 3D): System Programming Guide. Intel Corporation.
[43]
Jesse D. Kornblum. 2007. Using every part of the buffalo in windows memory analysis. Digital Investigation 4, 1 (2007), 24–29.
[44]
Kevin Krewell. 2017. Western Digital gives a billion unit boost to open source RISC-V CPU. Forbes. Retrieved April 2, 2022 from https://www.forbes.com/sites/tiriasresearch/2017/12/06/western-digital-gives-a-billion-unit-boost-to-open-source-risc-v-cpu/.
[45]
Jamie Levy. 2015. Using PROT_NONE on Linux. Volatility Labs. Retrieved April 2, 2022 from https://volatility-labs.blogspot.com/2015/05/using-mprotect-protnone-on-linux.html.
[46]
Zhiqiang Lin, Junghwan Rhee, Chao Wu, Xiangyu Zhang, and Dongyan Xu. 2012. Discovering semantic data of interest from un-mappable with confidence. In Proceedings of the 19th Network and Distributed System Security Symposium (NDSS’12).
[47]
Zhiqiang Lin, Junghwan Rhee, Xiangyu Zhang, Dongyan Xu, and Xuxian Jiang. 2011. SigGraph: Brute force scanning of kernel data structure instances using graph-based signatures. In Proceedings of the Network and Distributed System Security Symposium (NDSS’11). https://www.ndss-symposium.org/ndss2011/siggraph-brute-force-scanning-of-kernel-data-structure-instances-using-graph-based-signatures.
[48]
Zhiqiang Lin, Xiangyu Zhang, and Dongyan Xu. 2010. Automatic reverse engineering of data structures from binary execution. In Proceedings of the 11th Annual Information Security Symposium. 1–18.
[49]
Daniel Mercier, Aziem Chawdhary, and Richard Jones. 2017. dynStruct: An automatic reverse engineering tool for structure recovery and memory use analysis. In Proceedings of the 2017 IEEE 24th International Conference on Software Analysis, Evolution, and Reengineering (SANER’17). IEEE, Los Alamitos, CA, 497–501.
[50]
MIPS. 2015. MIPS Architecture for Programmers Vol. III: MIPS32/microMIPS32 Privileged Resource Architecture. Imagination Technologies.
[51]
Andrea Oliveri. 2022. Eurecom-s3/MMUShell. Retrieved April 2, 2022 from https://github.com/eurecom-s3/mmushell.
[52]
Fabio Pagani, Matteo Dell’Amico, and Davide Balzarotti. 2018. Beyond precision and recall: Understanding uses (and misuses) of similarity hashes in binary analysis. In Proceedings of the 8th ACM Conference on Data and Application Security and Privacy (CODASPY’18). ACM, New York, NY, 354–365.
[53]
Fabio Pagani, Oleksii Fedorov, and Davide Balzarotti. 2019. Introducing the temporal dimension to memory forensics. ACM Transactions on Privacy and Security 22, 2 (2019), 1–21.
[54]
Golden G. Richard III and Andrew Case. 2014. In lieu of swap: Analyzing compressed RAM in Mac OS X and Linux. Digital Investigation 11 (2014), S3–S12.
[55]
O. Sardar and D. Andonov. 2019. White Paper: Finding Evil in Windows 10 Compressed Memory. Technical Report. FireEye. https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/finding-evil-in-windows-10-compressed-mem-ory-wp.pdf.
[56]
Karla Saur and Julian B. Grizzard. 2010. Locating x86 paging structures in memory images. Digital Investigation 7, 1–2 (Oct. 2010), 28–37.
[57]
Asia Slowinska, Traian Stancescu, and Herbert Bos. 2010. DDE: Dynamic data structure excavation. In Proceedings of the 1st ACM Asia-Pacific Workshop on Systems. 13–18.
[58]
Asia Slowinska, Traian Stancescu, and Herbert Bos. 2011. Howard: A dynamic excavator for reverse engineering data structures. In Proceedings of the Network and Distributed System Security Symposium (NDSS’11).
[59]
Wei Song, Heng Yin, Chang Liu, and Dawn Song. 2018. DeepMem: Learning graph neural network models for fast and robust memory forensic analysis. In Proceedings of the 2018 ACM SIGSAC Conference on Computer and Communications Security (CCS’18). ACM, New York, NY, 606–618.
[60]
Katerina Troshina, Yegor Derevenets, and Alexander Chernov. 2010. Reconstruction of composite types for decompilation. In Proceedings of the 2010 10th IEEE Working Conference on Source Code Analysis and Manipulation. IEEE, Los Alamitos, CA, 179–188.
[61]
David Urbina, Yufei Gu, Juan Caballero, and Zhiqiang Lin. 2014. SigPath: A memory graph based approach for program data introspection and modification. In Proceedings of the European Symposium on Research in Computer Security. 237–256.
[62]
Sebastian Vogl and Blaine Stancill. 2019. Rekall support for Windows 10 memory compression. FireEye. Retrieved April 2, 2022 from https://github.com/mandiant/win10_rekall/blob/win10_compressed_memory/rekall-core/rekall/plugins/windows/win10_memcompression.py.
[63]
Volexity. 2022. Home Page. Retrieved April 2, 2022 from https://www.volexity.com/.
[64]
Aaron Walker. 2017. Volatility framework: Volatile memory artifact extraction utility framework. https://www.volatilityfoundation.org/.
[65]
Asanovic K. Waterman A. (Ed.). 2019. The RISC-V Instruction Set Manual, Volume II: Privileged Architecture, Document Version 20190608-Priv-MSU-Ratified. RISC-V Foundation.
[66]
William G. Wong. 2020. Ada and RISC-V secure Nvidia’s future. Endeavour Business Media. https://www.electronicdesign.com/markets/automotive/article/21121197/ada-and-riscv-secure-nvidias-future.
[67]
Haiquan Xiong, Zhiyong Liu, Weizhi Xu, and Shuai Jiao. 2012. Libvmi: A library for bridging the semantic gap between guest OS and VMM. In Proceedings of the 2012 IEEE 12th International Conference on Computer and Information Technology (CIT’12). IEEE, Los Alamitos, CA, 549–556.

Cited By

View all
  • (2024)Enhancing Reliability During Physical Memory Forensics: Strategies and PracticesSN Computer Science10.1007/s42979-023-02553-y5:1Online publication date: 8-Jan-2024
  • (2023)Design and Implementation of Memory Management Unit for LoongArch ArchitectureProceedings of the 2023 7th International Conference on Electronic Information Technology and Computer Engineering10.1145/3650400.3650643(1447-1452)Online publication date: 20-Oct-2023

Index Terms

  1. In the Land of MMUs: Multiarchitecture OS-Agnostic Virtual Memory Forensics

      Recommendations

      Comments

      Information & Contributors

      Information

      Published In

      cover image ACM Transactions on Privacy and Security
      ACM Transactions on Privacy and Security  Volume 25, Issue 4
      November 2022
      330 pages
      ISSN:2471-2566
      EISSN:2471-2574
      DOI:10.1145/3544004
      Issue’s Table of Contents

      Publisher

      Association for Computing Machinery

      New York, NY, United States

      Publication History

      Published: 09 July 2022
      Online AM: 30 March 2022
      Accepted: 01 March 2022
      Revised: 01 January 2022
      Received: 01 August 2021
      Published in TOPS Volume 25, Issue 4

      Permissions

      Request permissions for this article.

      Check for updates

      Author Tags

      1. Memory forensics
      2. OS-agnostic forensics
      3. virtual memory
      4. MMU

      Qualifiers

      • Research-article
      • Refereed

      Funding Sources

      • European Research Council (ERC)
      • European Unions Horizon 2020

      Contributors

      Other Metrics

      Bibliometrics & Citations

      Bibliometrics

      Article Metrics

      • Downloads (Last 12 months)113
      • Downloads (Last 6 weeks)4
      Reflects downloads up to 30 Aug 2024

      Other Metrics

      Citations

      Cited By

      View all
      • (2024)Enhancing Reliability During Physical Memory Forensics: Strategies and PracticesSN Computer Science10.1007/s42979-023-02553-y5:1Online publication date: 8-Jan-2024
      • (2023)Design and Implementation of Memory Management Unit for LoongArch ArchitectureProceedings of the 2023 7th International Conference on Electronic Information Technology and Computer Engineering10.1145/3650400.3650643(1447-1452)Online publication date: 20-Oct-2023

      View Options

      Get Access

      Login options

      Full Access

      View options

      PDF

      View or Download as a PDF file.

      PDF

      eReader

      View online with eReader.

      eReader

      Full Text

      View this article in Full Text.

      Full Text

      HTML Format

      View this article in HTML Format.

      HTML Format

      Media

      Figures

      Other

      Tables

      Share

      Share

      Share this Publication link

      Share on social media