question

Kohit-8404 avatar image
0 Votes"
Kohit-8404 asked Kohit-8404 commented

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

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


c++vs-general
· 9
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.


What things do you have inside of _penter and _pexit?

If you can identify the needed functions at runtime from the body of _penter and _pexit, maybe you can modify (replace programmatically with ‘nop’ instructions) certain portions of unneeded functions. Then extra time will happen on first call only.




0 Votes 0 ·

About 500,000 std function calls in each runtime, identify these functions in _penter certainly help, but there will still have 500k extra _penter calls in each runtime, its still a lot of time.

0 Votes 0 ·

Do you really achieve 500 000 different std functions (not calls of the same functions) in your program?

0 Votes 0 ·
Show more comments

But gcc have compile options like -nostdinc++ -nodefaultlibs

@Kohit-8404 ,I suggest you could try to use /nodefaultlib:LibName.


0 Votes 0 ·

As I said before, most of the stl implementation were in the header files, not in the outside library file.

0 Votes 0 ·

If you cannot work around the undesirable hooking of std functions maybe you could move the functions that you do want to instrument into a dll and then use Detours to hook them.

0 Votes 0 ·

1 Answer

Viorel-1 avatar image
0 Votes"
Viorel-1 answered Kohit-8404 commented

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://docs.microsoft.com/en-us/answers/questions/123941/gh-causing-infinite-loop.html.

Works with STL functions too.




· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Wow, this is cool!

0 Votes 0 ·