ASLR: Address Space Layout Randomization

From Writing Secure Code for Windows Vista book written by Michael Howard and David LeBlanc I learnt that Vista has the new ASLR feature:

  • Load address randomization (/dynamicbase linker option)
  • Stack address randomization (/dynamicbase linker option)
  • Heap randomization

The first randomization changes addresses across Vista reboots. The second randomization happens every time you launch an application linked with /dynamicbase option. The third randomization happens every time you launch an application linked with or without /dynamicbase option as we will see below.

The book shows some source code that prints addresses of various modules, functions and local parameters to show the feature. I decided to check that using more direct route by attaching WinDbg to calc, notepad and pre-Vista application TestDefaultDebugger. Obviously native Vista applications use ASLR.

Comparison between two calc.exe processes inspected separately before and after reboot shows that the main module and system dlls have different load addresses:

0:000> lm start end module name 009f0000 00a1e000 calc 74710000 748a4000 comctl32 75b10000 75bba000 msvcrt … … … 76f00000 76fbf000 ADVAPI32 770d0000 771a8000 kernel32 771b0000 7724e000 USER32 77250000 7736e000 ntdll

0:000> lm start end module name 00470000 0049e000 calc … … … 743e0000 74574000 comctl32 … 75730000 757da000 msvcrt 757e0000 7589f000 ADVAPI32 … 75e20000 75ebe000 USER32 … 76cf0000 76dc8000 kernel32 76dd0000 76eee000 ntdll …

Main module address has different 3rd byte across reboots. I don’t believe that 0×00 is allowed because then we would have 0×00000000 load address. Therefore we have 255 unique load addresses chosen randomly.

Stack addresses are different:

0:000> k
ChildEBP RetAddr
000ffc8c 771d199a ntdll!KiFastSystemCallRet
000ffc90 771d19cd USER32!NtUserGetMessage+0xc
000ffcac 009f24e8 USER32!GetMessageW+0×33
000ffd08 00a02588 calc!WinMain+0×278
000ffd98 77113833 calc!_initterm_e+0×1a1
000ffda4 7728a9bd kernel32!BaseThreadInitThunk+0xe
000ffde4 00000000 ntdll!_RtlUserThreadStart+0×23

0:000> k
ChildEBP RetAddr
0007fbe4 75e4199a ntdll!KiFastSystemCallRet
0007fbe8 75e419cd USER32!NtUserGetMessage+0xc
0007fc04 004724e8 USER32!GetMessageW+0×33
0007fc60 00482588 calc!WinMain+0×278
0007fcf0 76d33833 calc!_initterm_e+0×1a1
0007fcfc 76e0a9bd kernel32!BaseThreadInitThunk+0xe
0007fd3c 00000000 ntdll!_RtlUserThreadStart+0×23

Because module base addresses are different return addresses on call stacks are different too.

Heap base addresses are different:

0:000> !heap
Index Address
1: 00120000
2: 00010000
3: 00760000
4: 00990000
5: 00700000
6: 00670000
7: 01320000

0:000> !heap
Index Address
1: 001b0000
2: 00010000
3: 00a00000
4: 009c0000
5: 00400000
6: 00900000
7: 01260000

PEB and environment addresses are different:

notepad.exe (PID 1248):

0:000> !peb
PEB at 7ffd4000
...
Environment: 000507e8

notepad.exe (PID 1370):

0:000> !peb
PEB at 7ffd9000
...
Environment: 003a07e8

If we look inside TEB we would see that pointers to exception handler list are different and stack bases are different too:

notepad.exe (PID 1248):

TEB at 7ffdf000 ExceptionList: 0023ff34   StackBase: 00240000   StackLimit: 0022f000   SubSystemTib: 00000000   FiberData: 00001e00   ArbitraryUserPointer: 00000000   Self: 7ffdf000   EnvironmentPointer: 00000000   ClientId: 00001248 . 000004e0   RpcHandle: 00000000   Tls Storage: 7ffdf02c   PEB Address: 7ffd4000   LastErrorValue: 0   LastStatusValue: c0000034   Count Owned Locks: 0   HardErrorMode: 0

