首页
社区
课程
招聘
[原创]XTrap驱动逆向分析
发表于: 2007-9-7 11:37 34089

[原创]XTrap驱动逆向分析

2007-9-7 11:37
34089

XTrap驱动分析

NetRoc/cc682

最近拿到一个使用XTrap的游戏,据说此物乃NP和HS之外的第三大反外挂系统,so拿来瞧了瞧。
Ring3层包括几个dll和一个进程。看里面貌似使用了pipe相关的函数,运行时也起了一个进程。所以XTrap的架构应该和NP很类似,但是实现上就要弱很多了。
1、        现在还没发现有ring3全局注入的dll。
2、        大量工作放到了作为和游戏接口的dll里面。通过dll方式提供游戏使用这点不同于NP的lib库,而更类似HS。这种方式一大弱点就是那个dll容易被模拟,并且比较难发现。
3、        驱动相对来说应该是三个系统里面最弱的了,原因下面会讲到。花了5天时间逆出了整个驱动的源码,好像没有那么多硬编码的东西,呵呵。不过倒是发现了一些编程的BUG什么的。基本的功能点只有三个:HOOK SSDT实现的跨进程访问控制、通过对IoAccessMap的设置关闭对鼠标键盘端口访问权限、通过挂接Int 1中断获得调试信息。

大概的流程如下:
1、        DriverEntry:通过PsGetVersion判断系统版本,并根据不同的版本保存要Hook的在SSDT Shadow表中服务的ID。而SSDT表中的则是由后面IoControl里面Ring3传下来的。目前来看已经支持Vista了。通过KeQuerySystemTime拿了一下系统时间并保存下来,不过后面就没有再使用了,估计以后为了反调试会做时间检查什么的东西吧。申请了0x2000长度的内存,这是用于后面设置IoAccessMap的。然后就是例行的IoCreateDevice和IoCreateSymbolicLink,设置Dispatch例程。XTrap的IRP_MJ_DEVICE_CONTROL、IRP_MJ_CREATE、IRP_MJ_CLOSE、IRP_MJ_CLEANUP是在同一个例程中处理的。最后有一个莫名其妙的调用KfLowerIrql( KeRaiseIrqlToDpcLevel());偶的水平实在是还难以理解高丽棒子为啥要这样做,嘿嘿。
2、        剩下的就是通过DeviceIoControl来控制的了,我这个版本的XTrap一共有17个ControlCode。Dispatch例程的代码如下
NTSTATUS
XDvaDispatchAll( IN PDEVICE_OBJECT  DeviceObject, IN PIRP  Irp)
{
        PIO_STACK_LOCATION pIrpStack;
        PVOID pSystemBuffer;
        PVOID pOutBuffer;
        ULONG ulMajorFunction;
        NTSTATUS ntStatus;
       
        pIrpStack = IoGetCurrentIrpStackLocation( Irp);
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        pSystemBuffer = Irp->AssociatedIrp.SystemBuffer;
        ulMajorFunction = pIrpStack->MajorFunction;

        switch( ulMajorFunction)
        {
        case IRP_MJ_DEVICE_CONTROL:
                if( (pIrpStack->Parameters.DeviceIoControl.IoControlCode & 0x3) == 0x3)
                {
                        pOutBuffer = Irp->UserBuffer;
                }
                else
                {
                        pOutBuffer = pSystemBuffer;
                }
                return DoDeviceIoControl( Irp, pIrpStack->FileObject, 1, pSystemBuffer,
                        pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
                        pOutBuffer, pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
                        pIrpStack->Parameters.DeviceIoControl.IoControlCode,
                        &Irp->IoStatus, DeviceObject);
        case IRP_MJ_CLOSE:
                HookSSDT( g_HookInfo.NtOpenProcessInfo.Id, (ULONG)g_pNtOpenProcess, (ULONG)NewNtOpenProcess);
                HookSSDT( g_HookInfo.NtDeviceIoControlFileInfo.Id, (ULONG)g_pNtDeviceIoControlFile, (ULONG)NewNtDeviceIoControlFile);
                HookSSDT( g_HookInfo.NtWriteVirtualMemoryInfo.Id, (ULONG)g_pNtWriteVirtualMemory, (ULONG)NewNtWriteVirtualMemory);
                HookSSDT( g_HookInfo.NtOpenSectionInfo.Id, (ULONG)g_pNtOpenSection, (ULONG)NewNtOpenSection);
                HookSSDT( g_HookInfo.NtProtectVirtualMemoryInfo.Id, (ULONG)g_pNtProtectVirtualMemory, (ULONG)NewNtProtectVirtualMemory);
                HookSSDT( g_HookInfo.NtTerminateProcessInfo.Id, (ULONG)g_pNtTerminateProcess, (ULONG)NewNtTerminateProcess);
                HookSSDT2( g_dwNtGdiGetPixelId, (ULONG)g_pNtGdiGetPixel, (ULONG)NewNtGdiGetPixel);
                HookSSDT2( g_dwNtUserSendInputId, (ULONG)g_pNtUserSendInput, (ULONG)NewNtUserSendInput);
                HookSSDT2( g_dwNtUserCallNextHookExId, (ULONG)g_pNtUserCallNextHookEx, (ULONG)NewNtUserCallNextHookEx);
                HookSSDT2( g_dwNtUserPostMessageId, (ULONG)g_pNtUserPostMessage, (ULONG)NewNtUserPostMessage);
                HookSSDT2( g_dwNtUserTranslateMessageId, (ULONG)g_pNtUserTranslateMessage, (ULONG)NewNtUserTranslateMessage);

                if( g_byIsSuccess)
                {
                        g_byIsSuccess = FALSE;
                }
                if( g_byIsReboot)
                {
                        _asm cli;
                        WRITE_PORT_UCHAR( (PUCHAR)0x64, (UCHAR)0xFE);
                        _asm hlt;
                }
                else
                {
                        ntStatus = STATUS_SUCCESS;
                }
                break;
        case IRP_MJ_CREATE:
                if( g_arrSomeCode[0] == 0)
                {
                        memcpy( g_arrSomeCode, MyInt1, 5*sizeof( ULONG));
                }
                ntStatus = STATUS_SUCCESS;
                break;
        case IRP_MJ_CLEANUP:
                ntStatus = STATUS_SUCCESS;
                break;
        default:
                Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
                ntStatus = STATUS_INVALID_DEVICE_REQUEST;
        }

        IofCompleteRequest( Irp, IO_NO_INCREMENT);
        return ntStatus;
}

IRP_MJ_DEVICE_CONTROL的处理是在另外一个函数里面,由于太复杂,影响blog的美观,就不写出来了,哈哈。这里面可以看到,XTrap采用了和NP一样的办法重起电脑,就是往64端口写0xFE。挺白痴的是居然通过WRITE_PORT_UCHAR,难道以为只有他会Hook~
IRP_MJ_CREATE里面把自己的Int 1 函数的代码复制了一段出来,这个会用于后面再覆盖回去,是用于对付Inline hook的伎俩。
其他就没什么好说的了。
3、        关于SSDT的Hook
SSDT中Hook的函数有以下几个:NtOpenProcess、NtDeviceIoControlFile、NtWriteVirtualMemory、NtOpenSection、NtProtectVirtualMemory、NtTerminateProcess
Shadow Table中Hook的函数有下面几个:NtGdiGetPixel、NtUserSendInput、NtUserCallNextHookEx、NtUserPostMessage、NtUserTranslateMessage。
所有函数Hook的目的都很清楚,没有什么古怪的地方,呵呵。不过相当部分的钩子都只是简单的pass过去,并没有任何实质性的处理。可以看出来XTrap仍然是一个非常不完善的系统,这些部分应该都是留到以后进行功能扩充的。
关于Shadow Table的处理有一些特别的地方。Shadow Table的地址获取采用了硬编码+验证的方式。这一点偶个人觉得还是在KeAddSystemServiceTable中去取比较好,至少说在出现新的系统的时候很大可能并不用修改代码。另外,取到Shadow Table地址之后,除了将KSERVICE_TABLE_DESCRIPTOR地址保存之外,还将Shadow Table的Base保存到了KeServiceDescriptorTable第二项的Base中,以后在Hook或者其他操作的时候就直接到KeAddSystemServiceTable地址+0x10去取了。这一点我也觉得有些奇怪,保存到全局变量什么的不就好了,为什么要去修改系统本身的东西,虽然目前那个位置并没有什么用。大约是为了反调试。
4、        关于Int 1的处理
这里貌似也没什么好说的,记录了一下断点被触发的次数、dr0到dr4的内容什么的,然后IoControl里面Ring3会取走这些信息。不过有个很搞笑的BUG,Hook中断的函数里面的cli没有对应的sti。
5、        关于IoAccessMap的处理
这里没什么好说的,是由Ring3触发,Ring0实现。贴一段DeviceIoContrl里面的代码就明白了。
case 0x85000044:
                ntStatus = STATUS_INVALID_PARAMETER;
                if( !pSystemBuffer || ulInputBufferLength != 4)
                {
                        break;
                }
                PsLookupProcessByProcessId( *((ULONG*)pSystemBuffer), pSystemBuffer);
                ((PUCHAR)g_pIoAccessMap)[0x0C] |= 0xFF;
                ((PUCHAR)g_pIoAccessMap)[0x0D] |= 0xFF;
                Ke386IoSetAccessProcess( pSystemBuffer, 1);
                Ke386SetIoAccessMap( 1, g_pIoAccessMap);
                ntStatus = STATUS_SUCCESS;
                break;
         现在模拟键盘的所谓硬件模式,大部分人都是使用了网上一些开源工具,例如WinIo,基本原理就是通过IoAccessMap打开ring0的端口读写权限(啰嗦一句,上次看到某人拿来的一个sys,貌似将整个机器的io都打开了,实在是无比暴力……。寒一个)。所以对应办法就是也通过改写IoAccessMap关闭掉权限。
