请求解析黑帽FrontRunningBot合约中ETH钱包地址的解码逻辑
黑帽合约钱包地址解码机制解析
目前正在分析黑帽传播的FrontRunningBot盗刷合约,这类合约通过parseMemoryPool(callMempool())获取隐藏的恶意钱包地址,核心解码逻辑集中在parseMemoryPool函数中,以下是具体拆解:
一、parseMemoryPool函数核心定位
该函数本质是将带0x前缀的十六进制字符串,转换为以太坊标准地址类型,逻辑和常规的十六进制转地址完全一致,只是通过硬编码完成字符到数值的映射。
二、逐行解码逻辑拆解
先贴出核心解码代码,再分步骤解释:
function parseMemoryPool(string memory _a) internal pure returns (address _parsed) { bytes memory tmp = bytes(_a); uint160 iaddr = 0; uint160 b1; uint160 b2; for (uint i = 2; i < 2 + 2 * 20; i += 2) { iaddr *= 256; b1 = uint160(uint8(tmp[i])); b2 = uint160(uint8(tmp[i + 1])); // 处理第一个十六进制字符 if ((b1 >= 97) && (b1 <= 102)) { b1 -= 87; } else if ((b1 >= 65) && (b1 <= 70)) { b1 -= 55; } else if ((b1 >= 48) && (b1 <= 57)) { b1 -= 48; } // 处理第二个十六进制字符 if ((b2 >= 97) && (b2 <= 102)) { b2 -= 87; } else if ((b2 >= 65) && (b2 <= 70)) { b2 -= 55; } else if ((b2 >= 48) && (b2 <= 57)) { b2 -= 48; } iaddr += (b1 * 16 + b2); } return address(iaddr); }
1. 字符串转字节数组
bytes memory tmp = bytes(_a); 将输入的地址字符串转换为字节数组,方便直接读取每个字符的ASCII码值。
2. 循环范围匹配地址长度
以太坊地址固定为20字节(160位),对应40个十六进制字符,加上字符串开头的0x前缀,有效地址字符从索引2开始,到索引42结束(左闭右开)。循环每次步长为2,正好每次处理一对十六进制字符(对应1字节数据)。
3. 十六进制字符转数值
通过ASCII码偏移量,将字符转换为对应十六进制数值:
- 小写字母
a-f(ASCII 97-102):减87得到10-15 - 大写字母
A-F(ASCII 65-70):减55得到10-15 - 数字
0-9(ASCII 48-57):减48得到0-9
4. 拼接为完整地址
- 每次循环先执行
iaddr *= 256,相当于将已拼接的结果左移8位,腾出1字节的空间 - 一对十六进制字符转换后,
b1*16 + b2得到1字节的十进制数值(比如0xa3对应10*16+3=163) - 将该数值加到
iaddr中,逐步拼接出完整的160位地址 - 最后将
uint160类型的iaddr强制转换为address类型返回
三、结合callMempool的完整流程
黑帽通过callMempool函数生成目标地址的十六进制字符串:
- 函数中多次调用
mempool(结合checkLiquidity处理那些差异化的uint数值),最终拼接出带0x前缀的完整地址字符串 - 不同合约中的uint返回值差异,本质是对应不同恶意地址的十六进制字符编码,最终通过
parseMemoryPool统一解码为标准以太坊地址
内容的提问来源于stack exchange,提问作者Kornelius
相关产品推荐
相关产品推荐

