我们来回顾下raiky code
根据帖子里的讨论错误的疑点在于
1. 对每个像素所占字节的估算可能有误
wBitCount;位图中每个像素所占字节数 简单的赋值4
2. 涉及到后面的调色板的处理 我本人不喜欢调色板
3. 位图内存分配大小的错误
接下来对每一行试着运行一番看看效果吧
你问我有没有玩过debug?
买过书没看算么? 书到用时方恨少
哦 想起来了以前玩VBA 调试过代码 这和exe程序完全不能比啊
赶鸭子上架 用obdg v110.. 110 ..110…
开始之前我们先准备下全局变量的改造
因为帖子里的变量本来都是局部在给函数内部使用
被我把代码拉到了start内
因为我调试的时候不希望step into(F7)
我目前只会用F8(Step over) 这样能有效避免被跳晕
请看下面 变量声明被我改成这样了
.data
hBmp dd 0
;
.data? ;这些本来是local型的局部变量 我将它们挪到了全局变量里来 连struct BITMAPINFO也放来了
hDc dd ?
MemDc dd ?
Data dd ? ;普通变量?
bi BITMAPINFO <> ;结构体采用<>
BITMAPINFO 是个window.ini定义的结构体
别看简单的改动 我走了不少弯路
raiky简单的 一行LOCAL @bi:BITMAPINFO 就在函数内声明了
我当时想换到全局变量的时候网上搜了半天
没有扎实的基础每一步都好艰辛 以后得抽时间多看书
Debug环境的准备
对电脑整个屏幕的截图 最好是用个简单的solid color来分析
于是我隐藏了taskbar,隐藏了桌面图标
设置了电脑桌面为solid color
查看下这张图的B-G-R值对应16进制为 B1-63-00
对 你没有看错,顺序就是B-G-R后面会证实这点
Specifically in the order (blue, green and red, 8-bits per each sample). 听说这是微软说的
OllyDbg
先来一张入门的界面介绍
MASM32编译程序
然后 用OllyDbg打开生成的exe
刚打开exe是这样的 请注意下图黄色标注的地址
上面是77开头下面是0040开头 不在一个地址段
先按F8 几次 让他走几步….
等到程序运行到0040开头的地址后开始往下翻
找到CreateDIBSection函数处
还记得我们前面说过CreateDIBSection的参数Data吗
00403078就是Data, 也可以理解为电脑不知道Data这个名字,就是分配了这个地址00403078用来存变量 这个变量就是我们程序里的Data
你问我 我是怎么找到他的?
你看他前后的参数
一个叫DIB_RGB_COLORS
一个是NULL 那么夹在中间的肯定是Data
invoke CreateDIBSection,MemDc,addr bi,DIB_RGB_COLORS,addr Data,NULL,0
还记得Data是干嘛的吗 ?
对 Data就是存BMP信息的地址
这个Data是CreateDIBSection函数的参数ppBits=pointer to pointer variable
也就是说地址00403078存放着的另外一块内存的地址
现在内存地址00403078的内容还是空的0
继续F8
一旦函数CreateDIBSection执行完毕00403078的值就有了 如下图
02 15 00 00 (x86小数在前 所以要颠倒下)
打开view-memory
找到02-15-00-00 size是00-5e-f0-00
双击进去查看,目前还没有bitblt 从头至尾全是0
继续F8
执行完bitblt 马上Data所指向的这块memory就有内容了–我的天呐 我刚才抓屏的时候dbg界面最大化了 很多蓝色抓不到
我现在再run一次 这次getDC之前我将debug软件窗口缩小 尽量让四周都是蓝色桌面壁纸(这次我将前面的DbgDump注释掉了 可以少按很多F8)
这次地址变了 (因为我注释掉了一些函数?好像每次Data指向的RAM地址也都不固定)
bitblt之前data的内容依然是0
bitblt运行之后data的内容马上出来了
看到了吗 B1 63 00-B1 63 00-……
多么熟悉的数字
每个像素3个字节!!!
我自己用截图PrtSc快捷键截屏 粘贴到小画家保存壁纸为24bit BMP
用OllyDbg view file 打开这个文件
这个文件里除了开头一些字节 其余全是B1-63-00 这应该是没有调色板的 我就喜欢这种单纯的文件 懒得研究调色板了
我们的汇编里该怎么实现呢
好吧搜到了
bmiHeader初始化的时候bmiHeader.biCompression赋值为BI_RGB 这样就不会有调色板了
具体如下
mov bi.bmiHeader.biPlanes,1
mov bi.bmiHeader.biBitCount,24 ;ok
mov bi.bmiHeader.biCompression,BI_RGB ;当biCompression成员的值是BI_RGB(0)时,它没有调色板
前面已经用RtlZeroMemory将整个bi填充过一次0了
而BI_RGB本身就是0 所以这个biCompression可以忽略 不赋值0也一样的效果
这样bitblt出来的全是B1-63-00了 当然后面没有用完的地址默认还是00
<未完待续, 第四篇将会介绍文件的生成>