Changing Program Flow

ขณะที่เรา dynamic debugging บน GDB เนี่ย นอกจากแค่ทำตาม flow program ปกติแล้ว เรายังสามารถเปลี่ยน flow ของโปรแกรมได้ด้วย เช่น การแก้ข้อมูลต่างๆ, เปลี่ยน 1 เป็น 0, กระโดดไปมา, สั่ง function เพิ่ม เป็นต้น

อันนี้มีประโยชน์เมื่อผู้ใช้งานต้องการทดสอบอะไรบางอย่างบน GDB โดยที่ไม่ต้องเสียเวลาไปแก้โค้ด compile ใหม่หลายๆครั้งครับ ดู advance นิดหน่อย ในมหาลัยคงไม่จำเป็นต้องใช้ อ่านผ่านๆให้รู้ว่ามันมีนะ พอจะใช้จริงค่อยหาตาม search engine ดูก็ได้ครับ

สำหรับนัก reverse engineering ทั้งหลาย รวมทั้งนักเล่น CTF ต่างๆ หัวข้อนี้มีประโยชน์มหาศาลครับ บางข้อนี่ง่ายงงโจทย์เลย

Edit variables

แก้ variables ง่ายมากครับ เช่น

(gdb) r
Starting program: /home/bankde/Desktop/tmp/example.o
Put string to split: helloworld

Breakpoint 1, split (input=0x7fffffffdf40 "helloworld\n") at example.c:7
7      char** result = malloc(10*sizeof(char*));
(gdb) p input
$4 = 0x7fffffffdf40 "helloworld\n"
(gdb) set var input = "hello world"
(gdb) p input
$5 = 0x7ffff7fe1f20 "hello world"
(gdb) c
Continuing.
First str: Hello
Second str: World

จะเห็นว่า input ที่เราใส่เข้าไป helloworld แล้วปกติมันจะทำให้โปรแกรม crash ถูกเปลี่ยนเป็น hello world จนสามารถรันโปรแกรมได้ตามปกติได้ (ถ้า string อาจจะมีข้อจำกัดเรื่อง memory space นะครับ)

นอกจากนี้ยังสามารถแก้ registers ต่างๆได้ด้วย (ถ้าไม่ได้ลง asm มากๆ ข้ามส่วนนี้ไปได้ครับ) เช่น

ตัวอย่างแอบยากนิดนึงเพราะเป็น ZeroFlag ซึ่งไม่ได้มี register ของตัวเอง จึงต้องแก้ eflags แต่ถ้าในกรณี eax, rax ก็แค่ set $eax = -1 แบบนี้ได้เลย เท่านี้ส่วนของ main ก็จะได้รับ return เป็น -1 แล้วจบโปรแกรมได้ เช่น

Jump to any instruction

กระโดดได้เลยครับ ข้ามไปเลยยยยย จะเห็นว่าผมข้ามโค้ดส่วนที่เป็น toupper ไปทั้งก้อนเลย ต้องระวังให้ดีนะครับ เพราะการ jump เนี่ยไม่ได้มีการดัก scope อะไรให้เรา พังได้ง่ายๆ ปกติผมใช้ jump เพื่อทดสอบอะไรสั้นๆ เช่น ข้าม function ที่มีปัญหาไปก่อน เป็นต้น

Run function

เราสามารถสั่ง function อะไรก็ได้ที่เราต้องการได้ระหว่าง GDB อยู่ครับ (แต่ function ต้องถูกอ่าน define มาก่อนแล้ว) อย่างตัวอย่างผมอยู่ที่ main ยังไม่ทันรับ input จริงๆ ผมก็สั่ง split เพื่อดูผลลัพธ์ได้เลย

หรือใช้ p แทน call ก็ได้ครับ แล้วเปลี่ยน memory address เป็นเลขตัวแปรแทนก็ได้เช่นกัน

Last updated

Was this helpful?