当我只有可执行文件时,我尝试实现堆栈粉碎。 我使用objdump获取此源代码的汇编代码:
#include<stdio.h>
#include<string.h>
void func(char *str) {
char buffer[24];
int *ret;
strcpy(buffer,str);
}
int main(int argc, char **argv) {
int x;
x = 0;
func(argv[1]);
x = 1;
printf("%d\n”,x);
}
在运行时./a,out(value)....我需要在这里插入(值)我将NOP插入堆栈位置并且(value)的最后一部分是我的下一个地址指令。 在到达包含fun()的返回地址的位置之前,我有40个字节。
08048444 <func>:
8048444: 55 push %ebp
8048445: 89 e5 mov %esp,%ebp
8048447: 83 ec 48 sub $0x48,%esp
804844a: 8b 45 08 mov 0x8(%ebp),%eax
804844d: 89 45 d4 mov %eax,-0x2c(%ebp)
8048450: 65 a1 14 00 00 00 mov %gs:0x14,%eax
8048456: 89 45 f4 mov %eax,-0xc(%ebp)
8048459: 31 c0 xor %eax,%eax
804845b: 8b 45 d4 mov -0x2c(%ebp),%eax
804845e: 89 44 24 04 mov %eax,0x4(%esp)
8048462: 8d 45 dc lea -0x24(%ebp),%eax
8048465: 89 04 24 mov %eax,(%esp)
8048468: e8 eb fe ff ff call 8048358 <strcpy@plt>
804846d: 8b 45 f4 mov -0xc(%ebp),%eax
8048470: 65 33 05 14 00 00 00 xor %gs:0x14,%eax
8048477: 74 05 je 804847e <func+0x3a>
8048479: e8 fa fe ff ff call 8048378 <__stack_chk_fail@plt>
804847e: c9 leave
804847f: c3 ret
08048480 <main>:
8048480: 55 push %ebp
8048481: 89 e5 mov %esp,%ebp
8048483: 83 e4 f0 and $0xfffffff0,%esp
8048486: 83 ec 20 sub $0x20,%esp
8048489: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp)
8048490: 00
8048491: 8b 45 0c mov 0xc(%ebp),%eax
8048494: 83 c0 04 add $0x4,%eax
8048497: 8b 00 mov (%eax),%eax
8048499: 89 04 24 mov %eax,(%esp)
804849c: e8 a3 ff ff ff call 8048444 <func>
80484a1: c7 44 24 1c 01 00 00 movl $0x1,0x1c(%esp)
80484a8: 00
80484a9: b8 90 85 04 08 mov $0x8048590,%eax
80484ae: 8b 54 24 1c mov 0x1c(%esp),%edx
80484b2: 89 54 24 04 mov %edx,0x4(%esp)
80484b6: 89 04 24 mov %eax,(%esp)
80484b9: e8 aa fe ff ff call 8048368 <printf@plt>
80484be: b8 00 00 00 00 mov $0x0,%eax
80484c3: c9 leave
80484c4: c3 ret
80484c5: 90 nop
80484c6: 90 nop
问题如果我插入00考虑为(31)ASCII。如何插入十六进制值。
......我希望阙清楚
objdump -w -Mintel:
08048444 <func>:
8048444: 55 push ebp
8048445: 89 e5 mov ebp,esp
8048447: 83 ec 48 sub esp,0x48
804844a: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
804844d: 89 45 d4 mov DWORD PTR [ebp-0x2c],eax
8048450: 65 a1 14 00 00 00 mov eax,gs:0x14
8048456: 89 45 f4 mov DWORD PTR [ebp-0xc],eax
8048459: 31 c0 xor eax,eax
804845b: 8b 45 d4 mov eax,DWORD PTR [ebp-0x2c]
804845e: 89 44 24 04 mov DWORD PTR [esp+0x4],eax
8048462: 8d 45 dc lea eax,[ebp-0x24]
8048465: 89 04 24 mov DWORD PTR [esp],eax
8048468: e8 eb fe ff ff call 8048358 <strcpy@plt>
804846d: 8b 45 f4 mov eax,DWORD PTR [ebp-0xc]
8048470: 65 33 05 14 00 00 00 xor eax,DWORD PTR gs:0x14
8048477: 74 05 je 804847e <func+0x3a>
8048479: e8 fa fe ff ff call 8048378 <__stack_chk_fail@plt>
804847e: c9 leave
804847f: c3 ret
08048480 <main>:
8048480: 55 push ebp
8048481: 89 e5 mov ebp,esp
8048483: 83 e4 f0 and esp,0xfffffff0
8048486: 83 ec 20 sub esp,0x20
8048489: c7 44 24 1c 00 00 00 00 mov DWORD PTR [esp+0x1c],0x0
8048491: 8b 45 0c mov eax,DWORD PTR [ebp+0xc]
8048494: 83 c0 04 add eax,0x4
8048497: 8b 00 mov eax,DWORD PTR [eax]
8048499: 89 04 24 mov DWORD PTR [esp],eax
804849c: e8 a3 ff ff ff call 8048444 <func>
80484a1: c7 44 24 1c 01 00 00 00 mov DWORD PTR [esp+0x1c],0x1
80484a9: b8 90 85 04 08 mov eax,0x8048590
80484ae: 8b 54 24 1c mov edx,DWORD PTR [esp+0x1c]
80484b2: 89 54 24 04 mov DWORD PTR [esp+0x4],edx
80484b6: 89 04 24 mov DWORD PTR [esp],eax
80484b9: e8 aa fe ff ff call 8048368 <printf@plt>
80484be: b8 00 00 00 00 mov eax,0x0`
答案 0 :(得分:1)
您可以使用./a.out $(perl -e "print '\x97';")
并将\ x97替换为您要使用的十六进制。
答案 1 :(得分:1)
如果是C,字符串字符的结尾为0x00
(如果您愿意,则为'\0'
)。因此,如果你的字符串长度恰好为39个字符,那么第40个字符将为零 - 它将在正确的位置。除非使用strcpy
以外的函数(例如,memcpy
),否则无法在C字符串中复制多个零。但如果你依靠argv[1]
作为你的零的来源,那么这是唯一的方法。你当然可以在处理它之前从字符串中减去一些东西 - 如果你愿意,你可以做
L = strlen(argv[1]);
for(int ii = 0; ii < L; ii++) if(argv[1][ii] == '0') argv[1][ii] = '\0';
这会将每个'0'
变为'\0'
。但是,你不能做一个简单的strcpy
,你必须做memcpy
。
你必须希望你不会因为写入你不拥有的记忆而陷入错误......