1# Disassembler反汇编工具 2<!--Kit: ArkTS--> 3<!--Subsystem: ArkCompiler--> 4<!--Owner: @oatuwwutao; @luobohua--> 5<!--Designer: @hufeng20--> 6<!--Tester: @kirl75; @zsw_zhushiwei--> 7<!--Adviser: @foryourself--> 8 9## 简介 10 11Disassembler是ArkTS反汇编工具。如果需要分析方舟字节码文件(\*.abc)相关问题,开发者可以使用Disassembler将方舟字节码文件反编译为可读的汇编指令。 12 13工具随DevEco Studio SDK发布。以Windows平台为例,Disassembler工具位于DevEco Studio/sdk/default/openharmony/toolchains/ark_disasm.exe。 14 15## 命令行说明 16 17反汇编命令如下: 18 19``` 20ark_disasm.exe [options] input_file output_file 21``` 22 23参数说明: 24 25| 参数 | 是否可缺省 | 描述 | 26| -------- | -------- | -------- | 27| [options] | 可缺省 | 命令选项,详见下文options选项说明。 | 28| input_file | 不可缺省 | 待反汇编的方舟字节码文件路径。 | 29| output_file | 不可缺省 | 反汇编内容的输出文件路径。 | 30 31options选项说明: 32 33| 选项 | 必填 | 存在入参 | 描述 | 34| -------- | -------- | -------- | -------- | 35| --debug | 否 | 否 | 启用输出调试信息,默认输出到屏幕。 | 36| --debug-file | 否 | 是 | 如果使能了--debug,指定调试信息的输出文件。 | 37| --help | 否 | 否 | 打印帮助提示。 | 38| --skip-string-literals | 否 | 否 | 跳过对字符串字面量的反汇编。 | 39| --quiet | 否 | 否 | 使能所有'--skip-'开头的选项。 | 40| --verbose | 否 | 否 | 使能输出额外信息(字节位置、方舟字节码格式、操作码)。 | 41| --version | 否 | 否 | 显示配套的方舟字节码文件版本号以及最低支持的方舟字节码文件版本。 | 42 43## 使用示例 44 45假设已存在方舟字节码文件:test.abc,其源代码如下: 46 47``` 48let i = 99; 49function show(){return i;} 50show(); 51``` 52 53 54执行如下命令生成反汇编文件:test.txt,文件内包含操作码及格式等信息。 55 56``` 57ark_disasm.exe test.abc test.txt 58``` 59 60查看反汇编文件的内容。 61 62 63``` 64cat test.txt 65``` 66 67内容如下: 68 69``` 70# source binary: test.abc // 反汇编的方舟字节码文件 71 72.language ECMAScript 73 74# ==================== 75# LITERALS // 字面量数据 76 770 0x203 { 0 [ 78 MODULE_REQUEST_ARRAY: { 79 }; 80]} 81 82# ==================== 83# RECORDS // 模块定义数据 84 85.record _ESConcurrentModuleRequestsAnnotation { // _开头这些都是固定的模块数据 86} 87 88.record test { // 一个js文件对应一个模块数据,包含了模块的相关信息(在方舟字节码文件中的位置,是否是commonjs ...) 89 u8 isCommonjs = 0x0 90 u32 moduleRecordIdx = 0x203 91 ...... 92} 93 94# ==================== 95# METHODS // 方法定义数据 96 97L_ESSlotNumberAnnotation: 98 u32 slotNumberIdx { 0x0 } 99.function any test.#*#show(any a0, any a1, any a2) <static> { // 此方法源码中的show方法,同时这里也说明了,它属于test模块 100 ldlexvar 0x0, 0x0 101 ...... 102} 103 104L_ESSlotNumberAnnotation: 105 u32 slotNumberIdx { 0x3 } 106.function any test.func_main_0(any a0, any a1, any a2) <static> { // 此方法是自动生成的,可以理解成整个js文件就是一个方法,方法名为func_main_0 107 newlexenv 0x1 108 ...... 109} 110 111# ==================== 112# STRING // 符号表信息 113 114[offset:0x88, name_value:i] 115``` 116 117使用参数--verbose,可打印偏移量等更多详细信息。 118 119 120``` 121ark_disasm.exe --verbose test.abc test.txt 122``` 123 124此处列出部分示例。 125 126``` 127.record _ESSlotNumberAnnotation { # offset: 0x00cd, size: 0x0026 (38) // 这里打印了模块在方舟字节码文件中具体的位置和大小 128} 129 130.record test { # offset: 0x00f3, size: 0x0098 (152) // 这里打印了模块在方舟字节码文件中具体的位置 131 u32 moduleRecordIdx = 0x203 # offset: 0x0144 // 这里打印了模块信息的位置 132} 133...... 134.function any test.#*#show(any a0, any a1, any a2) <static> { # offset: 0x0153, code offset: 0x0245 // 这里打印了方法信息具体的位置和方法中指令的具体位置 135# CODE: 136 ldlexvar 0x0, 0x0 # offset: 0x0249, [IMM4_IMM4].........[0x3c 0x00] // 这里打印了每条指令的具体位置 137 ...... 138} 139``` 140