Rumah Tutorial sistem LINUX Terokai teknik pengendalian berubah-ubah dalam penyahpepijat Linux!

Terokai teknik pengendalian berubah-ubah dalam penyahpepijat Linux!

Jan 15, 2024 pm 11:09 PM
linux tutorial linux Topi Merah sistem linux arahan linux pensijilan linux linux topi merah video linux

Pengenalan Pembolehubah adalah licik. Kadang-kadang mereka akan dengan senang hati duduk dalam daftar, hanya untuk berakhir di timbunan sebaik sahaja mereka berpusing. Untuk tujuan pengoptimuman, pengkompil boleh membuangnya keluar dari tetingkap sepenuhnya. Tidak kira bagaimana pembolehubah bergerak dalam ingatan, kita memerlukan beberapa cara untuk menjejak dan memanipulasinya dalam penyahpepijat. Artikel ini akan mengajar anda cara mengendalikan pembolehubah dalam penyahpepijat dan menunjukkan pelaksanaan mudah menggunakan libelfin.
Indeks artikel bersiri
  1. Sediakan persekitaran
  2. Titik putus
  3. Daftar dan Memori
  4. DIRI dan KEDIRI
  5. Kod sumber dan isyarat
  6. Pelaksanaan langkah demi langkah pada tahap kod sumber
  7. Titik putus tahap sumber
  8. Peluasan tindanan
  9. Kendalikan pembolehubah
  10. Topik Lanjutan

Sebelum bermula, sila pastikan anda menggunakan versi libelfin fbreg di cawangan saya. Ini mengandungi beberapa penggodaman untuk menyokong mendapatkan alamat asas bingkai tindanan semasa dan menilai senarai lokasi, tidak satu pun daripadanya disediakan oleh libelfin asli. Anda mungkin perlu menghantar parameter -gdwarf-2 kepada GCC untuk menjana mesej DWARF yang serasi. Tetapi sebelum melaksanakannya, saya akan memperincikan cara pengekodan kedudukan berfungsi dalam spesifikasi DWARF 5 terkini. Jika anda ingin mengetahui lebih lanjut, anda boleh mendapatkan standard di sini.

Lokasi kerdil

Lokasi pembolehubah dalam ingatan pada masa tertentu dikodkan dalam mesej DWARF menggunakan atribut DW_AT_location. Perihalan lokasi boleh menjadi perihalan lokasi tunggal, perihalan lokasi komposit atau senarai lokasi.

  • Perihalan kedudukan mudah: Menerangkan kedudukan bahagian bersebelahan (biasanya semua bahagian) objek. Penerangan lokasi yang ringkas boleh menerangkan lokasi dalam memori boleh alamat atau daftar, atau kekurangannya (dengan atau tanpa nilai yang diketahui). Contohnya, DW_OP_fbreg -32: Keseluruhan pembolehubah tersimpan - 32 bait bermula dari pangkalan bingkai tindanan.
  • Perihalan lokasi komposit: Menggambarkan objek dari segi serpihan, setiap objek boleh terkandung dalam bahagian daftar atau disimpan di lokasi memori bebas daripada serpihan lain. Contohnya, DW_OP_reg3 DW_OP_piece 4 DW_OP_reg10 DW_OP_piece 2: Empat bait pertama berada dalam daftar 3 dan dua bait terakhir berada dalam pembolehubah dalam daftar 10.
  • Senarai Kedudukan: Menerangkan objek yang mempunyai hayat terhad atau menukar lokasi semasa hayatnya. contohnya:
      • [ 0]DW_OP_reg0
      • [ 1]DW_OP_reg3
      • [ 2]DW_OP_reg2
  • Pembolehubah yang lokasinya dialihkan antara daftar berdasarkan nilai semasa pembilang program.

DW_AT_location dikodkan dalam tiga cara berbeza bergantung pada jenis perihalan lokasi. exprloc mengekod huraian kedudukan mudah dan komposit. Ia terdiri daripada panjang bait diikuti dengan ungkapan DWARF atau perihalan lokasi. Senarai lokasi yang dikodkan untuk loclist dan loclistptr, yang menyediakan indeks atau offset dalam bahagian .debug_loclists, yang menerangkan senarai lokasi sebenar.

