DynamoRIO/drmemory

properly handle complex NtApphelpCacheControl parameters

Open

#1,758 opened on Aug 27, 2015

View on GitHub
 (1 comment) (0 reactions) (0 assignees)C (289 forks)auto 404
Bug-FalseNegativeBug-FalsePositiveComponent-DrSyscallOpSys-Windowshelp wanted

Repository metrics

Stars
 (2,727 stars)
PR merge metrics
 (PR metrics pending)

Description

On Windows 10, NtApphelpCacheControl's 2nd parameter is clearly not PUNICODE_STRING as we have it listed. In the past we put little effort into this as most instances of this syscall we've seen pass NULL. It sounds like the 2nd param is very complex and varies across Windows versions and maybe across enum values (1st param).

For now we may just want to mark it UNKNOWN and let the unknown-syscall code try to figure out what's written by the kernel, at least.

False positive on Win10

Xref #1669

Error #1: UNADDRESSABLE ACCESS: reading 0x00000010-0x0000002f 31 byte(s) within 0x00000010-0x0000002f
#0 system call NtApphelpCacheControl UNICODE_STRING content
    <system call>
#1 ntdll.dll!ZwApphelpCacheControl (0x77a53bca <ntdll.dll+0x83bca>)
    ??:0
#2 KERNEL32.dll!CompatCacheLookupExe (0x76bd853a <KERNEL32.dll+0x1853a>)
    ??:0
#3 KERNEL32.dll!BasepQueryAppCompat (0x76bd78c6 <KERNEL32.dll+0x178c6>)
    ??:0
#4 KERNELBASE.dll!CreateProcessInternalW (0x74c58896 <KERNELBASE.dll+0xb8896>)
    ??:0
#5 KERNELBASE.dll!CreateProcessInternalA (0x74c59e4b <KERNELBASE.dll+0xb9e4b>)
    ??:0
#6 KERNELBASE.dll!CreateProcessA (0x74c7f8fc <KERNELBASE.dll+0xdf8fc>)
    ??:0
#7 main         (0x013510a8 <procterm.exe+0x10a8>)
    d:\derek\drmemory\git\src\tests\procterm.c:79
Note: @0:00:01.312 in thread 3320

Shouldn't that match the blacklist? OK, the test passes -lib_blacklist_frames 0. We could add this to the default supp list. But our syscall def seems wrong: that is not a UNICODE_STRING (see below). I put in a suppression to at least avoid the false pos in 348ba7e.

Analysis: not a UNICODE_STRING

0:000> dds @@(mc->esp)
0056f2d0  77a53bca ntdll!NtApphelpCacheControl+0xa
0056f2d4  76bd853a KERNEL32!CompatCacheLookupExe+0x2ba
0056f2d8  00000000
0056f2dc  0056f2f0
0056f2e0  0056f9cc
0056f2e4  00000000
0056f2e8  0056f970
0056f2ec  00000004
0056f2f0  0000001f
0056f2f4  00000010
0056f2f8  00000000
0056f2fc  00000000

0:000> dt UNICODE_STRING 0056f2f0
procterm!UNICODE_STRING
 "--- memory read error at address 0x00000010 ---"
   +0x000 Length           : 0x1f
   +0x002 MaximumLength    : 0
   +0x004 Buffer           : 0x00000010  "--- memory read error at address 0x00000010 ---"

0:000> ?? mc->ebp-0x364
unsigned int 0x56f2f4

76bd83c3 e8c10e0000      call    KERNEL32!CompatCachepLookupFlagsToHintFlags (76bd9289)
76bd83c8 8bd3            mov     edx,ebx
76bd83ca 89859cfcffff    mov     dword ptr [ebp-364h],eax

KERNEL32!CompatCacheLookupExe+0x20de5:
76bf9065 838d9cfcffff02  or      dword ptr [ebp-364h],2
76bf906c e97bf3fdff      jmp     KERNEL32!CompatCacheLookupExe+0x16c (76bd83ec)

KERNEL32!CompatCacheLookupExe+0x20df1:
76bf9071 838d9cfcffff04  or      dword ptr [ebp-364h],4
76bf9078 e98df3fdff      jmp     KERNEL32!CompatCacheLookupExe+0x18a (76bd840a)

KERNEL32!CompatCacheLookupExe+0x20dfd:
76bf907d 838d9cfcffff08  or      dword ptr [ebp-364h],8
76bf9084 e9d6f3fdff      jmp     KERNEL32!CompatCacheLookupExe+0x1df (76bd845f)

The 0x1f is hardcoded here:

76bd833e c78598fcffff1f000000 mov dword ptr [ebp-368h],1Fh

The old Metasploit had this as PUNICODE_STRING. ReactOS has it as PVOID.

Further info

Xref James Forshaw's vulnerability research: https://code.google.com/p/google-security-research/issues/detail?id=118

Xref https://translate.google.co.uk/translate?hl=en&sl=zh-CN&u=http://blogs.360.cn/blog/ntapphelpcachecontrol_vulnerability_anaysis/&prev=search

Contributor guide