Ruby:将内存地址字符串转换为Shellcode可用字节
解决字符串格式缓冲区地址转Shellcode可用字节串的问题
我来帮你搞定这个地址转换的坑!你遇到的核心问题就是字符串格式的十六进制地址没法直接传给string.pack,因为它需要整数类型参数。下面给你两种靠谱的解决方法,还有细节说明:
方法一:先转整数再打包(最简洁)
这是最直接的方式,两步就能搞定:
- 把十六进制字符串转成Lua整数
- 用
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
相关产品推荐
相关产品推荐

