filecoin fla(www.ipfs8.vip):若何打造用于剖析V8字节码的Ghidra处置器模块(上)

去年,由于事情的需要,我们的团队不得不剖析V8字节码。那时,还没有任何工具可以对这些代码举行反编译,因此,这些代码处置起来异常让人头疼。于是,我们决议为Ghidra框架编写一个处置器模块。得益于形貌输出指令的语言的特征,我们不仅获得了一套可读的指令,而且还获得了一个类似C语言的反编译器。这篇文章是关于我们的Ghidra插件的系列文章(1,2)的续集。

从编写处置器模块到这篇文章,中央履历了几个月的时间。在这段时间里,SLEIGH规范保持稳固,所形貌的模块适用于9.1.2-9.2.2版本,这些版本是在已往六个月的时间内公布的。 

在ghidra.re网站和Ghidra附带的文档中,对该语言的功效举行了异常详尽的先容。以是,当您编写自己的模块之前,这些质料是异常值得一读的。由框架开发者公布的处置器模块都是一些异常棒的类型,稀奇是当您领会它们的系统结构的情形下。

凭证相关文档的先容,Ghidra的处置器模块是用SLEIGH语言编写的,这种语言派生自编码息争码规范语言(the Specification Language for Encoding,SLED),而且是专门为Ghidra而开发的。该语言能够将机械代码翻译成p代码——Ghidra用来构建反编译代码的中央语言。作为一种形貌处置器指令的语言,它具有许多限制,不外,我们可以通过作为Java代码实现的p代码注入机制来削减这些限制。

至于本文先容的新处置器模块的源代码,读者可以在github上举行下载。在本文中,我们将考察使用纯SLEIGH开发处置器模块时的要害观点,并以某些指令为例来睁开解说。关于若何使用常量池、p代码注入、剖析器和加载器的内容,我们将在其他文章中举行先容。此外,读者还可以在《The Ghidra Book: The Definitive Guide》中学习更多关于剖析器和加载器的内容。

那边着手

为了完成本文先容的义务,需要用到Eclipse IDE,并安装Ghidra附带的插件(GhidraDev和GhidraSleighEditor)。然后,确扬名称为v8_bytecode的Ghidra模块项目。这个新项目包罗了对处置器模块而言异常主要的模板文件;后面,我们将凭证需要对其举行响应的修改。

对于我们需要处置的文件的周全概述,我们可以参考官方文档或最近出书的《The Ghidra Book: The Definitive Guide》一书。下面,我们对这些文件举行简要先容:

*.cspec:编译器规范。

*.ldefs:语言的界说,包罗显示在界面中的处置器模块的各个参数,以及与*.sla文件、处置器规范和编译器规范相关的链接。

*.pspec:处置器规格

*.opinion:加载器的设置;鉴于我们将只形貌一种文件类型,以是,opinion文件可以留空,由于这里用不到它。

*.slaspec, *.sinc:形貌SLEIGH中处置器的寄存器、指令等的文件。

当项目第一次启动后,将泛起一个扩展名为.sla的文件。现实上,该文件是在SLASPEC文件的基础上天生的。

在着手开发处置器模块之前,我们需要弄清晰所选的处置器或注释用具有哪些寄存器,以及这些寄存器和客栈的使用方式等。

V8寄存器

我们感兴趣的JSC文件,是通过bytenode使用JavaScript Node.js 8.16.0运行环境构建的(这个模块有时会随Node.js一起提供,有时则需要通过npm手动安装)。从本质上讲,bytenode是行使Node.js的文档化功效来确立编译文件的。下面是JS中编译JSC文件的函数中的源代码片断:

 

读者可以同时下载编译后的Node.js及其原始源文件。在详细研究了源文件和指令实例后,我们就能弄清晰寄存器是若何以字节码编码的(其中bytecode-register.cc和bytecode-register.h将有助于明晰索引盘算)。下面是寄存器索引盘算与Node.js一致的V8指令示例:

若是您感受aX寄存器是用差其余字节来编码的,而且详细取决于函数参数的数目的话,那么恭喜您:您的感受就对了。下面的图表更清晰地展示了这一点。

 

