现在的位置: 首页 > 综合 > 正文

破解cnnic-1.2.0.1和分析icesword部分功能转贴]

2013年06月27日 ⁄ 综合 ⁄ 共 44701字 ⁄ 字号 评论关闭
文章目录

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 <sunwangme@hotmail.com>
 */

//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的钩子技术。

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=508721


[点击此处收藏本文]   发表于 2005年10月18日 8:33 PM

 

 

酒肉和尚 发表于2005-10-18 8:46 PM  IP: 211.100.21.*
是 cnnic2.2.0.1,另外补充一个我的手记:
cnnic 2.2.0.1技术分析
1.启动机制
1.1 安装bho为启动机制 cdniehlp.dll wmhlpr.dll
1.2 安装wh_cbt全局hook,cdnup.exe,然后如果是IE,就在IE内部安装CALLWNDPROC KEYWORD GETMESsAGE CALLWNDPROC钩子进程钩子

总的说来,就是cdniehlp.dll在ie内部安装了钩子,沟通钩子来实现功能。

2.cnnic拦截了SetWindowHookEx等函数,拦截了QueryRegValue等函数,这样,可以阻止别人做hook和bho。真狠。

3. 对付方法
3.1 ldrloaddll不让cdniehlp.dll起来
3.2 hook QueryRefValue来搞一个同样的cheat让bho不能起来
3.3 hook SetWindowsHookEx让cdniehlp.dll不能起作用【根据[ebp+4]及返回地址
来判断是那个调用了函数。可以enum当前process的module来得知其module's name。nt下,调用
SetWindowsHookEx时,并不会把dll加载到process里面,而是在有消息时候,由系统通过KiUserSetCallBack来通知User32.dll来加载响应的dll然后在调用相应的函数地址,user32.dll
加载dll也就是通过LoadLibraryExW。这样,就可以直接拦截LoadLibraryExW了事。系统内部应该
有个什么list来放Hook,等相应的消息出现后,在查询list并判断process是否加载了list里面的
dll,没有的话就先加载。可以直接拦截SetWindowsHookEx,这样就不允许设置hook,也可以直接
禁止dll的load。呵呵。所有的目标就是cdniehlp.dll。要在process第一行代码运行前就hook SetWindowsHookEx,必须采用特殊方法,哈哈,呵呵,如hackdef100。判断是不是自己的模块调用
了API,也可以判断[ebp+4],哈哈】
<29a-7.024>
pjf-防止全局钩子的侵入
3.4 动态uninstall它的bho,【知道了IID通过enum到的cp来查询iid,如果成功就断开

4.icesword的钩子怎么检测的?

 

酒肉和尚 发表于2005-10-18 8:53 PM  IP: 211.100.21.*
手记2:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "ntdll_x.h"

#pragma comment(lib,"ntdll.lib")
/*
fs:[0h] --> TEB
*/
/*
> dt -v -r ntdll!_TEB
struct _TEB, 64 elements, 0xfb4 bytes
+0x000 NtTib : struct _NT_TIB, 8 elements, 0x1c bytes
+0x01c EnvironmentPointer : Ptr32 to Void
+0x020 ClientId : struct _CLIENT_ID, 2 elements, 0x8 bytes
+0x028 ActiveRpcHandle : Ptr32 to Void
+0x02c ThreadLocalStoragePointer : Ptr32 to Void
+0x030 ProcessEnvironmentBlock : Ptr32 to struct _PEB, 66 elements, 0x210 bytes
*/
/*
> dt -v _NT_TIB $teb
struct _NT_TIB, 8 elements, 0x1c bytes
+0x000 ExceptionList : 0x0012ffb0 struct _EXCEPTION_REGISTRATION_RECORD, 2 elements, 0x8 bytes
+0x004 StackBase : 0x00130000
+0x008 StackLimit : 0x0012b000
+0x00c SubSystemTib : (null)
+0x010 FiberData : 0x00001e00
+0x010 Version : 0x1e00
+0x014 ArbitraryUserPointer : (null)
+0x018 Self : 0x7ffde000 struct _NT_TIB, 8 elements, 0x1c bytes
*/
/*
> dt -v -r ntdll!_PEB
struct _PEB, 66 elements, 0x210 bytes
+0x000 InheritedAddressSpace : UChar
+0x001 ReadImageFileExecOptions : UChar
+0x002 BeingDebugged : UChar
+0x003 SpareBool : UChar
+0x004 Mutant : Ptr32 to Void
+0x008 ImageBaseAddress : Ptr32 to Void
+0x00c Ldr : Ptr32 to struct _PEB_LDR_DATA, 7 elements, 0x28 bytes
*/
/*
> dt -v -r ntdll!_PEB_LDR_DATA
struct _PEB_LDR_DATA, 7 elements, 0x28 bytes
+0x000 Length : Uint4B
+0x004 Initialized : UChar
+0x008 SsHandle : Ptr32 to Void
+0x00c InLoadOrderModuleList : struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x014 InMemoryOrderModuleList : struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x01c InInitializationOrderModuleList : struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x024 EntryInProgress : Ptr32 to Void
*/
/*
> dt -v -r ntdll!_LIST_ENTRY
struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x000 Flink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x004 Blink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
*/
/* kproccheck中的说明是错误的。通过TEB-PEB枚举当前进程空间中用户模块列表.txt中才是对的。
typedef struct _LDR_MODULE
{
LIST_ENTRY Link;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
LPWSTR FullDllName;
LPWSTR BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;

} LDR_MODULE;
*/
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;

