Belirtilen yürütülebilir dosyanın dışındaki tek adımlı derleme kodunu gdb kullanmak, "geçerli işlevin sınırları bulunamıyor" hatasına neden oluyor


88

Gdb'nin hedef yürütülebilir dosyasının dışındayım ve bu hedefe karşılık gelen bir yığınım bile yok. Yine de tek adımda yapmak istiyorum, böylece montaj kodumda neler olup bittiğini doğrulayabilirim, çünkü x86 montajında ​​uzman değilim. Ne yazık ki, gdb bu basit derleme düzeyinde hata ayıklamayı yapmayı reddediyor. Uygun kesme noktasını ayarlamama ve durdurmama izin veriyor, ancak tek adımda ilerlemeye çalıştığım anda gdb "Geçerli işlevin sınırlarını bulamıyor" hatasını bildiriyor ve EIP değişmiyor.

Ek detaylar:

Makine kodu gcc asm ifadeleri tarafından oluşturuldu ve onu objdump -d'nin çıktısından çalıştırıldığı çekirdek bellek konumuna kopyaladım. Nesne kodumu yeniden konumlandırılmış bir adrese yüklemek için bir yükleyici kullanmanın basit bir yolunu kullanmaktan çekinmem, ancak yüklemenin bir çekirdek modülünde yapılması gerektiğini unutmayın.

Sanırım başka bir alternatif, gdb'ye verilecek sahte bir çekirdek modülü veya hata ayıklama bilgisi dosyası üretmek, bu alanın program kodu içinde olduğuna inanmasına neden olmak olabilir. gdb, çalıştırılabilir çekirdek üzerinde iyi çalışır.

(Gerçekten bilmek isteyenler için, bir VMware sanal makinesi içindeki Linux çekirdek veri alanına çalışma zamanında kod ekliyorum ve VMware Workstation'ın yerleşik gdb saplaması aracılığıyla çekirdeğin gdb uzaktan hata ayıklamasından hata ayıklama yapıyorum. Not Kernel yazmıyorum istismarlar; ben bir prototip yazan bir güvenlik mezunu öğrencisiyim.)

(Montajımın içindeki her talimat için bir kesme noktası belirleyebilirim. Bu işe yarıyor, ancak bir süre sonra oldukça zahmetli olacak çünkü x86 montaj talimatlarının boyutu değişiyor ve montajın konumu her yeniden başlattığımda değişiyor.)


Zeki ksplice.com çalışanları , "sahte" çekirdek modüllerini bir araya getirip bunları yükleyerek çekirdeğe veri ve kod enjekte eder. Ve eğer onlar yapabiliyorsa, sen neden yapamıyorsun? ;-)
ephemient

Yanıtlar:


118

Kullanabilirsiniz stepi veya nexti(ki kısaltılmış olabilir siya nida makine kodu ile adıma).


1
Vay. Geriye dönüp baktığımda stepi'yi nasıl unuttuğumu bilmiyorum. Sanırım gdb'nin kaynak kodu olmadığı için bu adımın montaj talimatlarına döneceğini varsaydım.
Paul

1
not: montaj programları için genellikle "ana parçayı kes", "çalıştır" yazamazsınız. Bunun yerine "düzen asm", "başlangıç" yazın. Bunu aşağıdaki mesajı okurken aldım ama bu yazıyı okuyan başka biri sabırlı olmayabilir.
Dmitry

1
@Dmitry start, tbreak mainardından gelen run(not: tbreakyerine break) ifadesine eşdeğerdir
Ruslan

154

Bunun yerine gdbkoş gdbtui. Ya çalıştırmak gdbile -tuianahtarı. Veya C-x C-agirdikten sonra tuşuna basın gdb. Artık GDB'nin TUI'sindesiniz modundasınız.

layout asmÜst pencere ekran montajını yapmak için girin - bu, aynı zamanda, hata ayıklama sırasında çerçeveleri değiştirebilir veya kaydırabilirsiniz, ancak bu, talimat işaretçinizi otomatik olarak takip edecektir. Basın C-x sSingleKey moduna girmek için run continue up down finishçok hızlı bir şekilde program sayesinde yürümeyi sağlayan tek bir tuş kısaltılmış vb.

   + ------------------------------------------------- -------------------------- +
B +> | 0x402670 <main>% r15'e basın |
   | 0x402672 <ana + 2> mov% edi,% r15d |
   | 0x402675 <ana + 5>% r14'e bas |
   | 0x402677 <ana + 7>% r13'e bas |
   | 0x402679 <ana + 9> mov% rsi,% r13 |
   | 0x40267c <ana + 12>% r12'ye bas |
   | 0x40267e <ana + 14>% rbp'ye bas |
   | 0x40267f <ana + 15>% rbx'e bas |
   | 0x402680 <ana + 16> $ 0x438,% rsp |
   | 0x402687 <ana + 23> mov (% rsi),% rdi |
   | 0x40268a <ana + 26> movq $ 0x402a10,0x400 (% rsp) |
   | 0x402696 <ana + 38> movq $ 0x0,0x408 (% rsp) |
   | 0x4026a2 <ana + 50> movq $ 0x402510,0x410 (% rsp) |
   + ------------------------------------------------- -------------------------- +
çocuk süreç 21518 Giriş: ana Satır: ?? PC: 0x402670
(gdb) dosya / opt / j64-602 / bin / jconsole
/Opt/j64-602/bin/jconsole...done'dan semboller okunuyor.
(hata ayıklama sembolü bulunamadı) ... bitti.
(gdb) düzen asm
(gdb) başlangıç
(gdb)

26

Burada yapabileceğiniz en yararlı şey display/i $pc, daha önce stepiR Samuel Klatchko'nun cevabında önerildiği gibi kullanmadan önce . Bu, gdb'ye, her seferinde komut istemi yazdırmadan hemen önce mevcut talimatı sökmesini söyler; sonra stepikomutu tekrarlamak için Enter tuşuna basmaya devam edebilirsiniz .

(Görmek fazla ayrıntı için başka bir soruya verdiğim cevaba - bu sorunun bağlamı farklıydı, ancak ilke aynıydı.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.