利用C++ R3層斷鏈實(shí)現(xiàn)模塊隱藏功能
一、模塊隱藏的實(shí)現(xiàn)原理
普通API查找模塊實(shí)現(xiàn)思路:其通過(guò)查詢?cè)赗3中的PEB(Process Environment Block 進(jìn)程環(huán)境塊)與TEB(Thread Environment Block 進(jìn)程環(huán)境塊)來(lái)找到一個(gè)雙向鏈表,通過(guò)遍歷雙向鏈表中某一成員(字符串)來(lái)查找全部模塊。
模塊隱藏實(shí)現(xiàn)思路:在R3層的模塊隱藏,我們需要做的就是將其該鏈表斷鏈,將某一模塊從這個(gè)雙向鏈表中摘除,這樣再調(diào)用傳統(tǒng)的API時(shí)就會(huì)搜索不到。
二、結(jié)構(gòu)體成員詳細(xì)介紹
<1> TEB結(jié)構(gòu)體 -- 內(nèi)存地址為 fs:[0] 處。
使用Windbg的 "dt _TEB"命令來(lái)查看TEB結(jié)構(gòu)體
kd> dt _TEB ntdll!_TEB +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB +0x034 LastErrorValue : Uint4B
1. 屬性介紹
1.1)_NT_TIB:重點(diǎn)兩個(gè)屬性,棧頂與棧大小。
http://www.nirsoft.net/kernel_struct/vista/NT_TIB.html
1.2) _CLIENT_ID: 存儲(chǔ)該進(jìn)程ID與當(dāng)前主線程ID。
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tsts/a11e7129-685b-4535-8d37-21d4596ac057?redirectedfrom=MSDN
1.3) _PEB:進(jìn)程環(huán)境塊 ,記住其在 TEB 偏移 0x30處即可。
2. 通過(guò)olldbg查看該結(jié)構(gòu)體
2.1) 打開(kāi)任意進(jìn)程,在寄存器窗口找到 fs:[0],查看其內(nèi)存地址。
2.2) 在內(nèi)存窗口使用命令 "db 5E7000" 跳轉(zhuǎn)到該內(nèi)存,使用地址格式(長(zhǎng)型-地址)顯示。
<2> PEB結(jié)構(gòu)體 -- fs:[0x30]
使用 Windbg 指令 dt _PEB 查看 PEB結(jié)構(gòu)體,重點(diǎn)關(guān)注最后一個(gè) 進(jìn)程加載信息表。
kd> dt _PEB ntdll!_PEB +0x000 InheritedAddressSpace : UChar +0x001 ReadImageFileExecOptions : UChar +0x002 BeingDebugged : UChar +0x003 BitField : UChar +0x003 ImageUsesLargePages : Pos 0, 1 Bit +0x003 IsProtectedProcess : Pos 1, 1 Bit +0x003 IsLegacyProcess : Pos 2, 1 Bit +0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit +0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit +0x003 SpareBits : Pos 5, 3 Bits +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void +0x00c Ldr : Ptr32 _PEB_LDR_DATA // PEB_LOADER_DATA 進(jìn)程加載信息表
1. 查看 _PEB_LDR_DATA 進(jìn)程加載信息表 的結(jié)構(gòu)體
1.1)重點(diǎn)關(guān)注 0x00c處的指針,其指向 _PEB_LDR_DATA 這個(gè)結(jié)構(gòu)體,在這個(gè)結(jié)構(gòu)體中 0x00c、0x014、0x01c 分別表示 模塊加載順序 / 加載后在內(nèi)存中的順序 / 模塊初始化的順序。
kd > dt _PEB_LDR_DATA ntdll!_PEB_LDR_DATA + 0x000 Length : Uint4B + 0x004 Initialized : UChar + 0x008 SsHandle : Ptr32 Void + 0x00c InLoadOrderModuleList : _LIST_ENTRY // 模塊加載順序 + 0x014 InMemoryOrderModuleList : _LIST_ENTRY // 加載后在內(nèi)存中的順序 + 0x01c InInitializationOrderModuleList : _LIST_ENTRY // 模塊初始化的順序 + 0x024 EntryInProgress : Ptr32 Void + 0x028 ShutdownInProgress : UChar + 0x02c ShutdownThreadId : Ptr32 Void
2.2)理解其三個(gè)成員的順序,其指向_LDR_DATA_TABLE_ENTRY元素中開(kāi)始的三個(gè)成員,而 _LDR_DATA_TABLE_ENTRY 中存儲(chǔ)著就是關(guān)于有關(guān)模塊信息的元素(比如模塊名等)
kd > dt _LDR_DATA_TABLE_ENTRY ntdll!_LDR_DATA_TABLE_ENTRY + 0x000 InLoadOrderLinks : _LIST_ENTRY + 0x008 InMemoryOrderLinks : _LIST_ENTRY + 0x010 InInitializationOrderLinks : _LIST_ENTRY + 0x018 DllBase : Ptr32 Void // 模塊基地址 + 0x01c EntryPoint : Ptr32 Void // 入口函數(shù)(對(duì)于 exe 模塊有效) + 0x020 SizeOfImage : Uint4B // 模塊大小 + 0x024 FullDllName : _UNICODE_STRING // 完成模塊名稱(帶路徑) + 0x02c BaseDllName : _UNICODE_STRING // 模塊名稱 + 0x034 Flags : Uint4B
2. 使用olldbg來(lái)查看查找首先加載模塊的模塊名稱(TEB->PEB-> InLoadOrderModuleList -> BaseDllName)
2.1)接之前TEB內(nèi)容查找到PEB的所在位置 fs:[0x30]。
2.2) 在其0x00c處發(fā)現(xiàn)InLoadOrderModuleList成員,其指向的是一個(gè)_LDR_DATA_TABLE_ENTRY 結(jié)構(gòu)體。
2.3) 跳轉(zhuǎn)到 _LDR_DATA_TABLE_ENTRY 結(jié)構(gòu)體,從0x0c開(kāi)始依次是三個(gè) _LIST_ENTRY 結(jié)構(gòu)體,該結(jié)構(gòu)體雙向鏈表存儲(chǔ)著兩個(gè)地址。
2.4)選中第一個(gè)進(jìn)入,在其偏移0x02c處(UNICODE結(jié)構(gòu)體占四字),可以查看字符串名稱。
2.5)通過(guò)開(kāi)頭 _LIST_ENTRY結(jié)構(gòu)體可以遍歷前一個(gè)模塊的內(nèi)容和下一個(gè)模塊的內(nèi)容。
三、利用C++斷鏈來(lái)實(shí)現(xiàn)模塊隱藏
如果你看懂上面分析,則源代碼非常好理解。
// 隱藏模塊.cpp : 此文件包含 "main" 函數(shù)。程序執(zhí)行將在此處開(kāi)始并結(jié)束。
//
#include "pch.h"
#include <iostream>
#include <Windows.h>
/* 所需要的結(jié)構(gòu)體
1. _LDR_DATA_TABLE_ENTRY 鏈表指向數(shù)據(jù)
2. _PEB_LDR_DATA 表示其 PEB0x處指向的數(shù)據(jù)表
3. _LIST_ENTRY 指針指向的鏈表
*/
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
}
UNICODE_STRING, *PUNICODE_STRING;
typedef struct _PEB_LDR_DATA
{
DWORD Length; // +0x00
bool Initialized; // +0x04
PVOID SsHandle; // +0x08
LIST_ENTRY InLoadOrderModuleList; // +0x0c
LIST_ENTRY InMemoryOrderModuleList; // +0x14
LIST_ENTRY InInitializationOrderModuleList;// +0x1c
} PEB_LDR_DATA, *PPEB_LDR_DATA; // +0x24
typedef struct _LDR_MODULE
{
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
void* BaseAddress;
void* EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
HANDLE SectionHandle;
ULONG CheckSum;
ULONG TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;
//所謂模塊句柄,即該模塊的入口地址
void hide_module(char* szDllName)
{
HMODULE hMod = GetModuleHandleA(szDllName);
PLIST_ENTRY Head, Cur;
PPEB_LDR_DATA ldr;
PLDR_MODULE ldm;
__asm
{
mov eax, fs:[0x30]
mov ecx, [eax + 0x0c] //Ldr
mov ldr, ecx
}
Head = &(ldr->InLoadOrderModuleList);
Cur = Head->Flink;
do
{
ldm = CONTAINING_RECORD(Cur, LDR_MODULE, InLoadOrderModuleList);
if (hMod == ldm->BaseAddress)
{
// 三個(gè)鏈表同時(shí)給斷掉
ldm->InLoadOrderModuleList.Blink->Flink =
ldm->InLoadOrderModuleList.Flink;
ldm->InLoadOrderModuleList.Flink->Blink =
ldm->InLoadOrderModuleList.Blink;
//
ldm->InInitializationOrderModuleList.Blink->Flink =
ldm->InInitializationOrderModuleList.Flink;
ldm->InInitializationOrderModuleList.Flink->Blink =
ldm->InInitializationOrderModuleList.Blink;
//
ldm->InMemoryOrderModuleList.Blink->Flink =
ldm->InMemoryOrderModuleList.Flink;
ldm->InMemoryOrderModuleList.Flink->Blink =
ldm->InMemoryOrderModuleList.Blink;
break;
}
Cur = Cur->Flink;
} while (Head != Cur);
}
int main()
{
// 通過(guò)模塊名,來(lái)獲取模塊句柄
printf("****按任意鍵隱藏模塊*****");
getchar();
hide_module((char*)"kernel32.dll");
printf("****隱藏模塊完成*****");
getchar();
getchar();
}
總結(jié)
以上所述是小編給大家介紹的利用C++ R3層斷鏈實(shí)現(xiàn)模塊隱藏功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)我們網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
上一篇:C++生成不重復(fù)的隨機(jī)整數(shù)
欄 目:C語(yǔ)言
下一篇:C++實(shí)現(xiàn)大數(shù)相乘算法
本文標(biāo)題:利用C++ R3層斷鏈實(shí)現(xiàn)模塊隱藏功能
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/190.html
您可能感興趣的文章
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開(kāi)原生自帶讀寫NTFS功能(圖文
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery


