能力值:
( LV12,RANK:760 )
|
-
-
2 楼
即使是多核的情况下 SwapContext的时候,切换IDT完全无压力的说~估计是你弄错了什么东西~
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
虚拟机开始设置的是单核CPU ,运行一切正常,但是设定为多核后屏幕就卡了,啥都打不开,放到真机也是,下面是代码,为啥那?
ULONG g_SwpContext = 0; //要HOOK的地址
ULONG g_SwpContextJmp = 0 ; //HOOK跳转到的地址
BOOLEAN g_SwpContextHook = FALSE ; //判断HOOK成功没有
JMPCODE g_SwpContextFun ; //定义一个结构来储存原来地址的内容
ULONG g_uOldIdtBase = 0; //保存一份原始的IDT表
ULONG g_uNewIdtBase = 0 ; //保存新的IDT表
//这里就是我的HOOK的处理函数了 为啥多核就不行那?
void FuckSwapContext(PETHREAD pTarget, PKPCR pKpcr)
{
//PEPROCESS pTargetProcess = (PEPROCESS)((ULONG)pTarget+0x44) ; //这里如果是多核处理器应该怎么处理那?
//if(GuardPID((ULONG)PsGetCurrentProcess())==TRUE && (ULONG)PsGetCurrentProcess()>0) //如果是保护进程的话
//{
// //IDT是原始的
//} else //如果不是保护进程的话
//{ //IDT表示被HOOK的
//}
///处理函数就是这个了, 恢复保存的IDT表,因为是测试,就没有加判断, 但是卡啊不蓝屏,就是什么程序都打不开
*pKpcr->IDT=(_KIDTENTRY*)g_uNewIdtBase ;
IDTINFO IdtInfo = {0} ;
IdtInfo.IDTLimit = 0x7ff ;
IdtInfo.HiIDTbase=(g_uNewIdtBase & 0xffff0000) >> 16 ;
IdtInfo.LowIDTbase=(g_uNewIdtBase & 0x0000ffff) ;
__asm lidt IdtInfo ;
DbgPrint("当前PID[%X]",(ULONG)PsGetCurrentProcess()) ;
}
__declspec(naked) void SwpContextFun()
{
//pushad
// pushfd
// push edi
// push ebx
// push eax
// mov esi,GetNtFuncAddr
// call esi
// mov dword ptr [esp+0x14],eax
// //call GetNtFuncAddr
// popfd
// popad
__asm
{
mov eax,dword ptr [esi+0x20]
mov dword ptr [ebx+0x18],eax //ESI是目标线程 EDI是当前线程 ebx KPCR处理器控制域
pushad
pushfd
push ebx
push esi
call FuckSwapContext
popfd
popad
push g_SwpContextJmp
retn
}
}
BOOLEAN HandleSwapContextHook()
{
/*804dc8bb 83ec0c sub esp,0Ch
804dc8be 89742408 mov dword ptr [esp+8],esi
804dc8c2 897c2404 mov dword ptr [esp+4],edi
804dc8c6 892c24 mov dword ptr [esp],ebp
804dc8c9 8bf0 mov esi,eax
804dc8cb 8bbb24010000 mov edi,dword ptr [ebx+124h]
804dc8d1 c7832801000000000000 mov dword ptr [ebx+128h],0
804dc8db 89b324010000 mov dword ptr [ebx+124h],esi
804dc8e1 8bcf mov ecx,edi
804dc8e3 c6475001 mov byte ptr [edi+50h],1
804dc8e7 e8eefdffff call nt!ExReleaseResourceLite+0x8a (804dc6da)
//804dc8ec b101 mov cl,1
//804dc8ee e831000000 call nt!KiDispatchInterrupt+0xb0 (804dc924) 取这里3行的特征码
//804dc8f3 8b2c24 mov ebp,dword ptr [esp]
804dc8f6 8b7c2404 mov edi,dword ptr [esp+4]
804dc8fa 8b742408 mov esi,dword ptr [esp+8]
804dc8fe 83c40c add esp,0Ch*/
// __asm int 3 ;
//---------------------------------------这里保存一份原始的IDT表
IDTINFO IdtInfo = {0} ;
__asm sidt IdtInfo ;
ULONG uIdtAdrr = MAKELONG(IdtInfo.LowIDTbase,IdtInfo.HiIDTbase);
if(uIdtAdrr==0)
{
DbgPrint("备份IDT失败\n") ;
return FALSE ;
}
g_uOldIdtBase = uIdtAdrr ;
ULONG uSize = IdtInfo.IDTLimit ; //IDT表的大小
g_uNewIdtBase= (ULONG)ExAllocatePool(NonPagedPool,uSize) ; //申请一个新表
if(g_uNewIdtBase==0)
{
DbgPrint("申请新的IDT表失败\n") ;
return FALSE ;
}
RtlCopyMemory((PVOID)g_uNewIdtBase,(PVOID)g_uOldIdtBase,uSize) ; //将原始表的内容拷贝到新表
ULONG uAddr = (ULONG)KiDispatchInterrupt ;
DbgPrint("KiDispatchInterrupt的地址是%X",uAddr) ;
PUCHAR p=(PUCHAR)uAddr ;
ULONG i=0 ;
BOOLEAN bFind = FALSE ;
while(i<0x200)
{
if(*p==0xe8 && *(p+5)==0x8b && *(p+6)==0x2c && *(p+7)==0x24 &&
*(p-1)==0x01 && *(p-2)==0xb1 && *(p+9)==0x7c && *(p+10)==0x24)
{
bFind = TRUE ;
break;
}
i++ ;
p++ ;
}
if(!bFind)
{
DbgPrint("获取SwapContext特征码失败!") ;
return FALSE ;
}
ULONG uSwapContext = (ULONG)p +5+*(PULONG)(p+1);
/*804dc981 8d09 lea ecx,[ecx]
804dc983 f740e400000200 test dword ptr [eax-1Ch],20000h
804dc98a 7503 jne nt!KiDispatchInterrupt+0x11b (804dc98f)
804dc98c 83e810 sub eax,10h
804dc98f 8b4b40 mov ecx,dword ptr [ebx+40h]
804dc992 894104 mov dword ptr [ecx+4],eax
804dc995 8b6628 mov esp,dword ptr [esi+28h]
804dc998 8b4620 mov eax,dword ptr [esi+20h] 自己感觉修改这里好像更合适点
804dc99b 894318 mov dword ptr [ebx+18h],eax 修改的这一行
804dc99e fb sti
804dc99f 8b4744 mov eax,dword ptr [edi+44h] //上面的处理函数中的44来源于这里
804dc9a2 3b4644 cmp eax,dword ptr [esi+44h]
804dc9a5 c6475000 mov byte ptr [edi+50h],0
804dc9a9 742c je nt!KiDispatchInterrupt+0x163 (804dc9d7)
804dc9ab 8b7e44 mov edi,dword ptr [esi+44h]
804dc9ae 66f74720ffff test word ptr [edi+20h],0FFFFh
804dc9b4 755b jne nt!KiDispatchInterrupt+0x19d (804dca11)*/
p=(PUCHAR)uSwapContext ;
i=0 ;
bFind = FALSE ;
while(i<0x200)
{
if(*p==0x8b && *(p+1)==0x46 && *(p+3)==0x89 && *(p+4)==0x43 &&
*(p+6)==0xfb && *(p+7)==0x8b)
{
bFind = TRUE ;
break;
}
i++ ;
p++ ;
}
if(!bFind)
{
DbgPrint("获取要HOOK的SwapContext地址失败!") ;
return FALSE ;
}
g_SwpContext=(ULONG)p ;
DbgPrint("要HOOK的地址为[%X]",(ULONG)p) ;
ULONG X = (ULONG)p ;
ULONG Y = (ULONG)SwpContextFun ;
g_SwpContextJmp = (ULONG)p + 6 ; //获取HOOK后跳转到的地址
DbgPrint("HOOK后跳转的地址为:%X",g_SwpContextJmp) ;
PJMPCODE pcur; //指针,指向函数当前的地址
JMPCODE JmpCode ; //要Jmp的地址保存
pcur=PJMPCODE(X) ; //当前地址的数值
g_SwpContextFun.E9=pcur->E9 ;
g_SwpContextFun.JMPADDR=pcur->JMPADDR ; //使用全部变量来保存一下原来的函数
//CodeArr=X ;
JmpCode.E9=0xE9 ;
JmpCode.JMPADDR=Y-X-5 ;
//KdPrint(("要写入函数的地址是%X",JmpCode.JMPADDR));
// __asm int 3 ;
DbgPrint("HOOK后跳转到函数地址是[%X]",JmpCode.JMPADDR) ;
MemoryRevise() ; //去除页面保护
pcur->E9=0xE9 ;
pcur->JMPADDR=JmpCode.JMPADDR ;
MemoryRecover() ; //恢复页面保护
DbgPrint("HOOK执行成功,SwapContext函数已经被拦截\n");
g_SwpContextHook=TRUE ;
return TRUE ;
}
BOOLEAN HandleSwapContextUnHook()
{
if(!g_SwpContextHook)
{
return FALSE;
}
PJMPCODE pcur; //指针,指向函数当前的地址
MemoryRevise() ; //去除页面保护
pcur=PJMPCODE(g_SwpContext) ; //当前地址的数值
pcur->E9=g_SwpContextFun.E9 ;
pcur->JMPADDR=g_SwpContextFun.JMPADDR ;
MemoryRecover() ; //恢复页面保护
DbgPrint("UNHOOK执行成功,SwapContext函数已经被恢复\n");
g_SwpContextHook=FALSE ;
return TRUE ;
}
|
能力值:
( LV12,RANK:760 )
|
-
-
4 楼
...表示lidt和修改kpcr已经够亮了...
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
额,还是不太懂,是我kpcr修改的缘故么? 呵呵
|
能力值:
( LV3,RANK:30 )
|
-
-
6 楼
学好基础吧,不要一来就到处hook……这种所谓的入门学习,对你没任何好处……除了提起兴趣外
|
能力值:
( LV3,RANK:30 )
|
-
-
7 楼
真的如你所说不是“伸手党”,确实想学东西,就不要搞hook这么急功近利的东西,一点点从基础学起
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
...表示lidt和修改kpcr已经够亮了...
/*
lidt和kpcr所获取的IDT都是当前CPU的。。。。其他核心的不能直接获取
*/
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
谢谢各位大大的回答,其实当初我也想是这个问题,努力学习中,谢谢啦
|
能力值:
( LV12,RANK:760 )
|
-
-
10 楼
其实 IDT直接memcpy去覆盖就不卡死了(覆盖前0x10个没见过出问题~~覆盖后面那些0x4X的东西很容易出问题),别用lidt去改~KPCR不需要修改~
不过你这么干还是不能躲过DPCRoutine的扫描...具体不多说了~
另外,HOOK这玩意也就适合玩玩,正规项目尽量用M$的东西~
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
听君一席话,胜读十年书啊
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
修改为HOOK SwpContext 后,发现是自己的线程就把当前IDT给恢复了,如果是其他的线程就把当前IDT在重新HOOK了,这样应该可以吧,哈哈
|