黃易群俠傳M脫機外掛應用程式黃易神行
6649
7

[分享] VB指針(二)

wen0116 發表於 2009-3-24 15:55:29 | 只看該作者 回帖獎勵 |倒序瀏覽 |
三、 程咬金的三板斧

  是的,程式二基本上就已經讓我們看到VB指標技術的模樣了。總結一下,在VB堨峆標技術我們需要掌握三樣東西:CopyMemory



VarPtr/StrPtr/ObjPtr, AdressOf. 三把斧頭,程咬金的三板斧,在VBHack的工具。


  1CopyMemory

  關於CopyMemoryBruce McKinney大師的傳奇,MSDNKnowledge Base中就有文章介紹,你可以搜索"ID: Q129947"的文章。


正是這位大師給32位的VB帶來了這個可以移動記憶體的API,也正是有了這個API,我們才能利用指標完成我們原來想都不敢想的一些工作,


感謝Bruce McKinney為我們帶來了VB的指標革命。


  如CopyMemory的聲明,它是定義在Kernel32.dll中的RtlMoveMemory這個API32位元C函數庫中的memcpy就是這個API的包裝,


MSDN文檔中所言,它的功能是將從Source指針所指處開始的長度為Length的記憶體拷貝到Destination所指的記憶體處。


它不會管我們的程式有沒有讀寫該記憶體所應有的許可權,一但它想讀寫被系統所保護的記憶體時,


我們就會得到著名的Access Violation Fault(記憶體越權訪問錯誤),甚至會引起更著名的general protection (GP) fault(通用保護錯誤)


所以,在進行本系列文章堛犒篘蝞氶A請注意隨時保存你的程式檔,在VB集成環境中將"工具"->"選項"中的"環境"選項卡堛"啟動程式時"設為"保存改變"


並記住在"立即"視窗中執行危險代碼之前一定要保存我們的工作成果。



  2VatPtr/StrPtr/ObjPtr

  它們是VB提供給我們的好寶貝,它們是VBA函數庫中的隱藏函數。為什麼要隱藏?因為VB開發小組,不鼓勵我們用指標嘛。

  實際上這三個函數在VB運行時庫MSVBVM60.DLL(或MSVBVM50.DLL)中是同一個函數VarPtr(可參見我在本系列第一篇文章堣雯衁漱隤k)。

  其庫型庫定義如下:

[entry("VarPtr"), hidden]
long _stdcall VarPtr([in] void* Ptr);
[entry("VarPtr"), hidden]
long _stdcall StrPtr([in] BSTR Ptr);
[entry("VarPtr"), hidden]
long _stdcall ObjPtr([in] IUnknown* Ptr);


  即然它們是VB運行時庫中的同一個函數,我們也可以在VBAPI方式重新聲明這幾個函數,如下:

Private Declare Function ObjPtr Lib "MSVBVM60" Alias "VarPtr" (var As Object) As Long
Private Declare Function VarPtr Lib "MSVBVM60" (var As Any) As Long

  (沒有StrPtr,是因為VB對字串處理方式有點不同,這方面的問題太多,我將在另一篇文章中詳談。順便提一下,


聽說VB.NET堥S有這幾個函數,但只要還能調用API,我們就可以試試上面的幾個聲明,這樣在VB.NET塈畯怳@樣可以進行指標操作。


但是請注意,如果通過API調用來使用VarPtr,整個程式二SwapPtr將比原來使用內置VarPtr函數時慢6倍。)

  如果你喜歡刨根問底,那麼下面就是VarPtr函數在C和組合語言堛獐豸l:

  在C媦豸l是這樣的:

long VarPtr(void* pv){
 return (long)pv;
}

  所對就的彙編代碼就兩行:

mov eax,dword ptr [esp+4]
ret 4 '彈出棧堸捊う滬並返回。

  之所以讓大家瞭解VarPtr的具體實現,是想告訴大家它的開銷並不大,因為它們不過兩條指令,即使加上參數賦值、壓棧和調用指令,


整個獲取指標的過程也就六條指令。當然,同樣的功能在C語言堙A由於語言的直接支援,僅需要一條指令即可。但在VB堙A


它已經算是最快的函數了,所以我們完全不用擔心使用VarPtr會讓我們失去效率!速度是使用指標技術的根本要求。

  一句話,VarPtr返回的是變數所在處的記憶體位址,也可以說返回了指向變數記憶體位置的指標,它是我們在VB堻B理指標最重要的武器之一。

  3ByValByRef

  ByVal傳遞的參數值,而ByRef傳遞的參數的地址。在這堙A我們不用去區別傳指標/傳位址/傳引用的不同,


VB堙A它們根本就是一個東西的三種不同說法,即使VB的文檔堣]有地方在混用這些術語(但在C++堛瑤T要區分指針和引用)

  初次接觸上面的程式二SwapPtr的朋友,一定要搞清在堶悸CopyMemory調用中,在什麼地方要加ByVal


什麼地方不加(不加ByVal就是使用VB缺省的ByRef),準確的理解傳值和傳地址(指標)的區別,是在VB堨蕭T使用指標的基礎。

  現在一個最簡單的實驗來看這個問題,如下面的程式三:

  【程式三】:

'體會ByValByRef
Sub TestCopyMemory()
 Dim k As Long
 k = 5
 Note: CopyMemory ByVal VarPtr(k), 40000, 4
 Debug.Print k
End Sub

  上面標號Note處的語句的目的,是將k賦值為40000,等同於語句k=40000,你可以在"立即"視窗試驗一下,會發現k的值的確成了40000