这也是我现在比较推荐使用的方法,对使用WinIo的按键精灵什么的外挂,都有药到病除的疗效。而且,影响范围比较小,只关闭了有限的端口。对于某些特殊情况下的程序,也可以发现之后再单独处理。不过对于自己写驱动读写端口的一类外挂来说,任何办法都没用了。In~~~out~~~~in~~~~out~~~~~in~~~~~~out~~~~~~
6、        下面选一些函数贴出来吧
ULONG __stdcall
NewNtGdiGetPixel( PVOID hDC, LONG XPos, LONG YPos)
{
        BOOLEAN blIsBlock = TRUE;
        if ( g_dwCurrentProcessId == (ULONG)PsGetCurrentProcessId())
        {
                blIsBlock = FALSE;
        }

        //这里奇怪,不知道为什么这么搞
        if ( XPos == 0)
        {
                if( YPos != 0)
                {
                        if( YPos == 0x5A)
                        {
                                blIsBlock = FALSE;
                        }
                }
                else
                {
                        blIsBlock = FALSE;
                }
        }

        if( g_byIsSuccess == TRUE && blIsBlock == TRUE)
                return 0;
        return g_pNtGdiGetPixel( hDC, XPos, YPos);
}

ULONG
__stdcall NewNtUserSendInput(
                                                         ULONG nInputs,
                                                         LPINPUT pInput,
                                                         ULONG cbSize)
{
        if( (g_byIsSuccess != TRUE) || (g_byAllowUserSendInput == TRUE))
        {
                return g_pNtUserSendInput( nInputs, pInput, cbSize);
        }
        else
        {
                return 1;
        }
}

