设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
楼主: 柳之一
打印 上一主题 下一主题

[原创发布] 快速存储Bitmap的Marshal(高难度API,不解释)

 关闭 [复制链接]

Lv1.梦旅人

风之塞尔达

梦石
0
星屑
50
在线时间
57 小时
注册时间
2005-10-22
帖子
2492

贵宾

41
发表于 2008-8-10 10:50:02 | 只看该作者
半夜睡不着, 爬上来研究这个脚本果然很有催眠效果{/gg}
lz会写这个脚本, 应该可以自己DIY  ruby了吧?
以下引用沉影不器于2008-8-9 22:26:18的发言:object_id * 2 + 16<---这个楼主很早就说明了在ruby资源文件里头说的
这脚本的伟大还在于真的需要了解到很多内部类的构成啊啊啊...

不会就是rb_obj_id 函数体里那段注释吧?  没看出来和object_id*2有什么关系{/gg}
到现在也没看懂 ruby的对象的self和他对应的C结构体指针怎么算...
找到对应函数, 看不懂里面过程{/gg}
在程序里延续塞尔达的传说, 在画板上勾勒塞尔达的轮廓!!
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
46
在线时间
10 小时
注册时间
2007-5-27
帖子
2558

第1届Title华丽大赛新人奖

42
发表于 2008-8-10 17:20:20 | 只看该作者
以下引用link006007于2008-8-10 2:50:02的发言:
不会就是rb_obj_id 函数体里那段注释吧?  没看出来和object_id*2有什么关系
到现在也没看懂 ruby的对象的self和他对应的C结构体指针怎么算...
找到对应函数, 看不懂里面过程

我没下载那些什么ruby资源之流,我是先默认'object_id*2 + 16'成立,那么所有内存操作都明显成立了.

如今对font和bitmap内部类兴趣,我们知道Bitmap类有个属性font,现在从这份脚本往回猜,可猜得font在bitmap中是作为实例变量存在的...
以上,我希望得到楼主的确认并告知更多,可惜他总避而不谈,只是一再强调rb_obj_id和DATA_PTR...可Bitmap是标准库么....


  1. class Bitmap
  2.   def font
  3.     self.font = Font.new("宋体",12)
  4.   end
  5. end
复制代码
签名被屏蔽
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
49
在线时间
0 小时
注册时间
2007-7-1
帖子
552
43
发表于 2008-8-11 20:38:50 | 只看该作者
以下引用link006007于2008-8-9 12:09:57的发言:

我一直很好奇  
我觉得  最关键是lz最早是怎么得到bitmap的图像数据是保存在Bitmap实例内存首地址偏移这么多的量之后的内存地址中的


你用OllDBG跟踪GAME.EXE试试吧,应该也能得到吧...{/fd}
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
120
在线时间
68 小时
注册时间
2007-12-16
帖子
75
44
发表于 2008-8-13 05:57:28 | 只看该作者
以下引用dna_7086于2008-8-11 12:38:50的发言:


以下引用link006007于2008-8-9 12:09:57的发言:

我一直很好奇  
我觉得  最关键是lz最早是怎么得到bitmap的图像数据是保存在Bitmap实例内存首地址偏移这么多的量之后的内存地址中的



你用OllDBG跟踪GAME.EXE试试吧,应该也能得到吧...


跟踪没用
因为主程序是RGSSX0XX.dll
而且这还是个直译器
能得到什么东西啊
还不就一堆直译器的指令



楼主
想问一下address
最后传回的是內存的实体地址
还是RGSS内部的地址


顺便介绍一下此脚本吧


# 贴上此脚本后
# 可直接用Marshal模组读写Bitmap类
# 不需多做修改
# 介绍一下Marshal模组运作原理
# 以脚本呈现
# 不代表实际执行的脚本
# def Marshal.dump(obj, port = nil, limit = 100)
#   result = # obj._dump(limit) or obj.marshal_dump 其中一个
#   return result if port == nil
#   写入 result 至 port
# end
# def Marshal.load(port)
#   dat = 读取 port
#   return # obj._load(dat) or obj.marshal_load(dat) 其中一个
# end
# 上面的 写入 和 读取 为一些IO的指令
class Font
  # Marshal.dump 对类调用的主程序
  def marshal_dump
  end
  # Marshal.load 对类调用的主程序
  def marshal_load(obj)
  end
  # 上面的方法没定义内容是因为
  # Font类对Bitmap类中的存储不重要
  # 而预设Font类也没有这2个方法
