热度 2||
关于柳之一的快速存储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"), 就是一个整数地址了
站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作
GMT+8, 2024-4-28 13:08
Powered by Discuz! X3.1
© 2001-2013 Comsenz Inc.