[DLL劫持] 3 DLL劫持之實踐 例子
該系列文章是依據本人平時對動態連結庫的學習,歸納總結,所做的學習筆記。如有錯誤或待改善之處,請留下您寶貴的意見或建議。
先說說DLL劫持的原理吧,以下這段來自百度百科對DLL劫持原理的說明:
由於輸入表中只包含DLL名而沒有它的路徑名,因此載入程式必須在磁碟上搜索DLL檔案。首先會嘗試從當前程式所在的目錄載入DLL,如果沒找到,則在Windows系統目錄中查詢,最後是在環境變數中列出的各個目錄下查詢。利用這個特點,先偽造一個系統同名的DLL,提供同樣的輸出表,每個輸出函式轉向真正的系統DLL。程式呼叫系統DLL時會先呼叫當前目錄下偽造的DLL,完成相關功能後,再跳到系統DLL同名函式裡執行。這個過程用個形象的詞來描述就是系統
利用這種方法取得控制權後,可以對主程式進行補丁。此種方法只對除kernel32.dll、ntdll.dll等核心系統庫以外的DLL有效,如網路應用程式的ws2_32.dll、遊戲程式中的d3d8.dll,還有大部分應用程式都呼叫的lpk.dll、sxs.dll,這些DLL都可被劫持。
偽造的dll製作好後,放到程式當前目錄下,這樣當原程式呼叫原函式時就呼叫了偽造的dll的同名函式,進入劫持DLL的程式碼,處理完畢後,再呼叫原DLL此函式。
這種補丁技術,對加殼保護的軟體很有效,選擇掛接的函式最好是在殼中沒有被呼叫的,當掛接函式被執行時,相關的程式碼已被解壓,可以直接補丁了。在有些情況下,必須用計數器統計掛接的函式的呼叫次數來接近
一些木馬或病毒也會利用DLL劫持技術搞破壞,因此當在應用程式目錄下發現系統一些DLL檔案存在時,如lpk.dll,應引起注意。
下面就通過一個簡單的例子,來實現一下DLL劫持:
1. 生成原始的DLL
建立一個dllTest工程,新增lib.h和lib.cpp檔案:
Lib.h
#ifndef LIB_H
#define LIB_H
extern "C" int __declspec(dllexport)add(int x, int y);
#endif
Lib.cpp
#include "lib.h" int add(int x, int y){ return x + y; }
編譯生成dllTest.dll。
2. 編寫應用程式(採用動態載入方式)
新建工程dllcall,新增檔案dllcall.cpp,修改呼叫目錄,生成,測試,ok!
(隱式方式:使用原來的.lib檔案,使用之後的dll)
Dllcall.cpp
// dllCall.cpp : 以顯式方式呼叫DLL
#include <stdio.h>
#include "windows.h"
typedef int ( * lpAddFun)(int,int);
int main(int argc, char* argv[])
{
HINSTANCE hDll; //DLL控制代碼
lpAddFun addFun; //函式指標
hDll = LoadLibrary("..\\Release\\dllTest.dll");
if (hDll != NULL)
{
addFun = (lpAddFun)GetProcAddress(hDll,"add");
if(addFun!=NULL)
{
int result = addFun(2,3);
printf("%d",result);
}
FreeLibrary(hDll);
}
system("pause");
return 0;
}
3. 使用AheadLib反編譯DLL
使用工具AheadLib.exe,反編譯dllTest.dll,生成dllTest.cpp,新建dll工程,編譯該cpp,生成第二個dllTest.dll。
DllText.cpp
// 標頭檔案
#include <Windows.h>
// 匯出函式
#pragma comment(linker, "/EXPORT:add=_AheadLib_add,@1")
// 巨集定義
#define EXTERNC extern "C"
#define NAKED __declspec(naked)
#define EXPORT __declspec(dllexport)
#define ALCPP EXPORT NAKED
#define ALSTD EXTERNC EXPORT NAKED void __stdcall
#define ALCFAST EXTERNC EXPORT NAKED void __fastcall
#define ALCDECL EXTERNC NAKED void __cdecl
// Hook 名稱空間
namespace Hook
{
HHOOK m_hHook;
// HOOK 控制代碼
// HOOK 函式
LRESULT CALLBACK HookProc(INT iCode, WPARAM wParam, LPARAM lParam)
{
if (iCode > 0)
{
;
}
return CallNextHookEx(m_hHook, iCode, wParam, lParam);
}
// Hook
inline BOOL WINAPI Hook(INT iHookId = WH_CALLWNDPROC)
{
m_hHook = SetWindowsHookEx(iHookId, HookProc, NULL, GetCurrentThreadId());
return (m_hHook != NULL);
}
// Unhook
inline VOID WINAPI Unhook()
{
if (m_hHook)
{
UnhookWindowsHookEx(m_hHook);
}
}
}
// AheadLib 名稱空間
namespace AheadLib
{
HMODULE m_hModule = NULL; // 原始模組控制代碼
DWORD m_dwReturn[1] = {0}; // 原始函式返回地址
// 載入原始模組
inline BOOL WINAPI Load()
{
TCHAR tzPath[MAX_PATH];
TCHAR tzTemp[MAX_PATH * 2];
lstrcpy(tzPath, TEXT("dllTestOrg"));
///這一句是為了證明我的ws2_32.dll能被執行
MessageBox(NULL, tzPath, TEXT("DLL Path"), MB_ICONSTOP);
m_hModule = LoadLibrary(tzPath);
if (m_hModule == NULL)
{
wsprintf(tzTemp, TEXT("無法載入 %s,程式無法正常執行。"), tzPath);
MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
}
return (m_hModule != NULL);
}
// 釋放原始模組
inline VOID WINAPI Free()
{
if (m_hModule)
{
FreeLibrary(m_hModule);
}
}
// 獲取原始函式地址
FARPROC WINAPI GetAddress(PCSTR pszProcName)
{
FARPROC fpAddress;
CHAR szProcName[16];
TCHAR tzTemp[MAX_PATH];
if (m_hModule == NULL)
{
if (Load() == FALSE)
{
ExitProcess(-1);
}
}
fpAddress = GetProcAddress(m_hModule, pszProcName);
if (fpAddress == NULL)
{
if (HIWORD(pszProcName) == 0)
{
wsprintf(szProcName, "%d", pszProcName);
pszProcName = szProcName;
}
wsprintf(tzTemp, TEXT("無法找到函式 %hs,程式無法正常執行。"), pszProcName);
MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
ExitProcess(-2);
}
return fpAddress;
}
}
using namespace AheadLib;
// 入口函式
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hModule);
Hook::Hook();
}
else if (dwReason == DLL_PROCESS_DETACH)
{
Free(); Hook::Unhook();
}
return TRUE;
}
// 匯出函式
ALCDECL AheadLib_add(void)
{
GetAddress("add");
__asm JMP EAX;
}
重新使用之前的應用程式測試
將第二個自己生成的dll替代原來的dll,將原來的dll名改成dllTestOrg.dll,放入相應的目錄,測試,OK!
5. Dll劫持成功
附件:
相關推薦
[DLL劫持] 3 DLL劫持之實踐 例子
該系列文章是依據本人平時對動態連結庫的學習,歸納總結,所做的學習筆記。如有錯誤或待改善之處,請留下您寶貴的意見或建議。 先說說DLL劫持的原理吧,以下這段來自百度百科對DLL劫持原理的說明: 由於輸入表中只包含DLL名而沒有它的路徑名,因此載入程式必須在磁碟上搜索DLL
[DLL劫持] 1 DLL劫持之DLL基礎(1)
該系列文章是依據本人平時對動態連結庫的學習,歸納總結,所做的學習筆記。如有錯誤或待改善之處,請留下您寶貴的意見或建議。 最近在研究逆向工程的相關知識,主要用到的是C++逆向,工具有IDA和OLLYDBG等,學了有一段時間了,一直苦於總結能力不夠,不知道逆向的東西該怎麼總結
劫持 Opengl32.dll 實現遊戲MOD
oca 方式 api img blank scrip 我只 assembly 方法 前提是你的遊戲是用的Opengl,如果是DX的,自行谷歌方法,應該差不多,參考GTA5 最近玩了款《天命奇禦》的國產網遊,自己手動寫了個MOD,本來是直接修改Chap-Assembl
實現DLL記憶體補丁,DLL劫持技術
在windows下當一個可執行檔案執行時,Windows載入器將可執行模組對映到程序的地址空間中,載入器分析可執行模組的輸入表,並設法找出任何需要的DLL,並將它們對映到程序的地址空間中。由於輸入表是根據DLL名來進行查詢,首先是查詢當前目錄下有沒這檔案,沒有話在去查
大資料ETL實踐探索(3)---- pyspark 之大資料ETL利器
5.spark dataframe 資料匯入Elasticsearch 5.1 dataframe 及環境初始化 初始化, spark 第三方網站下載包:elasticsearch-spark-20_2.11-6.1.1.jar http://spark.apache.org/t
Allegro學習之提示由於找不到cdsCommon.dll,libem.dll以及突然打不開PCB Editor等軟體
1.確認這兩個檔案都在,那就是沒有在環境變數裡新增路徑的問題,在安裝目錄SPB_16.6下搜尋cdsCommon.dll,libem.dll,如下圖所示:接著右鍵開啟檔案位置,複製路徑WIN10中右鍵我的電腦(此電腦),選擇屬性,開啟如下圖,選擇左側高階系統設定開啟環境變數:
OpenLayers 3實踐與原理探究3-ol3一個完整的例子
【注】所有程式碼掛在我的github上,本例對應demo2 接著我們看一個比較長的例子,例子實現的是可以繪製圖形,可以根據自己的設定列印地圖 我們先看顯示效果是: 由於ol3的api現在更新變化挺大的,所以自己執行的例子的時候注意版本是3.17.1
DNS 劫持及解決方案之 HTTPDNS
1. 為什麼會有 DNS DNS 即域名系統(Domain Name Server),其主要用於將域名解析為對應的 IP 地址。 那麼為什麼會有域名到 IP 地址的解析這一需要呢?就需要從人的角度和計算機的角度去分析了。 人的角度:網路上的主機一般是通過
Spring Security應用開發(11) 並發控制之實踐
nag line then 9.png page 總結 -c ole for 本文分別介紹了四種不同情況下,Spring Security的Session管理和並發控制的不同配置的配置方法,以及所產生的效果。 (1)首先編寫了session_error.jsp頁面,用於
Directx9.0 學習教程3 -圖形學之創建點 線 三角形 等
d3d custom 發現 介紹 data- directx 組成 water 詳細 1、首先 介紹點的表示方法 struct CUSTOMVERTEX { float x,y,z; }; CUSTOMVERTEX Vertices[] = { {-5.0
zabbix-3.2.6之監控一臺新主機
更改 nat eight 啟動 repo sel cpu ota wid 1、更改主機名 [[email protected]/* */ ~]#hostname zabbix-client [[email protected]/* */-
zabbix-3.2.6之自定制監控項參數 監控http 80端口是否正常
wid 正常 3.2 添加 1-1 items lan ati agen 1、自定義映射值 配置--->主機--->監控項 創建監控項----展示映像值 再輸入參數 點更新---拉到最下面,就可以看到新添加的參數。 2、item(監
zabbix-3.2.6之snmp監控(無需安裝agent也能監控)
6.0 send 是否 available 安全 scroll sna object 2.2.0 一、snmp監控介紹 概述 如果我們需要監控打印機、路由器、UPS等設備,肯定不能使用zabbix agentd,因為他們不能安裝軟件的,還好他們一般都支持SNMP協議,這
zabbix-3.2.6之單位符號Unit symbols
href 訪問 itl title target lan 解決 pla http 概述 在zabbix裏面,我們不需要使用大數字來,例如我們可以不使用86400來表示一天,這個數字又不容易理解也容易出錯。用什麽辦法來解決大數字問題呢?我們可以使用單位來簡化,例如簡化zab
zabbix-3.2.6之snmp方式監控windows
pfx name local ima div pan mask bit 成功 一、在windows中添加snmp 在服務中添加public和接受服務器的IP地址。 二、在zabbix-server服務器中安裝net-snmp軟件 1、修改配置文件
Python自動化3.0-------學習之路-------第一個程序用戶登錄!
hide lap 標記 之路 判斷 () exit isp 互信 一、用戶登錄程序 知識點:1.input() 2.while 循環 3.fot 循環
Python自動化3.0-------學習之路-------模塊初識!
div 函數 傳遞 情況 必須 sys 先來 存在 argv 模塊初識 Python的強大之處在於他有非常豐富和強大的標準庫和第三方庫,幾乎你想實現的任何功能都有相應的Python庫支持,以後的課程中會深入講解常用到的各種庫,現在,我們先來象征性的學2個簡單的
Python自動化3.0-------學習之路------日期和時間!
unix dst python自動化 相關 http -a 年份 字符串 cti Python 日期和時間 Python 程序能用很多方式處理日期和時間,轉換日期格式是一個常見的功能。 Python 提供了一個 time 和 calendar 模塊可以用於格式化日期和時間。
Python自動化3.0-------學習之路-------函數!
rgs 未命名 ack 結果 string 提示 mutable tab 外部 Python 函數 函數是組織好的,可重復使用的,用來實現單一,或相關聯功能的代碼段。 函數能提高應用的模塊性,和代碼的重復利用率。你已經知道Python提供了許多內建函數,比如print()。
架構師速成8.3-可用性之分庫分表
路由 運行 進行 一鍵 常量 popu 同步 width track 有狀態分布式,涉及的知識就比較多了,只是我們能夠拿幾個現實的樣例由淺入深的來理解。 數據庫的分庫分表 如果你是一個開發負責人,開始使用單機的數據庫,突然一天數據庫硬盤掛掉了。你沒有