Letztes Jahr musste unser Team den V8-Bytecode analysieren. Zu diesem Zeitpunkt gab es keine vorgefertigten Tools, mit denen ein solcher Code wiederhergestellt und eine bequeme Navigation ermöglicht werden konnte. Es wurde beschlossen, ein Prozessormodul für das Ghidra-Framework zu schreiben. Aufgrund der Besonderheiten der verwendeten Anweisungsbeschreibungssprache erhielten wir nicht nur einen lesbaren Befehlssatz, sondern auch einen C-ähnlichen Dekompiler. Dieser Artikel ist eine Fortsetzung einer Reihe von Materialien ( 1 , 2 ) über unser Plugin für Ghidra.
Zwischen dem Schreiben des Prozessormoduls und dem Artikel vergingen mehrere Monate. Während dieser Zeit hat sich die SLEIGH-Spezifikation nicht geändert, und das beschriebene Modul funktioniert mit den Versionen 9.1.2–9.2.2, die in den letzten sechs Monaten veröffentlicht wurden.
Auf ghidra.re und in der Dokumentation zu Ghidra finden Sie eine ziemlich gute Beschreibung der Sprachfähigkeiten. Diese Materialien sollten gelesen werden, bevor Sie Ihre eigenen Module schreiben. Die vorgefertigten Prozessormodule der Framework-Entwickler können hervorragende Beispiele sein, insbesondere wenn Sie die darin beschriebene Architektur kennen.
In der Dokumentation können Sie lesen, dass Prozessormodule für Ghidra in der Sprache SLEIGH geschrieben sind, die aus der SLED-Sprache (Specification Language for Encoding and Decoding) stammt und speziell für Ghidra entwickelt wurde. Es übersetzt Maschinencode in p-Code (eine Zwischensprache, die von Ghidra zum Erstellen von dekompiliertem Code verwendet wird). Als Sprache zur Beschreibung von Prozessoranweisungen weist sie viele Einschränkungen auf, die jedoch aufgrund des P-Code-Injektionsmechanismus in Java-Code gestoppt werden können.
github. , SLEIGH . , p-code, . The Ghidra Book: The Definitive Guide.
Eclipse, , Ghidra: GhidraDev GhidraSleighEditor. Ghidra Module Project v8_bytecode. , .
, , The Ghidra Book: The Definitive Guide. .
*.spec — .
*.ldefs — . . *.sla, .
*.pspec — .
*.opinion — ; , opinion : .
*.slaspec, *.sinc — , SLEIGH.
.sla, slaspec-.
, , , , . . .
V8
Jsc-, , c JavaScript Node.Js 8.16.0 bytenode ( Node.Js, npm). , bytenode Node.js . , jsc js:
Node.js , . , ( bytecode-register.cc, bytecode-register.h). v8 Node.js:
, aX , . .
— <this>, aX — , , rN — , . 1- , 2- Wide- 4- ExtraWide-. Wide- :
, SLEIGH , . , 124 rN 125 aX. , . :
, Node.js - . (X aX) . , , .
, , .
CSPEC
, cspec-, github. :
Ghidra . — , , . Ghidra SLEIGH , Intel x86, . , , . , , .
, :
Compiler Specific P-code Interpretation;
Compiler Datatype Organization ( <data_organization>);
Compiler Scoping and Memory Access ( <global>);
Compiler Special Purpose Registers ( <stackpointer>);
Parameter Passing ( <default_proto>).
, , .
<data_organization> <stackpointer> ; <prototype> <default_proto>, . : <input>
, <output>
, <unaffected>
.
, aX. . , register. . , , , , . (space="register"
) <input>
, , 0x14000 (0x14000 , , *.slaspec aX).
(acc), <output>
. , , . <unaffected>
, , , .
, <global>
register 0x2000.
LDEFS
— .ldefs. : ( le), (*.sla, *.pspec,*.cspec), id , Ghidra. - , Node.js, , <language>, *.ldefs , Ghidra.
, , .
PSPEC
( .pspec). processor_spec.rxg ( Ghidra ). - . , .
, ( <processor_spec> ).
SLASPEC
SLEIGH .slaspec.
. , , .
, ( register ram), define space, — define register. offset , , . size. , *.cspec , .
(https://ghidra.re/courses/languages/html/sleigh_constructors.html) , , — . SLEIGH , , , « ». 5 .
Table Header ( )
Display Section ( )
Bit Pattern Sections ( )
Disassembly Actions Section ( )
Semantics Actions Section ( )
, .
Table Header , , ( ).
Display Section — , Ghidra.
Bit Pattern Section — - , «» c ( ).
Disassembly Actions Section - , .
Semantics Actions Section , , .
( instruction), , .
, , . , , . . , ( ), .
, :
^ — / , ;
“” — , , ;
, ;
( - , , #, ).
. , . , . . , :
tokenMaxSize 8. , - . , , , . : start- endBitNumX 0 tokenMaxSize-1 startBitNumX <= endBitNumX.
v8 , . , , «&» «|».
: , , , «» , .
, . , . v8, ( Wide- ExtraWide- , , ). :
, op , Illegal Nop, :
«0xa7» Ghidra Illegal, . unimpl. , , . Nop , , . Nop Node.js , SwitchOnSmiNoFeedback, .
: LdaSmi, (acc ), AddSmi, c .
bytecodes.h Node.js, operand, . , (. AddSmi).
- LdaSmi [-02]. , , disassembly action ( , ).
AddSmi , op, , «;» operand. . , . , , (, , ).
«;» , , , ( ), .
PCode « » Ghidra. - , p-code.
v8 , lda, . acc . , acc, , .
return, , , :
, , . Mul, , .
« » , , , «» . kReg 8 . attach variables 0b 11111111b ( kReg) . , , , 0xfb (11111011b), kReg r0.
, kReg , :
interpreter-generator.cc Node.js. kReg , Table Header src. — export. p-code, export , «» src. Ghidra .
, :
goto
. SLEIGH goto. , kUImm, . disassembly action rel. inst_start SLEIGH .
SLEIGH . , ( ), , ( , p-code ), .
«» dest. *[ram]:4 rel , 4 rel. rel ram. «*» SLEIGH , ( Dynamic References).
[ram] ( ), . p-code, ram.
JumpIfFalse - . SLEIGH goto. js False , , pspec , , . , .
inst_start . TestGreaterThan, goto (<true> ) inst_next. : , , . .
goto inst_next . , «s>», . .
. .
, (. ), . v8, . , 4 CallProperty2 , . :CallProperty2 kReg, kReg, kReg, kReg, [kIdx] Sleigh . - :
, , . , callable, receiver, arg1 arg2 - attach :
kReg . — .
CallProperty2 , call [callable];, . v8 aX ( cspec). , , (, , sinc-, x86). , . Ghidra, . , - , . :
( : sp , ) CallUndefinedReceiver1:
, , java-. , , , SLEIGH. p-code .
, , . , acc , , . , , ( CallVariadicCallOther « » ). define pcodeop OperationName , .
p-code- : callotherfixup
cspec- .
java- , :
. bytenode jsc- js:
jsc- Ghidra. - , Ghidra , eclipse , . : sleigh .
, . 010. D F, . :
( SLEIGH), . , ( SLEIGH cpool) LdaGlobal. ( ):
, , JavaScript, , .slaspec ( .sinc). , p-code, , p-code. p-code .
v8 , / . . , , .
, , : ForInPrepare r9, r10!3. , , , , , .
,
. . , ARM: ( , - ).
, . , . . , , , , .
, CallProperty , «» , , . , : rangeSrc rangeDst. rangeSrc — , , rangeDst «» . rangeDst , : aX rX .
. «=», , disassembly action. - . , , , aX, rX, . : , , , .
. . , (contextreg ).
, , ( ), . counter offStart , .
, .
, , , - disassembly action. rangeSrc, , disassembly action offStart, — counter. «{».
, v8 range_size: , . rangeSrc .
rangeDst 5 .
a0 counter 0 ( ).
r0 counter 0 ( ).
offStart a0, disassembly action counter , offStart , rangedst1.
offStart r0, disassembly action counter offStart , rangedst1.
, rangedst1( , , , ).
. rangeDstN, N — , , aN/rN.
. rangeSrc , , rangeDst - , . epsilon, .
rangeDst, rangeDst1, rangeDst2, . , github. , rangeDst rangeDstX, , — , .
, . «&» «|».
CallProperty :
:
, , CallVariadicCallOther. github java- p-code. p-code call ( Node.js, , — ). slaspec, , , :
, :
rangeDst ( r7 ) , console.log(1,2,3,4,5,6). bytenode . 0x167, — 0x18b.
, , , , - ( , , , ).
, rangeDst , ( , 2 4 ):
, : , . , , . , , , . , , . , SLEIGH.
Node.js , , .
:
:
https://ghidra.re/courses/languages/html/sleigh.html — SLEIGH.
https://github.com/NationalSecurityAgency/ghidra/tree/master/Ghidra/Framework/SoftwareModeling/data/languages — *.cspec, *.pspec, *.opinion, *.ldefs.
https://spinsel.dev/2020/06/17/ghidra-brainfuck-processor-1.html — brainfuck Ghidra.
https://github.com/PositiveTechnologies/ghidra_nodejs — Ghidra .