这里,X是当前函数忽略传输的< this >的参数个数;aX是存放函数参数的寄存器;rN是用作局部变量的寄存器。对于通例指令,可以使用长度为1字节的值对寄存器举行编码;对于符号为Wide的指令,则需要使用长度为2字节的值举行编码;对于符号为ExtraWide的指令,则需要使用长度为4字节的值举行编码。下面展示的是Wide指令的示例编码及相关注释:

在Sergey Fedonin的文章中,对Node.js和V8举行了更为详尽的先容。

值得注重的是,SLEIGH语言并不完全适用于这种可注释的字节码,以是,用它编写的处置器模块具有许多限制。例如,界说work界说时,rN寄存器不能跨越124个,aX寄存器不能跨越125个。对此,我们可以用基于客栈的寄存器通讯模子来解决这个问题,由于它更相符整体观点。然而,在这种情形下,反汇编后的字节码更难阅读。

 

另外,若是不引入分外的伪指令、寄存器或内存区域,就不能能凭证Node.js盘算参数寄存器的名称,由于没有关于参数数目的信息可用。有鉴于此,我们决议在函数参数寄存器名称中以相反的顺序插入数字(aX中的X)。这并不故障代码的剖析,这对我们来说是一个主要的尺度。然而,在对照通过差异工具反汇编出来的指令效果时,它可能会引起混淆。

在研究了需要形貌的内容之后,我们就可以最先编写处置器模块所需的文件了。

CSPEC文件

您可以在github上的框架源文件中,找到一些关于CSPEC文件中使用的标签的相关信息。凭证该文件的形貌:

编译器规范是Ghidra语言模块的必须部门,用于支持特定处置器的反汇编和剖析。其目的是对有关目的二进制文件的信息举行编码,而这些信息是与天生该二进制文件的编译器慎密相关的。在Ghidra中,SLEIGH规范允许对特定处置器(如Intel x86)的机械指令举行解码,需要注重的是,可以天生这些指令的编译器却不止一个。对于特定的目的二进制文件,领会用于构建它的特定编译器的详细信息对于逆向工程历程异常主要。而编译器规范正好知足了这一需求,由于它对参数通报约定和客栈机制等观点给出了正式的形貌……

同时,我们也不难看出,这些标签可用于:

· 注释特定于编译器的P代码。

· 组织编译器的数据类型(我们使用的是< data_organization >)。

· 编译器的作用域治理和内存接见(我们使用的是< global >)。

· 编译器的专用寄存器(我们使用的是< stackpointer >)。

· 参数通报(我们使用的是< default_proto >)。

在研究模板结构、文档中形貌的标签以及类似文件的例子时,我们可以实验编译一个适合我们需求的文件。

其中,< data_organization >和< stackpointer >标签是相当典型的,以是这里不再赘述;相反,我们可以仔细考察一下< default_proto >中的< prototype >标签,它提供了关于函数挪用的协议的部门信息。为此,我们界说了以下内容:< input >、< output >与< unaffected >。

如上所述,参数是通过aX寄存器通报给函数的。在一个模块中,寄存器必须被界说为在某个空间中偏移的延续字节序列。一样平常来说,在这种情形下,会使用一个稀奇指定的空间来命名寄存器。然而,在理论上,只要您喜欢,也可以使用其他空间。当有大量的寄存器执行差异水平相同的功效时,最简朴的做法是不只独示意它们,而是可以简朴地在一个空间中用一组寄存器指定偏移量,并用它来界说它们。因此,我们在< input >标签中为寄存器空间(space="register")的内存区域做了符号,让参数通过该空间通报到函数中,偏移量为0x14000(注重,0x14000并不是牢固的,这只是一个偏移量,aX寄存器将在下面的*.slaspec中界说)。

在默认的情形下,函数挪用的效果被保留在累加器(acc)中,这可以通过< output >标签加以示意。对于保留函数返回的值的备用寄存器方案,我们可以在形貌指令时界说响应的逻辑。在< unaffected >标签中,我们注重到函数挪用对存储客栈指针的寄存器并不会带来影响。

为了处置某些寄存器,最利便的方式就是把它们界说为全局可改变的。以是,在< global >标签中,我们界说了一个寄存器空间,即从偏移量0x2000处最先的寄存器地址局限。

LDEFS文件