end
class Bitmap
  # 传送到内存的API函数
  # 读取内存用 参数为 字串 整数 整数
  RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
  # 写入内存用 参数为 整数 字串 整数
  RtlMoveMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i')
  # 在此整数为1字节的整数
  # Win32API 会帮忙转换
  # 供 Marshal 模组用的写入方法
  def _dump(limit) # limit 为 深度限制 但这里忽略不使用
    # 生成 4 * width * height 个字节的字串
    # 所以 "rgba" 可换成 任何4字节的字串 如 "\000" * 4
    # 在此为 RtlMoveMemory_pi 生成所需的内存空间
    data = "rgba" * width * height
    # 调用 RtlMoveMemory_pi 读取
    # 以address为地址
    # 长度为data.length ( 即 4 * width * height )
    # 的内存资料 并存入 data 中
    RtlMoveMemory_pi.call(data, address, data.length)
    # 将 [width, height, Zlib::Deflate.deflate(data)] 打包
    # [width, height, Zlib::Deflate.deflate(data)]
    # width,  height 为图片宽度 ( Bitmap 内属性 )
    # Zlib::Deflate.deflate(data)为压缩 data 内的文字 (GZip)
    # 至于 Array.pack 的参数是什么不重要
    # 只要跟 String.unpack 的参数一样就好
     # ※ 回传给 Marshal.dump 的资料必须为 String ( 字串 ) 类物件
    #   因为 _dump 或 marshal_dump 的工作即为
    #   将该类物件转为字串给 Marshal.dump 存入
   [width, height, Zlib::Deflate.deflate(data)].pack("LLa*") # ??
  end
  # 供 Marshal 模组用的读取方法
  def self._load(str) # str 为 Marshal.load 读出的字串
    # 解包 str
    # 并将解包后的阵列([width, height, data(压缩后)])
    # 分别存入w, h, zdata
    # w => width, h => height, zdata => data(压缩后)
    w, h, zdata = str.unpack("LLa*")
    # 生成 以 w 和 h 为宽高的图片
    # new 为继承 Object 的方法
    # 因此在任何物件中都有此方法
    b = new(w, h)
    # 调用 RtlMoveMemory_ip 修改
    # 以b.address为地址
    # Zlib::Inflate.inflate(zdata) 为资料
    # Zlib::Inflate.inflate(zdata) 为解压缩 zdata 内的文字 (GZip)
    # 长度为 w * h * 4
    # 的内存资料
    RtlMoveMemory_ip.call(b.address, Zlib::Inflate.inflate(zdata), w * h * 4)
    # 回传 b
    # 在 Ruby 中无 return 的话
    # 会自动回传最后一个指令的回传值
    b
  end
  # [[[bitmap.object_id * 2 + 16] + 8] + 16] == 数据的开头
  def address
    # 定义 buffer 和 ad 为 "xxxx" 和 object_id * 2 + 16
    # 这是Ruby的多重指定
    # 左边超过右边时 超出的部份不会带入数值 ( 即同于带入 nil )
    # 右边超过左边时 超出的部份不管
    # 但左边最后一个变量以*开头时
    # 超出部份会以阵列带入该变量
    # 左边1个而右边超过1个时
    # 同于 *变数 = 值1, 值2, ...
    buffer, ad = "xxxx", object_id * 2 + 16
    # 下方为以 RtlMoveMemory_pi 逐步取得地址
    # 在此不做说明
    RtlMoveMemory_pi.call(buffer, ad, 4)
    ad = buffer.unpack("L")[0] + 8
    RtlMoveMemory_pi.call(buffer, ad, 4)
    ad = buffer.unpack("L")[0] + 16
    RtlMoveMemory_pi.call(buffer, ad, 4)
    # 回传 buffer.unpack("L")[0]
    # buffer.unpack("L") 在此不做说明
    return buffer.unpack("L")[0]
  end
end
回复 支持 反对

使用道具 举报

Lv1.梦旅人

炎发灼眼的讨伐者

梦石
0
星屑
50
在线时间
1707 小时
注册时间
2007-8-4
帖子
904
45
发表于 2008-8-31 18:04:52 | 只看该作者
以下引用沉影不器于2008-8-10 9:20:20的发言:

我没下载那些什么ruby资源之流,我是先默认'object_id*2 + 16'成立,那么所有内存操作都明显成立了.

。。。。并不都是这样的。。。。  这个16是和扩展类的data指针偏移对应的……{/gg}
RMXP&amp;RMVX通用Web化完成- -|||
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-24 08:25

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表