ปลั๊กอิน BinaryNinja เพื่อสร้างกราฟแผนผังคำสั่ง BNIL และตัวจับคู่คำสั่ง meta-program python
รองรับการติดตั้งได้สองวิธี วิธีแรกโดยใช้ตัวจัดการปลั๊กอินใหม่และวิธีที่สองเป็นการติดตั้งด้วยตนเอง
ใช้ตัวจัดการปลั๊กอินใหม่โดยเลือก "จัดการปลั๊กอิน" จากเมนู "แก้ไข" ค้นหารายการปลั๊กอินสำหรับ "BNIL Instruction Graph" คลิกขวาแล้วคลิก "ติดตั้ง" จากนั้นคลิกขวาอีกครั้งและเลือก "เปิดใช้งาน"
$ git clone https://github.com/withzombies/bnil-graph.git
$ cd ~/Library/Application Support/Binary Ninja/plugins
$ ln -s ~/git/bnil-graph .
หากต้องการใช้กราฟ BNIL ให้คลิกขวาที่คำสั่งแล้วเลือก "กราฟคำสั่ง BNIL" ข้อมูลนี้จะสร้างกราฟคำสั่ง BNIL ที่เกี่ยวข้องกับที่อยู่นั้น และแสดงเป็นรูปแบบ HTML
Binary Ninja เพิ่มตัวดำเนินการตัวดำเนินการแบบไดนามิก ด้วยเหตุนี้ตัวเข้าถึงที่สะดวกจึงไม่แสดงในการเรียก dir()
หรือในเอกสาร API bnil-graph แสดงโครงสร้างของคำสั่ง IL รวมถึงชื่อตัวเข้าถึงที่ดี (เช่น insn.src
สำหรับรีจิสเตอร์หรือหน่วยความจำต้นทาง)
กราฟตัวอย่าง:
นอกจากปลั๊กอินกราฟแล้ว bnil-graph ยังสร้างฟังก์ชันตัวจับคู่ที่จะตรงกับคำสั่งที่เลือกทุกประการ คุณลักษณะนี้จะช่วยให้นักพัฒนาปลั๊กอินรายใหม่สามารถจับคู่คำแนะนำได้อย่างรวดเร็ว จุดประสงค์การใช้งานคือการค้นหาคำสั่งที่คล้ายกับคำสั่งที่คุณต้องการจับคู่ สร้างฟังก์ชันตัวจับคู่ จากนั้นแก้ไขฟังก์ชันที่สร้างขึ้นเพื่อรองรับความต้องการของคุณได้ดียิ่งขึ้น
ตัวอย่างจะพยายามค้นหาคำสั่ง MediumLevelILSSA MLIL_CALL_SSA ทั้งหมดที่รับพารามิเตอร์ 3 ตัว ฉันสร้างตัวจับคู่กับฟังก์ชันที่ไม่เกี่ยวข้องกับพารามิเตอร์ 0 ตัว:
def match_MediumLevelILSSA_140001194_0 ( insn ):
# mem#1 = 0x14000d49c() @ mem#0
if insn . operation != MediumLevelILOperation . MLIL_CALL_SSA :
return False
# invalid
if insn . output . operation != MediumLevelILOperation . MLIL_CALL_OUTPUT_SSA :
return False
if insn . output . dest_memory != 0x1 :
return False
if len ( insn . output . dest ) != 0 :
return False
# 0x14000d49c
if insn . dest . operation != MediumLevelILOperation . MLIL_CONST_PTR :
return False
if insn . dest . constant != 0x14000d49c :
return False
if len ( insn . params ) != 0 :
return False
if insn . src_memory != 0x0 :
return False
return True
เราสามารถแก้ไขสิ่งนี้เพื่อลบข้อจำกัดบางอย่าง:
def match_MediumLevelILSSA_140001194_0 ( insn ):
# mem#1 = 0x14000d49c() @ mem#0
if insn . operation != MediumLevelILOperation . MLIL_CALL_SSA :
return False
# invalid
if insn . output . operation != MediumLevelILOperation . MLIL_CALL_OUTPUT_SSA :
return False
# 0x14000d49c
if insn . dest . operation != MediumLevelILOperation . MLIL_CONST_PTR :
return False
if len ( insn . params ) != 0 :
return False
return True
เราลบปลายทางการโทรและข้อจำกัดการกำหนดเวอร์ชันของหน่วยความจำออก ถัดไป อัปเดตการตรวจสอบพารามิเตอร์เพื่อตรวจสอบพารามิเตอร์ 3 ตัว:
def match_3_param_MLIL_CALL_SSA ( insn ):
if insn . operation != MediumLevelILOperation . MLIL_CALL_SSA :
return False
if insn . output . operation != MediumLevelILOperation . MLIL_CALL_OUTPUT_SSA :
return False
if insn . dest . operation != MediumLevelILOperation . MLIL_CONST_PTR :
return False
if len ( insn . params ) != 3 :
return False
return True
ตอนนี้ เรามีตัวจับคู่ที่จะระบุคำสั่ง MLIL_CALL_SSA ด้วยพารามิเตอร์ 3 ตัว! ตอนนี้ทำซ้ำคำสั่ง MLIL SSA แล้วโทรหาตัวจับคู่ เท่านี้ก็เรียบร้อย:
if __name__ == '__main__' :
bv = binaryninja . BinaryViewType . get_view_of_file ( sys . argv [ 1 ])
bv . update_analysis_and_wait ()
for func in bv . functions :
mlil = func . medium_level_il
for block in mlil . ssa_form :
for insn in block :
if match_3_param_MLIL_CALL_SSA ( insn ):
print "Match: {}" . format ( insn )
ตัวจับคู่ตัวอย่าง:
โปรเจ็กต์นี้เป็นลิขสิทธิ์ของ Ryan Stortz (@withzombies) และเผยแพร่ภายใต้ลิขสิทธิ์ Apache 2.0