很早以前就想研究一下託管函式的掛鉤,但是一直沒有成功。前段時間又嘗試了一次,竟然成功了,這讓我十分的困惑——因為我幾乎沒有對**做任何改變!
這次實驗距離以前已經有很長時間了,我實在想不出有什麼不同之處,唯一的區別就是以前用的是控制台程式,這次是
winform
程式,但我想不可能是這個原因吧?不過我還是嘗試了一下,未曾料到竟真是如此!
我當然不會相信這樣的靈異事件!
於是我想,我平時寫**很隨意,一般不自己定義類,直接在自動生成的類裡定義函式,會不會是這個原因呢?
於是我將控制台的類派生之
form
,果然,掛鉤成功。
但是很顯然,不可能是因為
form
類,於是我很自然的想到了繼承樹上更高層次的
marshalbyrefobject
類,並驗證了一下,正如我所料,**如下:
namespace
clr_hook
static
void hook(action my,action you)
} class
cstod:marshalbyrefobject
public
void you()
} }
可以看到,我明明呼叫的是
cstod
類的my
方法,但是輸出結果告訴我們,實際呼叫的是
you方法,說明掛鉤成功了。
而如果我在掛鉤之前已經呼叫過該方法,則掛鉤失敗:
static
void main()
這讓我十分困惑,唯一能想到的理由是:
my方法的位址最初被存放在記憶體中的
a位址,當
my方法被呼叫後,又在記憶體中的
b位址存了乙份拷貝,以後再呼叫時,直接到
b位址去讀取
my方法的位址。
這樣的話,雖然我們修改了
a位址中的資料,但並不影響
my方法的呼叫。
當然,這只是我的猜測。
此路不通,我想了另乙個方法——直接修改函式體,用經典的
jmp指令跳轉。
但是,又失敗了,因為該記憶體受保護,根本不能寫:
static
void hook(action my, action you)
本來以為修改一下保護屬性就行了,結果連查詢保護屬性都失敗,
virtualquery
、virtualprotect
統統呼叫失敗。
我也嘗試用
marshal
類,unmanagedmemorystream
類,和writeprocessmemory
函式來修改記憶體,全部失敗。
另外,靜態函式無法掛鉤。
託管函式和非託管函式如何互相傳遞ansi字串?
先來介紹兩個預處理指令 pragma unmanaged pragma managed 這兩個預處理指令,控制函式編譯成託管函式,還是非託管函式。是函式級別的預控制指令。1.託管函式傳送字串給非託管函式 分三步走 a.先呼叫stringtohglobalansi將string轉換成intptr型別變...
託管函式和非託管函式如何互相傳遞ansi字串?
先來介紹兩個預處理指令 pragma unmanaged pragma managed 這兩個預處理指令,控制函式編譯成託管函式,還是非託管函式。是函式級別的預控制指令。1.託管函式傳送字串給非託管函式 分三步走 a.先呼叫stringtohglobalansi將string轉換成intptr型別變...
託管呼叫非託管的DLL
dllimport createnewprocess.dll charset charset.unicode public static extern bool createprocess marshalas unmanagedtype.lpwstr string fullpath 以上是定義入口,...