Log in

View Full Version : Cross Your T's and Dot Your Filenames


REBlog
March 27th, 2008, 05:31
I was developing some automation code recently and found that a process that I was injecting code into was crashing. At first I thought it was an error in my injected code, but when I looked at the crash-dump, I was amazed to see that the issue was in MFC42.DLL:

MOV EBX,104
PUSH EBX
LEA EAX,DWORD PTR SS:[EBP+szBuffer]
PUSH EAX
PUSH DWORD PTR DS:[ESI+6C]
CALL DWORD PTR DS:[<&KERNEL32.GetModuleFileNameA ("http://msdn2.microsoft.com/en-us/library/ms683197.aspx")>
LEA EAX,DWORD PTR SS:[EBP+szBuffer]
PUSH 2E
PUSH EAX
CALL DWORD PTR DS:[<&msvcrt._mbsrchr ("http://msdn2.microsoft.com/en-us/library/ftw0heb9(VS.80).aspx")>]
POP ECX
POP ECX
MOV DWORD PTR SS:[EBP-80],EAX
MOV BYTE PTR DS:[EAX],0 <-- Crash!

The code above is from MFC42.DLL, version 6.2.4131.0 from Windows XP SP2. It effectively does the following:

GetModuleFileName ("http://msdn2.microsoft.com/en-us/library/ms683197.aspx")(NULL, szBuffer, MAX_PATH);
*(_mbsrchr ("http://msdn2.microsoft.com/en-us/library/ftw0heb9(VS.80).aspx")(szBuffer, '.')) = 0;

The function _mbsrchr(...) ("http://msdn2.microsoft.com/en-us/library/ftw0heb9(VS.80).aspx") returns NULL if the character searched for is not found. This means that if there is no '.' in the current process's filename (which was the case for the file I was testing) then the highlighted line above will try to write the byte 0x00 to address 0x00000000, which will cause a crash.

I figured that this was some obscure function from MFC42.DLL that most applications don't make use of, however, after a little digging it turns out that this code is in CWinApp::SetCurrentHandles(), which is called by AfxWinInit(...) ("http://msdn2.microsoft.com/en-us/library/w04bs753(vs.80).aspx"). From http://msdn2.microsoft.com/en-us/library/w04bs753(vs.80).aspx:

"[AfxWinInit] is called by the MFC-supplied WinMain function, as part of the CWinApp initialization of a GUI-based application, to initialize MFC."

In other words, almost every MFC GUI program executes the code snippet above!

AAs surprised as I was by this, I figured that surely this had been fixed for Vista. Believe it or not, the same issue exists! Below is the code from MFC42.DLL version 6.6.8063.0 from Windows Vista Gold:

PUSH 104
LEA EDX,DWORD PTR SS:[EBP+szBuffer]
MOV [EDI+0C],ECX
MOV EAX,DWORD PTR DS:[ESI+6C]
PUSH EDX
PUSH EAX
CALL DWORD PTR DS:[<&KERNEL32.GetModuleFileNameA ("http://msdn2.microsoft.com/en-us/library/ms683197.aspx")>
TEST EAX,EAX
JZ LOC_722F1484
CMP EAX,104
JZ LOC_722F1484
LEA ECX,[EBP+szBuffer]
PUSH 2E
PUSH ECX
CALL __mbsrchr
MOV EBX,EAX
ADD ESP,8
TEST EBX,EBX
MOV [EBP+VAR_310],EBX
JZ LOC_7230DB7D
...

__________________________________________________________________________

__mbsrchr:
MOV EDI,EDI
PUSH EBP
MOV EBP,ESP
POP EBP
JMP DWORD PTR DS:[<&msvcrt._mbsrchr ("http://msdn2.microsoft.com/en-us/library/ftw0heb9(VS.80).aspx")>]

__________________________________________________________________________

LOC_7230DB7D:
...
JMP DWORD PTR DS:[<&msvcrt.CxxThrowException>]

While the code above checks for the lack of a '.' in the filename, it still throws an exception and causes a crash if there's no '.'.

The good news is that it doesn't seem easy to accidentally execute an executable file without a '.' in the filename in Vista:

C:\>copy c:\windows\notepad.exe notepad_exe
1 file(s) copied.

C:\>notepad_exe
'notepad_exe' is not recognized as an internal or external command, operable program or batch file.

C:\>start notepad_exe
[This opens the "Open With" dialog box in Explorer instead of executing the file.]

However, it is still possible to run non-dotted-files via API functions like CreateProcess(...) ("http://msdn2.microsoft.com/en-us/library/ms682425(VS.85).aspx") to cause the crash described above.

http://malwareanalysis.com/CommunityServer/aggbug.aspx?PostID=986

http://malwareanalysis.com/CommunityServer/blogs/geffner/archive/2008/03/26/986.aspx