$ checksec note2
Arch: amd64-64-little
RELRO: Partial RELRO # (.plt.got)段依然可写,只是(.got)段不在可写。
Stack: Canary found
NX: NX enabled # 栈不可执行
PIE: No PIE (0x400000)# 未开启地址随机化 patchelf后基址可能会改变0x3ff000 但是还是用0x400000来做即可
$ file note2
note2: ELF 64-bit LSB executable, x86-64, version 1(SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=46dca2e49f923813b316f12858e7e0f42e4a82c3, stripped
# 运行测试
$ ./note2
Input your name:
admin
Input your address:
0x00400000
1.New note
2.Show note
3.Edit note
4.Delete note
5.Quit
# New note
option--->>1
Input the length of the note content:(less than 128)10
Input the note content:
1234567890
note add success, the id is 0# Show note
option--->>2
Input the id of the note:
0
Content is 123456789# Edit note
option--->>3
Input the id of the note:
0do you want to overwrite or append?[1.overwrite/2.append]1
TheNewContents:123
Edit note success!# Delete note
option--->>4
Input the id of the note:
0
delete note success!
(三)IDA逆向分析
详见note2.i64文件
void __fastcall main(int a1, char **a2, char **a3)
{
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
alarm(0x3Cu); // 当程序执行到 alarm(60); 这行代码时,会设置一个定时器,1 分钟后发送 SIGALRM 信号给程序
puts("Input your name:"); // ".bss" 段是指 "Block Started by Symbol" 段,通常用于声明未初始化的全局或静态变量
read_input(name, 64LL, 10); // .bss:00000000006020E0 name db 40h dup(?) ; DATA XREF: main+7C↑o
puts("Input your address:");
read_input(address, 96LL, 10); // .bss:0000000000602180 address db 60h dup(?) ; DATA XREF: main+9A↑o
// 0x10是换行符
while ( 1 )
{
switch ( menu() )
{
case 1:
New_note(); // n快捷键修改函数名 /快捷键添加注释
// malloc chunk
break;
case 2:
Show_note();
break;
case 3:
Edit_note();
break;
case 4:
Delete_note(); // free chunk
break;
case 5:
puts("Bye~");
exit(0);
case 6:
exit(0);
default:
continue;
}
}
}
// 改成void类型
void __fastcall New_note()
{
unsigned int v0; // eax
unsigned int size; // [rsp+4h] [rbp-Ch]
char *malloc_ptr; // [rsp+8h] [rbp-8h]
if ( (unsigned int)note_count <= 3 )
{
puts("Input the length of the note content:(less than 128)");
size = get_number();
if ( size <= 0x80 )
{
malloc_ptr = (char *)malloc(size);
puts("Input the note content:");
read_input(malloc_ptr, size, 10); // 通过read_input溢出覆盖nextchunk
strip_baifenhao(malloc_ptr);
ptr[note_count] = malloc_ptr; // 这里应该是数组,将void *ptr改为void *ptr[]
sizes[note_count] = size;
v0 = note_count++;
printf("note add success, the id is %d\n", v0);
}
else
{
puts("Too long");
}
}
else
{
puts("note lists are full");
}
}
void __fastcall Show_note()
{
int v0; // [rsp+Ch] [rbp-4h]
puts("Input the id of the note:");
v0 = get_number();
if ( v0 >= 0 && v0 <= 3 )
{
if ( ptr[v0] )
printf("Content is %s\n", (const char *)ptr[v0]);
}
}