How to avoid std functions being instrumented by /Gh compile option?

Kohit _ 41 Reputation points
2020-11-04T13:32:25.203+00:00

I am using /Gh and /GH options to analyse my program.
However, compile with these options may hook those std functions which I'm not concerned but causing a lot extra time cost.
How can I avoid compiler to hook std functions?

update:
I’ve read some msvc stl source code and find out that it’s difficult to avoid being hook because most of the stl source code are implemented in header files.
But gcc have compile options like -nostdinc++ -nodefaultlibs
a libc++ usage example:
$ g++ -nostdinc++ -I<libcxx-install-prefix>/include/c++/v1 \
test.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc

Developer technologies C++
Developer technologies Visual Studio Other
{count} votes

Accepted answer
  1. Viorel 122.5K Reputation points
    2020-11-06T21:19:24.81+00:00

    If you like to research the idea of self-modifying code, then try an experiment for Visual Studio 2019:

    /*  
      
    Configuration:  
      
    	- Debug, Win32  
      
    Compiler options:  
      
    	- "Additional options": /Gh  
      
    Linker options:  
      
    	- "Enable Incremental Linking": NO  
      
    */  
      
    #include <Windows.h>  
    #include <iostream>  
    #include <cassert>  
      
      
    void f1()  
    {  
    	printf( "f1\n" );  
    }  
      
    void __stdcall MyHook( unsigned char* retAddress )  
    {  
    	//return; // uncomment to disable self-modification  
      
    	unsigned char* address_of_call_penter = retAddress - 5;  
    	unsigned char code = address_of_call_penter[0];  
    	assert( code = 0xE8 );  
      
    	unsigned char* address_of_f1 = (unsigned char*)&f1;  
      
    	if( address_of_call_penter != address_of_f1 )  
    	{  
    		// remove 'call _penter', replace with 'nop'  
      
    		MEMORY_BASIC_INFORMATION mbi;  
    		BOOL b;  
    		b = VirtualQuery( address_of_call_penter, &mbi, sizeof( mbi ) );  
      
    		DWORD old_protect;  
    		b = VirtualProtect( mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &old_protect );  
      
    		*(unsigned*)address_of_call_penter = 0x90909090;  
    		( (char*)address_of_call_penter )[4] = 0x90;  
      
    		b = VirtualProtect( mbi.BaseAddress, mbi.RegionSize, old_protect, &old_protect );  
    	}  
    }  
      
      
    bool recursive_call = false;  
    int counter = 0;  
      
    extern "C" void __declspec( naked ) __cdecl _penter( void )  
    {  
    	_asm  
    	{  
    		pushad  
    	}  
      
      
    	if( !recursive_call )  
    	{  
    		recursive_call = true;  
      
    		printf( "_penter %i\n", ++counter );  
      
    		__asm  
    		{  
    			mov eax, [esp + ( 8 ) * 4]  
    			push eax  
    			call MyHook  
    		}  
      
    		recursive_call = false;  
    	}  
      
    	_asm  
    	{  
    		popad  
    		ret  
    	}  
    }  
      
      
    int main()  
    {  
    	printf( "Calling 'f1'\n" );  
    	f1();  
    	printf( "Returned from 'f1'\n" );  
      
    	return 0;  
    }  
      
    

    The mandatory Project Properties are shown in the comment.

    It includes a sample “f1” function. If _penter is called for other function, like printf, then the call is removed (replaced with ‘nop’ instructions). The next time printf will not invoke _penter. It is possible to deal with more than just one “f1” function.

    The program displays “_penter” five times. When “//return” is uncommented to disable the self-modification, then _penter is called 12 times.

    To detect undesirable recursive infinite calls in single-threaded environment it uses a simple flag; see also: https://learn.microsoft.com/en-us/answers/questions/123941/gh-causing-infinite-loop.html.

    Works with STL functions too.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.