1

Following this question, I am trying to compile the code below:

// main.cpp

#include <iostream>

int main(int argc, char **argv)
{
    unsigned long long myVar;

    __security_init_cookie();

    myVar = __scrt_initialize_crt(1);

    return 0;
}

in the command line cl main.cpp but I get the error message

Microsoft (R) C/C++ Optimizing Compiler Version 19.31.31104 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
main.cpp(12): error C3861: '__scrt_initialize_crt': identifier not found

while the equivalent C code

// main.c

#include <stdio.h>

int main(int argc, char **argv)
{
    unsigned long long myVar;

    __security_init_cookie();

    myVar = __scrt_initialize_crt(1);

    return 0;
}

works just fine. I would appreciate it if you could help me understand what the problem is and how I can rewrite the C code in pure and canonical C++.

Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
  • 1
    What header file declares the `__scrt_initialize_crt` function? Have you tried to find any documentation about it, to read which header file you should include? – Some programmer dude Mar 05 '22 at 17:41
  • And if you want "code in pure and canonical C++" then you shouldn't be using compiler-specific extensions like `__scrt_initialize_crt`. – Some programmer dude Mar 05 '22 at 17:42
  • @Someprogrammerdude I have not been able to find that much documentation, if you check the original post, there are some links over there. the `stdio.h` header file works in the C file but not in the C++ version. – Foad S. Farimani Mar 05 '22 at 17:43
  • @Someprogrammerdude this is a follow-up question of [this original post](https://reverseengineering.stackexchange.com/q/30090/24943). I want to replicate a decompiled code. – Foad S. Farimani Mar 05 '22 at 17:44
  • Then perhaps include ``? Or at the very least take a look at the `` header file to see if it declares the function in itself, or what other header files it includes and try to find the declaration in one of them. – Some programmer dude Mar 05 '22 at 17:47
  • @Someprogrammerdude I had already tried the `cstdio` header, it didn't work either. – Foad S. Farimani Mar 05 '22 at 17:50
  • And the same for `` (it's still available in C++)? If it still doesn't work then as a hint you should look at declarations or header-file inclusion that is *not* performed in C++ (look for things similar to `#ifndef __cplusplus`). – Some programmer dude Mar 05 '22 at 17:53
  • @Someprogrammerdude If you take a look at my [original post](https://reverseengineering.stackexchange.com/q/30090/24943) and [this page](https://github.com/ojdkbuild/tools_toolchain_vs2017bt_1416/blob/master/VC/Tools/MSVC/14.16.27023/crt/src/vcruntime/utility.cpp), you may see the `__scrt_initialize_crt` function is specifically a C++ one, That's why I am trying to replicate the code in C++. The `stdio.h` doesn't help either. – Foad S. Farimani Mar 05 '22 at 17:56
  • I meant that you need to look in the system header files (like `stdio.h`) to look for declarations and other `#include` directives (and follow them to look in the included header files, and so on) for this function. And since the function isn't available when you include the file in a C++ source file, there's probably some kind of check for `__cplusplus` that you can look for in the header files when you read them. – Some programmer dude Mar 05 '22 at 17:58
  • @Someprogrammerdude well, that's beyond my experience and knowledge sadly. Hence asking for help here. If you know how this should be done, please educate me. – Foad S. Farimani Mar 05 '22 at 18:04
  • 2
    Well, tracking down that header file is easy. If you look at the _first non-comment line_ in the link you posted, it refers to `vcstartup_internal.h`, and sure enough, it's [declared in there](https://github.com/ojdkbuild/tools_toolchain_vs2017bt_1416/blob/master/VC/Tools/MSVC/14.16.27023/crt/src/vcruntime/vcstartup_internal.h). I'm not sure how this code is compiling in C++ without a prototype, actually. Maybe, as so often happens, MSVC is letting you get away with doing illegal stuff that other compilers don't. – Paul Sanders Mar 05 '22 at 18:04
  • @PaulSanders the code doesn't compile in C++, but in C. Are you telling me that even the `stdio.h` doesn't include the `__scrt_initialize_crt` but the compiler is letting us get away with it? I am not sure if I understand this! – Foad S. Farimani Mar 05 '22 at 18:11
  • Any decent editor or IDE will let you right-click on a header file `#include` and have alternatives to open that header file. Even for system header files. Then it's just a matter of using the editors built-in search functionality to find the function declaration, or to continue looking through the header files. – Some programmer dude Mar 05 '22 at 18:17
  • Oh right, sorry, I misread the error message. So yes, you need to #include `"path/to/vcstartup_internal.h"` (which will also fix a linker problem that you haven't encountered yet) and hopefully @Someprogrammerdude's suggestion will help you track it down. If not, you'll have to do so yourself. – Paul Sanders Mar 05 '22 at 18:18
  • 1
    @FoadS.Farimani Functions don't need to be declared in C89 to be callable. – user17732522 Mar 05 '22 at 18:18
  • @user17732522 that seems like a big flaw, doesn't it? How can I force `cl.exe` compiler to use a newer version of C standard? I guess this should be fixed in one of the newer standards, right? – Foad S. Farimani Mar 05 '22 at 18:21
  • @Someprogrammerdude I am using Visual Studio Code editor, and even though I have followed [these steps](https://stackoverflow.com/a/71300722/4999991) it doesn't give me the hint to look into the header files. Moreover if you follow the comments above, even the `stdio.h` header doesn't include the function. I need to find the `vcstartup_internal.h` header file and also link against it. – Foad S. Farimani Mar 05 '22 at 18:25
  • @user17732522 the `/Gs` option didn't help for me. But we are getting close I believe. Maybe [this page](https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170) provides an answer? – Foad S. Farimani Mar 05 '22 at 18:33
  • @FoadS.Farimani Sorry, I linked the wrong flag and page, I meant `/GS`, see https://learn.microsoft.com/en-us/cpp/build/reference/gs-buffer-security-check?view=msvc-170 – user17732522 Mar 05 '22 at 18:38
  • @user17732522 aha, so you are telling me the above functions are added automatically when the `/GS` is option is included in the options of the compiler and they can not be called/used directly? – Foad S. Farimani Mar 05 '22 at 18:46
  • 1
    @FoadS.Farimani That was just a feeling I had, according to the linked page that doesn't seem to be the case for `__security_init_cookie` though. It seems to be intended to be manually called if the CRT is not automatically initialized as normally would be the case. I couldn't find anything saying that `__scrt_initialize_crt` is supposed to be called from user code. But I don't know anything about how Windows works. – user17732522 Mar 05 '22 at 18:51
  • folks, I posted an answer, explaining some progress I had. maybe you can add to that already. – Foad S. Farimani Mar 05 '22 at 19:26
  • 1
    Functions such as `__security_init_cookie` and `__scrt_initialize_crt` are compiler specific and are not portable. In general, functions starting with `__` are compiler or library specific and should not be called directly from user code (there are exceptions!) – fpmurphy Mar 07 '22 at 12:21
  • @fpmurphy portability is not a requirement of my question. I want my code to be specifically compiled by MSV C and C++ compilers. – Foad S. Farimani Mar 08 '22 at 20:38
  • BTW @user17732522 I found out about the `/std:c11` and `/std:c17` compiler options and I am gonna try them to see if I get any errors. Interestingly enough there is no `/std:c99` option as if by default MSVC compiler includes some extensions to the C89 standard compliant to C99 as I read [here](https://learn.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version?view=msvc-170). – Foad S. Farimani Mar 09 '22 at 10:15

1 Answers1

-1

This is not an answer but to show the progress, if a better answer is to be added to the page I can delete this post.

So far I with below code

#ifndef _M_CEE
#define _M_CEE
#endif

#include <iostream>
#include <vcstartup_internal.h>
#include <gs_support.c>

int main(int argc, char **argv)
{
    unsigned long long myVar;

    __security_init_cookie();

    myVar = __scrt_initialize_crt(__scrt_module_type::exe);

    return 0;
}

compiled with

cl /clr /I "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\crt\src\vcruntime" main.cpp

I get the error:

Microsoft (R) C/C++ Optimizing Compiler Version 19.31.31104
for Microsoft (R) .NET Framework version 4.08.4470.0
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
Microsoft (R) Incremental Linker Version 14.31.31104.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:main.exe
main.obj
LINK : fatal error LNK1104: cannot open file 'MSCOREE.lib'
Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
  • Why are you compiling with the `/clr` switch all of a sudden? That seems just totally ... random. I have voted to close this question - it is totally pointless and just wasting everybody's time. The [other question you asked](https://reverseengineering.stackexchange.com/q/30090/24943) (under a different user account - why?) was answered perfectly well in the comments but you claim not to understand it. Your time would be better spent trying to do so. You don't _need_ to see the source code of `__security_init_cookie ` to understand what it does. You said as much in your other question. – Paul Sanders Mar 05 '22 at 21:57
  • 1
    @PaulSanders It is not a different user account. You can set the profile information and user name individually for each stackexchange site. – user17732522 Mar 06 '22 at 18:20
  • @PaulSanders This is not my profession but a hobby. I have three main goals: 1. dissect a specific proprietary software and learn its inside guts. 2. learn software reverse engineering. 3. learn MCVC/C++ compilers and the assembly they generate. And this post specifically is not an answer, but a placeholder meant to be deleted or modified when I learn more. – Foad S. Farimani Mar 06 '22 at 18:32
  • 1
    i answered your other question for just the compilation part @FoadS.Farimani and as is commented i am also not sure about the utility or futility of the answer take a look – blabb Mar 06 '22 at 21:03
  • 1
    @FoadS That's all fine, I have no problem with that, but this question has tied a lot of people in knots, that's what I'm objecting to. I had no trouble tracking down the information you have been asking for - you really need to try a bit harder before you start asking for help. I'm sorry about the 'two user accounts' business, by the way. That was a misunderstanding on my part and I apologise for insinuating that you were doing anything underhand. – Paul Sanders Mar 06 '22 at 23:06
  • 1
    @FoadS.Farimani. What are you trying to learn/do by invoking `__security_init_cookie` and `__scrt_initialize_crt` directly? – fpmurphy Mar 07 '22 at 12:26
  • @fpmurphy I tried to explain my motive in a couple of comments above. Eventually learning and enjoying. I am REing a proprietary software to understand what it does under the hood. At the same time, I want to learn MSV C and C++ compilers, as I will need them in my work soon. With the two questions specifically, the one on the RE SE was meant to understand what those functions do, and the question here is meant to replicate the original code as much as possible. So far I suspect the `__security_init_cookie` is most probably added by the compiler when the `/GS` option is invoked. – Foad S. Farimani Mar 08 '22 at 20:37
  • @FoadS.Farimani. The Microsoft documentation is clear - The global security cookie is used for buffer overrun protection in code compiled with /GS (Buffer Security Check) and in code that uses exception handling. – fpmurphy Mar 09 '22 at 05:02
  • Dear @fpmurphy thanks for the explanations. Though sadly available material on the internet, including MS documentation, are limited and not very clear for a novice like me. Anyway, I came to a similar conclusion in the comment section of the [previous question](https://reverseengineering.stackexchange.com/q/30090/24943). This question in this page is to replicate the original code and compiler options as much as possible. – Foad S. Farimani Mar 09 '22 at 06:23
  • 1
    @FoadS.Farimani. Documentation is limited because 99.999% percent of developers or reverse engineers have absolutely no need to know the details. For a general overview of stack canaries do an Internet search for "stack yellow red zone" – fpmurphy Mar 09 '22 at 10:07
  • @fpmurphy most probably you are right. again I am very novice in the field so my questions might look stupid to you folks. My apologies for that. I appreciate that you and the rest here patiently answer my questions. – Foad S. Farimani Mar 09 '22 at 10:10
  • 1
    @FoadS.Farimani. Your questions are not stupid. However you do need to learn about high level concepts such as calling conventions, stack frames, and stack canaries, yellow and red zones, etc. before diving into the implementation details. – fpmurphy Mar 09 '22 at 10:16