Tôi đang chạy Linux trên i386: x86_64.Tôi đã viết một đoạn mã c và tôi đã tháo rời nó cũng như đọc sổ đăng ký để hiểu cách chương trình hoạt động trong hội đồng. Dưới đây là chương trình c của tôi mà tôi đã viết.Tại sao địa chỉ bộ nhớ này có giá trị ngẫu nhiên?
#include <unistd.h>
#include <string.h>
#include <stdio.h>
char *string_in = "Did not work";
int test(char *this){
char sum_buf[6];
strncpy(sum_buf,this,32);
return 0;
}
int hello(){
printf("hello man");
string_in = "If this triggered, it means our shell code is working\n";
while(1){
printf("Worked!");
}
return 0;
}
int main(int argc, void **argv){
test("\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x28\x06\x06\x40\x00\x00\x00\x00\x00");//6f 73
printf("My string is %s",string_in);
return 0;
}
Đoạn mã mà tôi đã kiểm tra là hàm kiểm tra. Khi tôi tháo rời đầu ra chức năng thử nghiệm của tôi, tôi nhận được ...
0x00000000004005b4 <+0>: push %rbp
0x00000000004005b5 <+1>: mov %rsp,%rbp
0x00000000004005b8 <+4>: sub $0x20,%rsp
0x00000000004005bc <+8>: mov %rdi,-0x18(%rbp)
0x00000000004005c0 <+12>: mov %fs:0x28,%rax
=> 0x00000000004005c9 <+21>: mov %rax,-0x8(%rbp)
0x00000000004005cd <+25>: xor %eax,%eax
0x00000000004005cf <+27>: mov -0x18(%rbp),%rcx
0x00000000004005d3 <+31>: lea -0x10(%rbp),%rax
0x00000000004005d7 <+35>: mov $0x20,%edx
0x00000000004005dc <+40>: mov %rcx,%rsi
0x00000000004005df <+43>: mov %rax,%rdi
0x00000000004005e2 <+46>: callq 0x400490 <[email protected]>
0x00000000004005e7 <+51>: mov $0x0,%eax
0x00000000004005ec <+56>: mov -0x8(%rbp),%rdx
0x00000000004005f0 <+60>: xor %fs:0x28,%rdx
0x00000000004005f9 <+69>: je 0x400600 <test+76>
0x00000000004005fb <+71>: callq 0x4004a0 <[email protected]>
0x0000000000400600 <+76>: leaveq
0x0000000000400601 <+77>: retq
Bây giờ sở thích của tôi nằm ở dòng < 12>. Từ sự hiểu biết của tôi rằng hướng dẫn là nói cho máy tính để lấy 28 bit đầu tiên của phân khúc đăng ký %fs
và đặt nó vào %rax
ắc quy của tôi. Điều gì làm phiền tôi là trước và sau khi dòng này được thực thi, tôi đọc thanh ghi %fs
qua p/x $fs
hiển thị giá trị bằng không (ngay cả trong suốt chương trình) và do đó %rax
phải bằng 0. Tuy nhiên %rax
không hiển thị số không sau khi lệnh đã được thực hiện. Trong thực tế, kết quả là một số ngẫu nhiên. Số ngẫu nhiên này sau đó được đặt 8 byte trước %rbp
(vì nó là ít endian) và sau đó kiểm tra lại trong trường hợp có một bộ đệm trên dòng chảy đã ghi đè không gian đó.
Điều tôi muốn biết là những gì mov %fs:0x28,%rax
thực sự đang thực hiện. Tôi đã hiểu nó phải không? Tại sao tôi đọc số không cho %fs
khi ở trong p/x $fs
và làm cách nào để đọc giá trị chính xác?
Ok, điều đó có ý nghĩa. Làm thế nào tôi có thể đọc địa chỉ và giá trị này với gdb? –
Cách đơn giản nhất là xem nội dung của thanh ghi RAX trực tiếp sau thao tác MOV. – Jason