In MSVC the way to name/rename a thread is to call RaiseException with special parameters. More information can be found on MSDN.
The exception value is specific, it's 0x406D1388. If you see this exception value, it likely means that an application is trying to set a name for it's thread.
This is the case in CryEngine, however in my dumped exe, the code was failing. The exception handler used was _except_handler3, which is some generic handler in MSVCRT? Which also uses a secondary, user-provided handler table.
_except_handler3 has an internal check with VirtualQuery and checks the page access of this handler table. Specifically, 'MEMORY_BASIC_INFORMATION's 'Protect' member. Since the (user supplied)handler table was in the .rdata section, the protection should have been PAGE_READONLY, but in my case, it was PAGE_WRITECOPY. It was not set as read-only, because when I rebuilt the imports, some of the pointers were in the .rdata section, thus the import reconstructor made it writeable, this causes _except_handler3's page protection check to fail, thus it never calls any of the handlers, and the thread renaming exception never gets handled leading to a crash early on.
But here's the problem, if I make the .rdata section just read-only, the PE loader fails early as it cannot write the imports to the OriginalFirstThunk addresses. So essentially, I need proper import rebuilding.
UPDATE: Upon consulting with other people who pretty much solved my problem, I learned that it is normal for the IAT to reside in .rdata or a read-only section, the loader shouldn't choke, so we're not quite sure what the exact cause was, but upon closer inspection, the IAT RVA and IAT Size were set to 0 in the PE header. Upon fixing this, all was well.
No comments:
Post a Comment