c語言—–劫持原理

  • 2019 年 10 月 29 日
  • 筆記

1. 劫持原理介紹

  (1) 通過劫持技術我們可以實現某些進程的攔截,比如禁止創建文件,禁止打開qq,禁止關機等等一系列的操作

  (2) 彈窗攔截就是最常見的一種劫持技術的實現。

2. 使用的工具

  (1) vs2017   //編寫c語言程式      可以用其他的版本 但是不建議2010及以下的 其他的IDE我沒用過

  (2) DllInject.exe //查看當前所有的進程並且可以進行DLL注入

 

 

 

 

 

 

 

 

3. 使用的技術與原理

  (1) 函數名和函數實體

    函數名的本質就是一個地址,但是函數名的地址和函數實體的地址不是同一個地址。

例如:

1 void show(){  2     MessageBoxA(NULL,"我是文本","我是標題",0);  3 }

    在show()函數中,show()的函數名是一個地址,show()函數中的程式碼 MessageBoxA(NULL,我是文本“,我是標題“,0); 也就是函數實體也有一個地址。那麼怎麼證明呢?

    在vs2017中使用反彙編進行調試:(源碼如下)

 1 #include<stdio.h>   2 #include<stdlib.h>   3 #include<Windows.h>   4 void show(){   5     MessageBoxA(NULL,"我是文本","我是標題",0);   6 }   7 int main(){   8     printf("%pnn",show);   9     show();  10     return 0;  11 }

 1> 設置斷點

 

 

 

2>運行

 

 

3> 得到show()函數的地址(每次運行的結果不一樣)

 

 

4> 打開反彙編調試窗口

 

 

 

5> 將show()的地址002B128F輸入到箭頭所指位置(並改為0x002B128 or 002B128F  這兩個應該都可以,我用的第一個),並回車

 

 

 6> 現在已經跳轉到show()函數的首地址處

 

 

     _show:

    002B128F  jmp  show(02B3C90h)   

    這句話說明,地址將要從002B128F 跳轉到02B3C90h,這個02B3C90h就是函數實體的地址

7> 查看函數實體–將show(02B3C90h)中的地址輸入,並回車

 

 

 

 

 

 8> 結論:函數名和函數實體不是同一個地址

  (2) 劫持原理

    函數名和函數實體不是同一個地址,那麼也就是這樣:

 

 

     那麼如果我們把函數實體的地址從02B3C90h改為0x0000,是不是執行的函數實體就不一樣了呢?

 

 

 

 

       原理:修改函數實體的地址,即函數名不變(房子不變,把房子裡邊的人換了)

 

  (3) 函數指針

    既然函數名是一個地址,那麼我們就可以通過指針的方式進行操作。

    基本格式:

      void (*p)() = 函數名;

      p();

 1 #include<stdio.h>   2 #include<stdlib.h>   3 #include<Windows.h>   4 void show(){   5     MessageBoxA(NULL,"我是文本","我是標題",0);   6 }   7   8 void go(){   9     printf("%s","create process failed");  10 }  11 int main(){  12     /*printf("%pnn",show);  13     show();*/  14  15     void (*p)() = show;  16     p();//函數指針可以存儲不同函數的地址,執行不同的程式碼塊  17     p = go;  18     p();  19     return 0;  20 }

 (4) 劫持原理實現—exe文件生成

 1 #include<stdio.h>   2 #include<stdlib.h>   3 #include<Windows.h>   4 void show() {   5     MessageBoxA(NULL, "我是文本", "我是標題", 0);   6 }   7   8 void go() {   9     printf("%sn", "create process failed");  10 }  11 int main() {  12     void (*p)() = go;  13     printf("show=%ptgo=%pt&p=%pn",show,p,&p);  14     while (1)  15     {  16         p();  17         Sleep(1000);  18     }  19     return 0;  20 }

(5) 劫持原理實現—dll文件生成(具體程式碼看下一步,這一步只是說如何生成dll)

1> 右擊項目,選擇屬性

 

 

 2> 跟著箭頭走

 

 

 3> 跟著箭頭走 先點擊生成 -> 點擊生成解決方案

 

 

 (6) 劫持原理實現

1> 打開生成的exe文件

 

 

2> dll文件編寫

    首先我們需要找到指針p的地址,所以p是一個一級指針,需要一個二級指針獲取地址

    其次當前exe運行的程式是go(),我要更改為show()函數

1 _declspec(dllexport)void go(){  2     void (**p)() = 0x008ffce8;  3     *p= 0x001212a3;  4 }

    重新生成解決方案

3> 打開DllInject.exe 找到你剛剛打開的exe

 

 

 4> 點擊注入 ->找到你生成的dll文件->點擊確定->輸入你編寫的函數名

 

 

 

 

 

 5> 效果 (cmd控制台不再列印,然後彈出了對話框)