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

wowocock的Callback Ring3

2013年04月11日 ⁄ 综合 ⁄ 共 1982字 ⁄ 字号 评论关闭
#define HOOKINT 0x0f0

/* Buffer to store result of sidt instruction */
char buffer[6];

/* Pointer to structure to identify the limit and base of IDTR*/
PIdtr_t Idtr=(PIdtr_t)buffer;
IdtEntry OldEntry;
PIdtEntry pIdtEntry;
ULONG count;
PVOID NewHandler,TMP;
DWORD cur,tss_ring0esp;
WORD tr;
void __declspec(naked) callback(PVOID addr,PVOID stack)
{//stack是Ring3的stack,这个玩意map一下就可以搞到手了

//addr是ring3code的开始地址

//注意这个代码不是很稳定...不过可以自己构造ring3的stack和ring3code(就是找个r3的空间插进去不是么~)
_asm enter 256,0
_asm pushfd
_asm pushad
   _asm sidt buffer
   pIdtEntry = (PIdtEntry)Idtr->Base;
OldEntry = pIdtEntry[HOOKINT]; //#define HOOKINT 0xF0
_asm lea eax,interrupt
   _asm mov NewHandler,eax
   /*接管中断0xF0,目的是让应用程序能通过使用int 0f0h
   指令返回到核心态。
   int 0f0h起的作用正是等同于ret
   F0陷阱的处理函数恢复内核栈等至“调用”前的状态*/
   _asm cli
   pIdtEntry[HOOKINT].Dpl        = 3;
pIdtEntry[HOOKINT].Type       = 0xF;
pIdtEntry[HOOKINT].Present    = 1;
pIdtEntry[HOOKINT].OffsetLow = (unsigned short)NewHandler;
pIdtEntry[HOOKINT].OffsetHigh = /
   (unsigned short)((unsigned int)NewHandler>>16);
_asm sti
   _asm {
    str word ptr[tr]
    push eax
     sgdt [esp-2]
     pop eax
      movzx ebx,word ptr[tr]
      and ebx,0fffffff8h
       add eax,ebx
       mov ebx,[eax]
       and ebx,0ffff0000h
        shr ebx,16
        mov ecx,[eax+4]
        and ecx,0ffh
         shl ecx,16
         or ebx,ecx
         mov ecx,[eax+4]
         and ecx,0ff000000h
          or ebx,ecx //tss base
          mov ebx,[ebx+4]  
          mov tss_ring0esp,ebx
          mov cur,esp
   }
   count=tss_ring0esp-cur;
   TMP=(PVOID)ExAllocatePool( NonPagedPool,count);
   if(!TMP) goto exit;
   /*上面代码获取当前内核栈的地址与需保存大小
   下面代码保存栈内容*/
   _asm{
    mov ecx,count
     mov edi,TMP
     mov esi,cur
     cld
     rep movsb
   }
   /*模拟返回环境,不用多解释了
   iretd我们把它类比于call*/
   _asm{
    mov eax,3bh
     mov fs,ax
     mov eax,23h
     push eax
     mov eax,stack
     push eax
     pushfd
     mov eax,1bh
     push eax
     mov eax,addr
     push eax
     iretd
   }
   /*int 0f0h后返回这里开始执行*/
interrupt:
   _asm{
    mov eax,30h
     mov fs,ax
     mov ecx,count
     mov esi,TMP
     mov edi,cur
     cld
     rep movsb
     mov esp,cur
   }
   _asm cli
    pIdtEntry[HOOKINT] = OldEntry;
   _asm sti
exit:
    _asm popad
    _asm popfd
    _asm leave
    _asm ret 8
}

 

抱歉!评论已关闭.