Ekspresi kerdil

Gunakan ungkapan DWARF untuk mengira kedudukan sebenar pembolehubah. Ini termasuk satu siri operasi yang memanipulasi nilai tindanan. Terdapat banyak operasi DWARF yang tersedia, jadi saya tidak akan menerangkannya secara terperinci. Sebaliknya, saya akan memberikan beberapa contoh daripada setiap ungkapan untuk memberi anda sesuatu untuk diusahakan. Juga, jangan takut tentang perkara ini; libelfin akan menangani semua kerumitan ini untuk kami.

  • Pengekodan literal
    • DW_OP_lit0, DW_OP_lit1...DW_OP_lit31
      • Tolak huruf ke dalam tindanan
    • DW_OP_addr
      • Tolak operan alamat pada tindanan
    • DW_OP_constu
      • Tolak nilai yang tidak ditandatangani pada tindanan
  • Nilai daftar
    • DW_OP_fbreg
      • Tolak nilai yang terdapat pada dasar bingkai tindanan, diimbangi oleh nilai yang diberikan
    • DW_OP_breg0, DW_OP_breg1... DW_OP_breg31
      • Tolak kandungan daftar yang diberikan ditambah dengan offset yang diberikan ke dalam tindanan
  • Operasi tindanan
    • DW_OP_dup
      • Salin nilai di bahagian atas tindanan
    • DW_OP_deref
      • Anggap bahagian atas timbunan sebagai alamat memori dan gantikannya dengan kandungan alamat itu
  • Operasi aritmetik dan logik
    • DW_OP_dan
      • Letakkan dua nilai di bahagian atas timbunan dan tolak logiknya DAN
    • DW_OP_plus
      • Sama seperti DW_OP_and, tetapi menambah nilai
  • Kawal operasi aliran
    • DW_OP_le, DW_OP_eq, DW_OP_gt, dsb.
      • Pop dua nilai pertama, bandingkannya dan tolak 1 jika keadaannya benar, 0 sebaliknya
    • DW_OP_bra
      • Cawangan bersyarat: Jika bahagian atas tindanan bukan 0, langkau ke hadapan atau ke belakang dalam ungkapan melalui offset
  • Masukkan penukaran
    • DW_OP_convert
      • Tukar nilai di bahagian atas tindanan kepada jenis yang berbeza, yang diterangkan oleh entri maklumat DWARF pada offset yang diberikan
  • Operasi khas
    • DW_OP_nop
      • Buat apa-apa!
Jenis kerdil

Perwakilan jenis DWARF perlu cukup berkuasa untuk menyediakan perwakilan pembolehubah yang berguna untuk menyahpepijat pengguna. Pengguna selalunya mahu dapat menyahpepijat pada peringkat aplikasi dan bukannya pada peringkat mesin, dan mereka perlu memahami perkara yang dilakukan oleh pembolehubah mereka.

Jenis DWARF dikodkan dalam DIE bersama-sama dengan kebanyakan maklumat penyahpepijatan yang lain. Mereka boleh mempunyai sifat yang menunjukkan nama mereka, pengekodan, saiz, bait, dsb. Pelbagai teg jenis tersedia untuk mewakili penunjuk, tatasusunan, struktur, typedef dan apa-apa lagi yang mungkin anda lihat dalam program C atau C++.

Ambil struktur mudah ini sebagai contoh:

struct test{
int i;
float j;
int k[42];
test* next;
};
Salin selepas log masuk

Induk MATI struktur ini adalah seperti ini:

< 1><0x0000002a> DW_TAG_structure_type
DW_AT_name "test"
DW_AT_byte_size 0x000000b8
DW_AT_decl_file 0x00000001 test.cpp
DW_AT_decl_line 0x00000001
Salin selepas log masuk

Apa yang dinyatakan di atas ialah kami mempunyai struktur yang dipanggil ujian, dengan saiz 0xb8, diisytiharkan pada baris 1 test.cpp. Seterusnya terdapat beberapa sub-DIE yang menggambarkan ahli.