//*******************************************************************************************************
// Returns the name of the DLL that the given API address belongs to.
//
//*******************************************************************************************************

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;
}
}
}
}
ldr = (LDR_MODULE *)ldr->InLoadOrderModuleList.Flink;

if(ldr == headLdr)
break;
}
return NULL;
}

char * __stdcall EnumDLLofPEB(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);
}
ldr = (LDR_MODULE *)ldr->InLoadOrderModuleList.Flink;

if(ldr == headLdr)
break;
}
return NULL;
}

int __stdcall DisplayMyHostName(void)
{
//取返回地址,看看是谁在调用我
ULONG rip=0xffffffff;
__asm
{
mov eax,[ebp+04h]
mov rip,eax
}
printf("the host is from ebp+04h:%s/n",getDLLofAPI(rip));
printf("the host is from DisplayMyHostName :%s/n",getDLLofAPI((ULONG)DisplayMyHostName));
printf("the host is from MessageBox :%s/n",getDLLofAPI((ULONG)MessageBox));

return 1;
}

#define NOT_SUPPORTED 0
#define WIN2K 1
#define WINXP 2
DWORD gKernelVersion = NOT_SUPPORTED;
void __stdcall GetOSVersion(void)
{
OSVERSIONINFO ov;
ov.dwOSVersionInfoSize = sizeof(ov);
GetVersionEx(&ov);
if(ov.dwMajorVersion == 5)
{
if(ov.dwMinorVersion == 0)
gKernelVersion = WIN2K;
else if(ov.dwMinorVersion == 1)
gKernelVersion = WINXP;
}
}

//*********************************************************************************************
// Assign ie.loaddriver priviledge to our process, so we can load our support driver.
//
//*********************************************************************************************
//SeLoadDriverPrivilege
//SeDebugPrivilege
BOOL EnablePrivilege(char* PrivName)
{
HANDLE hToken;

if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
{
LUID huid;
if(LookupPrivilegeValue(NULL,PrivName , &huid))
{
LUID_AND_ATTRIBUTES priv;
priv.Attributes = SE_PRIVILEGE_ENABLED;
priv.Luid = huid;

TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0] = priv;

if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
{
return TRUE;
}
}
}
return FALSE;
}

