• 1110阅读
  • 1回复

用DEP实现BreakOnExecute [复制链接]

上一主题 下一主题
离线啊冲
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2016-02-03

用DEP实现BreakOnExecute


以前抄过OllyBone,但不大好用,很多时候停不下来,似乎在PTE上做的手脚没起作用。后来看到
DEP,这不就是我想要的功能么,又重新试了一次。

打开DEP后,系统工作在PAE下,PTE为64位。不过改了以后,还是存在拦不住的情况,用SoftIce跟了一下,
PTE的确被动过。Hook KeInterlockedSwapPte就可以了,估计OllyBone不好用也是同样道理。

前段时间写的东西,细节已经记不起来了。反正代码都贴出来了。功能跟OllyBone一样的。在xp sp2/sp3下测试可以用。




代码:#define MiGetPteAddressPAE(va)   ((PMMPTE)(PTE_BASE + ((((ULONG)(va)) >> 12) << 3)))typedef struct _HARDWARE_PTE_X86PAE {    union {        struct {        ULONGLONG Valid : 1;        ULONGLONG Write : 1;        ULONGLONG Owner : 1;        ULONGLONG WriteThrough : 1;        ULONGLONG CacheDisable : 1;        ULONGLONG Accessed : 1;        ULONGLONG Dirty : 1;        ULONGLONG LargePage : 1;        ULONGLONG Global : 1;        ULONGLONG CopyOnWrite : 1;   // software field        ULONGLONG Prototype : 1;     // software field        ULONGLONG reserved0 : 1;    // software field        ULONGLONG PageFrameNumber : 26;        //ULONGLONG reserved1 : 26;    // software field  ULONGLONG reserved1 : 25;    // software field  ULONGLONG ExecuteDisable : 1;  // 这个        };        struct {            ULONG LowPart;            ULONG HighPart;        };    };} HARDWARE_PTE_X86PAE, *PHARDWARE_PTE_X86PAE;VOID HookMemory(ULONG address, ULONG size){  ULONG i;  g_HookMem = TRUE;  g_HookStart = address;  g_HookEnd = address + size;  g_PteStart = (ULONG)MiGetPteAddressPAE(g_HookStart);  g_PteEnd   = (ULONG)MiGetPteAddressPAE(g_HookEnd);  //DbgPrint("PteStart = %08X, PteEnd = %08X", g_PteStart, g_PteEnd);    KeAttachProcess(g_ObjProc);  for (i = address; i < address+size; i += PAGE_SIZE) //4KB Pages only    HookPage((PUCHAR)i);    KeDetachProcess();}VOID HookPage(PUCHAR Page){    PHARDWARE_PTE_X86PAE PointerPte;        __try {    __asm {        mov   eax, Page        mov   eax, [eax]    }        PointerPte = (PHARDWARE_PTE_X86PAE)MiGetPteAddressPAE(Page);    if (PointerPte->Valid == 1) {      PointerPte->ExecuteDisable = 1;      DbgPrint("HookPage = %08X", Page);    }  }  __except(EXCEPTION_EXECUTE_HANDLER) {    DbgPrint("Exception captured while hooking page");  }}VOID UnhookPage(PUCHAR Page){  PHARDWARE_PTE_X86PAE PointerPte;  __try {        __asm {      mov  eax, Page        mov  eax, [eax]    }    PointerPte = (PHARDWARE_PTE_X86PAE)MiGetPteAddressPAE(Page);    if (PointerPte->Valid == 1) {      PointerPte->ExecuteDisable = 0;    }  }   __except(EXCEPTION_EXECUTE_HANDLER) {    DbgPrint("Exception captured while unhooking page");  }}VOID UnhookMemory(ULONG address, ULONG size){  ULONG i;  KeAttachProcess(g_ObjProc);    for (i = address; i < address+size; i += PAGE_SIZE)    UnhookPage((PUCHAR)i);    KeDetachProcess();}NTSTATUS FindSwapPte(ULONG ntosbase, PULONG result){  //  // Search KeInterlockedSwapPte in kernel space:)  // there are some lock cmpxchg8b, but this is the only one followed   // by a jnz   //  UCHAR code[] = { 0xF0, 0x0F, 0xC7, 0x0E,  // lock cmpxchg8b qword ptr [esi]       0x75, 0xFA,      // jnz     short loc_46EC60       0x5E,        // pop     esi       0x5B,        // pop     ebx       0xC2, 0x08, 0x00    // retn    8      };  NTSTATUS status = STATUS_UNSUCCESSFUL;  PIMAGE_DOS_HEADER mz;  PIMAGE_NT_HEADERS pe;  ULONG current, end, i;  SIZE_T size = sizeof(code);    mz = (PIMAGE_DOS_HEADER)ntosbase;  pe = (PIMAGE_NT_HEADERS)((ULONG)ntosbase + mz->e_lfanew);  *result = 0;  current = ntosbase;  end = ntosbase + pe->OptionalHeader.SizeOfImage - sizeof(code);    __try {    while (current < end) {      if (RtlCompareMemory((PVOID)current, code, size) == size) {                      // WARNING!        // the hook func CAN'T work in Win2K3! refer to wrk,        // the ULONG64 was pushed in stack instead of the pointer        //        for (i = 0; i < 32; i++) {          if (*(PUSHORT)(current - i) == 0x5653) {            *result = current - i;                        DbgPrint("KeInterlockedSwapPte = %08X", *result);            status = STATUS_SUCCESS;            break;          }        }      }      current++;    }  }  __except(EXCEPTION_EXECUTE_HANDLER) {    DbgPrint("Failed to retrive KeInterlockedSwapPte");    *result = 0;    return STATUS_FAIL_GET_KESWAPPTE;  }  return status;}VOID HookKeInterlockedSwapPte(){    ULONG  func = g_KeInterlockedSwapPte;  ULONG  newlowpart, newhighpart;  UCHAR  opcode[8] = {0x90};  opcode[0] = 0xE9;  *(PULONG)&opcode[1] = (ULONG)KeInterlockedSwapPte - (func+5);  newlowpart  = *(PULONG)&opcode[0];  newhighpart = *(PULONG)&opcode[4];  DisableWP      __asm {    pushad    mov   esi, func        mov   edi, offset g_SavedSwapPte    mov   edx, [esi+4]    mov   [edi+4], edx  // save the old opcode    mov   eax, [esi]    mov   [edi], eax    mov   ecx, newhighpart    mov   ebx, newlowpart__swapagain:    lock  cmpxchg8b qword ptr [esi]    jne   __swapagain          popad  }  EnableWP      DbgPrint("Hook KeInterlockedSwapPte OK");}VOID __declspec(naked) KeInterlockedSwapPte(){  //  // 这里的代码适用于xp,WRK压栈的是ULONG64,不是指针,要修改  //  //   ; ULONGLONG  //   ; InterlockedExchangePte (  //   ;     IN OUT PMMPTE Destination,  //   ;     IN ULONGLONG Exchange  //   ;     )  //   //   push    ebx  //    push    esi  //   mov     ebx, [esp] + 16         ; ebx = NewPteContents lowpart  //   mov     ecx, [esp] + 20         ; ecx = NewPteContents highpart  //   mov     esi, [esp] + 12         ; esi = PtePointer  __asm   {    push    ebx    push    esi    mov     ebx, dword ptr [esp+10h]  // ebx = pointer to Exchange    mov     esi, dword ptr [esp+0Ch]  // esi = PtePointer    mov     ecx, dword ptr [ebx+4]    // ecx = NewPteContents highpart    mov     ebx, dword ptr [ebx]    // ebx = NewPteContents lowpart    mov     edx, dword ptr [esi+4]    // edx = OldPteContents highpart    mov     eax, dword ptr [esi]    // eax = OldPteContents lowpart, return old contents in edx:eax        __swapagain:    lock  cmpxchg8b qword ptr [esi]    jne  __swapagain      // if z clear, exchange failed          pushad          // if debuggee, fuck up nx    call    dword ptr [IoGetCurrentProcess]    cmp  eax, g_ObjProc    jne  __end    cmp  esi, g_PteStart    jb  __end    cmp  esi, g_PteEnd    ja  __end    or  dword ptr [esi+4], 80000000h  //管用的就是这句  __end:    popad    pop     esi    pop     ebx    ret     8  }}volatile __declspec(naked) void NewInt0E_PAE(){  //   //  - Interrupt 0E Handler -  //  //  offset   | contains  //  ---------+-----------------------------  //  esp      : Error Code  //  esp + 4  : EIP Context  //  esp + 8  : CS  Context  //  esp + C  : EFLAGS  //  __asm   {    pushad    push    fs    push    ds    push    es    mov     eax, 30h    mov     fs, ax    mov     eax, 23h    mov     ds, ax    mov     es, ax    call  dword ptr [IoGetCurrentProcess]    cmp  eax, g_ObjProc     // debuggee?    jne  __oldint0e          mov  eax, [esp+20h+0Ch]  // error code    test  eax, 1      // not present    je  __oldint0e    test  eax, 4    je  __oldint0e    // skip kernel mode page fault          cmp  g_HookMem, 0    je  __oldint0e    mov  eax, cr2    // the faulting address    cmp  eax, g_HookStart    jb  __oldint0e    cmp  eax, g_HookEnd    jae  __oldint0e    cmp  eax, [esp+20h+0Ch+4]  // eip    jne  __oldint0e    // because of execution          pop     es    pop     ds    pop     fs              popad    add  esp, 4      // discard error code    jmp  g_KiTrap01    // fuck up int1__oldint0e:    pop     es            pop     ds          pop     fs          popad          jmp  g_KiTrap0E        }}最后感谢风月,把他的VMX代码给我。有时间再学习啦,我现在时间都耗在聊天上了哈。*转载请
善者 慈悲心常在 无怨无恨 以苦为乐
默认压缩密码www.hifyl.com
文件分享密码问题:http://www.hifyl.com/read-htm-tid-4444.html
离线v2680267313

只看该作者 沙发  发表于: 2016-04-30
用户被禁言,该主题自动屏蔽!
快速回复
限100 字节
批量上传需要先选择文件,再选择上传
 
上一个 下一个