15

我并没有真正了解这段代码是如何做的:

char shellcode[] = "\xbb\x00\x00\x00\x00"           
                   "\xb8\x01\x00\x00\x00"                  
                   "\xcd\x80";                  

int main()
{
    int *ret;
    ret = (int *)&ret + 2;
    (*ret) = (int)shellcode;
}

好的,我知道了:

int *ret;

设置一个 int 的指针。和:

ret = (int *)&ret + 2;

设置 ret 和 2 个字节的地址(我认为。)

但我不明白这意味着什么:

(int *)&ret

我知道什么&ret意思,但不知道什么(int *)&ret意思。此外,它如何通过分配 to 的值shellcode来执行 shellcode ret

更新:有什么区别:

(int *)&ret  + 2

和:

&ret + 2
4

1 回答 1

17

“字符串”shellcode包含某种机器代码。

int *ret;定义了一个变量,ret它是指向int.

赋值指向一个距离它自己的实际位置(或地址)大小为 2ret = (int *)&ret + 2;的位置;这是堆栈中的一个地址,大概是函数()的返回地址存储在堆栈中的位置。retintmain()

该赋值*ret = (int)shellcode;将 shell 代码的地址分配给返回地址。因此,当main()函数退出时,返回地址是shell代码,它会做任何事情而不是正常退出程序。

演员表掩盖了许多罪恶。该代码做出了大量不可移植的假设,这些假设在目标环境中可能是合理的,但在其他任何地方都不一定。


&ret+2和有什么区别(int *)&ret + 2

类型,主要是;这是前面提到的众多罪恶之一。 &ret具有类型int **(指向指针的指针int)而不是int *其自身的类型ret。由于sizeof(int *) == sizeof(int **)在所有实际机器上,强制转换只是平息了编译器的抱怨(关于分配错误类型的指针ret)而不改变数值结果。

于 2012-03-22T03:41:29.073 回答