//---------------------------------------------------------------------------
// _OpenThread
//
// This function is an OpenThread replasement for Windows NT 4.0.
//
// Parameters:
// dwDesiredAccess - requested access rights to the thread object
// bInheritHandle - handle inheritance flag
// dwThreadId - thread identifier
//
// Returns:
// thread handle if successful, NULL - otherwise.
//
HANDLE __stdcall _OpenThread(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwThreadId
)
{
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID ClientId;
HANDLE hThread;
NTSTATUS Status;

memset(&ObjectAttributes, 0, sizeof(ObjectAttributes));

if (bInheritHandle)
ObjectAttributes.uAttributes = OBJ_INHERIT;

ClientId.UniqueProcess = NULL;
ClientId.UniqueThread = (HANDLE)dwThreadId;

Status = NtOpenThread(&hThread, dwDesiredAccess,
&ObjectAttributes, &ClientId);

if (!NT_SUCCESS(Status))
{
return NULL;
}

return hThread;
}
HANDLE __stdcall _OpenProcess(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
)
{
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID ClientId;
HANDLE hThread;
NTSTATUS Status;

memset(&ObjectAttributes, 0, sizeof(ObjectAttributes));

if (bInheritHandle)
ObjectAttributes.uAttributes = OBJ_INHERIT;

ClientId.UniqueProcess =(HANDLE)dwProcessId ;
ClientId.UniqueThread = NULL;

Status = NtOpenProcess(&hThread, dwDesiredAccess,
&ObjectAttributes, &ClientId);

if (!NT_SUCCESS(Status))
{
return NULL;
}

return hThread;
}

//---------------------------------------------------------------------------
// TestOpenThread
//
// Tests OpenThread function.
//
// Parameters:
// dwThreadId - thread identifier
//
// Returns:
// no return value.
//
void __stdcall
TestOpenThread(
IN DWORD dwThreadId
)
{
NTSTATUS status;
HANDLE hThread = _OpenThread(THREAD_QUERY_INFORMATION,
FALSE, dwThreadId);
if (hThread == NULL)
{
printf("OpenThread failed with code %d/n",
GetLastError());
}
else
{
THREAD_BASIC_INFORMATION tbi;
DWORD dwRetByte=0;
status=NtQueryInformationThread(hThread,ThreadBasicInformation,&tbi,sizeof(tbi),&dwRetByte);
if(status != STATUS_SUCCESS)
{
printf("NtQueryInformationThread error/n");
}
else
{
printf("teb addr: 0x%08lx/n",tbi.TebBaseAddress);
PTEB pTeb=(PTEB)tbi.TebBaseAddress;

//这里已经不是自己进程的地址,不能直接访问,只能readprocessmemory搞回来
//PPEB pPeb =pTeb->Peb;
//printf("peb addr: 0x%08lx/n",tbi.TebBaseAddress);
//EnumDLLofPEB((DWORD)pPeb);
}
CloseHandle(hThread);
}
}

void __stdcall
TestOpenProcess(
IN DWORD dwProcessId
)
{
NTSTATUS status;
HANDLE hProcess = _OpenProcess(PROCESS_QUERY_INFORMATION,
FALSE, dwProcessId);
if (hProcess == NULL)
{
printf("_OpenProcess failed with code %d/n",
GetLastError());
}
else
{
PROCESS_BASIC_INFORMATION pbi;
DWORD dwRetByte=0;
status=NtQueryInformationProcess(hProcess,ProcessBasicInformation,&pbi,sizeof(pbi),&dwRetByte);
if(status != STATUS_SUCCESS)
{
printf("NtQueryInformationProcess error/n");
}
else
{
printf("peb addr: 0x%08lx/n",pbi.PebBaseAddress);
PPEB pPeb=(PPEB)pbi.PebBaseAddress;

//这里已经不是自己进程的地址,不能直接访问,只能readprocessmemory搞回来
//EnumDLLofPEB((DWORD)pPeb);
}
CloseHandle(hProcess);
}
}
//*********************************************************************************************
// Displays driver list obtained by traversing PsLoadedModuleList
//
//*********************************************************************************************

int __stdcall DisplayProcessList(void)
{
NTSTATUS status;
ULONG cbBuffer = 0x8000;
PVOID pBuffer = NULL;

do
{
pBuffer = malloc(cbBuffer);
if (pBuffer == NULL)
goto done;

status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, cbBuffer, NULL);

if(status == STATUS_INFO_LENGTH_MISMATCH)
{
free(pBuffer);
cbBuffer <<= 1;
}
else if(status != STATUS_SUCCESS)
{
free(pBuffer);
goto done;
}
}
while (status == STATUS_INFO_LENGTH_MISMATCH);

