对于我的学校,我正在做一个安全项目。第一个陡峭的是二进制,找到c代码源。
我在这里遇到一个问题,这是来自GDB学校二进制文件的asm代码: 主:
0x0804853f <+0>: push ebp
0x08048540 <+1>: mov ebp,esp
0x08048542 <+3>: and esp,0xfffffff0
0x08048545 <+6>: call 0x80484d4 <p>
0x0804854a <+11>: leave
0x0804854b <+12>: ret
func P:
0x080484d4 <+0>: push ebp
0x080484d5 <+1>: mov ebp,esp
0x080484d7 <+3>: sub esp,0x68
0x080484da <+6>: mov eax,ds:0x8049860
0x080484df <+11>: mov DWORD PTR [esp],eax
0x080484e2 <+14>: call 0x80483b0 <fflush@plt>
0x080484e7 <+19>: lea eax,[ebp-0x4c]
0x080484ea <+22>: mov DWORD PTR [esp],eax
0x080484ed <+25>: call 0x80483c0 <gets@plt>
0x080484f2 <+30>: mov eax,DWORD PTR [ebp+0x4]
0x080484f5 <+33>: mov DWORD PTR [ebp-0xc],eax
0x080484f8 <+36>: mov eax,DWORD PTR [ebp-0xc]
0x080484fb <+39>: and eax,0xb0000000
0x08048500 <+44>: cmp eax,0xb0000000
0x08048505 <+49>: jne 0x8048527 <p+83>
0x08048507 <+51>: mov eax,0x8048620
0x0804850c <+56>: mov edx,DWORD PTR [ebp-0xc]
0x0804850f <+59>: mov DWORD PTR [esp+0x4],edx
0x08048513 <+63>: mov DWORD PTR [esp],eax
0x08048516 <+66>: call 0x80483a0 <printf@plt>
0x0804851b <+71>: mov DWORD PTR [esp],0x1
0x08048522 <+78>: call 0x80483d0 <_exit@plt>
0x08048527 <+83>: lea eax,[ebp-0x4c]
0x0804852a <+86>: mov DWORD PTR [esp],eax
0x0804852d <+89>: call 0x80483f0 <puts@plt>
0x08048532 <+94>: lea eax,[ebp-0x4c]
0x08048535 <+97>: mov DWORD PTR [esp],eax
0x08048538 <+100>: call 0x80483e0 <strdup@plt>
0x0804853d <+105>: leave
0x0804853e <+106>: ret
我不知道 p + 30 这一行是因为 ebp + 4 是指函数P堆栈之前的变量,但 P没有参数 ...
你知道这个变量来自哪里?我怎么能找到她? Actualy这是我的source.c接近获取thx是错误的:)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//gcc -fno-stack-protector -z execstack -Wl,-z,norelro -m32 source.c
void p(void)
{
char str[0x40]
void *ptr;
fflush(stdin);
ptr = gets(str);;
if (((unsigned int)ptr & 0xb0000000) == 0xb0000000)
{
printf("(%p)\n", ptr);
exit(0x1);
}
puts(str);
strdup(str);
}
int main(int argc, char **argv)
{
p();
}
答案 0 :(得分:2)
制作堆栈帧后,[ebp+0x4]
是返回地址。在函数输入时,args从[esp+4]
开始,在您按[esp+8]
后变为ebp
。因此,对于堆栈帧,第一个arg将位于[ebp+8]
。
要让编译器为p
发出类似asm的内容,您需要使用类似GNU C __builtin_return_address
扩展名的内容。
#include <stdint.h>
void foo(void) {
uintptr_t ptr = (uintptr_t)__builtin_return_address(0);
// 0 means current function's ret addr.
// higher numbers backtrace up the call stack.
}
还有__builtin_frame_address
...