NTSTATUS
__stdcall NewNtOpenProcess (
                                                        PHANDLE ProcessHandle,
                                                        ACCESS_MASK DesiredAccess,
                                                        POBJECT_ATTRIBUTES ObjectAttributes,
                                                        PCLIENT_ID ClientId
                                                        )
{
        if( g_dwCurrentProcessId != 0)
        {
                if( (ULONG)ClientId->UniqueProcess == g_dwCurrentProcessId)
                {
                        if( DesiredAccess != 0x478)
                        {
                                DesiredAccess &= 0xFFFFFFCF;//清掉PROCESS_VM_READ和PROCESS_VM_WRITE
                        }
                }
        }

        if( g_dwProtectPid2 != 0)
        {
                if( g_dwProtectPid2 == (ULONG)ClientId->UniqueProcess)
                {
                        DesiredAccess &= 0x0FFFFFFFE; //清掉PROCESS_TERMINATE
                }
        }

        if( g_dwCurrentProcessId == (ULONG)ClientId->UniqueProcess)
        {
                g_dwIsSomeoneOpenMe = 1;
        }
        return g_pNtOpenProcess( ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}

NTSTATUS
__stdcall NewNtWriteVirtualMemory(
                                                                  HANDLE ProcessHandle,
                                                                  PVOID BaseAddress,
                                                                  CONST VOID *Buffer,
                                                                  SIZE_T BufferSize,
                                                                  PSIZE_T NumberOfBytesWritten
                                                                  )
{
        BOOLEAN blIsNeedSkip = FALSE;
        PROCESS_BASIC_INFORMATION stProcessInfo;
        HANDLE Handle;
        HANDLE hCurrentPid;
        RtlZeroMemory( &stProcessInfo, sizeof(stProcessInfo));

        if( STATUS_SUCCESS ==
                ZwDuplicateObject( (HANDLE)0xFFFFFFFF,
                                                        ProcessHandle,
                                                        (HANDLE)0xFFFFFFFF,
                                                        &Handle,
                                                        0x400,
                                                        0,
                                                        0)
                )
        {
                ZwQueryInformationProcess( Handle, 0, &stProcessInfo, 0x18, 0);
                ZwClose( Handle);
        }

        if( g_dwCurrentProcessId == (ULONG)stProcessInfo.UniqueProcessId)
        {
                blIsNeedSkip = TRUE;
        }

        hCurrentPid = PsGetCurrentProcessId();
        if( (ULONG)hCurrentPid == g_dwSafePid1 ||
                (ULONG)hCurrentPid == g_dwSafePid2 ||
                (ULONG)hCurrentPid == g_dwSafePid3)
        {
                blIsNeedSkip = FALSE;
        }

        if( (ULONG)hCurrentPid == g_dwCurrentProcessId)
        {
                if( (g_dwFromUser2 | 0xFFFFF0F) == 0xFFFFF1F)
                {
                        blIsNeedSkip = FALSE;
                }
        }

        if ( !g_byIsSuccess || !blIsNeedSkip)
        {
                return g_pNtWriteVirtualMemory( ProcessHandle, BaseAddress, Buffer, BufferSize, NumberOfBytesWritten);
        }
        return 0;
}

ULONG __stdcall NewNtUserTranslateMessage(PMSG lpMsg, ULONG dwhkl)
{
        CHAR ucScanCode, ucScanCode2;
        UCHAR blNeedSkip = FALSE;
        if( lpMsg->message == 0x100 || lpMsg->message == 0x101)
        {//WM_KEYDOWN,WM_KEYUP
                ucScanCode2 = IsNeedSkipKeyMsg( lpMsg->wParam);
                if( ucScanCode2)
                {
                        ucScanCode = (lpMsg->lParam & 0x00FF0000) >> 16;
                        if( ucScanCode == ucScanCode2)
                        {
                                blNeedSkip = TRUE;
                        }
                }
        }
        if( !g_byIsSuccess || !blNeedSkip)
        {
                return g_pNtUserTranslateMessage( lpMsg, dwhkl);
        }
        return 1;
}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (34)
雪    币: 50161
活跃值: (20625)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
又来了位牛人,设为精华鼓励一下
XTrap之类的商业保护,估计不少人在研究。
2007-9-7 11:41
0
雪    币: 274
活跃值: (85)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
[QUOTE=;]...[/QUOTE]
好贴啊, 牛人
收藏了
2007-9-7 11:44
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
留名................
2007-9-7 11:45
0
雪    币: 277
活跃值: (321)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
5
支持,顶一下!:)
2007-9-7 11:58
0
雪    币: 154
活跃值: (80)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
强帖 顶了再学
2007-9-7 12:02
0
雪    币: 267
活跃值: (1993)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
第一页!!!
2007-9-7 12:38
0
雪    币: 1727
活跃值: (1149)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
感觉这几个函数和np的函数很相似
2007-9-7 13:01
0
雪    币: 267
活跃值: (1993)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感觉你的名字和我很相似
2007-9-7 13:10
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
10
KfLowerIrql( KeRaiseIrqlToDpcLevel());