if(pBuffer)
{
printf("Process list by traversal of _ZwQuerySystemInformation/n");
_SYSTEM_PROCESS_INFORMATION_2000* pInfo=(_SYSTEM_PROCESS_INFORMATION_2000*)pBuffer;
do {
printf("process id:name: %d:%ws/n",pInfo->uUniqueProcessId,pInfo->usName.Buffer);

//process query
//if(GetCurrentProcessId()==pInfo->uUniqueProcessId)
{
TestOpenProcess(pInfo->uUniqueProcessId);

//thread enum
printf("thread count:%d/n",pInfo->uThreadCount);
SYSTEM_THREAD* pThread=(SYSTEM_THREAD*)(pInfo->aST);
DWORD ithread=0;
while(ithread<pInfo->uThreadCount && pInfo->uUniqueProcessId!=0 && pInfo->uUniqueProcessId!=4)
{
printf("thread%d: id:%d,start addr:0x%08lx/n",
ithread,
(DWORD)pThread[ithread].Cid.UniqueThread,
pThread[ithread].pStartAddress);

//thread query
TestOpenThread((DWORD)pThread[ithread].Cid.UniqueThread);
ithread+=1;
}
}

} while(
(pInfo->uNext) &&
(pInfo=(_SYSTEM_PROCESS_INFORMATION_2000*)((char*)pInfo+pInfo->uNext))
);

free(pBuffer);
}

done:
return 1;
}

int _cdecl main()
{
EnablePrivilege("SeDebugPrivilege");
EnablePrivilege("SeLoadDriverPrivilege");
GetOSVersion();
DisplayMyHostName();
DisplayProcessList();
__asm int 3;
return 0;
}

 

酒肉和尚 发表于2005-10-18 8:56 PM  IP: 211.100.21.*
手记3: 破解cnnic的加密
/*
sunwangme@gmail.com
2005-08-09
*/

#include <iostream>
#include <fstream>
#include <windows.h>

/*
byte_1000D030 db 7Ah ; DATA XREF: Decrypt+1E.r
db 63h ; c
db 6Bh ; k
db 0
*/
BYTE byte_1000D030[4]={0x7a,0x63,0x6b,0x00};
/*
Decrypt proc near ; CODE XREF: sub_10001540+DE.p
; sub_100017C0+15B.p ...

arg_0 = dword ptr 8
arg_4 = dword ptr 0Ch

push edi
mov edi, [esp+arg_4]
xor ecx, ecx ; Logical Exclusive OR
test edi, edi ; Logical Compare
jle short loc_10001170 ; Jump if Less or Equal (ZF=1 | SF!=OF)
push ebx
push esi
mov esi, [esp+8+arg_0]

loc_10001151: ; CODE XREF: Decrypt+2C.j
mov eax, ecx
mov ebx, 3
cdq ; EAX -> EDX:EAX (with sign)
idiv ebx ; Signed Divide
mov bl, [ecx+esi]
mov al, byte_1000D030[edx]
xor bl, al ; Logical Exclusive OR
mov [ecx+esi], bl
inc ecx ; Increment by 1
cmp ecx, edi ; Compare Two Operands
jl short loc_10001151 ; Jump if Less (SF!=OF)
pop esi
pop ebx

loc_10001170: ; CODE XREF: Decrypt+9.j
pop edi
retn ; Return Near from Procedure
Decrypt endp

; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
*/

void __declspec(naked) cnnic_decrypt(char* arg_0,int arg_4)
{
#define arg_0 dword ptr 8
#define arg_4 dword ptr 0Ch
__asm
{
push edi
mov edi, [esp+arg_4]
xor ecx, ecx ; Logical Exclusive OR
test edi, edi ; Logical Compare
jle short loc_10001170 ; Jump if Less or Equal (ZF=1 | SF!=OF)
push ebx
push esi
mov esi, [esp+8+arg_0]

loc_10001151: ; CODE XREF: Decrypt+2C.j
mov eax, ecx
mov ebx, 3
cdq ; EAX -> EDX:EAX (with sign)
idiv ebx ; Signed Divide
mov bl, [ecx+esi]
mov al, byte_1000D030[edx]
xor bl, al ; Logical Exclusive OR
mov [ecx+esi], bl
inc ecx ; Increment by 1
cmp ecx, edi ; Compare Two Operands
jl short loc_10001151 ; Jump if Less (SF!=OF)
pop esi
pop ebx

loc_10001170: ; CODE XREF: Decrypt+9.j
pop edi
retn ; Return Near from Procedure
}
}

