Bagaimana Anda mengekstrak informasi variabel lokal (alamat dan jenis) dari program Delphi atau info debug yang dihasilkan kompilator?

105

Cita-cita saya adalah:

  • Diberikan utas yang ditangguhkan dalam program Windows 32 atau 64-bit yang dikompilasi Delphi, untuk berjalan di tumpukan (dapat dilakukan)
  • Diberikan entri tumpukan, untuk menghitung variabel lokal di setiap metode dan nilainya. Yaitu, paling tidak, temukan alamat dan jenisnya (integer32 / 64 / signed / unsigned, string, float, record, class ...) yang kombinasinya dapat digunakan untuk menemukan nilainya.

Yang pertama baik-baik saja dan yang kedua tentang pertanyaan ini. Pada tingkat tinggi, bagaimana Anda menghitung variabel lokal yang diberi entri tumpukan di Delphi?


Pada tingkat rendah, inilah yang telah saya selidiki:

RTTI: tidak mencantumkan informasi semacam ini tentang metode. Ini bukanlah sesuatu yang sebenarnya pernah saya anggap sebagai pilihan yang realistis, tetapi tetap mendaftar di sini.

Informasi debug: Memuat info debug yang dihasilkan untuk build debug.

  • File peta: bahkan file peta terperinci (file format teks! Buka satu dan lihat) tidak berisi info variabel lokal. Ini pada dasarnya adalah daftar alamat dan nomor baris file sumber. Cocok untuk korelasi alamat ke file & baris, misalnya titik biru di selokan; tidak bagus untuk informasi yang lebih detail
  • Informasi debugging jarak jauh (file RSM) - tidak ada informasi yang diketahui tentang konten atau formatnya.
  • File TD32 / TDS: penelitian saya saat ini. Mereka mengandung simbol global dan lokal di antara banyak informasi lainnya.

Masalah yang saya hadapi di sini adalah:

  • Tidak ada dokumentasi format file TD32 (yang dapat saya temukan.)
  • Sebagian besar pengetahuan saya tentang mereka berasal dari kode Jedi JCL yang menggunakannya (JclTD32.pas) dan saya tidak yakin bagaimana menggunakan kode itu, atau apakah struktur di sana cukup luas untuk menampilkan vars lokal. Saya cukup yakin ini akan menangani simbol global, tetapi saya sangat tidak yakin tentang lokal. Ada berbagai macam konstanta yang ditentukan dan tanpa dokumentasi untuk formatnya, untuk membaca apa artinya, saya masih menebak-nebak. Namun, konstanta tersebut dan namanya pasti berasal dari suatu tempat.
  • Sumber yang dapat saya temukan menggunakan info TDS tidak memuat atau menangani simbol lokal.

Jika ini adalah pendekatan yang benar, maka pertanyaan ini menjadi 'Apakah ada dokumentasi untuk format file TDS / TD32, dan apakah ada contoh kode yang memuat variabel lokal?'

Contoh kode tidak penting tetapi bisa sangat berguna, meskipun sangat minim.

David
sumber
2
Saya belum benar-benar menggunakan unit Jedi JCL untuk mengakses informasi TD32 - Saya memiliki perpustakaan milik saya sendiri untuk itu, tetapi sepertinya semua pipa dasar yang Anda perlukan ada di JclTD32.pas. Tidak ada kode demo yang dapat saya temukan untuk mengakses informasi variabel, tetapi sampel yang ada di sana (di .. \ jcl \ contoh \ windows \ debug \ sourceloc) menunjukkan cara mendapatkan informasi nomor baris dari data TD32, jadi Anda harus bisa membangunnya untuk mendapatkan apa yang Anda butuhkan. Silakan laporkan kembali ke sini apa yang Anda temukan :)
500 - Kesalahan Server Internal
2
@ 500-InternalServerError Terima kasih. Info nomor baris itu mudah (bahkan di file peta) - tetapi dapatkah Anda memberikan info apa pun tentang apa yang Anda lihat di kode JCL yang secara khusus berkaitan dengan simbol lokal? Juga, karena penasaran, apa perpustakaan milik TD32 Anda, dan apakah itu diterbitkan / dapat digunakan secara publik atau hanya di rumah?
David
3
Setiap simbol prosedur / fungsi / metode di bawahnya secara bergantian berisi daftar simbol yang bersifat lokal. Sebagian besar definisi tampaknya ada di unit Jedi, tetapi beberapa dikomentari. Saran saya adalah membuat aplikasi uji kecil dan melihat apa yang dihasilkan oleh pencacahan simbol. Kode yang saya miliki adalah milik dan bukan untuk saya publikasikan. Itu tidak mencakup topik variabel lokal. Tetapi informasi yang mendasarinya bersifat semi-publik, jadi saya mungkin dapat membantu jika Anda menemui tembok tertentu.
500 - Kesalahan Server Internal
4
tds2pdb ( code.google.com/p/map2dbg ) tampaknya memiliki parser untuk file tds. Itu kode C #.
Graymatter
4
Dulu ada dokumen informal, ya, tapi kemudian Borland (pada saat itu) memutuskan untuk merilis dll sebagai gantinya untuk mengakses informasi debug sehingga mereka bisa mengubah format internal dan tidak perlu memperbarui dokumentasinya. Sayangnya, saya tidak dapat menemukan dokumen asli maupun dll sekarang. Saya sarankan Anda menghubungi dukungan teknis Embarcadero dan menanyakannya.
500 - Kesalahan Server Internal

