安全防御

DeeLMind大约 2 分钟

安全防御

DeeLMind 提示

安全防御,和传统安全一样,没有区别

安全防御

代码方向(静态)

  • 代码审计
  • 模糊测试
  • 形式化检验 (Formal Verification) TAL+ & Coq

行为方向(动态)

  • 调用流程监控

虚拟化保护

  • OLLVM
  • 混淆加密
  • 虚拟化保护
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract A {
    enum B {
        C,  // 0x00
        D,  // 0x01
        E,  // 0x02
        F,  // 0x03
        G   // 0x04, 新增 PUSH 操作码用于压入操作数
    }

    uint256[] private H;
    uint8[] private I;

    function J(uint8[] memory K) public {
        delete I;
        I = K;
    }

    function L() public {
        delete H;

        for (uint256 M = 0; M < I.length; M++) {
            B N = B(I[M]);

            if (N == B.G) {
                M++;
                O(uint256(uint8(I[M])));
            } else if (N == B.C) {
                O(P() + P());
            } else if (N == B.D) {
                uint256 Q = P();
                uint256 R = P();
                O(R - Q);
            } else if (N == B.E) {
                O(P() * P());
            } else if (N == B.F) {
                uint256 Q = P();
                uint256 R = P();
                require(Q != 0, "S");
                O(R / Q);
            } else {
                revert("T");
            }
        }
    }

    function P() internal returns (uint256) {
        uint256 U = H[H.length - 1];
        H.pop();
        return U;
    }

    function O(uint256 V) internal {
        H.push(V);
    }

    function W() public view returns (uint256) {
        return H[H.length - 1];
    }
}

contract SimpleVM {
    enum Opcode {
        ADD,    // 0x00
        SUB,    // 0x01
        MUL,    // 0x02
        DIV,    // 0x03
        PUSH    // 0x04, 新增 PUSH 操作码用于压入操作数
    }

    uint256[] public stack;
    uint8[] public program;

    function loadProgram(uint8[] memory _program) public {
        delete program;
        program = _program;
    }

    function execute() public {
        delete stack;

        for (uint256 i = 0; i < program.length; i++) {
            Opcode opcode = Opcode(program[i]);

            if (opcode == Opcode.PUSH) {
                i++;
                stackPush(uint256(uint8(program[i])));
            } else if (opcode == Opcode.ADD) {
                stackPush(stackPop() + stackPop());
            } else if (opcode == Opcode.SUB) {
                uint256 b = stackPop();
                uint256 a = stackPop();
                stackPush(a - b);
            } else if (opcode == Opcode.MUL) {
                stackPush(stackPop() * stackPop());
            } else if (opcode == Opcode.DIV) {
                uint256 b = stackPop();
                uint256 a = stackPop();
                require(b != 0, "Division by zero");
                stackPush(a / b);
            } else {
                revert("Invalid opcode");
            }
        }
    }

    function stackPop() internal returns (uint256) {
        uint256 value = stack[stack.length - 1];
        stack.pop();
        return value;
    }

    function stackPush(uint256 value) internal {
        stack.push(value);
    }

    function top() public view returns (uint256) {
        return stack[stack.length - 1];
    }
}

contract SimpleCompiler {
    SimpleVM public vm;

    constructor(address vmAddress) {
        vm = SimpleVM(vmAddress);
    }

    // 编译器将加减乘除表达式转换为操作码
    function compile(string memory expression) public pure returns (uint8[] memory) {
        bytes memory expr = bytes(expression);
        uint8[] memory opcodes = new uint8[](expr.length * 2); // 操作码和操作数

        uint256 idx = 0;
        for (uint256 i = 0; i < expr.length; i++) {
            if (expr[i] >= '0' && expr[i] <= '9') {
                uint256 value = uint256(uint8(expr[i])) - 48;
                opcodes[idx++] = uint8(SimpleVM.Opcode.PUSH); // 先生成 PUSH 操作码
                opcodes[idx++] = uint8(value);                // 再生成数字本身
            } else if (expr[i] == '+') {
                opcodes[idx++] = uint8(SimpleVM.Opcode.ADD);
            } else if (expr[i] == '-') {
                opcodes[idx++] = uint8(SimpleVM.Opcode.SUB);
            } else if (expr[i] == '*') {
                opcodes[idx++] = uint8(SimpleVM.Opcode.MUL);
            } else if (expr[i] == '/') {
                opcodes[idx++] = uint8(SimpleVM.Opcode.DIV);
            }
        }

        // 将操作码数组截取到正确的长度
        assembly { mstore(opcodes, idx) }

        return opcodes;
    }
    
    // 编译并执行
    function compileAndExecute(string memory expression) public returns (uint256) {
        uint8[] memory opcodes = compile(expression);
        vm.loadProgram(opcodes);
        vm.execute();
        return vm.top();
    }

    function compile2Opcode(string memory expression) public pure returns (uint8[] memory){
        return compile(expression);
    }
}

contract Test{
    function test() public returns (uint256){
        SimpleVM vm = new SimpleVM();
        SimpleCompiler compiler = new SimpleCompiler(address(vm));

        uint256 result = compiler.compileAndExecute("35+2*");
        return result;
    }

    function getOpcode() public returns (uint8[] memory){
        SimpleVM vm = new SimpleVM();
        SimpleCompiler compiler = new SimpleCompiler(address(vm));
        return compiler.compile2Opcode("34+2*");
    }
}
上次编辑于:
贡献者: DeeLMind,DeeLMind