< 2><0x00000032> DW_TAG_member
DW_AT_name "i"
DW_AT_type <0x00000063>
DW_AT_decl_file 0x00000001 test.cpp
DW_AT_decl_line 0x00000002
DW_AT_data_member_location 0
< 2><0x0000003e> DW_TAG_member
DW_AT_name "j"
DW_AT_type <0x0000006a>
DW_AT_decl_file 0x00000001 test.cpp
DW_AT_decl_line 0x00000003
DW_AT_data_member_location 4
< 2><0x0000004a> DW_TAG_member
DW_AT_name "k"
DW_AT_type <0x00000071>
DW_AT_decl_file 0x00000001 test.cpp
DW_AT_decl_line 0x00000004
DW_AT_data_member_location 8
< 2><0x00000056> DW_TAG_member
DW_AT_name "next"
DW_AT_type <0x00000084>
DW_AT_decl_file 0x00000001 test.cpp
DW_AT_decl_line 0x00000005
DW_AT_data_member_location 176(as signed = -80)
Salin selepas log masuk

Setiap ahli mempunyai nama, jenis (iaitu offset DIE), fail dan baris pengisytiharan, dan ofset bait kepada struktur di mana ahlinya berada. Titik jenisnya adalah seperti berikut.

< 1><0x00000063> DW_TAG_base_type
DW_AT_name "int"
DW_AT_encoding DW_ATE_signed
DW_AT_byte_size 0x00000004
< 1><0x0000006a> DW_TAG_base_type
DW_AT_name "float"
DW_AT_encoding DW_ATE_float
DW_AT_byte_size 0x00000004
< 1><0x00000071> DW_TAG_array_type
DW_AT_type <0x00000063>
< 2><0x00000076> DW_TAG_subrange_type
DW_AT_type <0x0000007d>
DW_AT_count 0x0000002a
< 1><0x0000007d> DW_TAG_base_type
DW_AT_name "sizetype"
DW_AT_byte_size 0x00000008
DW_AT_encoding DW_ATE_unsigned
< 1><0x00000084> DW_TAG_pointer_type
DW_AT_type <0x0000002a>
Salin selepas log masuk

Seperti yang anda lihat, int pada komputer riba saya ialah jenis integer bertanda 4-bait dan apungan ialah nombor titik terapung 4-bait. Jenis tatasusunan integer mempunyai elemen 2a dengan menunjuk ke taip int sebagai jenis elemen dan jenis saiz (anggap ia sebagai size_t) sebagai jenis indeks. Jenis ujian * ialah DW_TAG_pointer_type, yang merujuk kepada ujian DIE.

Melaksanakan pembaca pembolehubah mudah

Seperti yang dinyatakan di atas, libelfin akan mengendalikan kebanyakan kerumitan untuk kita. Walau bagaimanapun, ia tidak melaksanakan semua kaedah untuk mewakili kedudukan berubah, dan pengendalian ini dalam kod kami akan menjadi sangat rumit. Oleh itu, saya kini memilih untuk menyokong exprloc sahaja. Sila tambah sokongan untuk lebih banyak jenis ungkapan seperti yang diperlukan. Jika anda benar-benar berani, sila serahkan tampung kepada libelfin untuk membantu melengkapkan sokongan yang diperlukan!

Mengendalikan pembolehubah terutamanya melibatkan pengesanan bahagian yang berbeza dalam ingatan atau daftar, dan membaca atau menulis adalah sama seperti sebelumnya. Untuk memastikan perkara mudah, saya hanya akan memberitahu anda cara melaksanakan pembacaan.

Mula-mula kami perlu memberitahu libelfin cara membaca daftar daripada proses kami. Kami mencipta kelas yang mewarisi daripada expr_context dan menggunakan ptrace untuk mengendalikan segala-galanya:

class ptrace_expr_context : public dwarf::expr_context {
public:
ptrace_expr_context (pid_t pid) : m_pid{pid} {}
dwarf::taddr reg (unsigned regnum) override {
return get_register_value_from_dwarf_register(m_pid, regnum);
}
dwarf::taddr pc() override {
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, m_pid, nullptr, &regs);
return regs.rip;
}
dwarf::taddr deref_size (dwarf::taddr address, unsigned size) override {
//TODO take into account size
return ptrace(PTRACE_PEEKDATA, m_pid, address, nullptr);
}
private:
pid_t m_pid;
};
Salin selepas log masuk

