Re: [Valgrind-users] correct self-modifying-code for Valgrind
Thanks a lot Philippe! regarding the code that performs self-modifying-code check: *create_self_checks_as_needed*() (inside guest_generic_bb_to_IR.c). I am trying to write another statement to just print a string out when a self-modifying-code has been detected. To do that, I increase the allocated spaces for self-modifying-check from 21 (i.e., three extents, 7 statements each) to 24 (i.e, three extents, 8 statements each). The newly allocated space is used to perform a mkIRExprCCall to the print function. However, most of the existing support is for statements that create/modify values e.g., IRStmt_WrTmp,. I would like to have a mkIRExprCCall that simply calls a helper function (similar to checksum functions) to print out a string when self-modifying-code has been detected. Yet, if such a statement (of the corresponding function) is not used in the succeeding statement, the helper function is not triggered at run-time. Would you please let me know if there is a way to integrate such a helper function to print out a simple string indicating that a self-modifying-code has been detected by Valgrind. Thank you in advance for your help! Best regards, Duc On Sun, Aug 30, 2020 at 4:40 PM Philippe Waroquiers < philippe.waroqui...@skynet.be> wrote: > Valgrind has a lot of heuristics to optimise the speed of the JIT-ted code. > One of these heuristics is to chase jumps/calls to known destination. > > This is somewhat similar to inlining performed by the compiler, > but performed by valgrind at runtime, when it encounters a new call/jump. > > In this case, the function f1 is inlined twice following this heuristic. > So, the second inlining is using the modified function. > > If you disable chasing, then the code prints twice the same value: > valgrind --tool=none --smc-check=none --vex-guest-chase=no ... > produces twice 4660 as output. > > Also, if you do a loop > for (int j = 0; j < 2; j++) { > f1(); > here modify f1 code > } > > then valgrind inserts only once the code of f1, and it prints twice the > same > value, whatever the parameter --vex-guest-chase > > The code that does the self modifying code check is in the function > needs_self_check > in m_translate.c. This function is called by VEX. > > Philippe > > > On Fri, 2020-08-28 at 12:15 +0200, Duc Nguyen wrote: > > Hello everyone, > > > > I am trying the self-modifying-code check of Valgrind but I am not sure > if I understand the definition of self-modifying-code in Valgrind > correctly. > > > > I had prepared an example (see below) that has function f1 that is first > executed in main, outputs something (number 4660). Afterward, two > instructions of f1 are modified, and f1 is then executed one more time. It > then outputs something (number 22068) that is different from the first > time. > > > > When I run Valgrind with --smc-check=all and --smc-check=none I do not > see any difference in the outputs of Valgrind e.g., both times f1 produces > different numbers (e.g., self-modifying-code successfully runs despite the > --smc-check if turned on or off) > > > > Could someone please let me know if this behavior is expected from > Valgrind? > > > > I further looked into the source code and found > valgrind\VEX\priv\guest_generic_bb_to_IR.c that generates the code to > check. However, I do not know where such a check is executed. It would be > great if somebody knows where such a check takes place, and where we can > modify the source code to just simply say e.g., self-modifying-code is > found. > > > > Thank you very much in advance. > > > > Best regards, > > Duc > > > > > > = > > Self-modifying-code example > > --- > > > > > > > > #include > > #include > > #include > > > > __asm__( ".text" ); > > __asm__( ".align 4096" ); > > > > void f1( void ) > > { > > printf( "%d\n", 0x1234 ); > > } > > void f2( void ){ > > printf("this is just a dummy function"); > > } > > > > int main( void ) > > { > > int rc; > > int pagesize; > > char *p; > > int i; > > > > printf( "f1=0x%08X.\n", f1 ); > > > > f1( ); > > > > pagesize = sysconf( _SC_PAGE_SIZE ); > > printf( "pagesize=%d (0x%08X).\n", pagesize, pagesize ); > > if( pagesize == -1 ) > > return( 2 ); > > > > p = (char*) f1; > > rc = mprotect( p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC ); > > printf( "rc=%d.\n", rc ); > > if( rc != 0 ) > > return( 2 ); > > printf( "'mprotect()' succeeded.\n" ); > > > > > > for( i = 0; i+1 < (size_t) f2- (size_t)f1; i++ ) { > > if( ((char*) f1)[ i ] == 0x34 && ((char*) f1)[ i+1 ] == 0x12 ) { > > > ((char*) f1)[ i+1 ] =0x78;//here performs self-modifying-code > > ((char*) f1)[ i+1 ] =0x56;//here performs self-modifying-code > > } > >} > > > > f1( );//here the output of f1 will be different from the first f1() > call > > > > printf( "Call succeeded.\n" ); > > return( 0 ); > > } > > > > > > ___ > >
Re: [Valgrind-users] correct self-modifying-code for Valgrind
Valgrind has a lot of heuristics to optimise the speed of the JIT-ted code. One of these heuristics is to chase jumps/calls to known destination. This is somewhat similar to inlining performed by the compiler, but performed by valgrind at runtime, when it encounters a new call/jump. In this case, the function f1 is inlined twice following this heuristic. So, the second inlining is using the modified function. If you disable chasing, then the code prints twice the same value: valgrind --tool=none --smc-check=none --vex-guest-chase=no ... produces twice 4660 as output. Also, if you do a loop for (int j = 0; j < 2; j++) { f1(); here modify f1 code } then valgrind inserts only once the code of f1, and it prints twice the same value, whatever the parameter --vex-guest-chase The code that does the self modifying code check is in the function needs_self_check in m_translate.c. This function is called by VEX. Philippe On Fri, 2020-08-28 at 12:15 +0200, Duc Nguyen wrote: > Hello everyone, > > I am trying the self-modifying-code check of Valgrind but I am not sure if I > understand the definition of self-modifying-code in Valgrind correctly. > > I had prepared an example (see below) that has function f1 that is first > executed in main, outputs something (number 4660). Afterward, two > instructions of f1 are modified, and f1 is then executed one more time. It > then outputs something (number 22068) that is different from the first time. > > When I run Valgrind with --smc-check=all and --smc-check=none I do not see > any difference in the outputs of Valgrind e.g., both times f1 produces > different numbers (e.g., self-modifying-code successfully runs despite the > --smc-check if turned on or off) > > Could someone please let me know if this behavior is expected from Valgrind? > > I further looked into the source code and found > valgrind\VEX\priv\guest_generic_bb_to_IR.c that generates the code to check. > However, I do not know where such a check is executed. It would be great if > somebody knows where such a check takes place, and where we can modify the > source code to just simply say e.g., self-modifying-code is found. > > Thank you very much in advance. > > Best regards, > Duc > > > = > Self-modifying-code example > --- > > > > #include > #include > #include > > __asm__( ".text" ); > __asm__( ".align 4096" ); > > void f1( void ) > { > printf( "%d\n", 0x1234 ); > } > void f2( void ){ > printf("this is just a dummy function"); > } > > int main( void ) > { > int rc; > int pagesize; > char *p; > int i; > > printf( "f1=0x%08X.\n", f1 ); > > f1( ); > > pagesize = sysconf( _SC_PAGE_SIZE ); > printf( "pagesize=%d (0x%08X).\n", pagesize, pagesize ); > if( pagesize == -1 ) > return( 2 ); > > p = (char*) f1; > rc = mprotect( p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC ); > printf( "rc=%d.\n", rc ); > if( rc != 0 ) > return( 2 ); > printf( "'mprotect()' succeeded.\n" ); > > > for( i = 0; i+1 < (size_t) f2- (size_t)f1; i++ ) { > if( ((char*) f1)[ i ] == 0x34 && ((char*) f1)[ i+1 ] == 0x12 ) { > > ((char*) f1)[ i+1 ] =0x78;//here performs self-modifying-code > ((char*) f1)[ i+1 ] =0x56;//here performs self-modifying-code > } >} > > f1( );//here the output of f1 will be different from the first f1() call > > printf( "Call succeeded.\n" ); > return( 0 ); > } > > > ___ > Valgrind-users mailing list > Valgrind-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/valgrind-users ___ Valgrind-users mailing list Valgrind-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-users
[Valgrind-users] correct self-modifying-code for Valgrind
Hello everyone, I am trying the self-modifying-code check of Valgrind but I am not sure if I understand the definition of self-modifying-code in Valgrind correctly. I had prepared an example (see below) that has function f1 that is first executed in main, outputs something (number 4660). Afterward, two instructions of f1 are modified, and f1 is then executed one more time. It then outputs something (number 22068) that is different from the first time. When I run Valgrind with --smc-check=all and --smc-check=none I do not see any difference in the outputs of Valgrind e.g., both times f1 produces different numbers (e.g., self-modifying-code successfully runs despite the --smc-check if turned on or off) *Could someone please let me know if this behavior is expected from Valgrind?* I further looked into the source code and found valgrind\VEX\priv\guest_generic_bb_to_IR.c that generates the code to check. However, I do not know where such a check is executed. It would be great if somebody knows where such a check takes place, and *where we can modify the source code to just simply say e.g., self-modifying-code is found*. Thank you very much in advance. Best regards, Duc = Self-modifying-code example --- *#include #include #include __asm__( ".text" );__asm__( ".align 4096" );void f1( void ){ printf( "%d\n", 0x1234 );}void f2( void ){ printf("this is just a dummy function");}int main( void ){ int rc; int pagesize; char *p; int i; printf( "f1=0x%08X.\n", f1 ); f1( ); pagesize = sysconf( _SC_PAGE_SIZE ); printf( "pagesize=%d (0x%08X).\n", pagesize, pagesize ); if( pagesize == -1 )return( 2 ); p = (char*) f1; rc = mprotect( p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC ); printf( "rc=%d.\n", rc ); if( rc != 0 )return( 2 ); printf( "'mprotect()' succeeded.\n" ); for( i = 0; i+1 < (size_t) f2- (size_t)f1; i++ ) { if( ((char*) f1)[ i ] == 0x34 && ((char*) f1)[ i+1 ] == 0x12 ) { ((char*) f1)[ i+1 ] =0x78;//here performs self-modifying-code ((char*) f1)[ i+1 ] =0x56;//here performs self-modifying-code } }f1( );//here the output of f1 will be different from the first f1() call printf( "Call succeeded.\n" ); return( 0 );}* ___ Valgrind-users mailing list Valgrind-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-users