winapi【遠端注入】三種注入方案
; note that ecx contains the offset
:0040100c ff248d2c104000 jmp dword ptr [4*ecx+0040102c]
:00401013 b801000000 mov eax, 00000001 ; case 1: eax = 1;
:00401018 c3 ret
:00401019 b802000000 mov eax, 00000002 ; case 2: eax = 2;
:0040101e c3 ret
:0040101f b803000000 mov eax, 00000003 ; case 3: eax = 3;
:00401024 c3 ret
:00401025 b8b0a00000 mov eax, 0000a0b0 ; case 4: eax = 0xa0b0;
:0040102a c3 ret
:0040102b 90 nop
; 位址表 ***
:0040102c 13104000 dword 00401013 ; jump to case 1
:00401030 19104000 dword 00401019 ; jump to case 2
:00401034 1f104000 dword 0040101f ; jump to case 3
:00401038 25104000 dword 00401025 ; jump to case 4
看到switch-case是如何實現的了嗎?
它沒有去測試每個case分支,而是建立了乙個位址表(address table)。我們簡單地計算出在位址表中偏移就可以跳到正確的case分支。想想吧,這真是乙個進步,假設你有乙個50個分支的switch語句,假如沒有這個技巧,你不的不執行50次cmp和jmp才能到達最後乙個case,而使用位址表,你可以通過一次查表即跳到正確的case。使用演算法的時間複雜度來衡量:我們把o(2n)的演算法替換成了o(5)的演算法,其中:
1. o代表最壞情況下的時間複雜度。
2. 我們假設計算偏移(即查表)並跳到正確的位址需要5個指令。
現在,你可能認為上面的情況僅僅是因為case常量選擇得比較好,(1,2,3,4,5)。幸運的是,現實生活中的大多數例子都可以應用這個方案,只是偏移的計算複雜了一點而已。但是,有兩個例外:
●如果少於3個case分支,或
●如果case常量是完全相互無關的。(比如 1, 13, 50, 1000)。
最終的結果和你使用普通的if-else if是一樣的。
有趣的地方:如果你曾經為case後面只能跟常量而迷惑的話,現在你應該知道為什麼了吧。這個值必須在編譯期間就確定下來,這樣才能建立位址表。
回到我們的問題!
注意到0040100c處的jmp指令了嗎?我們來看看intel的文件對十六進製制操作碼ff的說明:
opcode instruction description
ff /4 jmp r/m32 jump near, absolute indirect,
address given in r/m32
jmp使用了絕對位址!也就是說,它的其中乙個運算元(在這裡是0040102c)代表乙個絕對位址。還用多說嗎?現在遠端的threadfunc會盲目第在位址表中004101c然後跳到這個錯誤的地方,馬上使遠端程序掛掉了。
f) 到底是什麼原因使遠端程序崩潰了?
如果你的遠端程序崩潰了,原因可能為下列之一:
1. 你引用了threadfunc中乙個不存在的字串。
2. threadfunc中乙個或多個指令使用了絕對定址(看附錄e中的例子)
3. threadfunc呼叫了乙個不存在的函式(這個函式呼叫可能是編譯器或聯結器新增的)。這時候你需要在反彙編器中尋找類似下面的**:
:004014c0 push ebp ; entry point of threadfunc
:004014c1 mov ebp, esp
...:004014c5 call 0041550 ; 在這裡崩潰了
; remote process
...:00401502 ret
如果這個有爭議的call是編譯器新增的(因為一些不該開啟的編譯開關比如/gz開啟了),它要麼在threadfunc的開頭要麼在threadfunc接近結尾的地方
不管在什麼情況下,你使用createremotethread & writeprocessmemory技術時必須萬分的小心,特別是編譯器/聯結器的設定,它們很可能會給你的threadfunc新增一些帶來麻煩的東西。
Spring三種注入方式
spring有三種依賴注入的方式,第一種是構造方法注入 12 xx cc ss ppp bean類 public class per public void get 這種方式缺點是在獲取bean物件時,注入資料是必須的操作,否則無法建立,即使是無用的資料也要注入。如果有多個構造方法,每個構造方法只有...
Spring DI三種依賴注入
1.賦值 name為屬性名,value為屬性值 這種方法的依賴注入,底層呼叫的方法是set方法 2.構造器注入 構造方法 在相應的類中需要新增構造方法 如果賦值的資料的8中簡單的型別,使用value,如果是應用型別 除了string 使用ref value屬性值,index為索引對應建構函式中的第幾...
注入的三種方式
依賴注入3種方式 1.set注入 通過set 賦值賦值,預設使用的是 set方法 依賴注入底層是通過反射實現的。2.構造器注入 通過構造方法賦值 需要注意 如果 的順序 與構造方法引數的順序不一致,則需要通過type或者index或name指定。3.p命名空間注入引入p命名空間 xmlns p 簡單...