我們來回顧下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
<未完待續, 第四篇將會介紹文件的生成>