int __stdcall WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd )
{
using namespace std;
char buffer[0xcbc]={0};
fstream inFile;
inFile.open("cdnprot.dat",ios_base::in | ios_base::binary);
inFile.read(buffer,0xcbc);
cnnic_decrypt(buffer,0xcbc);
fstream outFile;
outFile.open("cdnprot.dat.txt",ios_base::out);
outFile.write(buffer,0xcbc);
outFile.close();
inFile.close();
return 0;
}

 

酒肉和尚 发表于2005-10-21 9:16 PM  IP: 211.100.21.*
ICESword文件删除:
hook fsd的dispach函数,我已经成功的拦截到了icesword

 

酒肉和尚 发表于2005-10-21 9:17 PM  IP: 211.100.21.*
icesword注册表-多谢无名氏

初步分析发现 icesword在访问注册表的时候采用的是常规的native api注册表查询函数。不过他首先将函数恢复到原来的windows标准,然后调用。
1、恢复sdt;2、恢复函数体。
所以它能得到没有被hook的信息。

所以hook 以下对应函数就可以:
NtOpenKey--〉ObOpenObjectByName
NtEnumatekey-->CmEnumerateKey
NtEnumateValueKey --> CmEnumerateValueKey

 

酒肉和尚 发表于2005-10-21 9:18 PM  IP: 211.100.21.*
ICESword消息钩子

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, //<-------kernel PtiCurrent,可以在内核里面得到
//是否是hooked process&thread,不是的话,attachprocess
DWORD dwFlags);

PROC zzzSetWindowsHookAW(
int nFilterType,
PROC pfnFilterProc,
DWORD dwFlags)
{
PHOOK phk;

phk = zzzSetWindowsHookEx(NULL, NULL, PtiCurrent(),
nFilterType, pfnFilterProc, dwFlags);

/*
* If we get an error from zzzSetWindowsHookEx() then we return
* -1 to be compatible with older version of Windows.
*/
if (phk == NULL) {
return (PROC)-1;
}

/*
* Handle the backwards compatibility return value cases for
* SetWindowsHook. If this was the first hook in the chain,
* then return NULL, else return something non-zero. HKF_NZRET
* is a special case where SetWindowsHook would always return
* something because there was a default hook installed. Some
* apps relied on a non-zero return value in those cases.
*/
if ((phk->phkNext != NULL) || (abHookFlags[nFilterType + 1] & HKF_NZRET)) {
return (PROC)phk;
}

return NULL;
}

/*
* Libraries are loaded at different linear addresses in different
* process contexts. For this reason, we need to convert the filter
* proc address into an offset while setting the hook, and then convert
* it back to a real per-process function pointer when calling a
* hook. Do this by subtracting the 'hmod' (which is a pointer to the
* linear and contiguous .exe header) from the function index.
*/
phkNew->offPfn = ((ULONG_PTR)pfnFilterProc) - ((ULONG_PTR)hmod);

参考:
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 <sunwangme@hotmail.com>
*/

//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的钩子技术。如果根据ptiHooked来判断线程然后去掉进程,也可以。或者找到win32k.sys内部的atom<-->modulename
的函数的地址,调用就是了

4.动态禁止钩子
其实很简单了,首先取到钩子链表,然后遍历,找到自己想要的,去掉就是了。哈哈。
NtUserSetWindowsHookEx相反的一个函数就可以了。
这样,就不用去hook相关的函数就可以来禁止相互的hook了。真有意思。
当然,在卸载的时候,要判断PTHREADINFO的hooked thread是不是在自己的进程空间里面,如果不是,要
attche到目标进程空间,然后卸载了。哈哈。
hackdef hooks.c里面都有这样的代码。
ie.

