sxn ud
command sets up the debugger to send notification when a module is unloaded. I find very useful to analyze Windbg log during security testing, rather than just relying to find exception or memory corruption.Some time ago, during testing Internet Explorer 9, I noticed that Windbg screen had been flooded with the following messages.
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
The application continued running without displaying more of these messages and there was no sign the integrity of the application corrupted. My first thought was it's the result of one of Windbg commands I set up earlier just before executing the test. The second thought was that it is unlikely because it seems to be a CRT error message, that most likely comes from the runtime DLL. I knew there is a way to send message to the debugger from an executable and that is to call OutputDebugString
function.I set up a breakpoint for
OutputDebugString
, and rerun the test. Here is the call stack when the breakpoint hit.
0:005> k
Child-SP RetAddr Call Site
00000000`04448388 000007fe`fdfd2478 KERNELBASE!OutputDebugStringA
00000000`04448390 000007fe`fdfd249b msvcrt!invoke_watson+0x98
00000000`044488d0 000007fe`fdfb0439 msvcrt!invalid_parameter+0x13
00000000`04448910 00000000`6027290f msvcrt!wcsnicmp+0x40
00000000`04448950 00000000`6000b522 MSHTML!CMultimediaLog::ExtractVideoData+0x8f
00000000`04448a30 00000000`600077ba MSHTML!CDoc::ExecHelper+0x4308
00000000`044498b0 000007fe`f1a22805 MSHTML!CDoc::Exec+0x2a
00000000`04449900 000007fe`f1a222f1 IEFRAME!CDocObjectHost::_PopulateOnlineHistoryData+0x141
00000000`04449990 000007fe`f1a21ecb IEFRAME!CDocObjectHost::_UpdateHistoryAndIntSiteDB+0x229
00000000`0444cb10 000007fe`f1a22001 IEFRAME!CDocObjectHost::_OnReadyState+0x21b
00000000`0444cda0 000007fe`f1a220bc IEFRAME!CDocObjectHost::_OnChangedReadyState+0xd1
00000000`0444ce70 00000000`5ff33c27 IEFRAME!CDocObjectHost::OnChanged+0x1c
00000000`0444cea0 00000000`5ff31380 MSHTML!CBase::FirePropertyNotify+0x3a3
00000000`0444cf30 00000000`5ff7f874 MSHTML!CMarkup::SetReadyState+0x41a
00000000`0444cfb0 00000000`5ff323b1 MSHTML!CMarkup::OnLoadStatusDone+0x3eb
00000000`0444d070 00000000`5ff7ef3f MSHTML!CMarkup::OnLoadStatus+0xb2
00000000`0444d0a0 00000000`5ff2f4e0 MSHTML!CProgSink::DoUpdate+0x5f5
00000000`0444d530 00000000`5fffb468 MSHTML!GlobalWndOnMethodCall+0x18b
00000000`0444d5c0 00000000`76de9bd1 MSHTML!GlobalWndProc+0x36c
00000000`0444d640 00000000`76de98da USER32!UserCallWinProcCheckWow+0x1ad
00000000`0444d700 000007fe`f198af5e USER32!DispatchMessageWorker+0x3b5
00000000`0444d780 000007fe`f1937754 IEFRAME!CTabWindow::_TabWindowThreadProc+0x9c1
00000000`0444fbe0 00000000`771553b3 IEFRAME!LCIETab_ThreadProc+0x39f
00000000`0444fd80 000007fe`f1918dcb iertutil!CIsoScope::RegisterThread+0x10f
00000000`0444fdb0 00000000`76ee652d IEFRAME!Detour_DefWindowProcA+0x97
00000000`0444fdf0 00000000`774dc521 kernel32!BaseThreadInitThunk+0xd
00000000`0444fe20 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
Looking at the parameter of OutputDebugString I saw the followings.
0:005> db @rcx
000007fe`fe014110 49 6e 76 61 6c 69 64 20-70 61 72 61 6d 65 74 65 Invalid paramete
000007fe`fe014120 72 20 70 61 73 73 65 64-20 74 6f 20 43 20 72 75 r passed to C ru
000007fe`fe014130 6e 74 69 6d 65 20 66 75-6e 63 74 69 6f 6e 2e 0a ntime function..
000007fe`fe014140 00 00 00 00 3a 20 00 00-0a 00 0a 00 00 00 00 00 ....: ..........
000007fe`fe014150 2e 00 2e 00 2e 00 00 00-00 00 00 00 00 00 00 00 ................
000007fe`fe014160 4d 00 69 00 63 00 72 00-6f 00 73 00 6f 00 66 00 M.i.c.r.o.s.o.f.
000007fe`fe014170 74 00 20 00 56 00 69 00-73 00 75 00 61 00 6c 00 t. .V.i.s.u.a.l.
000007fe`fe014180 20 00 43 00 2b 00 2b 00-20 00 52 00 75 00 6e 00 .C.+.+. .R.u.n.
This confirms this function sends the message to the debugger. We also see that
I set up a breakpoint just before we call
OutputDebugString
is called from wcsnicmp
that is called from CMultimediaLog::ExtractVideoData
.I set up a breakpoint just before we call
wcsnicmp
.
0:005> ub MSHTML!CMultimediaLog::ExtractVideoData+0x8f
MSHTML!CMultimediaLog::ExtractVideoData+0x69:
00000000`602728e9 7409 je MSHTML!CMultimediaLog::ExtractVideoData+0x74 (00000000`602728f4)
00000000`602728eb 488b01 mov rax,qword ptr [rcx]
00000000`602728ee ff9020050000 call qword ptr [rax+520h]
00000000`602728f4 4c8b6c2428 mov r13,qword ptr [rsp+28h]
00000000`602728f9 488d15480f6900 lea rdx,[MSHTML!`string' (00000000`60903848)]
00000000`60272900 41b807000000 mov r8d,7
00000000`60272906 498bcd mov rcx,r13
00000000`60272909 ff1591ca5e00 call qword ptr [MSHTML!_imp__wcsnicmp (00000000`6085f3a0)]
The place of the breakpoint is the highlighted line above.
Here we are when the breakpoint is hit.
Here we are when the breakpoint is hit.
Breakpoint 2 hit
MSHTML!CMultimediaLog::ExtractVideoData+0x89:
00000000`60272909 ff1591ca5e00 call qword ptr [MSHTML!_imp__wcsnicmp (00000000`6085f3a0)] ds:00000000`6085f3a0={msvcrt!wcsnicmp (000007fe`fdf93330)}
Note that
I checked the parameters of
wcsnicmp
takes three parameters: string1
,
string2
, and count
. These describes null-terminated strings and number of characters to compare.I checked the parameters of
wcsnicmp
and saw the followings.
0:005> r rcx;r rdx;r r8
rcx=0000000000000000
rdx=0000000060903848
r8=0000000000000007
string2
and count
both look healthy however string1
is NULL but the API documentation expects a string.To make sure everything is ok with
string2
let's check.
0:005> du @rdx
00000000`60903848 "http://"
It's fine, so the only problem with parameter
Microsoft long time ago added security enhancements in the CRT library. One of them involves to call invalid parameter handler which, for example, checks for NULL pointer parameters, and we terminate gracefully rather than with invalid memory access exception.
As you can see the return value is the highest positive value that can be represented in signed 32-bit. If the application is not prepared to handle this edge value it could cause problem later on the execution. Fortunately, that was not the case with Internet Explorer.
string1
and the problem is that a NULL pointer is passed rather than a pointer to the string.Microsoft long time ago added security enhancements in the CRT library. One of them involves to call invalid parameter handler which, for example, checks for NULL pointer parameters, and we terminate gracefully rather than with invalid memory access exception.
As you can see the return value is the highest positive value that can be represented in signed 32-bit. If the application is not prepared to handle this edge value it could cause problem later on the execution. Fortunately, that was not the case with Internet Explorer.
0:005> g 6027290f
MSHTML!CMultimediaLog::ExtractVideoData+0x8f:
00000000`6027290f baffff0000 mov edx,0FFFFh
0:005> r eax
eax=7fffffff
The NULL check suppresses the crash but the application likely having problems managing the lifetime of objects.
Developers are advised to avoid the use of
References
Security Features in the CRT
Developers are advised to avoid the use of
wcsnicmp()
function as it's deprecated. Please check references what to use instead.References
Security Features in the CRT