汇编和机器码之间的多种转换方式(多架构)

最近研究逆向和汇编的时候常需要在汇编指令和机器码之间进行转换。这种转换的需求有时类似于查表,查那么几个就行。有时候又需要写代码进行大量转换,因此记录一下汇编和机器码之间的多种转换方式,以及他们之间的区别。

在线网站转换

该方式适用于初学汇编,只需要对自己疑惑的指令进行相互转换即可(也可以通过爬虫实现自动化,但不推荐)

Online ARM to HEX Converter (armconverter.com) 能够完成ARM架构的互相转换

Online Assembler and Disassembler (shell-storm.org) 多架构转换,使用keystone实现(后面会讲)

上述网站均支持大小端选择

 

IDA 插件 Patching

该项目支持Windows、Linux和macOS,以及x86/x64,arm/arm64,项目开源地址如下:

GitHub - gaasedelen/patching: An Interactive Binary Patching Plugin for IDA Pro 该项目依赖IDA pro 7.6和python3

可以根据需要自行安装,也可以下载我的安装好patching的IDA Pro

https://pan.baidu.com/s/1YzTcmNMdxxCd_fAvhXrOBw?pwd=gdgl

使用方式

使用IDA随意打开一个二进制文件,在汇编窗口选中指令右键,会出现一个assemble选项

 

在打开的窗口中可以修改汇编指令,图中的bytes窗口就可以输出相应的机器码,此时按下回车键还可以保存修改到当前的IDA数据库中。只能将汇编转换成机器码。

Keystone

keystone是个汇编框架,支持windows、linux以及arm、mips、x86等架构,提供C/Python接口。作者的官网和项目主页如下

Keystone – The Ultimate Assembler (keystone-engine.org)

https://github.com/keystone-engine/keystone

安装方式

使用python pip即可 

pip install keystone
pip install keystone-engine

使用方式

from keystone import *

ks = Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
code = 'ADD W8,W8,W16;ADD W9,W9,W10'
encode, count = ks.asm(code)
print(encode, count)

上述代码中,ks.asm需要输入一串汇编指令,多条汇编指令之间可用分号;隔开,它有两个返回值:

encode:返回由汇编指令转换来的机器码的一个list

count:返回由汇编指令转换得到的机器码的指令条数

因此上述代码若使用print打印出encode和count,将会得到如下结果

[8, 1, 16, 11, 41, 1, 10, 11] 2

此外,ks是Ks的一个对象,在这里指定目标架构和模式,构造的时候需要传入这两个参数arch和mode,它们实质上是一些整型的全局变量,加起来一共有90个全局变量,根据变量名称能够了解其对应的架构和模式,按照需要传递参数即可。示例为小端序的ARM64。

 

pwntools

作为CTF比赛中pwn方向最重要的工具,pwntools在其内部pwnlib.asm和pwnlib.disasm封装了汇编和机器码之间互相转换的方式

pwntools的安装方式请自行查询,网上教程很多,但在你使用asm和disasm时可能会出现一些问题,提示没有相关文件或者模块之类的,这是由于该函数依赖于binutils库,需要安装binutils,可参考官方文档进行安装:

Binutils — pwntools 2.2.1 documentation (python3-pwntools.readthedocs.io)

ubuntu下binutils的安装方式

apt-get install software-properties-common
apt-add-repository ppa:pwntools/binutils
apt-get update

apt-get install binutils-$ARCH-linux-gnu

其中$ARCH改为你希望适用的目标架构即可

使用方式

from pwn import *

context.arch = 'i386'
print(asm("mov eax,ebx"))
print(disasm(p32(0xd889)))

以上就能将‘mov eax,ebx’和d8 89在i386架构下进行转换,contex.arch注明的是整个脚本中的架构,此外还可以使用context.os来指明操作系统。

如果需要在一条语句中使用另一种架构,可以通过在asm函数中指明arch的方式进行,就像这样:asm("mov eax,ebx",arch = 'i386',os = 'linux')

上述代码运行之后的打印结果如下:

b'\x89\xd8'
0:   89 d8                   mov    eax, ebx

需要注意的是,由于大小端序的问题,disasm中传递参数和你看到的机器码的顺序问题。

此外,binutils我没找到能够在windows下安装的方法,因此该方式可能只适用于linux和macOS(尽管pwntools的大部分功能能够在windows下正常运行,但还是建议在linux下使用pwntools)

 

posted @ 2022-11-21 10:51  Uiharu  阅读(2888)  评论(0编辑  收藏  举报