VB內嵌彙編

2021-05-08 21:11:35 字數 2382 閱讀 5648

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棧的大小是在鏈結時決定的 如果是自己測的話,...