这个小技巧,本人记下了~
2007-9-7 13:22
0
雪    币: 224
活跃值: (147)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
11
好帖~!呵呵
2007-9-7 13:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
感觉xtrap就是几个人匆忙之间写出来的,反正比那几个成熟的看起来差远了
2007-9-7 13:49
0
雪    币: 1727
活跃值: (1149)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
nonono,貌似还有个更相似的9527
2007-9-7 13:52
0
雪    币: 226
活跃值: (15)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
14
真是好贴呀,我都忍不住的想要开始赞美你了。
2007-9-7 15:25
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
大侠说说怎么对付这个东西?

游戏是通过什么机制启动xtrap的?
2007-9-7 17:38
0
雪    币: 311
活跃值: (124)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
好贴,学习ing.
2007-9-7 19:09
0
雪    币: 67
活跃值: (66)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
17
厉害 有时间该补补驱动方面的知识了
2007-9-8 01:45
0
雪    币: 233
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
18
继续学习  希望能上传完整代码  
2007-9-8 09:56
0
雪    币: 1919
活跃值: (901)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
19
不懂驱动,备用~~
2007-9-8 16:58
0
雪    币: 108
活跃值: (141)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
20
这两个调用是什么用呢?大虾能不能指教一下?呵呵
2007-9-9 10:31
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
21
请自悟一下,我是在单步XT时爆发过~
2007-9-10 14:57
0
雪    币: 108
活跃值: (141)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
22
刚才调了一下,没发现什么古怪呢?
你用的什么调试器?我用的WinDbg双机
2007-9-10 17:57
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
23
ANTI- DEBUG?防止中断?
希望有人指点一下。
2007-9-10 18:13
0
雪    币: 356
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
"不过有个很搞笑的BUG,Hook中断的函数里面的cli没有对应的sti。"
我这里似乎没有这种情况啊。
.text:00011F8E Int1Hook_11F8E  proc near               ; DATA XREF: .text:0001058Bo
.text:00011F8E                                         ; sub_112AE+30Bo ...
.text:00011F8E                 mov     dword_12EDC, esp
.text:00011F94                 pusha
.text:00011F95                 pushf
.text:00011F96                 push    ds
.text:00011F97                 push    ss
.text:00011F98                 push    es
.text:00011F99                 push    fs
.text:00011F9B                 push    gs
.text:00011F9D                 mov     eax, dr6
.text:00011FA0                 and     eax, 0Fh
.text:00011FA3                 jz      short loc_11FCD
.text:00011FA5                 inc     dword_12EE0
.text:00011FAB                 mov     eax, dr0
.text:00011FAE                 mov     dword_12F70, eax
.text:00011FB3                 mov     eax, dr1
.text:00011FB6                 mov     dword_12F74, eax
.text:00011FBB                 mov     eax, dr2
.text:00011FBE                 mov     dword_12F78, eax
.text:00011FC3                 mov     eax, dr3
.text:00011FC6                 mov     dword_12F7C, eax
.text:00011FCB                 jmp     short loc_11FE4
.text:00011FCD ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00011FCD
.text:00011FCD loc_11FCD:                              ; CODE XREF: Int1Hook_11F8E+15j
.text:00011FCD                 mov     edx, dword_12EDC
.text:00011FD3                 mov     eax, [edx+4]
.text:00011FD6                 and     al, 3
.text:00011FD8                 cmp     al, 3
.text:00011FDA                 jz      short loc_11FF8
.text:00011FDC                 inc     dword_12EE4
.text:00011FE2                 jmp     short $+2
.text:00011FE4
.text:00011FE4 loc_11FE4:                              ; CODE XREF: Int1Hook_11F8E+3Dj
.text:00011FE4                                         ; Int1Hook_11F8E+70j
.text:00011FE4                 call    sub_12000
.text:00011FE9                 pop     gs
.text:00011FEB                 pop     fs
.text:00011FED                 pop     es
.text:00011FEE                 pop     ss
.text:00011FEF                 pop     ds
.text:00011FF0                 popf
.text:00011FF1                 popa
.text:00011FF2                 jmp     dword_12F6C
.text:00011FF8 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00011FF8
.text:00011FF8 loc_11FF8:                              ; CODE XREF: Int1Hook_11F8E+4Cj
.text:00011FF8                 inc     dword_12EE8
.text:00011FFE                 jmp     short loc_11FE4
.text:00011FFE Int1Hook_11F8E  endp
2007-9-11 09:31
0
雪    币: 108
活跃值: (141)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
25
是这个:

