1. cdnprot.sys hook SSDT
ZwClose 18 --[hooked by unknown at F8116416]--
ZwCreateKey 23 --[hooked by unknown at F811653A]--
ZwDeleteKey 35 --[hooked by unknown at F8116600]--
ZwDeleteValueKey 37 --[hooked by unknown at F81165D0]--
ZwEnumerateKey 3C --[hooked by unknown at FBE485D8]--
ZwEnumerateValueKey 3D --[hooked by unknown at FBE4865A]--
ZwOpenKey 67 --[hooked by unknown at FBE4818C]--
ZwQueryValueKey 9B --[hooked by unknown at FBE48816]--
ZwReplaceKey A9 --[hooked by unknown at F81164CE]--
ZwRestoreKey B4 --[hooked by unknown at F8116504]--
ZwSetValueKey D7 --[hooked by unknown at F8116588]--
和GDI SSDT 的
1212 0008:A0068F92 params=06 NtUserSetWindowsHookEx
(1212=0x1000+0x212,GDISSDT从0x1000编号)
2. 2k sp1原代码中关于NtUserSetWindowsHookEx
D:/Project/ntos5/w32/ntuser/kernel/hooks.c : 576
PHOOK zzzSetWindowsHookEx(
HANDLE hmod,
PUNICODE_STRING pstrLib, //<----------这里把CnsMin.dll阻止了
PTHREADINFO ptiThread,
int nFilterType,
PROC pfnFilterProc,
DWORD dwFlags);
参考:
cnnic 2.1.0.5 cdnprot.dat
[DenyHookName]
Number=3
1=CnsMin.dll
2=helper.dll
3=asnoad.dll
cnnic 2.2.0.1 cdnprot.dat
[DenyHookName]
Number=1
1=CnsMin.dll
如果patch了NtUserSetWindowsHookEx并让CnsMin.dll起来,那么,就直接在IE里面不让CdnIEHlp.dll设置钩子,
就可以把cnnic抢了。
参考:
/**
* @file HookFile.cpp
*
* @brief HookFile.cpp, v 1.0.0 2005/10/8 22:25:48 sunwang
*
* details here.
*
*
* @author sunwang <[email protected]>
*/
//precompile file
#include "stdafx.h"
//ntdll
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "ntdll_x.h"
//detours
#include "detours.h"
//strsafe
#include <strsafe.h>
//lib
#pragma comment(lib,"ntdll.lib")
//*******************************************************************************************************
// DebugString.
//
//*******************************************************************************************************
void DebugString( char *format, ... )
{
char buf[2048]={0};
char* prefix = "[test]";
StringCbCopy(buf,sizeof(buf),prefix);
va_list vl;
va_start(vl,format);
StringCbVPrintf((char*)buf+strlen(prefix), sizeof(buf)-strlen(prefix), format, vl);
OutputDebugString(buf);
}
//*******************************************************************************************************
// Returns the name of the DLL that the given API address belongs to.
//
//*******************************************************************************************************
typedef struct _LDR_MODULE
{
LIST_ENTRY InLoadOrderModuleList; // +0x00
LIST_ENTRY InMemoryOrderModuleList; // +0x08
LIST_ENTRY InInitializationOrderModuleList; // +0x10
PVOID BaseAddress; // +0x18
PVOID EntryPoint; // +0x1c
ULONG SizeOfImage; // +0x20
UNICODE_STRING FullDllName; // +0x24
UNICODE_STRING BaseDllName; // +0x2c
ULONG Flags; // +0x34
SHORT LoadCount; // +0x38
SHORT TlsIndex; // +0x3a
LIST_ENTRY HashTableEntry; // +0x3c
ULONG TimeDateStamp; // +0x44
// +0x48
} LDR_MODULE, *PLDR_MODULE;
char * __stdcall getDLLofAPI(DWORD apiAddr,DWORD pPEB=0)
{
LDR_MODULE *ldr, *headLdr;
LDR_MODULE *result = NULL;
if(pPEB==0)
{
__asm
{
mov eax, fs:[30h]; // get pointer to PEB from offset 30h into TEB
}
}
else
{
__asm
{
mov eax, pPEB; // get pointer to PEB from arg pPEB
}
}
__asm
{
mov eax, [eax+0ch]; // retrive value from offset 0ch into PEB
//mov esi, [eax+1ch]; // get the head pointer to InInitializationOrderModuleList
//一般"按初始化顺序"前向遍历链表时,第一个节点对应ntdll.dll,第二个结点对应
//kernel32.dll,我们不太关心其它模块。如果按加载顺序前向遍历,第一个节点对应
//EXE文件本身,第二个节点才对应ntdll.dll。
mov esi, [eax+0ch]; // get the head pointer to InLoadOrderModuleList
mov headLdr, esi;
}
ldr = headLdr;
while(true)
{
if(!IsBadReadPtr(ldr->BaseAddress, 4) && !IsBadReadPtr(ldr->BaseDllName.Buffer, 4))
{
//printf("BaseDllName: %ws/n",ldr->BaseDllName.Buffer);
//printf("FullDllName: %ws/n",ldr->FullDllName.Buffer);
DWORD dllEnd = (DWORD)ldr->BaseAddress + ldr->SizeOfImage;
if(apiAddr > (DWORD)ldr->BaseAddress && apiAddr < dllEnd)
{
DWORD nameLen = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, ldr->BaseDllName.Buffer, -1, NULL,
0, NULL, NULL);
if(nameLen)
{
LPSTR buffer = (LPSTR)malloc(nameLen + 1);
if(buffer)
{
WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, ldr->BaseDllName.Buffer, -1, buffer,
nameLen + 1, NULL, NULL);
return buffer;
}
}
}
}
// get the head pointer to InLoadOrderModuleList
ldr = (LDR_MODULE *)ldr->InLoadOrderModuleList.Flink;
if(ldr == headLdr)
break;
}
return NULL;
}
//*******************************************************************************************************
//hook SetWindowsHookExA
//
//*******************************************************************************************************
HHOOK __stdcall Real_SetWindowsHookExA(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
);
HHOOK __stdcall Hook_SetWindowsHookExA(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
);
DETOUR_TRAMPOLINE(
HHOOK __stdcall Real_SetWindowsHookExA(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId),
SetWindowsHookExA);
HHOOK __stdcall Hook_SetWindowsHookExA(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
)
{
DebugString("Hook_SetWindowsHookExA enter/n");
/*
* idHook的地址加4就是返回地址
*/
//取返回地址,看看是谁在调用我
ULONG rip=0xffffffff;
__asm
{
push eax
mov eax,[ebp+04h]
mov rip,eax
pop eax
}
DebugString("the module from ebp+04h:%s/n",getDLLofAPI(rip));
if(stricmp(getDLLofAPI(rip),"cdniehlp.dll")==0)
{
DebugString("Hook_SetWindowsHookExA leave,hacked/n");
return 0;
}
//调用原来的函数
HHOOK rtv = 0;
try
{
rtv = Real_SetWindowsHookExA(idHook,lpfn,hMod,dwThreadId);
}
catch (...)
{
}
DebugString("Hook_SetWindowsHookExA leave/n");
return rtv;
}
//*******************************************************************************************************
//hook SetWindowLongA
//
//*******************************************************************************************************
LONG __stdcall Real_SetWindowLongA(
HWND hWnd,
int nIndex,
LONG dwNewLong
);
LONG __stdcall Hook_SetWindowLongA(
HWND hWnd,
int nIndex,
LONG dwNewLong
);
DETOUR_TRAMPOLINE(
LONG __stdcall Real_SetWindowLongA(
HWND hWnd,
int nIndex,
LONG dwNewLong),
SetWindowLongA);
LONG __stdcall Hook_SetWindowLongA(
HWND hWnd,
int nIndex,
LONG dwNewLong
)
{
DebugString("Hook_SetWindowLongA enter/n");
//取返回地址,看看是谁在调用我
ULONG rip=0xffffffff;
__asm
{
push eax
mov eax,[ebp+04h]
mov rip,eax
pop eax
}
DebugString("the module from ebp+04h:%s/n",getDLLofAPI(rip));
if(stricmp(getDLLofAPI(rip),"cdniehlp.dll")==0)
{
DebugString("Hook_SetWindowLongA leave,hacked/n");
return 0;
}
//调用原来的函数
LONG rtv = 0;
try
{
rtv = Real_SetWindowLongA(hWnd,nIndex,dwNewLong);
}
catch (...)
{
}
DebugString("Hook_SetWindowLongA leave/n");
return rtv;
}
//*******************************************************************************************************
//hook Funcs
//
//*******************************************************************************************************
void __stdcall HookFuncs()
{
if(DetourFunctionWithTrampoline(
(PBYTE)Real_SetWindowLongA,
(PBYTE)Hook_SetWindowLongA)==FALSE)
{
DebugString("Hook SetWindowLongA function failed/n");
return;
}
DebugString("Hook SetWindowLongA function ok/n");
if(DetourFunctionWithTrampoline(
(PBYTE)Real_SetWindowsHookExA,
(PBYTE)Hook_SetWindowsHookExA)==FALSE)
{
DebugString("Hook SetWindowsHookExA function failed/n");
return;
}
DebugString("Hook SetWindowsHookExA function ok/n");
}
//*******************************************************************************************************
//DllMain
//
//*******************************************************************************************************
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
//display the host process path
TCHAR szHostPath[MAX_PATH]={0};
GetModuleFileName(NULL,szHostPath,MAX_PATH);
DebugString("DllMain entery,host process : (%s)/n",szHostPath);
//display the host process cmdline
LPCSTR lpCmdLine = GetCommandLine();
DebugString("host process cmdline: (%s)/n",lpCmdLine==0?"null":lpCmdLine);
//hook
HookFuncs();
}
break;
case DLL_PROCESS_DETACH:
{
//display the host process path
TCHAR szHostPath[MAX_PATH]={0};
GetModuleFileName(NULL,szHostPath,MAX_PATH);
DebugString("DllMain leave,host process : (%s)/n",szHostPath);
}
break;
}
return TRUE;
}
日志:
Rundll32.exe C:/WINNT/downlo~1/CnsMin.dll,Rundll32
驱动还是把cnsmin.dll给干掉了。奶奶的。2.2.0.1哦。
////////////////////
00000000 0.00000000 [772] [test]WinMain entry,cmdline:()
00000001 0.00064673 [772] [test]inject dll to iexplore.exe now,core = (hookfile.dll)
00000002 0.01409956 [772] [test]WinMain leave,cmdline:()
00000003 0.10764832 [540] [test]DllMain entery,host process : (C:/Program Files/Internet Explorer/iexplore.exe)
00000004 0.10805535 [540] [test]host process cmdline: ("C:/Program Files/Internet Explorer/iexplore.exe")
00000005 0.10859983 [540] [test]Hook SetWindowLongA function ok
00000006 0.10909934 [540] [test]Hook SetWindowsHookExA function ok
00000007 0.20042603 [540] [test]Hook_SetWindowLongA enter
00000008 0.20117640 [540] [test]the module from ebp+04h:alLiveEx.dll //<--------------3721
00000009 0.20145130 [540] [test]Hook_SetWindowLongA leave
00000010 0.22033164 [540] [test]Hook_SetWindowLongA enter
00000011 0.22073866 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000012 0.22109263 [540] [test]Hook_SetWindowLongA leave
00000013 0.25072154 [540] [test]Hook_SetWindowLongA enter
00000014 0.25119030 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000015 0.25158086 [540] [test]Hook_SetWindowLongA leave
00000016 0.25322801 [540] [test]Hook_SetWindowLongA enter
00000017 0.25363615 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000018 0.25400072 [540] [test]Hook_SetWindowLongA leave
00000019 0.25572664 [540] [test]Hook_SetWindowLongA enter
00000020 0.25736848 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000021 0.29035115 [540] [test]Hook_SetWindowLongA leave
00000022 0.41941810 [540] [test]Hook_SetWindowLongA enter
00000023 0.41991875 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000024 0.42058948 [540] [test]Hook_SetWindowLongA leave
00000025 0.42099065 [540] [test]Hook_SetWindowLongA enter
00000026 0.42139488 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000027 0.42437518 [540] [test]Hook_SetWindowLongA leave
00000028 0.44135860 [540] [test]Hook_SetWindowLongA enter
00000029 0.44183379 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000030 0.44503617 [540] [test]Hook_SetWindowLongA leave
00000031 0.44549656 [540] [test]Hook_SetWindowLongA enter
00000032 0.44587874 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000033 0.44977197 [540] [test]Hook_SetWindowLongA leave
00000034 0.45886949 [540] [test]Hook_SetWindowLongA enter
00000035 0.45932150 [540] [test]the module from ebp+04h:cdniehlp.dll //<---------------cnnic
00000036 0.45976123 [540] [test]Hook_SetWindowLongA leave
00000037 0.46008250 [540] [test]Hook_SetWindowsHookExA enter
00000038 0.46046969 [540] [test]the module from ebp+04h:cdniehlp.dll //<---------------cnnic
00000039 0.46089879 [540] [test]Hook_SetWindowsHookExA leave
00000040 0.46124327 [540] [test]Hook_SetWindowsHookExA enter
00000041 0.46162933 [540] [test]the module from ebp+04h:cdniehlp.dll //<---------------cnnic
00000042 0.46214423 [540] [test]Hook_SetWindowsHookExA leave
00000043 0.46254706 [540] [test]Hook_SetWindowsHookExA enter
00000044 0.46293676 [540] [test]the module from ebp+04h:cdniehlp.dll //<---------------cnnic
00000045 0.46329212 [540] [test]Hook_SetWindowsHookExA leave
00000046 0.46369413 [540] [test]Hook_SetWindowsHookExA enter
00000047 0.46408078 [540] [test]the module from ebp+04h:cdniehlp.dll //<---------------cnnic
00000048 0.46887329 [540] [test]Hook_SetWindowsHookExA leave
00000049 0.54656667 [540] [test]Hook_SetWindowLongA enter
00000050 0.54700249 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000051 0.54742515 [540] [test]Hook_SetWindowLongA leave
00000052 3.81119490 [540] [test]Hook_SetWindowLongA enter
00000053 4.31984472 [540] [test]the module from ebp+04h:SHLWAPI.dll
00000054 4.81727934 [540] [test]Hook_SetWindowLongA leave
3.PHOOK结构
D:/Project/ntos5/w32/ntuser/client/nt6/ntuser.h : 1986
typedef struct tagHOOK { /* hk */
THRDESKHEAD head;
struct tagHOOK *phkNext;
int iHook; // WH_xxx hook type
DWORD offPfn;
UINT flags; // HF_xxx flags
int ihmod;
PTHREADINFO ptiHooked; // Thread hooked.
PDESKTOP rpdesk; // Global hook pdesk. Only used when
// hook is locked and owner is destroyed
#ifdef HOOKBATCH
DWORD cEventMessages; // Number of events in the cache
DWORD iCurrentEvent; // Current cache event
DWORD CacheTimeOut; // Timeout between keys
PEVENTMSG aEventCache; // The array of Events
#endif // HOOKBATCH
} HOOK, *PHOOK;
要遍历,只要自己创建一个hook就得到了链表头,呵呵。这里的 ihmod 是 pstrLib的 atom,还没有分析怎么简单从ihmod取到pstrLib。
这基本是icesword的钩子技术。