Stack randomization changes the base address for every thread, which makes it more difficult for an attacker to find a place to jump to within an application. For example, assume the attacker wants to make a call to system, but the C runtime DLL is loaded in a random location that your code also calls system. If the application code is loaded at predictable addresses, the attacker can then just jump to where you called system yourself. Obviously, a real attack would also include setting up arguments and buffers, and some serious mistakes would need to be made before an attacker could have this much control.
Using the sample program listed in the ASLR section, you get the results shown in Table 3-1.
Original Value | After Restarting Application | |
---|---|---|
Address of main | 00281020 | 00F41020 |
Address of function foo | 00281000 | 00F41000 |
Address of g_GlobalVar | 0028336C | 00F4336C |
Address of StackBuffer | 001EFBC4 | 002EF8BC |
To get this protection, you have to use /dynamicbase in your linker options. Note that even though the starting address of the executable command is randomized, the offset between the various code elements remains constant. In this example, the offset between the entry point of main() and foo() is 32 bytes (0x20). If you have any important information stored in global variables, these addresses will be randomized as well. While it is generally a bad practice to store things such as function pointers in global memory, if you do, this mitigation will make your code more difficult to attack. Encoded pointers, which are discussed in Chapter 9, Miscellaneous Defenses and Security Technologies should also be used.
Even though the address of the stack buffers has always been somewhat unpredictable in multithreaded applications, when using this mitigation we find that the location of the stack for the main thread is randomized; an interesting aspect to take note of is that the offset between the stack and the main module’s code isn’t fixed from one instance of the application to the next. If we’ve depriving the attackers of fixed addresses, knowledge of offsets becomes even more important, and there’s no longer a relationship between the stack addresses and the code addresses.
Unless you are doing something really unusual (and inadvisable), there shouldn’t be any performance or compatibility issues because of randomized stack locations.