进程中dll模块的隐藏
生活随笔
收集整理的這篇文章主要介紹了
进程中dll模块的隐藏
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
標 題:
【原創】進程中dll模塊的隱藏
作 者: NetRoc
時 間: 2008-02-20,17:28:30
鏈 接: http://bbs.pediy.com/showthread.php?t=59932
進程中dll模塊的隱藏
cc682/NetRoc
?http://netroc682.spaces.live.com/ ????????為了避免自己的某個dll模塊被別人檢測出來,有時候希望在自己加載一個dll之后,或者將dll注入到他人進程之后避免被檢查出來。這就需要想辦法抹掉這個dll的模塊信息,使得Toolhelp、psapi等枚舉模塊的API無法枚舉它。
????????我們可以先簡單看看Windows枚舉進程內模塊的辦法吧:
????????首先是BOOL?EnumProcessModules(?HANDLE?hProcess,?HMODULE*?lphModule,?DWORD?cb,?LPDWORD?lpcbNeeded);
????????EnumProcessModules實際調用EnumProcessModulesInternal進行枚舉。下面是vista下psapi的代碼片斷:
.text:514024B8?????????????????push????ebx
.text:514024B9?????????????????push????18h
.text:514024BB?????????????????lea?????eax,?[ebp+stProcessBasicInfo]
.text:514024BE?????????????????push????eax
.text:514024BF?????????????????push????ebx??;ebx=0
.text:514024C0?????????????????push????[ebp+hProcess]
.text:514024C3?????????????????call????ds:__imp__NtQueryInformationProcess@20?;?NtQueryInformationProcess(x,x,x,x,x)
.text:514024C9?????????????????cmp?????eax,?ebx
.text:514024CB?????????????????jge?????short?loc_514024E0
????????調用NtQueryInformationProcess獲得ProcessBasicInformation,在PROCESS_BASIC_INFORMATION結構中取得PEB地址。然后讀取指定進程PEB中的數據
text:514024E0?loc_514024E0:???????????????????????????;?CODE?XREF:?EnumProcessModulesInternal(x,x,x,x,x)+24?j
.text:514024E0?????????????????mov?????eax,?[ebp+stProcessBasicInfo.PebBaseAddress]
.text:514024E3?????????????????cmp?????eax,?ebx
.text:514024E5?????????????????jnz?????short?loc_514024EE
.text:514024E7?????????????????push????8000000Dh
.text:514024EC?????????????????jmp?????short?loc_514024CE
.text:514024EE?;?---------------------------------------------------------------------------
.text:514024EE
.text:514024EE?loc_514024EE:???????????????????????????;?CODE?XREF:?EnumProcessModulesInternal(x,x,x,x,x)+3E?j
.text:514024EE?????????????????push????ebx?????????????;?lpNumberOfBytesRead
.text:514024EF?????????????????push????4???????????????;?nSize
.text:514024F1?????????????????lea?????ecx,?[ebp+Ldr]
.text:514024F4?????????????????push????ecx?????????????;?lpBuffer
.text:514024F5?????????????????add?????eax,?0Ch
.text:514024F8?????????????????push????eax?????????????;?lpBaseAddress
.text:514024F9?????????????????push????[ebp+hProcess]??;?hProcess
.text:514024FC?????????????????mov?????edi,?ds:__imp__ReadProcessMemory@20?;?ReadProcessMemory(x,x,x,x,x)
.text:51402502?????????????????call????edi?;?ReadProcessMemory(x,x,x,x,x)?;?ReadProcessMemory(x,x,x,x,x)
這里讀取的是PEB地址+0C處的四個字節。
通過WinDbg我們可以看看nt!_PEB的結構
0:?kd>?dt?nt!_PEB
???+0x000?InheritedAddressSpace?:?UChar
???+0x001?ReadImageFileExecOptions?:?UChar
???+0x002?BeingDebugged????:?UChar
???+0x003?SpareBool????????:?UChar
???+0x004?Mutant???????????:?Ptr32?Void
???+0x008?ImageBaseAddress?:?Ptr32?Void
???+0x00c?Ldr??????????????:?Ptr32?_PEB_LDR_DATA
???+0x010?ProcessParameters?:?Ptr32?_RTL_USER_PROCESS_PARAMETERS
……
+0C處是一個_PEB_LDR_DATA結構指針,里面包含了和LDR相關的一些數據,進程的模塊鏈表就保存在Ldr中。下面是_PEB_LDR_DATA的結構:
0:?kd>?dt?nt!_PEB_LDR_DATA
???+0x000?Length???????????:?Uint4B
???+0x004?Initialized??????:?UChar
???+0x008?SsHandle?????????:?Ptr32?Void
???+0x00c?InLoadOrderModuleList?:?_LIST_ENTRY
???+0x014?InMemoryOrderModuleList?:?_LIST_ENTRY
???+0x01c?InInitializationOrderModuleList?:?_LIST_ENTRY
???+0x024?EntryInProgress??:?Ptr32?Void
其中,InLoadOrderModuleList、InMemoryOrderModuleList、InInitializationOrderModuleList就是進程當前已加載模塊的鏈表,只是按照不同的方式排序。EnumProcessModules是通過InMemoryOrderModuleList鏈表枚舉的,而根據Win2k代碼,ToolHelp32函數是通過InLoadOrderModuleList枚舉。這三個_LIST_ENTRY都是在一個RTL_PROCESS_MODULE_INFORMATION結構中的成員。這個結構在2k代碼中有引用,不過沒有確切的定義,下面是ReactOS中的定義,不過看起來我的vista?PSAPI中使用的結構已經有所變化了,這里只作參考。
//
//?Loader?Data?Table?Entry
//
typedef?struct?_LDR_DATA_TABLE_ENTRY
{
????LIST_ENTRY?InLoadOrderLinks;
????LIST_ENTRY?InMemoryOrderModuleList;
????LIST_ENTRY?InInitializationOrderModuleList;
????PVOID?DllBase;
????PVOID?EntryPoint;
????ULONG?SizeOfImage;
????UNICODE_STRING?FullDllName;
????UNICODE_STRING?BaseDllName;
????ULONG?Flags;
????USHORT?LoadCount;
????USHORT?TlsIndex;
????union
????{
????????LIST_ENTRY?HashLinks;
????????PVOID?SectionPointer;
????};
????ULONG?CheckSum;
????union
????{
????????ULONG?TimeDateStamp;
????????PVOID?LoadedImports;
????};
????PVOID?EntryPointActivationContext;
????PVOID?PatchInformation;
}?LDR_DATA_TABLE_ENTRY,?*PLDR_DATA_TABLE_ENTRY;
到這里,隱藏模塊的方法就已經明了了:通過PEB取得Ldr數據,拿到三個模塊鏈表,并將要隱藏的模塊斷鏈即可。下面是主要代碼實現:
BOOL?HideMyself()
{
??HMODULE?hMod?=?GetModuleHandle(?_T(?"ntdll.dll"));
??HMODULE?hModMyself?=?GetModuleHandle(?_T("dll.dll"));
??pfnNtQueryInformationProcess?p?=?(pfnNtQueryInformationProcess)::GetProcAddress(?hMod,?"NtQueryInformationProcess");
??PROCESS_BASIC_INFORMATION?stInfo?=?{0};
??DWORD?dwRetnLen?=?0;
??DWORD?dw?=?p(?GetCurrentProcess(),?0,?&stInfo,?sizeof(stInfo),?&dwRetnLen);
??PPEB?pPeb?=?stInfo.PebBaseAddress;
??PLIST_ENTRY?ListHead,?Current;
??PLDR_DATA_TABLE_ENTRY?pstEntry?=?NULL;
??ListHead?=?&(?stInfo.PebBaseAddress->Ldr->InLoadOrderModuleList);
??Current?=?ListHead->Flink;
??while?(?Current?!=?ListHead)
??{
????pstEntry?=?CONTAINING_RECORD(?Current,?LDR_DATA_TABLE_ENTRY,?InLoadOrderLinks);
????//DebugOutW(?L"Module:%s,?base:0x%X\r\n",?pstEntry->FullDllName.Buffer,?pstEntry->EntryPoint);
????if?(?pstEntry->DllBase?==?hModMyself)
????{
??????pstEntry->InLoadOrderLinks.Flink->Blink?=?pstEntry->InLoadOrderLinks.Blink;
??????pstEntry->InLoadOrderLinks.Blink->Flink?=?pstEntry->InLoadOrderLinks.Flink;
??????DebugOut(?_T(?"Hide?injected?dll."));
??????break;
????}
????Current?=?pstEntry->InLoadOrderLinks.Flink;
??}
??ListHead?=?&(?stInfo.PebBaseAddress->Ldr->InMemoryOrderModuleList);
??Current?=?ListHead->Flink;
??while?(?Current?!=?ListHead)
??{
????pstEntry?=?CONTAINING_RECORD(?Current,?LDR_DATA_TABLE_ENTRY,?InMemoryOrderModuleList);
????DebugOutW(?L"Module:%s,?base:0x%X\r\n",?pstEntry->FullDllName.Buffer,?pstEntry->EntryPoint);
????if?(?pstEntry->DllBase?==?hModMyself)
????{
??????pstEntry->InMemoryOrderModuleList.Flink->Blink?=?pstEntry->InMemoryOrderModuleList.Blink;
??????pstEntry->InMemoryOrderModuleList.Blink->Flink?=?pstEntry->InMemoryOrderModuleList.Flink;
??????DebugOut(?_T(?"Hide?injected?dll."));
??????break;
????}
????Current?=?pstEntry->InMemoryOrderModuleList.Flink;
??}
??DebugOutW(?L"\r\n");
??ListHead?=?&(?stInfo.PebBaseAddress->Ldr->InInitializationOrderModuleList);
??Current?=?ListHead->Flink;
??while?(?Current?!=?ListHead)
??{
????pstEntry?=?CONTAINING_RECORD(?Current,?LDR_DATA_TABLE_ENTRY,?InInitializationOrderModuleList);
????DebugOutW(?L"Module:%s,?base:0x%X\r\n",?pstEntry->FullDllName.Buffer,?pstEntry->EntryPoint);
????if?(?pstEntry->DllBase?==?hModMyself)
????{
??????pstEntry->InInitializationOrderModuleList.Flink->Blink?=?pstEntry->InInitializationOrderModuleList.Blink;
??????pstEntry->InInitializationOrderModuleList.Blink->Flink?=?pstEntry->InInitializationOrderModuleList.Flink;
??????DebugOut(?_T(?"Hide?injected?dll."));
??????break;
????}
????Current?=?pstEntry->InInitializationOrderModuleList.Flink;
??}
??//DebugOut(?_T("Out?HideMyself\r\n"));
??return?TRUE;
}
????????這樣處理之后,通過常規的枚舉進程方式已經枚舉不到隱藏模塊,ProcessExplorer也無法枚舉。但是,通過枚舉進程內存空間等非常規方法,仍然是可以找到的。關于PSAPI和Toolhelp函數枚舉模塊的原理,可以逆向Windows代碼,或者查找網上的代碼看看就明白了。
作 者: NetRoc
時 間: 2008-02-20,17:28:30
鏈 接: http://bbs.pediy.com/showthread.php?t=59932
進程中dll模塊的隱藏
cc682/NetRoc
?http://netroc682.spaces.live.com/ ????????為了避免自己的某個dll模塊被別人檢測出來,有時候希望在自己加載一個dll之后,或者將dll注入到他人進程之后避免被檢查出來。這就需要想辦法抹掉這個dll的模塊信息,使得Toolhelp、psapi等枚舉模塊的API無法枚舉它。
????????我們可以先簡單看看Windows枚舉進程內模塊的辦法吧:
????????首先是BOOL?EnumProcessModules(?HANDLE?hProcess,?HMODULE*?lphModule,?DWORD?cb,?LPDWORD?lpcbNeeded);
????????EnumProcessModules實際調用EnumProcessModulesInternal進行枚舉。下面是vista下psapi的代碼片斷:
.text:514024B8?????????????????push????ebx
.text:514024B9?????????????????push????18h
.text:514024BB?????????????????lea?????eax,?[ebp+stProcessBasicInfo]
.text:514024BE?????????????????push????eax
.text:514024BF?????????????????push????ebx??;ebx=0
.text:514024C0?????????????????push????[ebp+hProcess]
.text:514024C3?????????????????call????ds:__imp__NtQueryInformationProcess@20?;?NtQueryInformationProcess(x,x,x,x,x)
.text:514024C9?????????????????cmp?????eax,?ebx
.text:514024CB?????????????????jge?????short?loc_514024E0
????????調用NtQueryInformationProcess獲得ProcessBasicInformation,在PROCESS_BASIC_INFORMATION結構中取得PEB地址。然后讀取指定進程PEB中的數據
text:514024E0?loc_514024E0:???????????????????????????;?CODE?XREF:?EnumProcessModulesInternal(x,x,x,x,x)+24?j
.text:514024E0?????????????????mov?????eax,?[ebp+stProcessBasicInfo.PebBaseAddress]
.text:514024E3?????????????????cmp?????eax,?ebx
.text:514024E5?????????????????jnz?????short?loc_514024EE
.text:514024E7?????????????????push????8000000Dh
.text:514024EC?????????????????jmp?????short?loc_514024CE
.text:514024EE?;?---------------------------------------------------------------------------
.text:514024EE
.text:514024EE?loc_514024EE:???????????????????????????;?CODE?XREF:?EnumProcessModulesInternal(x,x,x,x,x)+3E?j
.text:514024EE?????????????????push????ebx?????????????;?lpNumberOfBytesRead
.text:514024EF?????????????????push????4???????????????;?nSize
.text:514024F1?????????????????lea?????ecx,?[ebp+Ldr]
.text:514024F4?????????????????push????ecx?????????????;?lpBuffer
.text:514024F5?????????????????add?????eax,?0Ch
.text:514024F8?????????????????push????eax?????????????;?lpBaseAddress
.text:514024F9?????????????????push????[ebp+hProcess]??;?hProcess
.text:514024FC?????????????????mov?????edi,?ds:__imp__ReadProcessMemory@20?;?ReadProcessMemory(x,x,x,x,x)
.text:51402502?????????????????call????edi?;?ReadProcessMemory(x,x,x,x,x)?;?ReadProcessMemory(x,x,x,x,x)
這里讀取的是PEB地址+0C處的四個字節。
通過WinDbg我們可以看看nt!_PEB的結構
0:?kd>?dt?nt!_PEB
???+0x000?InheritedAddressSpace?:?UChar
???+0x001?ReadImageFileExecOptions?:?UChar
???+0x002?BeingDebugged????:?UChar
???+0x003?SpareBool????????:?UChar
???+0x004?Mutant???????????:?Ptr32?Void
???+0x008?ImageBaseAddress?:?Ptr32?Void
???+0x00c?Ldr??????????????:?Ptr32?_PEB_LDR_DATA
???+0x010?ProcessParameters?:?Ptr32?_RTL_USER_PROCESS_PARAMETERS
……
+0C處是一個_PEB_LDR_DATA結構指針,里面包含了和LDR相關的一些數據,進程的模塊鏈表就保存在Ldr中。下面是_PEB_LDR_DATA的結構:
0:?kd>?dt?nt!_PEB_LDR_DATA
???+0x000?Length???????????:?Uint4B
???+0x004?Initialized??????:?UChar
???+0x008?SsHandle?????????:?Ptr32?Void
???+0x00c?InLoadOrderModuleList?:?_LIST_ENTRY
???+0x014?InMemoryOrderModuleList?:?_LIST_ENTRY
???+0x01c?InInitializationOrderModuleList?:?_LIST_ENTRY
???+0x024?EntryInProgress??:?Ptr32?Void
其中,InLoadOrderModuleList、InMemoryOrderModuleList、InInitializationOrderModuleList就是進程當前已加載模塊的鏈表,只是按照不同的方式排序。EnumProcessModules是通過InMemoryOrderModuleList鏈表枚舉的,而根據Win2k代碼,ToolHelp32函數是通過InLoadOrderModuleList枚舉。這三個_LIST_ENTRY都是在一個RTL_PROCESS_MODULE_INFORMATION結構中的成員。這個結構在2k代碼中有引用,不過沒有確切的定義,下面是ReactOS中的定義,不過看起來我的vista?PSAPI中使用的結構已經有所變化了,這里只作參考。
//
//?Loader?Data?Table?Entry
//
typedef?struct?_LDR_DATA_TABLE_ENTRY
{
????LIST_ENTRY?InLoadOrderLinks;
????LIST_ENTRY?InMemoryOrderModuleList;
????LIST_ENTRY?InInitializationOrderModuleList;
????PVOID?DllBase;
????PVOID?EntryPoint;
????ULONG?SizeOfImage;
????UNICODE_STRING?FullDllName;
????UNICODE_STRING?BaseDllName;
????ULONG?Flags;
????USHORT?LoadCount;
????USHORT?TlsIndex;
????union
????{
????????LIST_ENTRY?HashLinks;
????????PVOID?SectionPointer;
????};
????ULONG?CheckSum;
????union
????{
????????ULONG?TimeDateStamp;
????????PVOID?LoadedImports;
????};
????PVOID?EntryPointActivationContext;
????PVOID?PatchInformation;
}?LDR_DATA_TABLE_ENTRY,?*PLDR_DATA_TABLE_ENTRY;
到這里,隱藏模塊的方法就已經明了了:通過PEB取得Ldr數據,拿到三個模塊鏈表,并將要隱藏的模塊斷鏈即可。下面是主要代碼實現:
BOOL?HideMyself()
{
??HMODULE?hMod?=?GetModuleHandle(?_T(?"ntdll.dll"));
??HMODULE?hModMyself?=?GetModuleHandle(?_T("dll.dll"));
??pfnNtQueryInformationProcess?p?=?(pfnNtQueryInformationProcess)::GetProcAddress(?hMod,?"NtQueryInformationProcess");
??PROCESS_BASIC_INFORMATION?stInfo?=?{0};
??DWORD?dwRetnLen?=?0;
??DWORD?dw?=?p(?GetCurrentProcess(),?0,?&stInfo,?sizeof(stInfo),?&dwRetnLen);
??PPEB?pPeb?=?stInfo.PebBaseAddress;
??PLIST_ENTRY?ListHead,?Current;
??PLDR_DATA_TABLE_ENTRY?pstEntry?=?NULL;
??ListHead?=?&(?stInfo.PebBaseAddress->Ldr->InLoadOrderModuleList);
??Current?=?ListHead->Flink;
??while?(?Current?!=?ListHead)
??{
????pstEntry?=?CONTAINING_RECORD(?Current,?LDR_DATA_TABLE_ENTRY,?InLoadOrderLinks);
????//DebugOutW(?L"Module:%s,?base:0x%X\r\n",?pstEntry->FullDllName.Buffer,?pstEntry->EntryPoint);
????if?(?pstEntry->DllBase?==?hModMyself)
????{
??????pstEntry->InLoadOrderLinks.Flink->Blink?=?pstEntry->InLoadOrderLinks.Blink;
??????pstEntry->InLoadOrderLinks.Blink->Flink?=?pstEntry->InLoadOrderLinks.Flink;
??????DebugOut(?_T(?"Hide?injected?dll."));
??????break;
????}
????Current?=?pstEntry->InLoadOrderLinks.Flink;
??}
??ListHead?=?&(?stInfo.PebBaseAddress->Ldr->InMemoryOrderModuleList);
??Current?=?ListHead->Flink;
??while?(?Current?!=?ListHead)
??{
????pstEntry?=?CONTAINING_RECORD(?Current,?LDR_DATA_TABLE_ENTRY,?InMemoryOrderModuleList);
????DebugOutW(?L"Module:%s,?base:0x%X\r\n",?pstEntry->FullDllName.Buffer,?pstEntry->EntryPoint);
????if?(?pstEntry->DllBase?==?hModMyself)
????{
??????pstEntry->InMemoryOrderModuleList.Flink->Blink?=?pstEntry->InMemoryOrderModuleList.Blink;
??????pstEntry->InMemoryOrderModuleList.Blink->Flink?=?pstEntry->InMemoryOrderModuleList.Flink;
??????DebugOut(?_T(?"Hide?injected?dll."));
??????break;
????}
????Current?=?pstEntry->InMemoryOrderModuleList.Flink;
??}
??DebugOutW(?L"\r\n");
??ListHead?=?&(?stInfo.PebBaseAddress->Ldr->InInitializationOrderModuleList);
??Current?=?ListHead->Flink;
??while?(?Current?!=?ListHead)
??{
????pstEntry?=?CONTAINING_RECORD(?Current,?LDR_DATA_TABLE_ENTRY,?InInitializationOrderModuleList);
????DebugOutW(?L"Module:%s,?base:0x%X\r\n",?pstEntry->FullDllName.Buffer,?pstEntry->EntryPoint);
????if?(?pstEntry->DllBase?==?hModMyself)
????{
??????pstEntry->InInitializationOrderModuleList.Flink->Blink?=?pstEntry->InInitializationOrderModuleList.Blink;
??????pstEntry->InInitializationOrderModuleList.Blink->Flink?=?pstEntry->InInitializationOrderModuleList.Flink;
??????DebugOut(?_T(?"Hide?injected?dll."));
??????break;
????}
????Current?=?pstEntry->InInitializationOrderModuleList.Flink;
??}
??//DebugOut(?_T("Out?HideMyself\r\n"));
??return?TRUE;
}
????????這樣處理之后,通過常規的枚舉進程方式已經枚舉不到隱藏模塊,ProcessExplorer也無法枚舉。但是,通過枚舉進程內存空間等非常規方法,仍然是可以找到的。關于PSAPI和Toolhelp函數枚舉模塊的原理,可以逆向Windows代碼,或者查找網上的代碼看看就明白了。
總結
以上是生活随笔為你收集整理的进程中dll模块的隐藏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: http error code
- 下一篇: 获取系统进程信息和进程依赖的dll信息-