Bacaan akan dikendalikan oleh fungsi read_variables dalam kelas debugger kami:

void debugger::read_variables() {
using namespace dwarf;
auto func = get_function_from_pc(get_pc());
//...
}
Salin selepas log masuk

Perkara pertama yang kita lakukan di atas ialah mencari fungsi yang kita ada sekarang, maka kita perlu mengulangi entri dalam fungsi itu untuk mencari pembolehubah:

for (const auto& die : func) {
if (die.tag == DW_TAG::variable) {
//...
}
}
Salin selepas log masuk

Kami mendapat maklumat lokasi dengan mencari entri DW_AT_location dalam DIE:

auto loc_val = die[DW_AT::location];
Salin selepas log masuk

Kemudian kami pastikan ia exprloc dan minta libelfin menilai ungkapan kami:

if (loc_val.get_type() == value::type::exprloc) {
ptrace_expr_context context {m_pid};
auto result = loc_val.as_exprloc().evaluate(&context);
Salin selepas log masuk

Sekarang kita telah menilai ungkapan, kita perlu membaca kandungan pembolehubah. Ia boleh berada dalam ingatan atau daftar, jadi kami akan mengendalikan kedua-dua kes:

switch (result.location_type) {
case expr_result::type::address:
{
auto value = read_memory(result.value);
std::cout << at_name(die) << " (0x" << std::hex << result.value << ") = "
<< value << std::endl;
break;
}
case expr_result::type::reg:
{
auto value = get_register_value_from_dwarf_register(m_pid, result.value);
std::cout << at_name(die) << " (reg " << result.value << ") = "
<< value << std::endl;
break;
}
default:
throw std::runtime_error{"Unhandled variable location"};
}
Salin selepas log masuk

Anda boleh melihat bahawa berdasarkan jenis pembolehubah, saya mencetak nilai tanpa penjelasan. Mudah-mudahan dengan kod ini anda dapat melihat bagaimana terdapat sokongan untuk menulis pembolehubah, atau mencari pembolehubah dengan nama tertentu.

Akhirnya kami boleh menambah ini pada penghurai arahan kami:

else if(is_prefix(command, "variables")) {
read_variables();
}
Salin selepas log masuk
Ujinya

Tulis beberapa fungsi kecil dengan beberapa pembolehubah, susunkannya tanpa pengoptimuman dan dengan maklumat nyahpepijat, kemudian lihat jika anda boleh membaca nilai pembolehubah itu. Cuba tulis ke alamat memori tempat pembolehubah disimpan dan lihat bagaimana program mengubah tingkah laku.

Sudah ada sembilan artikel, dan yang terakhir tinggal! Lain kali saya akan membincangkan beberapa konsep yang lebih maju yang mungkin menarik minat anda. Kini anda boleh mencari kod untuk siaran ini di sini.

Atas ialah kandungan terperinci Terokai teknik pengendalian berubah-ubah dalam penyahpepijat Linux!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Empat cara untuk melaksanakan multithreading dalam bahasa c Empat cara untuk melaksanakan multithreading dalam bahasa c Apr 03, 2025 pm 03:00 PM

Multithreading dalam bahasa dapat meningkatkan kecekapan program. Terdapat empat cara utama untuk melaksanakan multithreading dalam bahasa C: Buat proses bebas: Buat pelbagai proses berjalan secara bebas, setiap proses mempunyai ruang ingatan sendiri. Pseudo-Multithreading: Buat pelbagai aliran pelaksanaan dalam proses yang berkongsi ruang memori yang sama dan laksanakan secara bergantian. Perpustakaan multi-threaded: Gunakan perpustakaan berbilang threaded seperti PTHREADS untuk membuat dan mengurus benang, menyediakan fungsi operasi benang yang kaya. Coroutine: Pelaksanaan pelbagai threaded ringan yang membahagikan tugas menjadi subtask kecil dan melaksanakannya pada gilirannya.

Cara Membuka Web.xml Cara Membuka Web.xml Apr 03, 2025 am 06:51 AM

Untuk membuka fail web.xml, anda boleh menggunakan kaedah berikut: Gunakan editor teks (seperti Notepad atau TextEdit) untuk mengedit arahan menggunakan persekitaran pembangunan bersepadu (seperti Eclipse atau NetBeans) (Windows: Notepad Web.xml; Mac/Linux: Open -A -A TextEdit Web.xml)

Bolehkah penterjemah Python dipadam dalam sistem Linux? Bolehkah penterjemah Python dipadam dalam sistem Linux? Apr 02, 2025 am 07:00 AM

Mengenai masalah menghapuskan penterjemah python yang dilengkapi dengan sistem Linux, banyak pengagihan Linux akan memasang semula penterjemah python apabila dipasang, dan ia tidak menggunakan pengurus pakej ...

Untuk apa yang paling baik digunakan oleh Linux? Untuk apa yang paling baik digunakan oleh Linux? Apr 03, 2025 am 12:11 AM

Linux paling baik digunakan sebagai pengurusan pelayan, sistem tertanam dan persekitaran desktop. 1) Dalam pengurusan pelayan, Linux digunakan untuk menjadi tuan rumah laman web, pangkalan data, dan aplikasi, menyediakan kestabilan dan kebolehpercayaan. 2) Dalam sistem tertanam, Linux digunakan secara meluas di rumah pintar dan sistem elektronik automotif kerana fleksibiliti dan kestabilannya. 3) Dalam persekitaran desktop, Linux menyediakan aplikasi yang kaya dan prestasi yang cekap.

