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控制台不再列印,然後彈出了對話框)