这是我得到的一个数组:
char overflow[16]="\xEF\xBE\xAD\xDE\xEF\xBE\xAD\xDE"
"\xEF\xBE\xAD\xDE\xEF\xBE\xAD\xDE";
这是地址:“0x1234B000”
如何编辑上面的数组以使其溢出并将返回地址更改为上面的新地址?
最佳答案
这实际上取决于堆栈上的内容,这决定了您至少必须覆盖多少字节。函数参数和局部变量将妨碍堆栈指针,这是您尝试覆盖的正确内容吗?我会说用 1k 相同的重复字节模式来溢出它,并使用 gdb 或其他一些调试器来获取堆栈跟踪。
例如1。 (您需要写入数组 sizeof(int) 字节才能到达堆栈指针。)
void testFunction(int arg0){
char overflow[16] = {0};
char HUGE_ARRAY[10000] = {0};// what does the stack look like in this case? This giant block of memory should be on the stack AFTER your target array
//do something that allows the user to overflow the overflow array for w/e reason
}
ex2。 (您需要写入数组 sizeof(int) bytes + 10000 bytes 才能到达堆栈指针。)
void testFunction(int arg0){
char HUGE_ARRAY[10000] = {0};// what does the stack look like in this case? This giant block of memory should be on the stack BEFORE your target array.
char overflow[16] = {0};
//do something that allows the user to overflow the overflow array for w/e reason
}
如果您知道目标环境(例如,已知 sizeof int)、函数参数的数量和类型,以及当您输入要覆盖其堆栈指针的函数时弹出到堆栈上的局部变量的数量和类型,那么理论上您可以写入函数堆栈指针的确切字节。
或者,您可以通过将 0x00 值写入溢出缓冲区并每次增加超过 16 个字节的距离来解决这个问题,直到出现段错误。一旦你发现了段错误,你就找到了函数的堆栈指针。
一般来说,堆栈通过按以下顺序弹出以下内容来增长:返回地址 -> 函数参数 -> 局部变量。
就您的情况而言,您可以通过写入比您需要的更多的字节来测试它。 (只要在溢出弹出到堆栈之前将 <4k 分配给该函数堆栈,就可以工作)
for (offset = 0; offset < 1000; offset++){
(int)(*overflow + 4 + offset) = 0x1234B000;
}
GL。
关于c - 如何使用特定的返回地址溢出缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52824795/