During the development of Windows Vista, the application comaptibility team traced a bunch of issues back to people corrupting the stack by using the rundll32
program to call functions that were not designed to be called by rundll32
.
The problems were often subtle. For example, a batch file which used rundll32
incorrectly ended up hanging because the rundll32
process never returned. The misaligned stack resulted in registers being restored from the stack incorrectly, and then the cleanup code inside rundll32
ends up getting confused and wedging itself. The programs got away with it on previous versions of Windows by sheer luck. The version of the compiler used by Windows Vista contains different optimizations, and it ended up arranging stack variables and using registers differently, and what in previous versions of Windows was some corruption that went largely unnoticed became corruption that resulted in the program getting stuck in an infinite loop. Lucky no longer.
I was asked to come up with a solution for this problem, to fix the rundll32
program so it was more resilient to people who used it incorrectly. To fix other people’s bugs for them.
The solution: Before calling the function, push a hundred bytes of garbage onto the stack (in case the called function pops too many bytes off the stack) and save the stack pointer in a global variable. After the function returns, restore the stack pointer, in case the called function pops too many or too few bytes off the stack. I think I may even have saved the processor registers in global variables, I forget.
Do not consider this free license to continue abusing the rundll32
program. When the pet store opens on Sundays, that doesn’t mean that it’s okay to keep throwing garbage on the sidewalk.
0 comments