首页
社区
课程
招聘
[分享]微软的Hot Patch代码
发表于: 2011-6-27 21:37 18144

[分享]微软的Hot Patch代码

2011-6-27 21:37
18144
基本的方法MJ已经说了, 并给出了主要的代码. 此方法简单易用. 相当不错.
可惜偶比较菜, 到现在才来学习. 补全了MJ的代码, 增加了卸载驱动恢复原函数的代码. 跟我一样的菜鸟可以看看, 大牛飘过.
MJ的帖子: http://www.debugman.com/discussion/670#a

先用WinDbg看下原函数:


Hook示意图:


代码如下:
#include "ntddk.h"

typedef unsigned char BYTE;
BYTE OriginalBytes[2]={0};
  
KSPIN_LOCK SDTSpinLock;
ULONG g_uCr0 = 0;

extern POBJECT_TYPE *PsProcessType;

VOID WPOFF();
VOID WPON();

NTKERNELAPI
NTSTATUS
ObReferenceObjectByHandle(               
                                                  IN HANDLE  Handle,
                                                  IN ACCESS_MASK  DesiredAccess,
                                                  IN POBJECT_TYPE  ObjectType  OPTIONAL,
                                                  IN KPROCESSOR_MODE  AccessMode,
                                                  OUT PVOID  *Object,
                                                  OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL
                                                  );

//HOOK函数
NTSTATUS
DetourMyObReferenceObjectByHandle(                  
                                                                  IN HANDLE  Handle,           
                                                                  IN ACCESS_MASK  DesiredAccess,
                                                                  IN POBJECT_TYPE  ObjectType  OPTIONAL,
                                                                  IN KPROCESSOR_MODE  AccessMode,
                                                                  OUT PVOID  *Object,
                                                                  OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL
                                           );

void WPOFF()
{
   
    ULONG uAttr;
   
    _asm
    {
        push eax;
        mov eax, cr0;
        mov uAttr, eax;
        and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
        mov cr0, eax;
        pop eax;
        cli
    };
   
    g_uCr0 = uAttr;  
   
}

VOID WPON()
{  
    _asm
    {
        sti
        push eax;
        mov eax, g_uCr0;
        mov cr0, eax;
        pop eax;
    };   
}

NTSTATUS InlineHookFuncXP(IN PVOID FuncAddress,
                         IN PVOID NewFuncAddress)
{
        //FuncAddress:orignal function address
        //NewFuncAddress:new function address to hook
        //if function successed,the old function which the hook function will jump to
        //is the FuncAddress+2

        KIRQL OldIrql ;
        NTSTATUS stat;

    KeAcquireSpinLock( &SDTSpinLock, &OldIrql );

    WPOFF();
        //保存原函数的头两个字节
        RtlCopyMemory(OriginalBytes,(BYTE *)ObReferenceObjectByHandle,2);

    __asm
    {
        push eax
        push ecx
        lea eax,[FuncAddress]
        mov eax,[eax]
        cmp byte ptr[eax],0x8b               
        jnz failtohook
        cmp byte ptr[eax+1],0xff  ;判断函数开始头部是不是 "mov edi,edi"
        jnz failtohook
        mov ecx,0xffffffff                  ;-1
loopcheck:
        cmp byte ptr[eax+ecx],0x90
        jnz failtohook
        dec ecx
        cmp ecx,0xfffffffa ;循环5次, 判断函数开始上面部分是不是"nop"
        jnz loopcheck
        
                ;保存函数原始的指令

        mov byte ptr[eax],0xeb        ; 短跳jmp
        mov byte ptr[eax+1],0xf9 ; 0x00-偏移量-指令长度 = 0x00-5-2 = f9
        ;write the new function header:jmp short funcaddr-5(0x00-0x07)
        mov byte ptr[eax-5],0xe9 ;远跳jmp
        ;write 1 byte :jmp xxxxx
        mov ecx,[NewFuncAddress]
        sub ecx,eax                ;得到跳转的相对偏移
        mov dword ptr[eax-4],ecx
        jmp hookok
failtohook:
        mov stat,0xc0000001
        jmp end
hookok:
        mov stat,0
end:
        pop ecx
        pop eax
    }
    WPON();
    KeReleaseSpinLock( &SDTSpinLock, OldIrql );

    return stat;
}

