设置代码

如果要让CPU能运行你的指令,你要先去把你的代码,放到内存中,供CPU读取。

所以,第一个优先要放到内存中的,就是:代码

  • 注:代码==指令==二进制==opcode

而你把代码放到具体哪个位置,就是内存布局中,代码的地址空间范围。

举例

官网示例

官网示例 unicorn/sample_arm.py 中的:

# code to be emulated
ARM_CODE   = b"\x37\x00\xa0\xe3\x03\x10\x42\xe0" # mov r0, #0x37; sub r1, r2, r3

就是对应的:要运行的代码

被翻译成ARM汇编的话,对应的内容就是,代码后面的注释的部分

mov r0, #0x37
sub r1, r2, r3

怎么看出来上面的二进制就是上面的ARM汇编代码的?

如之前:什么是指令 所解释的:

此处的 二进制 == ARM的指令

而具体如何看出来:

  • 二进制:\x37\x00\xa0\xe3\x03\x10\x42\xe0

就是对应的ARM汇编代码:

mov r0, #0x37
sub r1, r2, r3

则可以:

此处以在线网站

Online ARM to HEX Converter (armconverter.com)

举例来说明:

  • ARM汇编指令mov r0, #0x37对应的ARM的指令=二进制是:3700A0E3 = \x37\x00\xA0\xE3
    • arm_mov_r0
  • ARM汇编指令sub r1, r2, r3对应的ARM的指令=二进制是:031042E0 == \x03\x10\x42\xE0
    • arm_sub_r1

-》把 \x37\x00\xA0\xE3\x03\x10\x42\xE0加起来,就是此处的二进制:\x37\x00\xa0\xe3\x03\x10\x42\xe0 了。

自己的实例

自己在后续示例

模拟akd函数symbol2575

中,其中的设置代码的部分就是:

def readBinFileBytes(inputFilePath):
    fileBytes = None
    with open(inputFilePath, "rb") as f:
        fileBytes = f.read()
    return fileBytes

# for arm64: ___lldb_unnamed_symbol2575$$akd
akd_symbol2575_FilePath = "input/akd_getIDMSRoutingInfo/arm64/akd_arm64_symbol2575.bin"
logging.info("akd_symbol2575_FilePath=%s", akd_symbol2575_FilePath)
ARM64_CODE_akd_symbol2575 = readBinFileBytes(akd_symbol2575_FilePath) # b'\xff\xc3\x03\xd1\xfco\t\xa9\xfag\n\xa9\xf8_\x0b\xa9\xf6W\x0c\xa9\xf4O

就是从,输入文件

  • input/akd_getIDMSRoutingInfo/arm64/akd_arm64_symbol2575.bin
    • symbol2575_input_code_hex_view

中,读取对应代码=二进制数据,供后续模拟运行的。

而该文件的数据是来自于,lldb调试期间,从内存中导出的:

(lldb) memory read --binary --force --outfile /Users/crifan/dev/tmp/lldb_mem_dump/akd_arm64_symbol2575.bin 0x10485d98c 0x1048600dc
10064 bytes written to '/Users/crifan/dev/tmp/lldb_mem_dump/akd_arm64_symbol2575.bin'

其中0x10485d98c0x1048600dc是该函数的起始地址和结束地址。

results matching ""

    No results matching ""