實際上上面這個語句,翻譯成白話,就是從保存常數40000的臨時變數處拷貝4個位元組到變數k所在的記憶體中。

  現在我們來改變一個Note處的語句,若改成下面的語句:

Note2: CopyMemory ByVal VarPtr(k), ByVal 40000, 4

  這句話的意思就成了,從位址40000拷貝4個位元組到變數k所在的記憶體中。由於位址40000所在的記憶體我們無權訪問,作業系統會給我們一個Access Violation記憶體越權訪問錯誤,告訴我們"試圖讀取位置0x00009c40處記憶體時出錯,該記憶體不能為'Read'"

  我們再改成如下的語句看看。

Note3: CopyMemory VarPtr(k), 40000, 4

  這句話的意思就成了,從保存常數40000的臨時變數處拷貝4個位元組到到保存變數k所在記憶體位址值的臨時變數處。


這不會出出記憶體越權訪問錯誤,但k的值並沒有變。
收藏收藏 分享分享 讚 幹 分享分享 FB分享
回覆

使用道具 舉報


Goldenwolf 當前離線
UID
1166302
熱心
75 值
嘉獎
0 次
違規
0 次
在線時間
17 小時
經驗
75 點
積分
426
精華
0
最後登錄
2009-10-8
閱讀權限
25
註冊時間
2009-3-28
論壇幣
259 幣
聯合幣
0 枚
幸運鑽
0 顆
招待卷
0 點
查看詳細資料
Rank: 3
Goldenwolf 2009-4-1 10:40:51
研讀中 感謝大大的分享!!
回覆

使用道具 舉報

193157339 當前離線
UID
701507
熱心
5 值
嘉獎
0 次
違規
0 次
在線時間
3 小時
經驗
5 點
積分
5
精華
0
最後登錄
2009-4-13
閱讀權限
5
註冊時間
2008-1-6
論壇幣
3 幣
聯合幣
0 枚
幸運鑽
0 顆
招待卷
0 點
查看詳細資料
Rank: 1
193157339 2009-4-2 23:42:39
研讀中 感謝大大的分享!!
回覆

使用道具 舉報

may05005 當前離線
UID
1208553
熱心
42 值
嘉獎
0 次
違規
0 次
在線時間
15 小時
經驗
32 點
積分
146
精華
0
最後登錄
2018-8-6
閱讀權限
20
註冊時間
2009-5-7
論壇幣
50 幣
聯合幣
6 枚
幸運鑽
0 顆
招待卷
0 點
查看詳細資料
Rank: 2Rank: 2
may05005 2009-5-12 16:22:53
研讀中 感謝大大的分享!!
本文章轉自外掛聯合國http://www.wgun.net
回覆

使用道具 舉報

jaydiy 當前離線
UID
1140322
熱心
50 值
嘉獎
0 次
違規
0 次
在線時間
17 小時
經驗
54 點
積分
54
精華
0
最後登錄
2009-12-16
閱讀權限
20
註冊時間
2009-2-22
論壇幣
533 幣
聯合幣
0 枚
幸運鑽
0 顆
招待卷
0 點
查看詳細資料
Rank: 2Rank: 2
5
jaydiy 2009-8-2 03:10:52
感謝大大的分享哦~ YCT47B

在學習研究中...感覺您的分享~

YCT65B
回覆

使用道具 舉報

隨火 當前離線
UID
1294953
熱心
214 值
嘉獎
0 次
違規
0 次
在線時間
6 小時
經驗
14 點
積分
14
精華
0
最後登錄
2011-4-5
閱讀權限
10
註冊時間
2009-8-20
論壇幣
78 幣
聯合幣
0 枚
幸運鑽
0 顆
招待卷
0 點
查看詳細資料
Rank: 1
6
隨火 2009-9-1 09:42:54
謝謝大大無私的分享  
使我更賞一成樓
回覆

使用道具 舉報

star456852 當前離線
UID
1311284
熱心
45 值
嘉獎
0 次
違規
0 次
在線時間
34 小時
經驗
44 點
積分
157
精華
0
最後登錄
2018-12-14
閱讀權限
20
註冊時間
2009-9-13
論壇幣
24 幣
聯合幣
9 枚
幸運鑽
2 顆
招待卷
0 點
查看詳細資料
Rank: 2Rank: 2
7
star456852 2009-9-13 17:19:47
看一看感覺好複雜ㄛ~~~  慢慢學吧!!!!!!!!!!!
回覆

使用道具 舉報

173ch 當前離線
UID
1437534
熱心
22 值
嘉獎
0 次
違規
0 次
在線時間
1 小時
經驗
22 點
積分
22
精華
0
最後登錄
2010-4-4
閱讀權限
20
註冊時間
2010-4-4
論壇幣
35 幣
聯合幣
0 枚
幸運鑽
0 顆
招待卷
0 點
查看詳細資料
Rank: 2Rank: 2
8
173ch 2010-4-4 21:58:38
努力學習中....很卸卸大大!!
YCT55B
回覆

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 註冊


手機版 | Archiver | 外掛聯合國

GMT+8, 2024-9-20 23:28 , Processed in 0.060975 second(s), 16 queries , Memcache On.

版權說明:
  本站不會製作、經銷、代理外掛程式。僅免費提供外掛程式下載前之掃毒及掃木馬等安全檢測驗證,協助會員遠離盜號危險程式。本站所有資料均來自網際網路收集整理,說明文字暨下載連結轉載自原程 式開發站。站上出現之公司名稱、遊戲名稱、程式等,商標及著作權,均歸各公司及程式原創所有,本站程式所有權歸外掛聯合國所有。本程式所有權歸外掛聯合國所有.......

回頂部
第二步?
第三步?