DynamoRIO / DynamoRIO/drmemory
CRASH: VS2013+ /GL /Ob0 /O2 uses fastcall for exe-internal wmemcpy, breaking memcpy replacement
- Dominant language
- C
- Stars
- 2.7k
- Forks
- 290
- PR merge metrics
- No merged PRs in 30d
Description
This problem and the code below are from https://groups.google.com/forum/#!topic/DrMemory-Users/toYtAXIT3Yk
```
#include
#include
std::wstring get_this_module_file_name()
{
return L"bbbb";
}
int main()
{
std::wstring aaa = get_this_module_file_name();
printf("%u", (unsigned)aaa.length());
}
```
Reproducing requires "/GL /Ob0 /O2" with VS2013 or VS2015 (does not happen in VS2010):
```
% cl /Zi /Fewassign.exe wassign.cpp /EHsc /MT /GL /Ob0 /O2
~~Dr.M~~ Error #1: UNADDRESSABLE ACCESS: writing 0x00000004-0x00000008 4 byte(s)
~~Dr.M~~ # 0 replace_memcpy [d:\drmemory_package\drmemory\replace.c:246]
~~Dr.M~~ # 1 std::basic_string<>::assign [f:\program files (x86)\microsoft visual studio 14\vc\include\xstring:1167]
```
From the log:
```
New basic block @0x73b3a200 == drmemorylib.dll!replace_wmemcpy+0x0
```
Debugger:
```
Breakpoint 0 hit
eax=00000004 ebx=7efde000 ecx=0016f7ec edx=010955cc esi=0016f7ec edi=00000004
eip=010512c0 esp=0016f7a8 ebp=0016f808 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
wassign!wmemcpy:
010512c0 8b442404 mov eax,dword ptr [esp+4] ss:002b:0016f7ac=04000000
0:000> dds esp
0016f7a8 010515f4 wassign!std::basic_string,std::allocator >::assign+0x54 [f:\program files (x86)\microsoft visual studio 14\vc\include\xstring @ 1167]
0016f7ac 00000004
0016f7b0 0109980c wassign!__argv
0:000> Uf wassign!wmemcpy
wassign!wmemcpy [c:\program files (x86)\windows kits\10\include\10.0.10240.0\ucrt\wchar.h @ 231]:
231 010512c0 8b442404 mov eax,dword ptr [esp+4]
234 010512c4 03c0 add eax,eax
234 010512c6 50 push eax
234 010512c7 52 push edx
234 010512c8 51 push ecx
234 010512c9 e802940300 call wassign!memcpy (0108a6d0)
234 010512ce 83c40c add esp,0Ch
236 010512d1 c3 ret
```
It's using fastcall! (1st 2 args in ecx and edx, 3rd (count here) on stack.)
Very disturbing: how can we replace these libc routines when they're static
and their interfaces are changed? Yet another thing that never happens
on Linux.
It is unclear how to easily fix. Not replacing risks false positives, and while that is better than crashing it is not a great solution either. Probably we should recommend not using /GL.
Contributor guide
Assessment
This issue has not been assessed yet.