Jawaban:

2

Periksa apakah simbol debugging tidak ada dalam biner. Juga mungkin menggunakan GDB (pada Windows port itu). Akan lebih bagus jika Anda menemukan file .dbg atau .dSYM. Mereka berisi kode sumber, mis.

gdb> list foo
56 void foo()
57 {
58  bar();
59  sighandler_t fnc = signal(SIGHUP, SIG_IGN);
60  raise(SIGHUP);
61  signal(SIGHUP, fnc);
62  baz(fnc);
63 }

Jika Anda tidak memiliki file debugging, Anda dapat mencoba untuk mendapatkan MinGW atau Cygwin, dan menggunakan nm (1) ( halaman manual ). Ini akan membaca nama simbol dari biner. Mereka mungkin berisi beberapa jenis, seperti C ++:

int abc::def::Ghi::jkl(const std::string, int, const void*)

Jangan lupa untuk menambahkan --demangleopsi atau Anda akan mendapatkan sesuatu seperti:

__ZN11MRasterFont21getRasterForCharacterEh

dari pada:

MRasterFont::getRasterForCharacter(unsigned char)
Sekret Atas
sumber
2
Jakub, terima kasih atas jawabannya. Sayangnya saya mungkin perlu membaca format debug tertentu - TDS. Aplikasi Delphi tidak dikompilasi dengan info debug yang kompatibel dengan GDB di Windows. Saya tidak yakin bagaimana nm akan membantu, karena ini akan bergantung pada format file debug tertentu yang mungkin bukan salah satu yang dihasilkan oleh Delphi. Atau apakah saya salah memahami jawaban Anda - dapatkah GDB membaca simbol Delphi, misalnya?
David
@DavidM, komentar Anda sangat penting. Coba cari port GNU Binutils atau GNU Debugger di Windows (saya hanya tahu port Binutils). Ada perpustakaan BFD untuk GDB. Ini digunakan juga di Binutils. Ini memungkinkan untuk membaca berbagai format file dan mengenalinya dengan angka ajaib mereka. Jika semuanya gagal, gunakan alat yang disebut strings. Ini akan mengekstrak string dari file biner apa pun. Lihat halaman manual . Ini akan mencetak string yang mungkin tetapi tidak harus berguna
Sekret Atas
0

Lihat http://download.xskernel.org/docs/file%20formats/omf/borland.txt Open Architecture Handbook. Itu sudah lama, tetapi mungkin Anda menemukan beberapa informasi yang relevan tentang format file.

Muetze1
sumber
Bisakah Anda menambahkan beberapa konteks, tautan tersebut mungkin rusak di masa mendatang.
Hintham
Tautan tersebut berisi dokumen resmi dari borland tentang format file OMF yang digunakan oleh kompiler Borland dan format file biner lainnya yang digunakan oleh Borland. Beberapa tahun yang lalu saya melihat format file TDS dan sepertinya ada beberapa bagian yang kompatibel dengan format file yang didokumentasikan. Saat mencoba mengumpulkan informasi apa pun tentang variabel lokal dari file TDS, dokumentasi terkait harus digunakan atau direferensikan. Jika tautannya rusak, jawaban saya tidak akan berguna dan informasi yang dibutuhkan akan hilang. "Buku Pegangan Arsitektur Terbuka" yang ditautkan adalah bagian dari rilis Turbo Pascal dan C lama.
Muetze1