You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby:将内存地址字符串转换为Shellcode可用字节

解决字符串格式缓冲区地址转Shellcode可用字节串的问题

我来帮你搞定这个地址转换的坑!你遇到的核心问题就是字符串格式的十六进制地址没法直接传给string.pack,因为它需要整数类型参数。下面给你两种靠谱的解决方法,还有细节说明:


方法一:先转整数再打包(最简洁)

这是最直接的方式,两步就能搞定:

  1. 把十六进制字符串转成Lua整数
  2. 用string.pack按对应字节序打包成字节串

示例代码

-- 假设你从socket.get_once捕获到的地址字符串(带/不带0x前缀都可以)
local leaked_addr_str = "0x7fffeabc1234" -- 或者 "7fffeabc1234"

-- 第一步:将十六进制字符串转为整数(第二个参数16表示按十六进制解析)
local addr_int = tonumber(leaked_addr_str, 16)

-- 第二步:打包成适合x86_64架构的小端字节串(<Q表示小端64位无符号整数)
local packed_addr = string.pack('<Q', addr_int)

关键说明

  • tonumber能自动处理带0x前缀的十六进制字符串,不用手动去掉前缀
  • 格式符<Q对应小端字节序(x86/x86_64架构默认用小端),如果你的目标架构是大端,就换成>Q
  • 这样得到的packed_addr就是可以直接嵌入shellcode的字节串了

方法二:手动拆分反转(对应你之前尝试的思路)

如果你想手动处理字节序(比如验证底层逻辑),可以把地址拆成对的十六进制片段,反转后转成字符再拼接:

示例代码

local leaked_addr_str = "7fffeabc1234"
-- 先去掉可能存在的0x前缀
local clean_addr = leaked_addr_str:gsub('^0x', '')

-- 从后往前每两个字符取一段,转成ASCII字符后存入数组
local byte_array = {}
for i = #clean_addr, 1, -2 do
    -- 取两个字符的十六进制片段,转成十进制整数再转成字符
    local byte = string.char(tonumber(clean_addr:sub(i-1, i), 16))
    table.insert(byte_array, byte)
end

-- 拼接成最终的字节串
local packed_addr = table.concat(byte_array)

为什么这个方法有效?

x86_64架构用小端字节序,也就是地址的低字节存在内存低地址,所以需要把十六进制字符串的后半段(对应地址的低字节)放到字节串的前面,反转片段就实现了这个效果。


为什么你之前会报错?

string.pack('Q')要求传入整数类型的参数,但你直接传了字符串格式的地址,Lua会因为类型不匹配抛出错误。只要先把字符串转成整数,或者手动转成字符拼接,就能解决这个问题。

内容的提问来源于stack exchange,提问作者blazers_99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:52:37