WinAPI 遠端注入 三種注入方案

2021-06-03 19:03:50 字數 2443 閱讀 2546

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 簡單...