下面代码实现的是对notepad进程的插入APC的监控,
使用的是naked约定
跟了一下,在堆栈平衡中,发现调用的函数strcmp,等,是自己实现堆栈平衡,不是说cdecl的调用约定是调用者实现的吗
然后改了一下
,驱动编译通过,加载,运行,但是一打开目标进程(记事本),就会蓝,为什么会这样?
请大牛指点一下 _declspec(naked) Translate_KiInsertQueueApc(PKAPC Apc, KPRIORITY Increment)
{
KAPC *pApc;
ULONG pTargetThread;
//PKTHREAD pTargetThread;
ULONG pTargetProcess;
//PEPROCESS pTargetProcess;
UCHAR *pTargetProcessName;
DWORD dwTargetProcessId;
PEPROCESS pCurrentEprocess;
UCHAR *pCurrentProcessName;
DWORD dwCurrentProcessId;
_asm{
//int 3
nop
nop
nop
nop
nop
push ebp
mov ebp,esp
sub esp,__LOCAL_SIZE
pushad
mov edi,ecx
mov pApc,edi
}
pTargetThread=*((PULONG)((ULONG)pApc+0x008));//currentthread是_kthread结构
pTargetProcess =*((PULONG)((ULONG)pTargetThread + 0x044 ));
pTargetProcessName=(UCHAR *)(pTargetProcess+0x174);
dwTargetProcessId = *((DWORD*)((ULONG)pTargetProcess+0x084));
//当前调用KI函数的进程信息
pCurrentEprocess=PsGetCurrentProcess();//自己完成恢复堆栈操作
pCurrentProcessName=(UCHAR *)((ULONG)pCurrentEprocess+0x174);
dwCurrentProcessId=(DWORD)((ULONG)pCurrentEprocess+0x084);
//DbgPrint("\nCurrent process name is:%s",pCurrentProcessName);
//DbgPrint("\nCurrent process id is:%d",dwCurrentProcessId);
//将进程名转换成小写
_strlwr(pCurrentProcessName);
//_asm add esp,4,这里不用恢复堆栈,strlwr(不是cdecl的约定吗)自己恢复,为什么会这样
_strlwr(pTargetProcessName);
//_asm add esp,4
//如果是对我们关注的进程进行插入APC
if(strcmp(pTargetProcessName,"notepad.exe")==0)
{
//如果不是target进程自己发起的插入APC
//_asm add esp,8
if(strcmp(pCurrentProcessName,"notepad.exe")!=0)
{
//恢复上一个strcmp的堆栈
//_asm add esp,8
_asm{
//popfd
popad
mov esp,ebp
pop ebp
ret 8
}
}
}
//_asm add esp,8
_asm{
popad
mov esp,ebp
pop ebp
}
//实现原API的前5个字节
_asm{
mov edi,edi
push ebp
mov ebp,esp
}
//跳转到原API的第六个字节处执行
_asm{
mov eax,g_KiInsertQueueApc
add eax,5
jmp eax
}
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课