Chinaunix首页 | 论坛 | 博客
  • 博客访问: 663033
  • 博文数量: 36
  • 博客积分: 8068
  • 博客等级: 中将
  • 技术积分: 1377
  • 用 户 组: 普通用户
  • 注册时间: 2005-04-11 22:36
文章存档

2011年(2)

2010年(1)

2009年(20)

2008年(13)

我的朋友

分类: LINUX

2009-06-21 14:21:23

程序在运行过程序中,修改自己的代码段内存,改变了原先的代码指令。
这种编程思路在某些方面相当实用,能很好的提高程序的效率。
比如一段代码在第一次运行后就不再使用了,但每次都要对其进行判断,像某些模拟器程序中,这种判断就会占去很多的效率,如果使用这种自修改思路,即把某些只要执行一次的代码在执行过后除去,那将很好的提高了效率。

下面是一个在网上DOWNLOAD的一个示例程序,我在 Linux 2.6.28 , gcc 4.3.3 环境测试成功。

$ cat -n smc.c
     1    /*
     2     * Self Modifying Code  smc.c
     3     */
     4    
     5    #include
     6    #include
     7    #include
     8    #include
     9    #include
    10    #include
    11    
    12    /*    gcc is oblivious to asm level so we have to spell out
    13        our intentions.. it's an ugly hack. if you know of
    14        a proper way to do it in pure C please tell me. */
    15    
    16    extern char injectHere;
    17    extern char injectionStart;
    18    extern char injectionEnd;
    19    
    20    void dummyTextContext( void )
    21    {
    22        /*    sometimes gcc is just too smart.. in an ideal world
    23            we would write smthng like (*(&exit))( 42 ); and get
    24            an indirect call (via absolute address). anyway,
    25            we don't get that so we have to make one pointer for
    26            every type of function we want to call */
    27    
    28        int (*callPrintf)( const char *format, ... );
    29        void (*callExit)( int ); /* man 3 printf exit */
    30    
    31        asm volatile( "injectionStart:" );
    32    
    33        /*    do what you like here but keep it relocatable
    34            fire up objdump, gdb or whatever to check what you get */
    35    
    36        (*(callPrintf=&printf))( "Hello :-)\n" );
    37        (*(callPrintf=&printf))( "No endless loop here!\n" );
    38    
    39        (*(callExit=&exit))( 42 ); /* the meaning of life (for this proggie anyway..) */
    40    
    41        asm volatile( "injectionEnd:" );
    42    }
    43    
    44    int main( void )
    45    {
    46        /*    it's fairly safe to assume page is 2^N,
    47            now.. let's find us a page to bash >:*/
    48    
    49        unsigned page = (unsigned)&injectHere & ~( getpagesize() - 1 );
    50    
    51        /*    chmod u=rwx page ;-) */
    52    
    53        if( mprotect( (char*)page, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC ) )
    54        {
    55            perror( "mprotect failed" );
    56            exit( errno );
    57        }
    58    
    59    endlessLoop:
    60    
    61        asm volatile( "injectHere:" );    /* ground zero */
    62    
    63        /*    a few stats to ease debugging (and some code to fill our loop too) */
    64    
    65        printf( "PAGE(0x%x): cp <0x%x>[0..%u] <0x%x>\n",
    66                page, (int)&injectionStart, &injectionEnd - &injectionStart, (int)&injectHere );
    67    
    68        /*    inject some */
    69    
    70        memcpy( &injectHere, &injectionStart, &injectionEnd - &injectionStart );
    71    
    72        goto endlessLoop;
    73    
    74        return 0;
    75    }
阅读(2901) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

x9112009-06-24 13:43:06

这个比较实用。不错......