Removing MSCRT
Last updated
Last updated
The Microsoft C Run-Time Library is a set of low level functions and macros that provide support for C & C++ programs. It includes functions for memory management, string manipulations, and I/O functions.
The reason why we'd want to do this is to reduce entropy in the binary.
Depending on the compiler you use, the CRT DLL library names will differ. Below are screenshots of the
Visual Studio is as follows: vcruntimeXXX.dll
where XXX is the version number of the CRT library used. There's also api-ms-win-crt-stdio-l1-1-0.dll
, api-ms-win-crt-runtime-l1-1-0.dll
and api-ms-win-crt-locale-l1-1-0.dll
that are also related to the CRT library. Each exporting it's own functions.
MinGW stands for "minimalist GNU". Mingw uses msvcrt.dll
to export all functions.
To remove CRT in mingw2, we can add these additional flags to our Mafefile.
-nostartfiles
, -nostdlib
, -static-libgcc
, and -static
Note:** The only one we really need is -nostartfiles
**
Example Makefile:
Now that our our code is running independent from the C Standard Library, writing one's own version of functions such as printf
, strlen
, strcat
, memcpy
is necessary.
We are now only importing KERNEL32.dll & USER32.dll (wsprintf).
When building CRT independent malware it's important to keep in mind that some functions and macros use CRT to perform tasks.
We can manually set custom versions of CRT-based functions like memset
. Forcing the compiler to deal with this custom function instead of using the CRT exported version. Macros like ZeroMemory
will also use this custom function.
Our custom version of the memset
function can be specified to the compiler in the following manner, using the intrinsic
keyword. The intrinsic function is a function that the compiler implements directly when possible.
Intrinsic functions are provided by the compiler, and do not require a #include like inline functions.
Libraries like may be used for this purpose. For example, replaces the strcmp
function for string comparison.
ZeroMemory: Uses CRT memset to populate it's buffer with zeros. We need to find an alternative method then. The function can be used as a replacement.