吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 163|回复: 0
上一主题 下一主题
收起左侧

[学习记录] 一个有助于小白了解代码虚拟化的c++源码

[复制链接]
跳转到指定楼层
楼主
qq465881818 发表于 2026-8-15 21:09 回帖奖励
[C++] 纯文本查看 复制代码
#include <iostream>
#include <vector>
#include <cstdint>
#include <stdexcept>

enum class VM_OPCODE : uint8_t
{
    NOP = 0x00,
    PUSH,
    POP,
    ADD,
    SUB,
    MUL,
    DIV,
    PRINT,
    JMP,
    JNZ,
    HALT
};




struct VM_CONTEXT
{ 
    std::vector<int64_t> vStack;
    size_t vEip=0;
    std::vector<uint8_t> bytecode;
};


class MiniCodeVM
{
    VM_CONTEXT m_ctx;
    int64_t fetch_imm()
    {
        if (m_ctx.vEip + 4 > m_ctx.bytecode.size())
        {
            throw std::runtime_error("bytecode out of range");
        }

        int64_t val = 0;
        val |= m_ctx.bytecode[m_ctx.vEip + 0] << 0;
        val |= m_ctx.bytecode[m_ctx.vEip + 1] << 8;
        val |= m_ctx.bytecode[m_ctx.vEip + 2] << 16;
        val |= m_ctx.bytecode[m_ctx.vEip + 3] << 24;
        m_ctx.vEip += 4;
        return val;
    }
public:
    void load_bytecode(const std::vector<uint8_t>& code)
    {
        m_ctx.bytecode = code;
        m_ctx.vEip = 0;
        m_ctx.vStack.clear();
    }
    void run()
    {
        while (m_ctx.vEip < m_ctx.bytecode.size())
        {
            VM_OPCODE op = static_cast<VM_OPCODE>(m_ctx.bytecode[m_ctx.vEip]);
            m_ctx.vEip++;
            
            switch (op)
            {
                case VM_OPCODE::NOP:
                    break;
                case VM_OPCODE::PUSH:
                    {
                        int64_t val = fetch_imm();
                        m_ctx.vStack.push_back(val);
                        
                    }
                    break;
                   
                case VM_OPCODE::POP:
                    {
                    if (m_ctx.vStack.empty()) {break;}
                        m_ctx.vStack.pop_back();
                 
                    }
                    break;

                case VM_OPCODE::ADD:
                {
                    auto b = m_ctx.vStack.back(); m_ctx.vStack.pop_back();
                    auto a = m_ctx.vStack.back();m_ctx.vStack.pop_back();
                    m_ctx.vStack.push_back(a + b);
                  
                }
                break;

                case VM_OPCODE::SUB:
                {
                    auto b = m_ctx.vStack.back(); m_ctx.vStack.pop_back();
                    auto a = m_ctx.vStack.back();m_ctx.vStack.pop_back();
                    m_ctx.vStack.push_back(a - b);
                  
                }
                break;

                case VM_OPCODE::MUL:
                {
                    auto b = m_ctx.vStack.back(); m_ctx.vStack.pop_back();
                    auto a = m_ctx.vStack.back();m_ctx.vStack.pop_back();
                    m_ctx.vStack.push_back(a * b);
                  
                }
                break;

                case VM_OPCODE::DIV:
                {
                    auto b = m_ctx.vStack.back(); m_ctx.vStack.pop_back();
                    auto a = m_ctx.vStack.back();m_ctx.vStack.pop_back();
                    m_ctx.vStack.push_back(a / b);
                  
                }
                break;

                case VM_OPCODE::PRINT:
                {
                    if (!m_ctx.vStack.empty())
                    {
                        std::cout <<"[VM Output]" << m_ctx.vStack.back() << std::endl;
                       
                    }
                   
                }
                break;

                case VM_OPCODE::JMP:
                {
                    int64_t offset =static_cast<int64_t>(fetch_imm());
                    m_ctx.vEip = offset;
                }   
                break;

                case VM_OPCODE::JNZ:
                {
                    int64_t offset = static_cast<int64_t>(fetch_imm());
                    if (!m_ctx.vStack.empty())
                    {
                        if (m_ctx.vStack.back() != 0)
                        {
                            m_ctx.vEip = offset;
                        }
                    }
                }
                break;

                case VM_OPCODE::HALT:
                {
                    std::cout << "VM halted successfully" << std::endl;
                    m_ctx.vEip = m_ctx.bytecode.size();
                }
                break;

                default:
                    throw std::runtime_error("invalid opcode");

            }

        }

    }
};

std::vector<uint8_t> compile_sample()
{
    std::vector<uint8_t> code;

    // PUSH 10
    code.push_back(static_cast<uint8_t>(VM_OPCODE::PUSH));
    for (int i = 0; i < 4; i++) code.push_back((10 >> (8 * i)) & 0xFF);

    // PUSH 20
    code.push_back(static_cast<uint8_t>(VM_OPCODE::PUSH));
    for (int i = 0; i < 4; i++) code.push_back((20 >> (8 * i)) & 0xFF);

    // ADD  -> 栈顶=30
    code.push_back(static_cast<uint8_t>(VM_OPCODE::ADD));

    // PUSH 5
    code.push_back(static_cast<uint8_t>(VM_OPCODE::PUSH));
    for (int i = 0; i < 4; i++) code.push_back((5 >> (8 * i)) & 0xFF);

    // MUL -> 30*5=150
    code.push_back(static_cast<uint8_t>(VM_OPCODE::MUL));

    // PRINT 输出结果
    code.push_back(static_cast<uint8_t>(VM_OPCODE::PRINT));

    // 停止虚拟机
    code.push_back(static_cast<uint8_t>(VM_OPCODE::HALT));

    return code;
}





int main()
{
   
    MiniCodeVM vm;
    vm.load_bytecode(compile_sample());
    vm.run();

    std::cin.get();

    return 0;
}

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-8-16 08:07

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表