vb簡單易用,但功能有時候受限制。vc,delphi可以直接在程式中寫彙編**,可惱的是,vb不行。我看過網上也有關於vb嵌入彙編的,不過有些方法,過於複雜,而且也沒相應 的介紹。我這裡提供一種方法,也許大家以後可能有用!
基本思路:彙編**,可以存在乙個byte型別的陣列中,然後,通過某種手段,把系統控制權,轉交給這段彙編**,我們的彙編**段,就得到了執行。
但如何,讓這段彙編**,獲得系統的控制許可權呢?查查win api手冊,可以知道有callwindowproc這個函式。這個函式本是,用於呼叫使用者自己定義的視窗過程的,其原形如下:
function callwindowproc lib "user32" alias "callwindowproca" ( byval lpprevwndfunc as long, byval hwnd as long, byval msg as long, byval wparam as long, byval lparam as long) as long
它有5個引數。lpprevwnfunc是乙個long型,等於使用者自己視窗過程的位址,其餘3個都是視窗過程所必須的引數,詳見msdn。我們只需要關心第乙個引數:lpprevwndfunc,視窗過程位址。如果,我們把自己的彙編**位址,傳進去會怎麼樣?當然,callwindowproc就把這個位址,當成視窗過程位址,然後,呼叫這段彙編**了。我們的彙編**便得到執。。
當然,也得裝摸做樣的吧,將其餘4個引數傳進去,就傳4個0算了,因為這4個引數,我們更本不用,但又是callwindowproc必須的,不要忘了,我們傳進去的lpprevwndfunc,並非真正的視窗過程位址,而是自己的彙編碼位址。
具體一點,比如,我們要嵌入一段什麼也不幹的彙編**:先
dim asmcode() as byte
redim asmcode(8)
』生成機器**
asmcode(0) = &h58 』pop eax
asmcode(1) = &h59 』pop ecx
asmcode(2) = &h59 』pop ecx
asmcode(3) = &h59 』pop ecx
asmcode(4) = &h59 』pop ecx
asmcode(5) = &h50 』push eax
』你可以在這裡新增你想執行的asm**...
』.....如果新增的話,後面的陣列偏移需要做相應改動
』你新增的**在這裡結束
』將控制權交還主程式
asmcode(6) = &hc3 』ret
』.....
然後:
calldllfunction = callwindowproc(varptr(asmcode(0), 0, 0, 0, 0)varptr函式,用於取變數位址。返回乙個long 型值。
為什麼前面要執行幾個pop和乙個push呢?因為我們是以一段彙編**首位址,偽裝成乙個視窗過程的,系統呼叫callwindowproc時,實際上除lpprevwndfunc,我們還傳入了4個引數,就是上面的的4個0.而callwindoproc函式在呼叫lpprevwndfunc這段彙編**程式時,把其餘4個引數是壓入了堆疊的。相當於執行了以下**:
***x00a4h: push 0
***x00a6h: push 0
***x00a8h: push 0
***x00aah: push 0
***x00ach: call varptr(asmcode(0))(這段**我們是看不見的,是callwindoproc在內部做的處理)
***x00afh: ......
因為我們根本沒有用到這4個引數,所以我們只需要將它彈出。所以,我們執行了4個pop ecx,就是把這4個不用的引數彈出,以保持堆疊指標的正確性。但為什麼還要,第一句的:pop eax,還是因為callwindowproc把lpprevwndfunc當成乙個視窗過程的原故,因為作為乙個正常的視窗過程,在執行call語句的時候,得把call語句的下一條指令位址push到堆疊中,用於子程式ret。在上面這段**就是執行了:
push ***x00afh。事實上,在callwindowproc中,
實際上隱含執行這麼幾句,我們必須關心的**:
push 0;引數入棧
push 0
push 0
push 0
push ***x00afh;(當執行call 時,自動執行)
為了能讓視窗過程執行結束後堆疊指標保持平衡,當然要執行相應的pop指令,第乙個pop eax是把子程式返回的位址暫時儲存在暫存器eax中,然後彈出4個不用的引數。接著把儲存在eax中返回位址,壓回堆疊。當執行ret時,就能正確返回到callwindowproc中了。
關於內嵌彙編
最近才發現原來noi不給用內嵌彙編 那麼這篇文章除了平常做做oj以外就沒什麼意義了 參考自 嗯 搞oi久了應該都會碰到這麼一種問題 爆棧 當然,手寫棧是最普遍的一種解決方法 比如noi2011 day2 t1,ms是臨時換的一道水題,只要會手寫棧就可以水過 pascal黨是很舒服的,因為可以在 中手...
GCC內嵌彙編
gcc內嵌彙編 限制字元 限制字元有很多種,有些是與特定體系結構相關,此處僅列出常用的限定字元和i386中可能用到的一些常用的限定符。它們的作用是指示編譯器如何處理其後的c語言變數與指令運算元之間的關係,例如是將變數放在暫存器中還是放在記憶體中等,下表列出了常用的限定字母。b 將輸入變數放入ebx ...
關於內嵌彙編
參考自 嗯 搞oi久了應該都會碰到這麼一種問題 爆棧 當然,手寫棧是最普遍的一種解決方法 比如noi2011 day2 t1,ms是臨時換的一道水題,只要會手寫棧就可以水過 pascal黨是很舒服的,因為可以在 中手動把棧開大 但是c c 黨不行 因為ms棧的大小是在鏈結時決定的 如果是自己測的話,...