I386 üzerinde linux çalıştırıyorum: x86_64.Ç bir parça kod yazdım ve programın nasıl çalıştığını anlamak için yazmaçları okuduğum kadar bunları da parçalarına ayırdım. Aşağıda yazdığım programım var.Bu bellek adresi neden rasgele bir değere sahip?
#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;
}
İncelemekte olduğum kodumun parçası test işlevidir. Ben olsun çıktı benim test fonksiyonunu ... sökerken
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
Şimdi benim ilgi hattı < 12> yatıyor. Anladığım kadarıyla, bu talimatın, bilgisayara
%fs
bölümünün ilk 28 bitini almasını ve
%rax
akümülatörüme koymasını söylüyorum. Beni rahatsız eden şey, bu satırın uygulanmasından önce ve sonra,
%fs
kayıt numarasını
p/x $fs
üzerinden okuyarak sıfır değerini (program boyunca bile) gösterir ve böylece
%rax
sıfır olmalıdır. Ancak, talimat yürütüldükten sonra
%rax
sıfır göstermez. Aslında sonuç ne rasgele bir sayıdır. Bu rasgele sayı daha sonra
%rbp
'dan önce 8 byte yerleştirilir (küçük endian olduğu için) ve daha sonra bu alanın üzerine yazılan akış üzerinde bir tampon olması durumunda tekrar kontrol edilir.
Bilmek istediklerim, mov %fs:0x28,%rax
'un gerçekten ne yaptığıdır. Bunu doğru mu anladım? p/x $fs
numaralı telefondan %fs
için neden sıfır okuyorum ve doğru değeri nasıl okuyacağım?
Tamam, bu mantıklı. Bu adresi ve değeri gdb ile nasıl okuyabilirim? –
En basit yol, MOV operasyonundan sonra RAX kaydının içeriğine doğrudan bakmaktır. – Jason