I have chosen the "GetModuleFileNameExW" function of psapi.dll v5.1.2600.5512, the one shipped with Windows XP SP3.
The function's prototype is:
As you can see from the source code above, if the function is called with the "hMod" parameter set to Zero, the "ImageBaseAddress" value in the PEB (Process Environment Block) is retrieved and then the "InMemoryOrderModuleList" doubly linked list is traversed and each "LDR_MODULE" structure is queried for its "BaseAddress" field . If the "BaseAddress" field is equal to the "ImageBaseAddress" value, the function successfully returns.
And if the "hMod" parameter is set to nonzero, the doubly linked list is directly traversed and each "LDR_MODULE" structure is queried for its "BaseAddress" field. If the "BaseAddress" field is equal to the "hMod" value, the function successfully returns.
So, if we manipulate any LDR_MODULE structure to point at itself instead of pointing at the next structure, then we can cause any application that uses the function against our process to go into an infinite loop.
Here is a demo that causes OllyDbg v1.10 to go into an infinite loop when you open the "Select process to attach" dialog box. You can also use the second demo for OllyDbg v2.0.
Trying to test these demos on Windows 7, you will notice that everything is okay and no infinite loops occur. So, let's check the "_FindModule@12" function in psapi.dll shipped with windows 7 (WOW64).
If we compare the source code of both versions, we will easily see that Microsoft fixed that bug by defining a value for the maximum number of modules that can be loaded in a process. The value is 0x2710.
Any ideas or comments are very welcome.
You can follow me on Twitter @waleedassar