Mechanism: Address Translation
- efficiency: hardware support
- control: security + hardware support
- flexibility: programmer ease
Assumptions
- address space must be placed contiguously
- address space is smaller than physical memory
- all address spaces are same size
TIP
Interposition is powerful, and helps you add transparency (invisibility) to your systems
An Example
┌ 22: int main (int argc, char **argv, char **envp);
│ afv: vars(1:sp[0xc..0xc])
│ 0x00001119 55 push rbp
│ 0x0000111a 4889e5 mov rbp, rsp
│ 0x0000111d c745fcb80b.. mov dword [var_4h], 0xbb8 ; 3000
│ 0x00001124 8345fc03 add dword [var_4h], 3
│ 0x00001128 b800000000 mov eax, 0
│ 0x0000112d 5d pop rbp
└ 0x0000112e c3 ret
0x0000000000001119 <+00>: push rbp
0x000000000000111a <+01>: mov rbp,rsp
0x000000000000111d <+04>: mov DWORD PTR [rbp-0x4],0xbb8
0x0000000000001124 <+11>: add DWORD PTR [rbp-0x4],0x3
0x0000000000001128 <+15>: mov eax,0x0
0x000000000000112d <+20>: pop rbp
0x000000000000112e <+21>: ret
obviously the process is not being stored exactly in 0x00000
like the debuggers say because that’s not possible and a waste of space, so we need some translations going on
$ pmap 3336
3336: ./test
000063a42ecb3000 4K r---- test # asm is stored here
000063a42ecb4000 4K r-x-- test
000063a42ecb5000 4K r---- test
000063a42ecb6000 4K r---- test
000063a42ecb7000 4K rw--- test
000063a437779000 132K rw--- [ anon ] # There's some heap memory here
00007d02eea97000 12K rw--- [ anon ]
00007d02eea9a000 144K r---- libc.so.6
00007d02eeabe000 1436K r-x-- libc.so.6 # ???
00007d02eec25000 340K r---- libc.so.6
00007d02eec7a000 16K r---- libc.so.6
00007d02eec7e000 8K rw--- libc.so.6
00007d02eec80000 40K rw--- [ anon ]
00007d02eecae000 8K r---- [ anon ]
00007d02eecb0000 8K r---- [ anon ]
00007d02eecb2000 8K r-x-- [ anon ]
00007d02eecb4000 4K r---- ld-linux-x86-64.so.2
00007d02eecb5000 164K r-x-- ld-linux-x86-64.so.2
00007d02eecde000 44K r---- ld-linux-x86-64.so.2
00007d02eece9000 8K r---- ld-linux-x86-64.so.2
00007d02eeceb000 4K rw--- ld-linux-x86-64.so.2
00007d02eecec000 4K rw--- [ anon ]
00007ffe99617000 132K rw--- [ stack ] # And here's the stack
ffffffffff600000 4K --x-- [ anon ]
total 2536K
Dynamic (Hardware-Based) Relocation
add two registers
base
: offset to start atbounds
/limits
register: max size of virtual space now when the process runs any virtual address is converted to physical asphysical address = virtual address + $base
and ensures it is within the bounds
This is a good example of interposition
Static Relocation
Initially before running a program, a loader would translate every address to the desired offset The issue with this is protection is breached. In general you need hardware support for true protection
Hardware Support
The setting of the base
and bounds
registers is a privileged operation, and must be done so only in kernel mode.
OS Issues
- gotta find space for every new process → free list
- clean up memory after process terminates
- base and bounds registers are to be added to the process struct
- note: the os could easily move the address space of an interrupted process
- create an illegal mem access trap handler