173 lines
7.7 KiB
Python
173 lines
7.7 KiB
Python
#include <stdio.h>
|
||
from stdint import *
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <stddef.h>
|
||
import t, c
|
||
|
||
MAX_INSN_LEN: t.CDefine = 15 # x86_64 最长指令 15 字节
|
||
TABLE_SIZE: t.CDefine = 256
|
||
|
||
# 指令名表( opcode → 指令名 )
|
||
opcode_table: t.CConst | list[str, TABLE_SIZE]
|
||
def opcode_init():
|
||
global opcode_table
|
||
opcode_table[0x00] = "add"; opcode_table[0x01] = "add"; opcode_table[0x02] = "add"; opcode_table[0x03] = "add"
|
||
opcode_table[0x04] = "add"; opcode_table[0x05] = "add"; opcode_table[0x08] = "or"; opcode_table [0x09] = "or"
|
||
opcode_table[0x0A] = "or"; opcode_table [0x0B] = "or"; opcode_table [0x0C] = "or"; opcode_table [0x0D] = "or"
|
||
opcode_table[0x10] = "adc"; opcode_table[0x11] = "adc"; opcode_table[0x12] = "adc"; opcode_table[0x13] = "adc"
|
||
opcode_table[0x14] = "adc"; opcode_table[0x15] = "adc"; opcode_table[0x18] = "sbb"; opcode_table[0x19] = "sbb"
|
||
opcode_table[0x1A] = "sbb"; opcode_table[0x1B] = "sbb"; opcode_table[0x1C] = "sbb"; opcode_table[0x1D] = "sbb"
|
||
opcode_table[0x20] = "and"; opcode_table[0x21] = "and"; opcode_table[0x22] = "and"; opcode_table[0x23] = "and"
|
||
opcode_table[0x24] = "and"; opcode_table[0x25] = "and"; opcode_table[0x28] = "sub"; opcode_table[0x29] = "sub"
|
||
opcode_table[0x2A] = "sub"; opcode_table[0x2B] = "sub"; opcode_table[0x2C] = "sub"; opcode_table[0x2D] = "sub"
|
||
opcode_table[0x30] = "xor"; opcode_table[0x31] = "xor"; opcode_table[0x32] = "xor"; opcode_table[0x33] = "xor"
|
||
opcode_table[0x34] = "xor"; opcode_table[0x35] = "xor"; opcode_table[0x38] = "cmp"; opcode_table[0x39] = "cmp"
|
||
opcode_table[0x3A] = "cmp"; opcode_table[0x3B] = "cmp"; opcode_table[0x3C] = "cmp"; opcode_table[0x3D] = "cmp"
|
||
opcode_table[0x40] = "rex"; opcode_table[0x41] = "rex.b"; opcode_table[0x42] = "rex.x"; opcode_table[0x43] = "rex.xb"
|
||
opcode_table[0x44] = "rex.r"; opcode_table[0x45] = "rex.rb"; opcode_table[0x46] = "rex.rx"; opcode_table[0x47] = "rex.rxb"
|
||
opcode_table[0x48] = "rex.w"; opcode_table[0x49] = "rex.wb"; opcode_table[0x4A] = "rex.wx"; opcode_table[0x4B] = "rex.wxb"
|
||
opcode_table[0x4C] = "rex.wr"; opcode_table[0x4D] = "rex.wrb"; opcode_table[0x4E] = "rex.wrx"; opcode_table[0x4F] = "rex.wrxb"
|
||
opcode_table[0x50] = "push"; opcode_table[0x51] = "push"; opcode_table[0x52] = "push"; opcode_table[0x53] = "push"
|
||
opcode_table[0x54] = "push"; opcode_table[0x55] = "push"; opcode_table[0x56] = "push"; opcode_table[0x57] = "push"
|
||
opcode_table[0x58] = "pop"; opcode_table[0x59] = "pop"; opcode_table[0x5A] = "pop"; opcode_table[0x5B] = "pop"
|
||
opcode_table[0x5C] = "pop"; opcode_table[0x5D] = "pop"; opcode_table[0x5E] = "pop"; opcode_table[0x5F] = "pop"
|
||
opcode_table[0x66] = "opsize"; opcode_table[0x67] = "addrsize"
|
||
opcode_table[0x70] = "jo"; opcode_table [0x71] = "jno"; opcode_table[0x72] = "jb"; opcode_table [0x73] = "jnb"
|
||
opcode_table[0x74] = "jz"; opcode_table [0x75] = "jnz"; opcode_table[0x76] = "jbe"; opcode_table[0x77] = "ja"
|
||
opcode_table[0x78] = "js"; opcode_table [0x79] = "jns"; opcode_table[0x7A] = "jp"; opcode_table [0x7B] = "jnp"
|
||
opcode_table[0x7C] = "jl"; opcode_table [0x7D] = "jge"; opcode_table[0x7E] = "jle"; opcode_table[0x7F] = "jg"
|
||
opcode_table[0x80] = "alu"; opcode_table[0x81] = "alu"; opcode_table[0x83] = "alu",
|
||
opcode_table[0x88] = "mov"; opcode_table[0x89] = "mov"; opcode_table[0x8A] = "mov"; opcode_table[0x8B] = "mov"
|
||
opcode_table[0x90] = "nop"
|
||
opcode_table[0xB8] = "mov"; opcode_table[0xB9] = "mov"; opcode_table[0xBA] = "mov"; opcode_table[0xBB] = "mov"
|
||
opcode_table[0xBC] = "mov"; opcode_table[0xBD] = "mov"; opcode_table[0xBE] = "mov"; opcode_table[0xBF] = "mov"
|
||
opcode_table[0xC3] = "ret"; opcode_table[0xC9] = "leave"; opcode_table[0xCB] = "retf"; opcode_table[0xCD] = "int"
|
||
opcode_table[0xE8] = "call"; opcode_table[0xE9] = "jmp"; opcode_table[0xEB] = "jmp"
|
||
opcode_table[0xFF] = "push/call"
|
||
|
||
|
||
# 64位通用寄存器表
|
||
reg64_table: t.CConst | list[str, 16] = [
|
||
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
|
||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
|
||
]
|
||
|
||
class insn:
|
||
bytes: list[UINT8, MAX_INSN_LEN];
|
||
length: UINT8
|
||
addr: t.CUInt64T
|
||
mnemonic: t.CConst | str
|
||
opstr: list[t.CChar, 64]
|
||
|
||
# 解析 MOD-R/M 字节
|
||
@c.CReturn(t.CInt, t.CInt, t.CInt)
|
||
def decode_modrm(modrm: UINT8):
|
||
# mod, reg, rm
|
||
return ((modrm >> 6) & 3), ((modrm >> 3) & 7), ((modrm >> 0) & 7)
|
||
|
||
# 反汇编单条 x86_64 指令
|
||
def disassemble_x86_64(code: t.CConst | UINT8PTR, addr: UINT64, out: insn | t.CPtr) -> t.CInt:
|
||
memset(out, 0, insn.__sizeof__())
|
||
length: UINT8 = 1 # code[length++]
|
||
op: UINT8 = code[0]
|
||
out.addr = addr
|
||
out.mnemonic = opcode_table[op] if opcode_table[op] else "db"
|
||
out.bytes[0] = op
|
||
|
||
# 单字节指令(nop / ret / 等)
|
||
if op == 0x90 or op == 0xC3 or op == 0xCB or op == 0xC9:
|
||
out.length = length
|
||
return 1
|
||
|
||
# 跳转/调用(E8/E9/EB)
|
||
if op == 0xE8 or op == 0xE9 or op == 0xEB:
|
||
off: INT32
|
||
if op == 0xEB:
|
||
off = INT8(code[length])
|
||
length += 1
|
||
else:
|
||
off = c.Deref(INT32PTR(c.Addr(code[length])))
|
||
length += 4
|
||
snprintf(out.opstr, out.opstr.__sizeof__(), "0x%lx", addr + length + off)
|
||
out.length = length
|
||
return 1
|
||
|
||
# 条件跳转(70~7F)
|
||
if (op & 0xF0) == 0x70:
|
||
off: INT8 = code[length]
|
||
length += 1
|
||
snprintf(out.opstr, out.opstr.__sizeof__(), "0x%lx", addr + length + off)
|
||
out.length = length
|
||
return 1
|
||
|
||
# MOV r64, imm64(B8~BF)
|
||
if (op & 0xF8) == 0xB8:
|
||
reg: int = op & 7
|
||
imm: UINT64 = c.Deref(UINT64PTR(c.Addr(code[length])))
|
||
length += 8
|
||
snprintf(out.opstr, out.opstr.__sizeof__(), "%s, 0x%lx", reg64_table[reg], imm)
|
||
out.length = length
|
||
return 1
|
||
|
||
# 带 MOD-R/M 的指令(88/89/8A/8B/00~03 等)
|
||
if ((op & 0xC7) == 0x00 or (op & 0xC7) == 0x08 or
|
||
(op & 0xC7) == 0x10 or (op & 0xC7) == 0x18 or
|
||
(op & 0xC7) == 0x20 or (op & 0xC7) == 0x28 or
|
||
(op & 0xC7) == 0x30 or (op & 0xC7) == 0x38 or
|
||
op == 0x88 or op == 0x89 or op == 0x8A or op == 0x8B):
|
||
modrm: UINT8 = code[length]
|
||
length += 1
|
||
length += 1
|
||
mod: int
|
||
reg: int
|
||
rm: int
|
||
reg, rm, mod = decode_modrm(modrm)
|
||
snprintf(out.opstr, out.opstr.__sizeof__(), "%s, %s", reg64_table[reg], reg64_table[rm])
|
||
out.length = length
|
||
return 1
|
||
|
||
# 未完全解码 → 按原始字节输出
|
||
snprintf(out.opstr, out.opstr.__sizeof__(), "0x%02x", op);
|
||
out.length = length
|
||
return 1
|
||
|
||
|
||
# 反汇编整个裸二进制文件
|
||
def disassemble_file():
|
||
# 这就是你的裸机二进制!
|
||
code: list[UINT8, None] = [
|
||
0x90, # nop
|
||
0x48, 0xC7, 0xC0, 0x01, 0x00, 0x00, 0x00, # mov rax, 1
|
||
0xC3 # ret
|
||
]
|
||
code_length: t.CSizeT = code.__sizeof__()
|
||
base_addr: UINT64 = 0x1000
|
||
|
||
print(";; x86_64 内嵌二进制反汇编\n")
|
||
print(";; 地址 指令字节 汇编\n")
|
||
|
||
i: t.CSizeT = 0
|
||
for i in range(code_length):
|
||
_insn: insn
|
||
disassemble_x86_64(code + i, base_addr + i, c.Addr(_insn))
|
||
|
||
# 打印地址
|
||
printf("%08lx ", insn.addr)
|
||
|
||
# 打印字节
|
||
for j in range(_insn.length):
|
||
printf("%02x ", insn.bytes[j])
|
||
for j in range(_insn.length, 10):
|
||
printf(" ")
|
||
|
||
# 打印指令
|
||
printf("%-6s %s\n", insn.mnemonic, insn.opstr);
|
||
|
||
i += insn.length
|
||
|
||
def main() -> int:
|
||
opcode_init()
|
||
disassemble_file()
|
||
return 0
|