| 
 | 
 
 
发表于 2009-5-11 21:46:49
|
显示全部楼层
 
 
 
#define H strlen(a) 
main() 
{ 
        char *a="ChinaPYG!"; 
                //mov         dword ptr [ebp-4],offset string "ChinaPYG!" 
                //将字符串地址放入局部变量之中。所放的四个字节为从ebp-1到ebp-4 
        int  *b=0; 
                //mov         dword ptr [ebp-8],0 
                //将0放入局部变量2中,该地址里面内容为0,作为指针指向地址0 
                //所放的位置为从ebp-5到ebp-8,四个字节。 
        for( ; *((char *)&b+1) < H ; (*((char *)&b+1))++) 
                /* 
          jmp         main+30h (00401040) 
          mov         al,byte ptr [ebp-7] 
                  //第一次循环结束跳转到这里,以后的每次循环都从这里开始。 
                  //取b的一个字节到al 
          add         al,1 
                  //al自加1 
          mov         byte ptr [ebp-7],al 
                  //将自加结果放回b中 
          movsx       esi,byte ptr [ebp-7] 
                  //第一次直接跳到这里,ebp-7是取b的四字节中的一个字节 
          mov         ecx,dword ptr [ebp-4]   
                  //ebp-4保存的是字符串地址,放入ecx中 
          push        ecx 
                  //ecx存入堆栈 
          call        strlen (00401120) 
                  //获得字符串长度 
          add         esp,4 
                  //strlen 由调用函数来恢复堆栈esp+4,使堆栈平衡 
          cmp         esi,eax 
          jae         main+5Fh (0040106f) 
                  //esi如果大于等于eax,eax=字符串长度。就跳走,跳到的位置就是程序结束。否则,继续向下执行。 
                  */ 
        printf("%c",*(a + *((char *)&b+1))); 
                /* 
            movsx       edx,byte ptr [ebp-7] 
                        //b放入edx中 
            mov         eax,dword ptr [ebp-4] 
                        //eax指向字符串 
            movsx       ecx,byte ptr [eax+edx] 
                        //以字符串地址作为基址,以b作为偏移,取一个字节,放入ecx中。 
            push        ecx 
            push        offset string "%c" (0042201c) 
            call        printf (004010a0) 
                        //调用函数输出这一个字节。 
            add         esp,8 
                        //恢复堆栈 
            jmp         main+28h (00401038) 
                        //跳转到前面 
                */ 
                 
                 
} 
 
总结:关键是这句*((char *)&b+1),b本身就是一个指针,这句,取了b的地址,也就是堆栈中的地址,我的是0012ff78, 
然后,强制转换0012ff78为字符类指针,大家都知道,字符类型指针指向的乃是一个字节, 
所以,此时(char *)&b指向0012ff78这个地址的一个字节,该字节在堆栈中,然后是(char *)&b+1 
该指针上移一位,指向0012ff79,因为内存是由高到底分配的,所以说是上移。 
最后是一个取内容的“*”操作,取出0012ff79所存储的一个字节,也就是ebp-7中所存储的一个字节。 |   
 
 
 
 |