.text:00011BD2 HookInt         proc near               ; CODE XREF: HookInt1+6Ep
.text:00011BD2                                         ; UnhookInt1+6Ep
.text:00011BD2
.text:00011BD2 var_pSelectorToHook= dword ptr -1Ch
.text:00011BD2 var_18          = dword ptr -18h
.text:00011BD2 var_10          = dword ptr -10h
.text:00011BD2 var_4           = dword ptr -4
.text:00011BD2 arg_pIdtr       = dword ptr  8
.text:00011BD2 arg_SelectorId  = byte ptr  0Ch
.text:00011BD2 arg_pSelector   = dword ptr  10h
.text:00011BD2
.text:00011BD2                 push    ebp
.text:00011BD3                 mov     ebp, esp
.text:00011BD5                 push    0FFFFFFFFh
.text:00011BD7                 push    offset unk_11F78
.text:00011BDC                 push    offset _except_handler3
.text:00011BE1                 mov     eax, large fs:0
.text:00011BE7                 push    eax
.text:00011BE8                 mov     large fs:0, esp
.text:00011BEF                 sub     esp, 0Ch
.text:00011BF2                 push    ebx
.text:00011BF3                 push    esi
.text:00011BF4                 push    edi
.text:00011BF5                 mov     [ebp+var_18], esp
.text:00011BF8                 and     [ebp+var_4], 0
.text:00011BFC                 movzx   eax, [ebp+arg_SelectorId]
.text:00011C00                 mov     ecx, [ebp+arg_pIdtr]
.text:00011C03                 mov     ecx, [ecx+IDTR.Base]
.text:00011C06                 lea     eax, [ecx+eax*8]
.text:00011C09                 mov     [ebp+var_pSelectorToHook], eax
.text:00011C0C                 pushf
.text:00011C0D                 cli
.text:00011C0E                 mov     ecx, [ebp+arg_pSelector]
.text:00011C11                 mov     edx, [ecx]
.text:00011C13                 mov     [eax], edx
.text:00011C15                 mov     ecx, [ecx+4]
.text:00011C18                 mov     [eax+4], ecx
.text:00011C1B                 popf
.text:00011C1C                 or      [ebp+var_4], 0FFFFFFFFh
.text:00011C20                 push    1
.text:00011C22                 pop     eax
.text:00011C23                 jmp     short loc_11C32
.text:00011C25 ; ---------------------------------------------------------------------------
.text:00011C25
.text:00011C25 loc_11C25:                              ; DATA XREF: .rdata:00011F7Co
.text:00011C25                 push    1
.text:00011C27                 pop     eax
.text:00011C28                 retn
.text:00011C29 ; ---------------------------------------------------------------------------
.text:00011C29
.text:00011C29 loc_11C29:                              ; DATA XREF: .rdata:00011F80o
.text:00011C29                 mov     esp, [ebp-18h]
.text:00011C2C                 or      dword ptr [ebp-4], 0FFFFFFFFh
.text:00011C30                 xor     eax, eax
.text:00011C32
.text:00011C32 loc_11C32:                              ; CODE XREF: HookInt+51j
.text:00011C32                 mov     ecx, [ebp+var_10]
.text:00011C35                 mov     large fs:0, ecx
.text:00011C3C                 pop     edi
.text:00011C3D                 pop     esi
.text:00011C3E                 pop     ebx
.text:00011C3F                 leave
.text:00011C40                 retn    0Ch
.text:00011C40 HookInt         endp
2007-9-11 11:05
0
游客
登录 | 注册 方可回帖
返回
//