接下来,我们最先考察语言界说文件:这是一个扩展名为.ldefs的文件。该文件需要的形貌信息为:字节顺序(这里是le)、要害文件的名称(*.sla、*.pspec和*.cspec)、id和字节码名称,当把文件导入Ghidra时,它们将显示在支持的处置器模块列表中。若是我们需要给为Node.js版本编译的文件添加一个处置器模块,若是这个版本与当前版本有很大差异,那么就需要确立另一个标签来形貌它,就像在作为Ghidra一部门提供的*.defs模块中形貌处置器系列那样。

在实验导入文件时,将看到与文件界说无关的信息的现实应用。

,

AllbetGmaing电脑版下载

欢迎进入AllbetGmaing电脑版下载(www.aLLbetgame.us),欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

,

PSPEC文件

就文档而言,处置器规范(扩展名为.spec的文件)的情形更为庞大。在这种情形下,我们可以求助于框架自己的现成解决方案或processor_spec.rxg文件。在编写这个处置器模块的时刻,还没有更详细的资料可用。未来的话,开发职员也可能会公布官方文档。

在眼下这个项目中,我们现在可能只需要处置器规范中的程序计数器;我们将保留新建项目尺度模板中的响应标签(事实上我们可以让< processor_spec >为空)。

SLASPEC文件

现在我们可以在一个扩展名为.slaspec的文件中对SLEIGH的指令举行现实形貌。

预处置器的基本界说和宏

在形貌它时,首先,我们需要指定字节顺序。此外,我们还可以通过使用预处置器的宏来界说对齐方式和形貌历程中可能需要的常数。

对于用来形貌字节码的地址空间(这里确立了名称为register和ram的空间)来说,应该以界说空间的方式举行界说,而寄存器则通过界说寄存器的方式举行界说。另外,寄存器界说中的偏移值着实并不主要;相反,最主要的是寄存器必须位于差其余偏移量处。寄存器占用的字节数由参数size举行界说。需要注重的是,若是您引用这些寄存器的话,那么这里界说的信息必须对应于对*.cspec和剖析器中类似抽象和值的挪用。

关于指令

凭证相关文档的先容,指令是通过表来界说的,这些表由一个和多个组织器组成,并带有相关的族符号标识符。SLEIGH中的表是辅助确立族符号的构件。我们不会在本文中详细先容符号的界说;我们建议人人阅读文档中的“Introduction to Symbols”部门,但可能读完本文后,也许这些观点就弄清晰了。组织器由五个部门组成。

1、表头

2、显示部门

3、比特模式部门

4、反汇编操作部门

5、语义操作部门

 

这些看起来有些让人摸不着头脑,以是,先让我们简要先容一下:

1、表头可以存放可以在其他组织器中使用的标识符,或者为空(在这种情形下,含有指令的形貌)。

2、显示部门是用于说明若何将指令显示到Ghidra列表中的模板。

3、比特模式部门是一个标识符列表,这些标识符以程序的现实二进制位为指令,并凭证显示部门(有时使用下一个部门)的模式显示在列表中。

4、反汇编操作部门用于通过盘算来弥补比特模式部门,若是比特模式在纯粹形式方面不够完善的话。

5、语义操作部门用于形貌指令的作用,以便在反编译器中显示其作用。

最初,会提供一个根指令表(标识符instruction与其关联在一起),所有表头内容为空的组织器都市成为它的一部门,这些组织器在显示部门中的第一个标识符被识别为指令的助记符。 

对于表头中含有标识符的组织器,都市确立一个具有响应名称的新表。若是该表已经存在,那么,这个组织器就会成为该表的一部门。这种情形将在关于寄存器局限的章节中举行先容。当在另一个表中使用一个表的标识符时,被引用的表被视为当前表的一部门。换句话说,确立一个其标识符没有在任何地方使用的表(它们将与指令的根表完全没有联系)是没有任何现实意义的。

下面是显示部门的一些特征: 

· 插入符(^),用于离开标识符和/或部门字符,它们之间不应该有空格。

· 引号(""),用于插入不被视为标识符的硬编码字符串。

· 当空缺字符位于各部门的最先和竣事位置时,将被截断——也就是说,由这些字符组成的序列将被压缩成一个空格。

· 会将一些标点符号和特殊字符插入到模板中(它们不用于任何特定的功效,与之差其余是,某些符号是有特定用途的,例如,用于注释)。

