Files
TransPyC/test.py
2026-06-16 16:09:42 +08:00

173 lines
7.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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, imm64B8~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