GNU/Linux >> Belajar Linux >  >> Linux

Alat Rekayasa Terbalik di Linux – string, nm, ltrace, strace, LD_PRELOAD

Artikel ini menjelaskan tentang alat dan perintah yang dapat digunakan untuk merekayasa balik executable di lingkungan Linux.

Rekayasa terbalik adalah tindakan mencari tahu apa yang dilakukan perangkat lunak, di mana tidak ada kode sumber yang tersedia. Rekayasa terbalik mungkin tidak memberi Anda detail yang tepat dari perangkat lunak. Namun Anda dapat memahami dengan baik tentang bagaimana perangkat lunak diimplementasikan.

Rekayasa balik melibatkan tiga langkah dasar berikut:

  1. Mengumpulkan Info
  2. Menentukan perilaku Program
  3. Mencegah panggilan perpustakaan

Aku. Mengumpulkan Info

Langkah pertama adalah mengumpulkan informasi tentang program sasaran dan apa yang dilakukan. Untuk contoh kita, kita akan mengambil perintah 'siapa'. Perintah 'who' mencetak daftar pengguna yang sedang login.

1. Perintah String

Strings adalah perintah yang mencetak string karakter yang dapat dicetak dalam file. Jadi sekarang mari kita gunakan ini untuk melawan perintah target (siapa).

# strings /usr/bin/who

Beberapa string penting adalah,

users=%lu
EXIT
COMMENT
IDLE
TIME
LINE
NAME
/dev/
/var/log/wtmp
/var/run/utmp
/usr/share/locale
Michael Stone
David MacKenzie
Joseph Arceneaux

Dari output about, kita dapat mengetahui bahwa ‘who’ menggunakan 3 file (/var/log/wtmp, /var/log/utmp, /usr/share/locale).

Baca lebih lanjut:Contoh Perintah String Linux (Teks Pencarian di File Biner UNIX)

2. Perintah nm

Perintah nm, digunakan untuk membuat daftar simbol dari program target. Dengan menggunakan nm, kita dapat mengetahui fungsi local dan library serta variabel global yang digunakan. nm tidak dapat bekerja pada program yang bergaris menggunakan perintah 'strip'.

Catatan:Secara default perintah 'siapa' dilucuti. Untuk contoh ini, saya mengkompilasi perintah 'who' sekali lagi.

# nm /usr/bin/who

Ini akan mencantumkan yang berikut:

08049110 t print_line
08049320 t time_string
08049390 t print_user
08049820 t make_id_equals_comment
080498b0 t who
0804a170 T usage
0804a4e0 T main
0804a900 T set_program_name
08051ddc b need_runlevel
08051ddd b need_users
08051dde b my_line_only
08051de0 b time_format
08051de4 b time_format_width
08051de8 B program_name
08051d24 D Version
08051d28 D exit_failure

Pada keluaran di atas:

  • t|T – Simbol ada di bagian .text code
  • b|B – Simbol ada di bagian .data yang diinisialisasi PBB
  • D|d – Simbol ada di bagian .data yang Diinisialisasi.

Huruf Kapital atau Kecil, menentukan apakah simbol itu lokal atau global.

Dari output about, kita dapat mengetahui hal berikut,

  • Memiliki fungsi global (main,set_program_name,usage,dll..)
  • Ini memiliki beberapa fungsi lokal (print_user,time_string dll..)
  • Ini memiliki variabel yang diinisialisasi global (Versi,exit_failure)
  • Ini memiliki variabel yang diinisialisasi PBB (format_waktu, lebar_format_waktu, dll.)

Terkadang, dengan menggunakan nama fungsi, kita dapat menebak apa yang akan dilakukan oleh fungsi tersebut.

Baca selengkapnya:10 Contoh Perintah Linux nm Praktis

Perintah lain yang dapat digunakan untuk mendapatkan informasi adalah

  • perintah ldd
  • perintah fuser
  • perintah lsof
  • /sistem file proc

II. Menentukan Perilaku Program

3. Perintah ltrace

Ini melacak panggilan ke fungsi perpustakaan. Itu mengeksekusi program dalam proses itu.

# ltrace /usr/bin/who

Outputnya ditunjukkan di bawah ini.

utmpxname(0x8050c6c, 0xb77068f8, 0, 0xbfc5cdc0, 0xbfc5cd78)          = 0
setutxent(0x8050c6c, 0xb77068f8, 0, 0xbfc5cdc0, 0xbfc5cd78)          = 1
getutxent(0x8050c6c, 0xb77068f8, 0, 0xbfc5cdc0, 0xbfc5cd78)          = 0x9ed5860
realloc(NULL, 384)                                                   = 0x09ed59e8
getutxent(0, 384, 0, 0xbfc5cdc0, 0xbfc5cd78)                         = 0x9ed5860
realloc(0x09ed59e8, 768)                                             = 0x09ed59e8
getutxent(0x9ed59e8, 768, 0, 0xbfc5cdc0, 0xbfc5cd78)                 = 0x9ed5860
realloc(0x09ed59e8, 1152)                                            = 0x09ed59e8
getutxent(0x9ed59e8, 1152, 0, 0xbfc5cdc0, 0xbfc5cd78)                = 0x9ed5860
realloc(0x09ed59e8, 1920)                                            = 0x09ed59e8
getutxent(0x9ed59e8, 1920, 0, 0xbfc5cdc0, 0xbfc5cd78)                = 0x9ed5860
getutxent(0x9ed59e8, 1920, 0, 0xbfc5cdc0, 0xbfc5cd78)                = 0x9ed5860
realloc(0x09ed59e8, 3072)                                            = 0x09ed59e8
getutxent(0x9ed59e8, 3072, 0, 0xbfc5cdc0, 0xbfc5cd78)                = 0x9ed5860
getutxent(0x9ed59e8, 3072, 0, 0xbfc5cdc0, 0xbfc5cd78)                = 0x9ed5860
getutxent(0x9ed59e8, 3072, 0, 0xbfc5cdc0, 0xbfc5cd78)

