某算法的python执行汇编

python 复制代码
#!/usr/bin/env python3
import struct
import unicorn as uc
import unicorn.arm64_const as arm64
from capstone import CS_ARCH_ARM64, CS_MODE_ARM, Cs, CS_MODE_LITTLE_ENDIAN
from keystone import Ks, KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN
from unicorn import UcError, UC_HOOK_CODE

# ---------- 1. 汇编 ----------
ASM = """
mov x11, #0xd21
ldr x8, [x0, #0x20]
mov w9, #0x5680
movk x11, #0x20d2, lsl #16
mov w10, #0xb0df
movk w9, #0x9d2c, lsl #16
movk x11, #0xd20d, lsl #32
movk w10, #0x9908, lsl #16
movk x11, #0xd20, lsl #48
mov w8, wzr
mov x13, xzr
mov w15, #0x270
mov w16, #-0x103a0000
ldr x17, [x14, #0x1380]
mov x12, x17
add x17, x17, #1
lsr x1, x17, #4
add x2, x12, #0x18d
lsl x12, x12, #3
lsr x3, x2, #4
umulh x1, x1, x11
umulh x3, x3, x11
lsr x1, x1, #1
msub x17, x1, x15, x17
lsr x1, x3, #1
msub x1, x1, x15, x2
ldr x2, [x14, x12]
and x2, x2, #0xffffffff80000000
ldr x3, [x14, x17, lsl #3]
and x4, x3, #0x7ffffffe
ldr x1, [x14, x1, lsl #3]
sbfx x3, x3, #0, #1
orr x2, x4, x2
eor x1, x1, x2, lsr #1
and x2, x3, x10
eor x1, x1, x2
str x1, [x14, x12]
ldr x12, [x14, #0x1380]
ldr x12, [x14, x12, lsl #3]
str x17, [x14, #0x1380]
ubfx x1, x12, #0xb, #0x20
eor x12, x1, x12
lsl w1, w12, #7
and x1, x1, x9
eor x12, x1, x12
lsl w1, w12, #0xf
and x1, x1, x16
eor x12, x1, x12
eor x1, x12, x12, lsr #18
ldr x12, [x0, #0x28]
ldr x2, [x0, #0x10]
ldr w3, [x0, #0x38]
add x13, x13, #1
ldr x12, [x0, #0x20]
lsl w8, w8, w2
cmp x2, #0x20
and w1, w3, w1
"""


# ---------- 2. 编译 ----------
ks = Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
code = bytes(ks.asm(ASM)[0])

# ---------- 3. 内存布局(一般可以不变) ----------
BASE = 0x1000000  #代码段起始内存
BASE_SIZE = 0x4000 #代码区的大小
STACK = 0x2000000  #栈空间起始内存
STACK_SIZE = 0x20000  #栈空间的大小
DATA = 0x3000000  #数据区起始内存
DATA_SIZE = 0x5000  #数据区的大小

mu = uc.Uc(uc.UC_ARCH_ARM64, uc.UC_MODE_ARM)
mu.mem_map(BASE, BASE_SIZE, uc.UC_PROT_READ | uc.UC_PROT_EXEC)
mu.mem_map(STACK, STACK_SIZE, uc.UC_PROT_READ | uc.UC_PROT_WRITE)
mu.mem_map(DATA, DATA_SIZE, uc.UC_PROT_READ | uc.UC_PROT_WRITE)

# ---------- 4. 写入代码和数据 ----------
mu.mem_write(BASE, code)
mu.mem_write(DATA, b'\x00' * DATA_SIZE) #给数据区初始化填充0

# X0 指向 DATA
mu.reg_write(arm64.UC_ARM64_REG_X0, DATA) #根据汇编把x0和x14指向了DATA
mu.reg_write(arm64.UC_ARM64_REG_X14, DATA)

mu.mem_write(DATA + 0x1380, struct.pack('<Q', 0x9)) #根据汇编调整数据区的数据
mu.mem_write(DATA + 0x48, struct.pack('<Q', 0xbd2a6569))
mu.mem_write(DATA + (0xa<<3), struct.pack('<Q', 0x3bed4641))
mu.mem_write(DATA + (0x196<<3), struct.pack('<Q', 0x9d8e582b))
mu.mem_write(DATA + 0x38, struct.pack('<Q', 0x3ff))
# ---------- 5. 初始化寄存器 ----------
mu.reg_write(arm64.UC_ARM64_REG_SP, STACK + STACK_SIZE//2) #初始化栈内存的起始地址,设置SP在栈空间中间

# ---------- 4. Trace 回调 ----------
md = Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN) #打印每一步汇编的流程
def hook_code(uc, address, size, user_data):
    code = uc.mem_read(address, size)
    for insn in md.disasm(code, address):
        print(f"0x{insn.address:x}:\t{insn.mnemonic}\t{insn.op_str}")
        # 打印关键寄存器
        x1 = uc.reg_read(arm64.UC_ARM64_REG_X1)
        x2 = uc.reg_read(arm64.UC_ARM64_REG_X2)
        x3 = uc.reg_read(arm64.UC_ARM64_REG_X3)
        x4 = uc.reg_read(arm64.UC_ARM64_REG_X4)
        print(f"    X1=0x{x1:x}, X2=0x{x2:x},X3=0x{x3:x}, X4=0x{x4:x}")