VOID UnInlineHookFuncXP(IN PVOID FuncAddress)
{
        KIRQL OldIrql ;
        NTSTATUS stat;
       
    KeAcquireSpinLock( &SDTSpinLock, &OldIrql );
    WPOFF();

        // 恢复函数的前两个字节
        RtlCopyMemory((BYTE *)FuncAddress, OriginalBytes, 2);

        // 恢复函数上面的5个nop
        __asm
        {
                push ecx
                push eax
                lea eax,[FuncAddress]
                mov eax,[eax]
                mov ecx,0xffffffff                  ;-1
loopcheck:
                mov byte ptr[eax+ecx],0x90
                dec ecx
                cmp ecx,0xfffffffa
                jnz loopcheck
                pop eax
                pop ecx
        }

        WPON();
    KeReleaseSpinLock( &SDTSpinLock, OldIrql );
}

_declspec (naked)
NTSTATUS
OriginalObReferenceObjectByHandle(
                                                                  IN HANDLE  Handle,
                                                                  IN ACCESS_MASK  DesiredAccess,
                                                                  IN POBJECT_TYPE  ObjectType  OPTIONAL,
                                                                  IN KPROCESSOR_MODE  AccessMode,
                                                                  OUT PVOID  *Object,                              
                                                                  OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL
                                                                  )
                                                                  
{
        _asm   
        {   
                mov edi,edi  // 手动写ObReferenceObjectByHandle函数开头的2个字节, 可用WinDbg查看
                mov eax,ObReferenceObjectByHandle
                add eax,2
                jmp eax                  
        }  
}

NTSTATUS
DetourMyObReferenceObjectByHandle(
                                                                  IN HANDLE  Handle,
                                                                  IN ACCESS_MASK  DesiredAccess,
                                                                  IN POBJECT_TYPE  ObjectType  OPTIONAL,
                                                                  IN KPROCESSOR_MODE  AccessMode,
                                                                  OUT PVOID  *Object,
                                                                  OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL
                                                                  )
                                                                  
{
        NTSTATUS status;

        status = OriginalObReferenceObjectByHandle(Handle,DesiredAccess, ObjectType,AccessMode,Object,HandleInformation);
        if((status==STATUS_SUCCESS)&&(DesiredAccess==1)) // 如果是关闭软件, 从DesiredAccess == 1可知
        {   
                if(ObjectType== *PsProcessType)  
                {
                        if( _stricmp((char *)((ULONG)(*Object)+0x174),"notepad.exe")==0)
                        {   
                                ObDereferenceObject(*Object);
                                return STATUS_INVALID_HANDLE;
                        }
                }
        }

        return status;
}

VOID
DriverUnload(
                         IN PDRIVER_OBJECT pDriverObj
                         )
{       
        UnInlineHookFuncXP(ObReferenceObjectByHandle);
        KdPrint(("[inlineHook] Unloaded Success\r\n"));
        return;
}