Anda dapat mengamati bahwa ada satu set panggilan ke getutxent dan keluarga fungsi perpustakaannya. Anda juga dapat mencatat bahwa ltrace memberikan hasil dalam urutan fungsi yang dipanggil dalam program.

Sekarang kita tahu bahwa perintah 'who' bekerja dengan memanggil getutxent dan keluarga fungsinya untuk mendapatkan pengguna yang login.

4. strace Perintah

perintah strace digunakan untuk melacak panggilan sistem yang dibuat oleh program. Jika sebuah program tidak menggunakan fungsi library apa pun, dan hanya menggunakan panggilan sistem, maka menggunakan ltrace biasa, kami tidak dapat melacak eksekusi program.

# strace /usr/bin/who
[b76e7424] brk(0x887d000)               = 0x887d000
[b76e7424] access("/var/run/utmpx", F_OK) = -1 ENOENT (No such file or directory)
[b76e7424] open("/var/run/utmp", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
.
.
.
[b76e7424] fcntl64(3, F_SETLKW, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}) = 0
[b76e7424] read(3, "\10\325"..., 384) = 384
[b76e7424] fcntl64(3, F_SETLKW, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}) = 0

Anda dapat mengamati bahwa setiap kali fungsi malloc dipanggil, ia memanggil panggilan sistem brk(). Fungsi perpustakaan getutxent sebenarnya memanggil panggilan sistem 'terbuka' untuk membuka '/var/run/utmp' dan menempatkan kunci baca dan membaca konten kemudian melepaskan kunci.

Sekarang kami mengkonfirmasi bahwa perintah who membaca file utmp untuk menampilkan output.

Baik 'strace' dan 'ltrace' memiliki serangkaian opsi bagus yang dapat digunakan.

  • -p pid – Menempel pada pid yang ditentukan. Berguna jika program sudah berjalan dan Anda ingin mengetahui perilakunya.
  • -n 2 – Indentasi setiap panggilan bersarang dengan 2 spasi.
  • -f – Ikuti garpu

Baca lebih lanjut:7 Contoh Strace untuk Debug Eksekusi Program di Linux

III. Mencegat panggilan perpustakaan

5. LD_PRELOAD &LD_LIBRARY_PATH

LD_PRELOAD memungkinkan kita untuk menambahkan perpustakaan ke eksekusi program tertentu. Fungsi di perpustakaan ini akan menimpa fungsi perpustakaan yang sebenarnya.

Catatan:Kami tidak dapat menggunakan ini dengan program yang disetel dengan bit 'suid'.

Mari kita ikuti program berikut.

#include <stdio.h>
int main() {
  char str1[]="TGS";
  char str2[]="tgs";
  if(strcmp(str1,str2)) {
    printf("String are not matched\n");
  }
  else {
    printf("Strings are matched\n");
  }
}

Kompilasi dan jalankan program.

# cc -o my_prg my_prg.c
# ./my_prg

Ini akan mencetak “String tidak cocok”.

Sekarang kita akan menulis perpustakaan kita sendiri dan kita akan melihat bagaimana kita dapat mencegat fungsi perpustakaan.

#include <stdio.h>
int strcmp(const char *s1, const char *s2) {
  // Always return 0.
  return 0;
}

Kompilasi dan setel variabel LD_LIBRARY_PATH ke direktori saat ini.

# cc -o mylibrary.so -shared library.c -ldl
# LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH

Sekarang sebuah file bernama 'library.so' akan dibuat.
Setel variabel LD_PRELOAD ke file ini dan jalankan program perbandingan string.

# LD_PRELOAD=mylibrary.so ./my_prg

Sekarang ia akan mencetak 'Strings are matched' karena menggunakan fungsi strcmp versi kami.

Catatan:Jika Anda ingin mencegat fungsi pustaka apa pun, maka fungsi pustaka Anda sendiri harus memiliki prototipe yang sama dengan fungsi pustaka asli.

Kami baru saja membahas hal-hal yang sangat mendasar yang diperlukan untuk merekayasa balik sebuah program.

Bagi mereka yang ingin mengambil langkah selanjutnya dalam rekayasa balik, memahami format file ELF dan Program Bahasa Perakitan akan lebih membantu.


Linux
  1. 5 alat Rust yang patut dicoba di baris perintah Linux

  2. Cara menggunakan perintah strace dan ltrace di Linux

  3. Perintah Linux untuk menemukan Strings dalam file Binary atau non ascii

  1. 5 Alat Baris Perintah untuk Menemukan File dengan Cepat di Linux

  2. Perintah mv Linux

  3. Linux du perintah

  1. 4 Alat penurunan harga untuk baris perintah Linux

  2. Perintah ip Linux

  3. Perintah cd Linux