notepad.exe (PID 1370):

0:000> !teb TEB at 7ffdf000 ExceptionList: 001ffa00   StackBase: 00200000   StackLimit: 001ef000   SubSystemTib: 00000000   FiberData: 00001e00   ArbitraryUserPointer: 00000000   Self: 7ffdf000   EnvironmentPointer: 00000000   ClientId: 00001370 . 00001454   RpcHandle: 00000000   Tls Storage: 7ffdf02c   PEB Address: 7ffd9000   LastErrorValue: 5   LastStatusValue: c0000008   Count Owned Locks: 0   HardErrorMode: 0

However if we look at old applications that weren’t linked with /dynamicbase option we would see that the main module and old dll base addresses are the same:

0:000> lm
start end module name
00400000 00435000 TestDefaultDebugger
20000000 2000d000 LvHook

To summarize different alternatives I created the following table where

“New” column - processes linked with /dynamicbase option, no reboot
“New/Reboot” column - processes linked with /dynamicbase option, reboot
“Old” column - old processes, no reboot
“Old/Reboot” column - old processes, reboot

Randomization   | New/Reboot | New | Old/Reboot | Old
------------------------------------------------------
Module          |      +     |  -  |      -     |  -
------------------------------------------------------
System DLLs     |      +     |  -  |      +     |  -
------------------------------------------------------
Stack           |      +     |  +  |      -     |  -
------------------------------------------------------
Heap            |      +     |  +  |      +     |  +
------------------------------------------------------
PEB             |      +     |  +  |      +     |  +
------------------------------------------------------
Environment     |      +     |  +  |      +     |  +
------------------------------------------------------
ExceptionList   |      +     |  +  |      -     |  -

From PEB and process heap base addresses we can see that environment addresses are always correlated with the heap:

0:000> !heap Index Address Name Debugging options enabled   1: 005f0000

0:000> !peb PEB at 7ffd7000 ... ... ...   ProcessHeap: 005f0000   ProcessParameters: 005f1540   Environment: 005f07e8

I think the reason why Microsoft didn’t enable ASLR by default is to prevent Changed Environment pattern from appearing.

- Dmitry Vostokov -

8 Responses to “ASLR: Address Space Layout Randomization”

  1. Pirks Says:

    Dmitry, is this ASLR feature a Vista x64 specific one? Or is it available in both 32-bit and 64-bit Vista?

  2. Dmitry Vostokov Says:

    I haven’t installed x64 Vista yet but it looks like it has been added:

    What You Need to Know About Windows Vista x64 Versions’ Unique Security Features

    Windows Vista Feature Focus: 64-Bit (x64) Support

    and there is some indirect evidence that Vista x64 supports ASLR on MS web site:

    http://support.microsoft.com/kb/922822/

  3. Nicolas RUFF Says:

    Stack address changes on every program execution, not on reboot. I have just been testing on my Vista32 with this 1-liner:

    int main() {
    int i;
    printf(”%08x”, &i);
    }

  4. Dmitry Vostokov Says:

    Agree, this is what my table says (both +):

    Randomization   | New/Reboot | New | Old/Reboot | Old
    ------------------------------------------------------
    Stack           |      +     |  +  |      -	|  -
    ------------------------------------------------------ 

    Thanks,
    Dmitry

  5. Nicolas RUFF Says:

    Indeed, but this is not consistent with the introduction:

    “* Load address randomization (/dynamicbase linker option)
    * Stack address randomization (/dynamicbase linker option)
    * Heap randomization
    The first two randomizations change addresses across Vista reboots.”

  6. Dmitry Vostokov Says:

    Thanks for pointing to this! I have corrected the text.

  7. Crash Dump Analysis » Blog Archive » Crash Dump Analysis Patterns (Part 10a) Says:

    […] similar address space reshuffling happens with ASLR-enabled applications with the difference that system DLLs are never remapped below […]

  8. Crash Dump Analysis » Blog Archive » Exception Addresses from Event Logs Says:

    […] on Vista and W2K8 due to ASLR system DLLs could be at different addresses if we take the dump of a different running process […]

Leave a Reply

You must be logged in to post a comment.