|
发表于 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中所存储的一个字节。 |
|