Ultimul dezasamblator

motor

Construire și programare cu motor „dietă”

Această documentație introduce cum să construim arhitectura Capstone pentru X86 pentru a minimiza bibliotecile în scopul încorporării.

Partea ulterioară prezintă API-urile legate de această caracteristică și recomandă zonele pe care programatorii ar trebui să le acorde atenție în codul lor.

1. Construirea unui motor de „dietă”

De obicei, folosim Capstone pentru aplicații obișnuite, unde greutatea bibliotecii nu contează cu adevărat. Într-adevăr, începând cu versiunea 2.1-RC1, întregul motor are doar 1,9 MB, inclusiv toți arhitecții, iar această dimensiune nu ridică nicio problemă majorității oamenilor.

Cu toate acestea, există cazuri în care dorim să încorporăm Capstone în medii speciale, cum ar fi driverul kernel-ului OS sau firmware-ul, în care dimensiunea acestuia ar trebui să fie cât mai mică posibil din cauza restricției de spațiu. Deși putem întotdeauna să compilăm doar arhitecți selectați pentru a face bibliotecile mai compacte, totuși dorim să le reducem mai mult.

Spre acest obiect, de la versiunea 2.1, Capstone acceptă modul dietă, în care sunt eliminate unele date non-critice, făcând astfel dimensiunea motorului cu cel puțin 40% mai mică.

În mod implicit, Capstone este construit în modul standard. Pentru a construi un motor de dietă, faceți: (demonstrația este pe sistemele * nix)


Dacă construim doar arhitecți selectați, motorul este și mai mic. Găsiți mai jos dimensiunea pentru fiecare arhitectură individuală compilată în modul dietă.

Biblioteca de arhitectură Binar standard „Diet” binar Dimensiune redusă
Braţ libcapstone.a
libcapstone.dylib
730 KB
599 KB
603 KB
491 KB
18%
19%
Arm64 libcapstone.a
libcapstone.dylib
519 KB
398 KB
386 KB
273 KB
26%
32%
Mips libcapstone.a
libcapstone.dylib
206 KB
164 KB
136 KB
95 KB
34%
43%
PowerPC libcapstone.a
libcapstone.dylib
140 KB
103 KB
69 KB
50 KB
51%
52%
X86 libcapstone.a
libcapstone.dylib
809 KB
728 KB
486 KB
452 KB
40%
38%
Combinați toate arcurile libcapstone.a
libcapstone.dylib
2,3 MB
1,9 MB
1,6 MB
1,3 MB
31%
32%


(Statisticile de mai sus au fost colectate începând cu versiunea 2.1-RC1, construită pe Mac OSX 10.9.1 cu clang-500.2.79)

2. Programarea cu motorul „dietă”

2.1 Câmpuri de date irelevante cu motor „dietă”

Pentru a reduce semnificativ dimensiunea motorului, unele date interne trebuie sacrificate. Mai exact, următoarele câmpuri de date din structura cs_insn devin irelevante.

Câmp de date Semnificație Înlocuit cu
@mnemonic Mnemonica instruirii @id
@op_str Șir de instrucțiuni operand @ detail-> operanzi
@ detail-> regs_read
@ detail-> regs_read_count
Registrele citite implicit prin instrucțiuni Nu
@ detail-> regs_write
@ detail-> regs_write_count
Registrele scrise implicit prin instrucțiuni Nu
@ detaliu-> grupuri
@ detaliu-> grupuri_cont
Instrucțiunile grupurilor semantice aparțin Nu


În timp ce aceste informații lipsesc, din fericire putem totuși să elaborăm câteva informații critice cu câmpurile de date rămase din structura cs_insn.

@mnemonic

Fără informații mnemonice, ne putem baza pe câmpul @id al structurii cs_insn.

De exemplu, instrucțiunea „ADD EAX, EBX” ar avea @id ca X86_INS_ADD.

@op_str

Fără șir de operandi, putem extrage informații echivalente din @ detail-> operanzi, care conține toate detaliile despre operanzi de instrucțiuni.

De exemplu, instrucțiunea „ADD EAX, EBX” ar avea 2 operanzi de tip registru X86_OP_REG, cu ID-uri de registru X86_REG_EAX și X86_REG_EBX.

În plus, toate detaliile structurilor dependente de arhitectură, cum ar fi cs_arm, cs_arm64, cs_mips, cs_ppc & cs_x86, sunt încă acolo pentru ca noi să elaborăm toate informațiile necesare, chiar și fără câmpurile lipsă.

2.2 API-uri irelevante cu motor „dietă”

Deși majoritatea API-urilor Capstone funcționează în continuare exact la fel, datorită acestor câmpuri de date absente, următoarele API devin irelevante.

cs_reg_name ()

Având un ID de registru (cum ar fi X86_REG_EAX), nu mai putem prelua numele acestuia.

cs_insn_name ()

Având un ID de instrucțiune (cum ar fi X86_INS_SUB), nu mai putem prelua numele instrucțiunii sale.

cs_insn_group ()

Nu mai avem informații despre grup, deci nu putem verifica dacă o instrucțiune aparține unui anumit grup.

cs_reg_read ()

Nu mai avem informații despre registre citite implicit de instrucțiuni, deci nu putem spune dacă o instrucțiune citește un anumit registru.

cs_write_read ()

Nu mai avem informații despre registre citite implicit de instrucțiuni, deci nu putem spune dacă o instrucțiune modifică un anumit registru.


Prin irelevanță, înțelegem că API-urile de mai sus ar returna o valoare nedefinită. Prin urmare, programatorii au fost avertizați să nu folosească aceste API-uri în regim alimentar.

2.3 Verificarea stării de „dietă” a motorului

Capstone ne permite să verificăm dacă motorul a fost compilat în regim alimentar cu cs_support () API, după cum urmează - eșantion de cod în C.


Cu Python, putem verifica modul de dietă prin intermediul funcției cs_support a modulului capstone, după cum urmează.


Sau putem folosi și dietă getter din clasa Cs în același scop, după cum urmează.