[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] Correcting the prototype of __getmainargs and add validat

From: Carlos Montiers
Subject: [Tinycc-devel] Correcting the prototype of __getmainargs and add validation to crt1.c
Date: Wed, 16 Jul 2014 23:39:29 -0400

I found that the current protoype of __getmainargs in crt1.c return void.
But according to the official internal.h from microsoft sdk it return int.

The documentation says: return 0 if successful; a negative value if unsuccessful.
I decompiled it from msvcrt.dll for windows xp.
And the only possible return value for error is -1 and is caused because a malloc cannot get memory.

It do a similar to this:
if ( globb ) {
    result = __setargv;
} else {
    result = _setargv();
if ( result >= 0 ) {
*argc = __argc;
*argv = __argv;
*env = _environ;
return result;

It only change the values of argc y argv if success the internal function that it call.
This internals functions __setargv and __setargv() ask for memory with malloc and if it is sucess set that pointer in the global variable __argv. if __argv is NULL because the memory cannot allocated on the heap. It return -1. Then __getmainargs check the return, if it is not a negative number it set argc, argv and env to the corresponding global variables: __argc, __argv, __environ.

Also i write a demo that demostrates that __getmainargs left untouched argc and argv if it fails. (attached)

When you run, it ful the heap (warning: it not free it. I tested on a a virtual machine with windows xp with 64 mb).

When you run it print:
Setting argc to -1 and argv to 1.
Content of argc:-1 argv:0x1
Calling __getmainargs.
__getmainargs failed!
Result of __getmainargs: -1
Content of argc:-1 argv:0x1

Beause it, if __getmainargs fails, it not set argv to NULL or argc to 0.
I added a if that check it, and print out a error message. But I not know if this is the recommended way for handle this error. A maybe possibles ways for handle it is:
set argc to 0 and argv to NULL and env to NULL
call to abort()
call to _exit(3)
call to exit(3)
call to ExitProcess(3)

I choose the last, and also I ad a error message, but it is can be optional:
This is the handle that I added:
if (__getmainargs(&argc, &argv, &env, 0, &start_info)) {
        // __getmainargs failed because possible few memory on the heap.
        fprintf(stderr, "Error getting the main args.");
        // terminate with exit code of 3, similar to abort()

The documentation not says nothing about free argv, maybe because on sucess it points to the global variable __argv and maybe because it is global is free with exit functions (but i not know if this is true).

Here I prefer use ExitProcess instead of exit, because internally exit do some things and in the end it call to ExitProcess.
I think that ExitProcess is more speedy than exit, but maybe it not do the cleans that exit function makes. Exit function maybe deallocate the global variable __argv

Also, I found that avira antivir detect as false positive a executable compiled with tiny c when it not use ExitProcess, then have a crt using ExitProcess in some point avoid a false detection of our executable.

I use this in some crt for bypass a false detection:
  This function is never called.
  Is used for avoid AntiVir false detection: TR/Crypt.XPACK.Gen
void nothing(void)

Because it I choose use ExitProcess for handle the error of __getmainargs function.


Attachment: poc_getmainargs.c
Description: Text Data

reply via email to

[Prev in Thread] Current Thread [Next in Thread]