El año pasado, nuestro equipo se enfrentó a la necesidad de analizar el código de bytes V8. En ese momento, no había herramientas listas para usar que pudieran restaurar dicho código y proporcionar una navegación conveniente a través de él. Se decidió intentar escribir un módulo de procesador para el marco de Ghidra. Debido a las peculiaridades del lenguaje de descripción de instrucciones utilizado, obtuvimos no solo un conjunto de instrucciones legibles, sino también un descompilador tipo C. Este artículo es una continuación de una serie de materiales ( 1 , 2 ) sobre nuestro complemento para Ghidra.
Pasaron varios meses entre la redacción del módulo procesador y el artículo. Durante este tiempo, la especificación SLEIGH no ha cambiado y el módulo descrito funciona en las versiones 9.1.2–9.2.2, que se lanzaron durante los últimos seis meses.
Ahora en ghidra.re y en la documentación adjunta a Ghidra hay una descripción bastante buena de las capacidades del lenguaje; vale la pena leer estos materiales antes de escribir sus propios módulos. Los módulos de procesador listos para usar de los desarrolladores del marco pueden ser excelentes ejemplos, especialmente si conoce la arquitectura que se describe en ellos.
En la documentación, puede leer que los módulos de procesador para Ghidra están escritos en el lenguaje SLEIGH, que se originó en el lenguaje SLED (Specification Language for Encoding and Decoding) y fue desarrollado expresamente para Ghidra. Traduce código de máquina a código p (un lenguaje intermedio utilizado por Ghidra para construir código descompilado). Como lenguaje destinado a describir las instrucciones del procesador, tiene muchas limitaciones, que, sin embargo, pueden detenerse debido al mecanismo de inyección de código p en el código java.
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. : , , . .
. .
, (. ), . 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 .