/***************************************************************************/
* CheckWHFBits
*
* This routine checks to see if any hooks for nFilterType exist, and clear
* the appropriate WHF_ in the THREADINFO and SERVERINFO.
*
* History:
* 08-17-92 DavidPe Created.
/***************************************************************************/

VOID CheckWHFBits(
PTHREADINFO pti,
int nFilterType)
{
BOOL fClearThreadBits;
BOOL fClearDesktopBits;
PHOOK phook;

/*
* Assume we're are going to clear local(thread) and
* global(desktop) bits.
*/
fClearThreadBits = TRUE;
fClearDesktopBits = TRUE;
/*
* Get the first valid hook for this thread
*/
phook = PhkFirstValid(pti, nFilterType);
if (phook != NULL) {
/*
* If it found a global hook, don't clear the desktop bits
* (that would mean that there are no local(thread) hooks
* so we fall through to clear the thread bits)
*/
if (phook->flags & HF_GLOBAL) {
fClearDesktopBits = FALSE;
} else {
/*
* It found a thread hook so don't clear the thread bits
*/
fClearThreadBits = FALSE;
/*
* Check for global hooks now. If there is one, don't
* clear the desktop bits
*/
phook = PhkFirstGlobalValid(pti, nFilterType);
fClearDesktopBits = (phook == NULL);
}
} /* if (phook != NULL) */

if (fClearThreadBits) {
pti->fsHooks &= ~(WHF_FROM_WH(nFilterType));
/*
* Set the flags in the thread's TEB
*/
if (pti->pClientInfo) {
BOOL fAttached;
/*
* If the hooked thread is in another process, attach
* to that process to access its address space.
*/
if (pti->ppi != PpiCurrent()) {
KeAttachProcess(&pti->ppi->Process->Pcb);
fAttached = TRUE;
} else
fAttached = FALSE;

pti->pClientInfo->fsHooks = pti->fsHooks;

if (fAttached)
KeDetachProcess();
}
}

if (fClearDesktopBits) {
pti->pDeskInfo->fsHooks &= ~(WHF_FROM_WH(nFilterType));
}
}

/***************************************************************************/
* zzzUnhookWindowsHook (API)
*
* This is the old version of the Unhook API. It does the same thing as
* zzzUnhookWindowsHookEx(), but takes a filter-type and filter-proc to
* identify which hook to unhook.
*
* History:
* 01-28-91 DavidPe Created.
/***************************************************************************/

BOOL zzzUnhookWindowsHook(
int nFilterType,
PROC pfnFilterProc)
{
PHOOK phk;
PTHREADINFO ptiCurrent;

if ((nFilterType < WH_MIN) || (nFilterType > WH_MAX)) {
RIPERR0(ERROR_INVALID_HOOK_FILTER, RIP_VERBOSE, "");
return FALSE;
}

//这样还必须切换或者inject到目标进程和目标thread来直接调用unhook.
ptiCurrent = PtiCurrent();

for (phk = PhkFirstValid(ptiCurrent, nFilterType); phk != NULL; phk = PhkNextValid(phk)) {
/*
* Is this the hook we're looking for?
*/
if (PFNHOOK(phk) == pfnFilterProc) {

/*
* Are we on the thread that set the hook?
* If not return an error.
*/
if (GETPTI(phk) != ptiCurrent) {
RIPERR0(ERROR_ACCESS_DENIED,
RIP_WARNING,
"Access denied in zzzUnhookWindowsHook: "
"this thread is not the same as that which set the hook");

return FALSE;
}

return zzzUnhookWindowsHookEx( phk );
}
}

/*
* Didn't find the hook we were looking for so return FALSE.
*/
RIPERR0(ERROR_HOOK_NOT_INSTALLED, RIP_VERBOSE, "");
return FALSE;
}

typedef struct tagTHREADINFO {
W32THREAD;

//***************************************** begin: USER specific fields

PTL ptl; // Listhead for thread lock list

PPROCESSINFO ppi; // process info struct for this thread

PQ pq; // keyboard and mouse input queue

PKL spklActive; // active keyboard layout for this thread

PCLIENTTHREADINFO pcti; // Info that must be visible from client

PDESKTOP rpdesk;
PDESKTOPINFO pDeskInf

抱歉!评论已关闭.