符号及其字段

我们需要界说比特字段来形貌指令组织器。通过它们,可以将程序的某些部门与将被翻译成的语言的某些抽象联系在一起。例如,助记符或操作数就属于这样的抽象观点。这些字段是在符号的界说历程中界说的,其界说语法如下:

 

符号的长度(tokenMaxSize)必须是8的倍数。若是使用较小的位数对指令的操作数或细微差异举行编码的话,可能会很不利便。另一方面,这可以通过提供确立差异长度的字段的能力来举行抵偿,这样的话,就能在符号指定的巨细局限内对随便的二进制位举行位置解码。对于这样的字段来说,必须遵守以下条件:startBitNumX和endBitNumX在0到tokenMaxSize-1的局限内,而且startBitNumX < = endBitNumX。

对于剖析后的V8字节码,没有需要确立其长度与符号长度差其余字段。然而,若是存在这样的字段,而且还需要混用的话,则可以通过逻辑运算符“&”或“|”将其统一起来。

注重:纵然您在比特模式部门使用了一个字段或一组字段,然则这些字段的位掩码并没有笼罩它们所属的符号的所有巨细,由符号巨细决议的位数仍将从操作数的程序字节中抽取。 

现在让我们来形貌一个异常简朴的字节码指令,该指令中不含操作数。我们先来界说形貌指令操作码的字段。正如我们在上面关于V8的部门所看到的,指令代码由一个字节形貌(固然,还存在更长的Wide和ExtraWide指令,但这里不思量它们,由于从本质上讲,它们只是使用大尺寸的操作数和分外的指令操作码字节)。因此,我们将获得:

现在,使用op字段来确定界说Illegal和Nop指令的第一个也是唯一的一个操作码,我们为它们编写的组织器如下所示:

 

当我们使用Ghidra输出字节0xa7时,它将被显示为一条没有操作数的Illegal指令。在这个例子中,我们使用了unimpl要害字,示意这是一条未实现的指令,进一步的反编译将被中止,这对于跟踪未实现的语义形貌是异常利便的。另外,Nop的语义部门为空,这意味着该下令不会影响反编译器中的显示,而这正是该指令应该做的。现实上,在我们的Node.js版本中,Nop并不作为一条指令存在的;相反,这里我们人为地引入了它,以实现SwitchOnSmiNoFeedback的功效,关于这方面的内容,读者可以参阅Vladimir Kononovich的相关文章。

小结

在这篇文章中,我们将为读者详细先容若何打造用于剖析V8字节码的Ghidra处置器模块,由于篇幅过长,我们将分多篇举行公布,更多精彩内容,敬请期待!

(未完待续)

本文翻译自:https://swarm.ptsecurity.com/creating-a-ghidra-processor-module-in-sleigh-using-v8-bytecode-as-an-example/

万利逆商

万利逆商网(www.ipfs8.vip)是FiLecoin致力服务于使用FiLecoin存储和检索数据的官方权威平台。IPFS网实时更新FiLecoin(FIL)行情、当前FiLecoin(FIL)矿池、FiLecoin(FIL)收益数据、各类FiLecoin(FIL)矿机出售信息。并开放FiLecoin(FIL)交易所、IPFS云矿机、IPFS矿机出售、租用、招商等业务。

  • 评论列表:
  •  泰达币交易所官网
     发布于 2021-06-21 00:02:43  回复
  •   第三种双摄是由尺度+长焦双摄像头,其适用法和第二种一样,单独使用,长焦就是拍摄远距离物体,iPhone7 Plus之以是能够拍出去画质更好的照片出来,不是由于双摄的缘故原由,而是iPhone摄影原本就很好,可以对比下iPhone7,实在照片质量都相差不大,多了一个长焦摄像头带来了更多的可玩性。  实在双摄像头对于喜欢玩摄影的人来说,确实是最好的选择,带来了更多的可玩兴趣,而且广角和长焦可以随便选择,这样用户大部门都是摄影手艺很强,明空手动摄影,否则就像单反一样,手动模式玩不来想拍出高质量的照片也很难,以是喜欢双摄的用户着手能力异常强,对于照片要求也要,经常拍完之后还要通事后期处置。路过看看不走了

添加回复:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。