2015-04-07 17 views
5

Yüklenen ve linux içinde çalıştırılan nesne dosyasının nasıl çalıştığını incelemek için en basit c kodunu, basit bir dosya adı.__libc_start_main @ plt nasıl çalışır?

int main(){} 

Ardından, nesne dosyası oluşturup nesne dosyasını metin dosyası olarak kaydediyorum. Birçok internet makaleden

$gcc ./simple.c 
$objdump -xD ./a.out > simple.text 

, o gcc dinamik benzeri plt @ _start, _init, __libc_start_main gibi başlatma işlevlerini yükleyin ve yakalayabiliriz. Bu yüzden, http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html'un yardım ettiği montaj kodumu okumaya başladım.

Burada montaj kodunun bir kısmı var.

080482e0 <[email protected]>: 
80482e0:  ff 25 10 a0 04 08  jmp *0x804a010 
80482e6:  68 08 00 00 00   push $0x8 
80482eb:  e9 d0 ff ff ff   jmp 80482c0 <_init+0x2c> 

Disassembly of section .text: 

080482f0 <_start>: 
80482f0:  31 ed     xor %ebp,%ebp 
80482f2:  5e      pop %esi 
80482f3:  89 e1     mov %esp,%ecx 
80482f5:  83 e4 f0    and $0xfffffff0,%esp 
80482f8:  50      push %eax 
80482f9:  54      push %esp 
80482fa:  52      push %edx 
80482fb:  68 70 84 04 08   push $0x8048470 
8048300:  68 00 84 04 08   push $0x8048400 
8048305:  51      push %ecx 
8048306:  56      push %esi 
8048307:  68 ed 83 04 08   push $0x80483ed 
804830c:  e8 cf ff ff ff   call 80482e0 <[email protected]> 
8048311:  f4      hlt 
8048312:  66 90     xchg %ax,%ax 
8048314:  66 90     xchg %ax,%ax 
8048316:  66 90     xchg %ax,%ax 
8048318:  66 90     xchg %ax,%ax 
804831a:  66 90     xchg %ax,%ax 
804831c:  66 90     xchg %ax,%ax 
804831e:  66 90     xchg %ax,%ax 

080483ed <main>: 
80483ed:  55      push %ebp 
80483ee:  89 e5     mov %esp,%ebp 
80483f0:  b8 00 00 00 00   mov $0x0,%eax 
80483f5:  5d      pop %ebp 
80483f6:  c3      ret 
80483f7:  66 90     xchg %ax,%ax 
80483f9:  66 90     xchg %ax,%ax 
80483fb:  66 90     xchg %ax,%ax 
80483fd:  66 90     xchg %ax,%ax 
80483ff:  90      nop 



... 

Disassembly of section .got: 

08049ffc <.got>: 
8049ffc:  00 00     add %al,(%eax) 
     ... 

Disassembly of section .got.plt: 

0804a000 <_GLOBAL_OFFSET_TABLE_>: 
804a000:  14 9f     adc $0x9f,%al 
804a002:  04 08     add $0x8,%al 
     ... 
804a00c:  d6      (bad) 
804a00d:  82      (bad) 
804a00e:  04 08     add $0x8,%al 
804a010:  e6 82     out %al,$0x82 
804a012:  04 08     add $0x8,%al 

Soruma;

0x804830c'de, 0x80482e0 çağrılıyor (zaten önceki yönergeleri aldım.).

0x80482e0'de, işlem 0x804a010'a atlar. 0x804a010 yılında

, talimat

... bekleyin < dışarı% arkadaşları, $ 0x82> olduğunu. sadece dışarı? % Al'de ne vardı ve 0x82 nerede? Bu hatta sıkıştım.

Lütfen yardım

....

* P.S.. Linux ve işletim sistemine yeni başlıyorum. Okul sınıfı tarafından işletim sistemi kavramlarını inceliyorum, ancak yine de uygun linux derleme dilini nasıl okuyacağımı bulamıyorum. Ben zaten intel işlemci kılavuzunu indirdim ama okumak için çok büyük. Bana benim için iyi malzeme bildiren var mı? Teşekkürler.

cevap

6
80482e0:  ff 25 10 a0 04 08  jmp *0x804a010 

Bu, "0x804a010'da saklanan 4 baytlık adrese erişme ve ona atla" anlamına gelir.

804a010:  e6 82     out %al,$0x82 
804a012:  04 08     add $0x8,%al 

olanlar 4 bayt

değil talimatları gibi, bir adres, 0x80482e6 olarak işlem görecektir.

80482e0:  ff 25 10 a0 04 08  jmp *0x804a010 
80482e6:  68 08 00 00 00   push $0x8 
80482eb:  e9 d0 ff ff ff   jmp 80482c0 <_init+0x2c> 

Bu nedenle, bize tam olarak bir yönerge aktarmış olan bir yönerge uyguladık. Bu noktada, muhtemelen bunun için iyi bir neden olup olmadığını merak ediyorsunuz.

Var. Bu tipik bir PLT/GOT uygulamasıdır. Bir diyagram dahil olmak üzere çok daha fazla ayrıntı Position Independent Code in shared libraries: The Procedure Linkage Table adresindedir.

__libc_start_main için gerçek kod, glibc paylaşılan bir kitaplıktadır.Kod çalıştırma sırasında nerede olacak derleyici ve derleme zamanı bağlayıcı bilmiyorum, dolayısıyla bunların derlenmiş programda sadece üç talimatlar içeren kısa __libc_start_main işlevini yerleştirin: belirtilen bir konuma

  • atlama 4 (veya 5, sizin gibi bağlı olarak 0'dan saymak veya 1'e) depo üzerine GOT
  • itme 8 $ giriş
  • rutin bir Resolverde

Eğer __libc_start_main ilk kez aradığınızda için atlama , çözümleyici kodu çalışır. Paylaşılan bir kütüphanede __libc_start_main'un gerçek yerini bulacaktır ve GOT'un 4. girişi bu adreste olacaktır. Programınız __libc_start_main'u tekrar ararsa, jmp *0x804a010 talimatı, programı doğrudan paylaşılan kütüphanedeki koda alacaktır.

Herkes benim için iyi malzeme bilgilendirebilir mi?

Wikibooks'taki x86 Assembly kitabının kitabı başlamak için tek bir yer olabilir.

+0

Ne güzel bir açıklama! Teşekkürler! – casamia

+0

'__libc_start_main' program ana çağırmak ve geri dönüş değeri ile çıkmak için bir sistem çağrısı yapmak zorunda sanıyorum. 'Hlt' (sys çıkışında temizleme ile bir gecikme/yarış olduğu durumlarda izin verdiğinden şüpheleniyorum) ihtiyacını genişletmek ister misiniz, 'hlt' ayrıcalıklı bir talimattır, sadece yasadışı tuzağa düşmek için bir noktadır oraya ulaşırsa talimat Xchg'nin kızağı ne olacak? –

+0

* xchg nop kızağı. –