注册会员 登录
Project1 返回首页

羽箭草船 https://rpg.blue/?115768 [收藏] [复制] [分享] [RSS] 弓箭手.剑兰!

日志

[RM]《Bitmap高速Marshal》取得地址的技术讲解

热度 2已有 681 次阅读2011-5-29 20:30 |个人分类:RM技术| Bitmap, 内存地址, RtlMoveMemory

关于柳之一的快速存储Bitmap的Marshal(高难度API,不解释)的技术讲解,
原本的这个是苏告诉我们的(这里:http://bbs.66rpg.com/forum.php?mod=viewthread&tid=183521&fromuid=115768)
因为我想将此记录下来,于是重写一次。

class Bitmap
  #--------------------------------------------------------------------------
  # ● 传送到内存的API函数
  #--------------------------------------------------------------------------
  RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
  #--------------------------------------------------------------------------
  # ● Bitmap地址
  #--------------------------------------------------------------------------
  def address
    buffer = " " * 4
   
ad = object_id * 2 + 16
    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)
    return buffer.unpack("L")[0]
  end
end


先简述 RtlMoveMemory 怎么用,RtlMoveMemory(目的地, 源址, 字节数),你可以:
(String, address, String#size)->内存中 address (地址)之后的 String#size 字节拷贝为 String。
(address, String, String#size)->将String拷贝到 address (地址)之后的 String#size 字节。
大致是这两种用法。address 是一个 Long 类型,总之就是内存的地址位置的偏移量(数字)。

然后就是关于 object_id 了,Ruby的对象的 object_id * 2 就是底层的结构(首)地址。
而 buffer 是四个字节的原因是因为这储存了指针(4字节)。

 

以前国外有人逆向分析出 Bitmap 的结构,大致如此:

 

typedef struct rgss_bitmap_t rgss_bitmap_t;
typedef struct rgss_bminfo_t rgss_bminfo_t;
typedef struct bitmap_t bitmap_t;

struct rgss_bitmap_t
{
    uint32_t flags;
    uint32_t klass;
    void (*dmark)(void*);
    void (*dfree)(void*);
    bitmap_t* bm;
}

struct bitmap_t
{
    uint32_t unk1;
    uint32_t unk2;
    rgss_bminfo_t *bminfo;
}

struct rgss_bminfo_t
{
    uint32_t unk1;
    uint32_t unk2;
    BITMAPINFOHEADER *infoheader;
    RGBQUAD *first;
    RGBQUAD *last;
}

头三行其实可以54= =,然后我将他们以图案表示:

先著名, 内存地址就是首部/头部/位置。还有指针的值就是内存地址。

 

buffer = " " * 4
解说:分配指针占的4个字节

 

ad = object_id * 2 + 16
解说:rgss_bitmap_t 的地址偏移 16 ,就是 *bm 的头部

 

RtlMoveMemory_pi.call(buffer, ad, 4)
解说:拷贝 *bm 指针 (四个字节), 指向 bitmap_t 内存地址

 

ad = buffer.unpack("L")[0] + 8
解说:unpack("L")后就是 bitmap_t 的内存地址, 偏移 8 , 在 *bminfo 头

 

RtlMoveMemory_pi.call(buffer, ad, 4)
解说:拷贝 *bminfo 指针 (4 bytes), 指向(内存地址) rgss_bminfo_t 结构体的头部

 

ad = buffer.unpack("L")[0] + 16
解说:unpack("L")后在 rgss_bminfo_t 结构的内存地址, 偏移 16 到达 *last

 

RtlMoveMemory_pi.call(buffer, ad, 4)
解说:拷贝 *last , 就是颜色值的地址

 

return buffer.unpack("L")[0]
解说:将这个地址unpack("L"), 就是一个整数地址了


鸡蛋
2

鲜花

刚表态过的朋友 (2 人)

发表评论 评论 (1 个评论)

回复 DeathKing 2011-6-4 00:30
辛苦了。看到偶喜欢的Courier New字体了。

facelist doodle 涂鸦笔

您需要登录后才可以评论 登录 | 注册会员

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

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

GMT+8, 2024-4-16 23:41

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

返回顶部