mu.hook_add(UC_HOOK_CODE, hook_code)
try:
    #开始执行汇编
    mu.emu_start(BASE, BASE + len(code))
except UcError as e:
    #打印执行异常的汇编位置
    pc = mu.reg_read(arm64.UC_ARM64_REG_PC)
    md = Cs(CS_ARCH_ARM64, CS_MODE_ARM)
    for i in md.disasm(code, BASE):
        print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
    print("Error at PC = 0x%x" % pc)
    raise
# ---------- 7. 读取寄存器 ----------
x1_val = mu.reg_read(arm64.UC_ARM64_REG_X1)
x2_val = mu.reg_read(arm64.UC_ARM64_REG_X2)
print("x1",hex(x1_val))
print("x2",hex(x2_val))

java运行

打印python的code值

python 复制代码
code = bytes(ks.asm(ASM)[0])
print(", ".join(f"(byte)0x{b:02x}" for b in code))

引入依赖

xml 复制代码
<dependency>
    <groupId>com.github.zhkl0228</groupId>
    <artifactId>unicorn</artifactId>
    <version>1.0.14</version>
</dependency>
java 复制代码
package org.example.demo1boot.util;

import unicorn.Unicorn;
import unicorn.UnicornConst;
import unicorn.Arm64Const;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class UnicornDemo {

    // 内存布局
    static final long BASE       = 0x1000000L;
    static final long STACK      = 0x2000000L;
    static final int  STACK_SIZE = 0x20000;
    static final long DATA       = 0x3000000L;
    static final int  DATA_SIZE  = 0x5000;

    public static void main(String[] args) {
        // 初始化 Unicorn,ARM64 模式
        Unicorn mu = new Unicorn(UnicornConst.UC_ARCH_ARM64, UnicornConst.UC_MODE_ARM);

        // 映射内存
        mu.mem_map(BASE, 0x4000, UnicornConst.UC_PROT_ALL);
        mu.mem_map(STACK, STACK_SIZE, UnicornConst.UC_PROT_ALL);
        mu.mem_map(DATA, DATA_SIZE, UnicornConst.UC_PROT_ALL);

        // TODO: 在 Java 里没有 Keystone,所以机器码要自己准备
        // 这里先假设你用 Python 把 ASM 编译好,得到 byte[] code
        byte[] code = new byte[] {
            // TODO: 填入 keystone 编译出的 ARM64 机器码
                (byte)0x2b, (byte)0xa4, (byte)0x81, (byte)0xd2, (byte)0x4b, (byte)0x1a, (byte)0xa4, (byte)0xf2, (byte)0xab, (byte)0x41, (byte)0xda, (byte)0xf2, (byte)0x0b, (byte)0xa4, (byte)0xe1, (byte)0xf2, (byte)0x08, (byte)0x10, (byte)0x40, (byte)0xf9, (byte)0x09, (byte)0xd0, (byte)0x8a, (byte)0x52, (byte)0x89, (byte)0xa5, (byte)0xb3, (byte)0x72, (byte)0xea, (byte)0x1b, (byte)0x96, (byte)0x52, (byte)0x0a, (byte)0x21, (byte)0xb3, (byte)0x72, (byte)0xe8, (byte)0x03, (byte)0x1f, (byte)0x2a, (byte)0xed, (byte)0x03, (byte)0x1f, (byte)0xaa, (byte)0x0f, (byte)0x4e, (byte)0x80, (byte)0x52, (byte)0xd0, (byte)0xf8, (byte)0xbd, (byte)0x52, (byte)0xd1, (byte)0xc1, (byte)0x49, (byte)0xf9, (byte)0xec, (byte)0x03, (byte)0x11, (byte)0xaa, (byte)0x31, (byte)0x06, (byte)0x00, (byte)0x91, (byte)0x21, (byte)0xfe, (byte)0x44, (byte)0xd3, (byte)0x82, (byte)0x35, (byte)0x06, (byte)0x91, (byte)0x8c, (byte)0xf1, (byte)0x7d, (byte)0xd3, (byte)0x43, (byte)0xfc, (byte)0x44, (byte)0xd3, (byte)0x21, (byte)0x7c, (byte)0xcb, (byte)0x9b, (byte)0x63, (byte)0x7c, (byte)0xcb, (byte)0x9b, (byte)0x21, (byte)0xfc, (byte)0x41, (byte)0xd3, (byte)0x31, (byte)0xc4, (byte)0x0f, (byte)0x9b, (byte)0x61, (byte)0xfc, (byte)0x41, (byte)0xd3, (byte)0x21, (byte)0x88, (byte)0x0f, (byte)0x9b, (byte)0xc2, (byte)0x69, (byte)0x6c, (byte)0xf8, (byte)0x42, (byte)0x80, (byte)0x61, (byte)0x92, (byte)0xc3, (byte)0x79, (byte)0x71, (byte)0xf8, (byte)0x64, (byte)0x74, (byte)0x7f, (byte)0x92, (byte)0xc1, (byte)0x79, (byte)0x61, (byte)0xf8, (byte)0x63, (byte)0x00, (byte)0x40, (byte)0x93, (byte)0x82, (byte)0x00, (byte)0x02, (byte)0xaa, (byte)0x21, (byte)0x04, (byte)0x42, (byte)0xca, (byte)0x62, (byte)0x00, (byte)0x0a, (byte)0x8a, (byte)0x21, (byte)0x00, (byte)0x02, (byte)0xca, (byte)0xc1, (byte)0x69, (byte)0x2c, (byte)0xf8, (byte)0xcc, (byte)0xc1, (byte)0x49, (byte)0xf9, (byte)0xcc, (byte)0x79, (byte)0x6c, (byte)0xf8, (byte)0xd1, (byte)0xc1, (byte)0x09, (byte)0xf9, (byte)0x81, (byte)0xa9, (byte)0x4b, (byte)0xd3, (byte)0x2c, (byte)0x00, (byte)0x0c, (byte)0xca, (byte)0x81, (byte)0x61, (byte)0x19, (byte)0x53, (byte)0x21, (byte)0x00, (byte)0x09, (byte)0x8a, (byte)0x2c, (byte)0x00, (byte)0x0c, (byte)0xca, (byte)0x81, (byte)0x41, (byte)0x11, (byte)0x53, (byte)0x21, (byte)0x00, (byte)0x10, (byte)0x8a, (byte)0x2c, (byte)0x00, (byte)0x0c, (byte)0xca, (byte)0x81, (byte)0x49, (byte)0x4c, (byte)0xca, (byte)0x03, (byte)0x38, (byte)0x40, (byte)0xb9, (byte)0x61, (byte)0x00, (byte)0x01, (byte)0x0a

        };
        mu.mem_write(BASE, code);

        // 初始化数据区(全 0)
        mu.mem_write(DATA, new byte[DATA_SIZE]);

        // 设置寄存器
        mu.reg_write(Arm64Const.UC_ARM64_REG_X0, DATA);
        mu.reg_write(Arm64Const.UC_ARM64_REG_X14, DATA);

        // 写入测试数据
        mu.mem_write(DATA + 0x1380, pack64(0x9L));
        mu.mem_write(DATA + 0x48,   pack64(0xbd2a6569L));
        mu.mem_write(DATA + (0xa << 3), pack64(0x3bed4641L));
        mu.mem_write(DATA + (0x196 << 3), pack64(0x9d8e582bL));
        mu.mem_write(DATA + 0x38, pack64(0x3ffL));

        // 设置 SP
        mu.reg_write(Arm64Const.UC_ARM64_REG_SP, STACK + STACK_SIZE/2);
        // 启动执行
        try {
            mu.emu_start(BASE, BASE + code.length, 0, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 取寄存器结果
        long x1_val = (long) mu.reg_read(Arm64Const.UC_ARM64_REG_X1);
        long x2_val = (long) mu.reg_read(Arm64Const.UC_ARM64_REG_X2);
        System.out.printf("x1=0x%x\n", x1_val);
        System.out.printf("x2=0x%x\n", x2_val);
    }

    // 工具函数:小端打包 long → byte[]
    private static byte[] pack64(long value) {
        ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        buffer.putLong(value);
        return buffer.array();
    }
}
相关推荐
gpfyyds6668 分钟前
Python代码练习
开发语言·python
YuTaoShao20 分钟前
【LeetCode 每日一题】1653. 使字符串平衡的最少删除次数——(解法三)DP 空间优化
算法·leetcode·职场和发展
茉莉玫瑰花茶26 分钟前
C++ 17 详细特性解析(5)
开发语言·c++·算法
cpp_250138 分钟前
P10570 [JRKSJ R8] 网球
数据结构·c++·算法·题解
cpp_250144 分钟前
P8377 [PFOI Round1] 暴龙的火锅
数据结构·c++·算法·题解·洛谷
uesowys1 小时前
Apache Spark算法开发指导-Factorization machines classifier
人工智能·算法
aiguangyuan1 小时前
使用LSTM进行情感分类:原理与实现剖析
人工智能·python·nlp
季明洵1 小时前
C语言实现单链表
c语言·开发语言·数据结构·算法·链表
shandianchengzi1 小时前
【小白向】错位排列|图文解释公考常见题目错位排列的递推式Dn=(n-1)(Dn-2+Dn-1)推导方式
笔记·算法·公考·递推·排列·考公
I_LPL1 小时前
day26 代码随想录算法训练营 回溯专题5
算法·回溯·hot100·求职面试·n皇后·解数独