NTSTATUS
DriverEntry(
                        IN PDRIVER_OBJECT pDriverObj,
                        IN PUNICODE_STRING pRegistryString
                        )
{
        NTSTATUS status = STATUS_SUCCESS;
       
        KdPrint(("Enter DriverEntry!\n"));
        pDriverObj->DriverUnload = DriverUnload;
        status = InlineHookFuncXP(ObReferenceObjectByHandle, DetourMyObReferenceObjectByHandle);
        if (NT_SUCCESS(status))
                KdPrint(("Inline Hook Success!\n"));
        else
                KdPrint(("Inline Hook UnSuccess!\n"));

        return status;
}

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 7
支持
分享
最新回复 (36)
雪    币: 601
活跃值: (256)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
2
一贯作风,先回帖,再看帖
2011-6-27 21:38
0
雪    币: 242
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
先恭喜一下莫兄荣升版主,好文章支持!
2011-6-27 22:00
0
雪    币: 302
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
果然好东西啊。。收藏了
2011-6-27 22:16
0
雪    币: 37
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
贴过留名。看后再做评论
2011-6-27 22:19
0
雪    币: 253
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
win7 是7个字节吧?
2011-6-27 22:30
0
雪    币: 2177
活跃值: (2045)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
7
呵呵, 多谢兄弟支持了. 大家一起加油.
2011-6-27 22:39
0
雪    币: 2177
活跃值: (2045)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
8
手上没有WIN7, 所以没有研究, 兄弟可以自己用WinDbg查看下, 在做相应的修改, 应该不难的.
2011-6-27 22:40
0
雪    币: 72
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9
好东西哇 学习了
2011-6-27 22:58
0
雪    币: 67
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
10
这个自己早就做过了……没想到还能打上MS的旗号来 “招摇撞骗”
2011-6-28 04:18
0
雪    币: 2177
活跃值: (2045)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
11
这个本来就是微软的做法,mj也是逆出来的。我贴出来只是方便像我一样的菜鸟学习,看前面的回帖还是有一部分同学是不知道的。也希望以后兄弟能多多发帖啊!你懂的别人不一定懂,也方便吾等小白增长知识。
2011-6-28 06:54
0
雪    币: 67
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
12
表激动……没看见那个引号?俺是支持你的
2011-6-28 07:02
0
雪    币: 2177
活跃值: (2045)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
13
激动到木有. 只是现在这个区的学习气氛不怎么好, 鼓励大家多多发帖呢. 呵呵.  
兄弟也很早嘛, 你的智能主防研究的肿么样了啊, 嘿嘿~.
2011-6-28 07:11
0
雪    币: 67
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
14
what? 你怎么知道的……不会是我QQ里的某某吧?
2011-6-28 07:33
0
雪    币: 2177
活跃值: (2045)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
15
那没有, 因为兄弟在论坛里还是很犀利了, 我老早关注你了嘛, 嘿嘿~
2011-6-28 07:41
0
雪    币: 67
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
16
晕……! 我表示很蛋疼 =。=
哥睡了
2011-6-28 07:55
0
雪    币: 384
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
好文章  纯支持
2011-6-28 09:22
0
雪    币: 1644
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
学习思路。。。
2011-6-28 12:45
0
雪    币: 217
活跃值: (67)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
先回贴 再看贴
2011-6-28 13:33
0
雪    币: 116
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
很强大!学习!
2011-6-28 13:44
0
雪    币: 8599
活跃值: (5065)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
谢谢。。。。学习了。
2011-6-29 09:25
0
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
22
水平太菜,不是很明白。
1. WPOFF和WPON有什么用?
2. 在多核系统中,Hook函数的时候不怕有程序正在使用这个函数嘛?
3. 函数开头的5个字节已经是固定的了
mov edi, edi,
push ebp
mov ebp, esp

为什么需要使用前面的5个nop,不直接在这inline hook?
2011-6-29 10:35
0
雪    币: 544
活跃值: (264)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
23
mov byte ptr[eax],0xeb  ; 短跳jmp
        mov byte ptr[eax+1],0xf9 ; 0x00-偏移量-指令长度 = 0x00-5-2 = f9
        ;write the new function header:jmp short funcaddr-5(0x00-0x07)
        mov byte ptr[eax-5],0xe9 ;远跳jmp
        ;write 1 byte :jmp xxxxx
        mov ecx,[NewFuncAddress]
        sub ecx,eax    ;得到跳转的相对偏移
        mov dword ptr[eax-4],ecx
        jmp hookok

这里很有问题,实际运行中可能会蓝的。

参考:http://www.debugman.com/discussion/2232/
2011-6-29 10:51
0
雪    币: 102
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
函数开头不是必须要是mov edi,edi吧,用海风大大的getpachsize保存指令就好
另外前5个也不一定要是nop吧?int3不也一样,KeAttachProcess前5好像就是int3
2011-6-29 10:57
0
雪    币: 2177
活跃值: (2045)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
25
[QUOTE=KiDebug;974984]mov byte ptr[eax],0xeb  ; 短跳jmp
        mov byte ptr[eax+1],0xf9 ; 0x00-偏移量-指令长度 = 0x00-5-2 = f9
        ;write the new function header:jmp short f...[/QUOTE]

有啥问题,请KiDebug兄弟指点。
2011-6-29 10:57
0
游客
登录 | 注册 方可回帖
返回
//