Bagaimana keserasian Debian Hadoop Bagaimana keserasian Debian Hadoop Apr 02, 2025 am 08:42 AM

Debianlinux terkenal dengan kestabilan dan keselamatannya dan digunakan secara meluas dalam persekitaran pelayan, pembangunan dan desktop. Walaupun kini terdapat kekurangan arahan rasmi mengenai keserasian langsung dengan Debian dan Hadoop, artikel ini akan membimbing anda tentang cara menggunakan Hadoop pada sistem Debian anda. Keperluan Sistem Debian: Sebelum memulakan konfigurasi Hadoop, sila pastikan sistem Debian anda memenuhi keperluan operasi minimum Hadoop, yang termasuk memasang Java Runtime Environment (JRE) dan pakej Hadoop. Langkah Penyebaran Hadoop: Muat turun dan Unzip Hadoop: Muat turun versi Hadoop yang anda perlukan dari laman web Apachehadoop rasmi dan selesaikannya

Adakah saya perlu memasang klien oracle semasa menyambung ke pangkalan data oracle menggunakan GO? Adakah saya perlu memasang klien oracle semasa menyambung ke pangkalan data oracle menggunakan GO? Apr 02, 2025 pm 03:48 PM

Adakah saya perlu memasang klien oracle semasa menyambung ke pangkalan data oracle menggunakan GO? Semasa membangun di GO, menyambung ke pangkalan data Oracle adalah keperluan biasa ...

Adakah debian rentetan serasi dengan pelbagai pelayar Adakah debian rentetan serasi dengan pelbagai pelayar Apr 02, 2025 am 08:30 AM

"Debianstrings" bukan istilah standard, dan makna khususnya masih belum jelas. Artikel ini tidak dapat mengulas secara langsung mengenai keserasian penyemak imbasnya. Walau bagaimanapun, jika "debianstrings" merujuk kepada aplikasi web yang dijalankan pada sistem Debian, keserasian penyemak imbasnya bergantung kepada seni bina teknikal aplikasi itu sendiri. Sebilangan besar aplikasi web moden komited untuk keserasian penyemak imbas. Ini bergantung kepada standard web berikut dan menggunakan teknologi front-end yang serasi (seperti HTML, CSS, JavaScript) dan teknologi back-end (seperti PHP, Python, Node.js, dll.). Untuk memastikan bahawa aplikasi itu serasi dengan pelbagai pelayar, pemaju sering perlu menjalankan ujian silang dan menggunakan responsif

See all articles