-
-
[讨论]进程保护
-
发表于: 2012-5-2 11:59 3893
-
#include <NTDDK.h>
#include <windef.h>
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
typedef struct _ssdt
{
PVOID base;
PVOID Count;
LONG nums;
PVOID param;
}*PSsdt;
extern PSsdt KeServiceDescriptorTable;
// KeServiceDescriptorTable;
ULONG *oldaddress; //服务函数的原始地址
ULONG *ADDR; //原始存放服务函数的地址
PEPROCESS pEpro;
//他们之间的关系就是在ADDR处存放了oldaddress, *ADDR = oldaddress
NTSTATUS ddkunload(IN PDRIVER_OBJECT pd);
typedef NTSTATUS
(* NTTERMINATEPROCESS )(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
);
NTTERMINATEPROCESS oldnt = NULL;
NTSTATUS
MyNtTerminateProcess(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
);
#pragma INITCODE
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriver,
IN PUNICODE_STRING pRegPath)
{
//_asm int 3;
ULONG *addr,*tablebase;
//_asm int 3
tablebase = (PLONG)KeServiceDescriptorTable->base;
KdPrint(("当前ServiceTableBase地址为%x \n",tablebase));
addr = (PLONG)((CHAR *)tablebase + 4*0x101);
ADDR = addr;
KdPrint(("当前序号NtTerminateProcess地址为%x \n", *addr ));
oldaddress = *addr;
__asm //去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
*addr = MyNtTerminateProcess; //替换为自己的函数地址,
//addr存放服务函数的地址,*addr服务函数的地址。
__asm //恢复页保护
{
mov eax,cr0
or eax,10000h //or eax,not 0FFFEFFFFh
mov cr0,eax
sti
}
pDriver->DriverUnload = ddkunload;
return 1;
}
#pragma PAGECODE
//NTSTATUS ddkunload(IN PDRIVER_OBJECT pDriverObject)
NTSTATUS ddkunload(IN PDRIVER_OBJECT pd)
{
KdPrint(("驱动成功被卸载...OK-----------")); //需要这样一个宏 相当于sprintf,printf
//pd->DeviceObject;
__asm //去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
//memset(ADDR,oldaddress,4);
*ADDR = (ULONG)oldaddress;
__asm //恢复页保护
{
mov eax,cr0
or eax,10000h //or eax,not 0FFFEFFFFh
mov cr0,eax
sti
}
return 1;
}
NTSTATUS
MyNtTerminateProcess(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
)
{
char name[50];
//UNICODE_STRING orl;
//DWORD PID;
//ULONG *orladdr;
NTSTATUS rc; //返回的值
PEPROCESS pEProcess;
//DWORD dwcal;
//_asm int 3;
KdPrint(("MyNtTerminateProcess\n"));
//dwcal = *ADDR;
oldnt = oldaddress;
//RtlInitUnicodeString(&orl, L"NtTerminateProcess");
//orladdr = (ULONG*)MmGetSystemRoutineAddress(&orl);
//oldaddress = orladdr; //存放了原来的服务函数地址,然后再call原来的服务函数地址
//KdPrint(("当前ServiceTableBase地址为MyNtTerminateProcess : %x \n",orladdr));
//ObReferenceObjectByHandle (
// __in HANDLE Handle, //传入对象句柄
// __in ACCESS_MASK DesiredAccess,
// __in_opt POBJECT_TYPE ObjectType, //对象类型
// __in KPROCESSOR_MODE AccessMode,
// __out PVOID *Object, //返回对象体指针
// __out_opt POBJECT_HANDLE_INFORMATION HandleInformation
// )
ObReferenceObjectByHandle(ProcessHandle,
GENERIC_READ,
0,
KernelMode,
&pEProcess,
NULL);
// ObReferenceObjectByHandle(Handle,DesiredAccess,ObjectType,AccessMode,&Process,NULL);
//status = ObReferenceObjectByHandle(ProcessHandle,
// FILE_READ_DATA,0,KernelMode,&process,NULL); //获取进程
KdPrint(("be termited process is %s \n",(char*)pEProcess+0x174));
//strcpy(name, (char *)pEProcess+0x174);
// name = (char *)pEProcess+0x174;
if (strcmp(((char*)pEProcess+0x174),"try.exe") == 0)
{
_asm int 3;
KdPrint(("try.exe"));
}
//if (1)
//{
// //ProcessHandle = NULL; //这个是关键
// rc = STATUS_ACCESS_DENIED; //这个返回值表示拒绝访问
// ObDereferenceObject(pEProcess);
// return rc;
//}
if (pEProcess == PsGetCurrentProcess())
{
KdPrint(("the same\n"));
oldnt(ProcessHandle,ExitStatus);
}
//{//情况一:当前进程不是我们所保护的进程
// //换句话说也就是其他进程试图结束我们所保护的进程,当然不能让他结束
// KdPrint(("[-]进程保护,外部程序试图关闭保护进程\n"));
//rc = STATUS_ACCESS_DENIED;
// return rc;
//ObDereferenceObject(pEProcess);
//_asm call oldaddress //调用原来的函数
oldnt(ProcessHandle,ExitStatus);
}
帮忙看下怎么总是蓝或者异常。。
另外还有几点疑惑
//ObReferenceObjectByHandle (
// __in HANDLE Handle, //传入对象句柄
// __in ACCESS_MASK DesiredAccess,
// __in_opt POBJECT_TYPE ObjectType, //对象类型
// __in KPROCESSOR_MODE AccessMode,
// __out PVOID *Object, //返回对象体指针
// __out_opt POBJECT_HANDLE_INFORMATION HandleInformation
// )
这个函数的第4个参数如果要获得进程的EPROCESS 是不是一定要 *PsProcessType,还是赋值0,我测试了貌似2者都能获取到正确的EPROCESS地址,
2.
//RtlInitUnicodeString(&orl, L"NtTerminateProcess");
//orladdr = (ULONG*)MmGetSystemRoutineAddress(&orl);
//oldaddress = orladdr; //存放了原来的服务函数地址,然后再call原来的服务函数地址
//KdPrint(("当前ServiceTableBase地址为MyNtTerminateProcess : %x \n",orladdr));
这种方式能获取到原始的NtTerminateProcess地址?我测试出来怎么得到的是EPROCESS地址是0,帮忙看看那里有错误
3.如果拒绝结束要保护的进程,那么MYNtTerminateProcess是不用调用原始的NtTerminateProcess,那返回值怎么处理,返回值可以更改,然后传递进来的句柄ProcessHandle这个怎么处理,它是IN OUT,是需要返回的吧,怎么写这一块
#include <windef.h>
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
typedef struct _ssdt
{
PVOID base;
PVOID Count;
LONG nums;
PVOID param;
}*PSsdt;
extern PSsdt KeServiceDescriptorTable;
// KeServiceDescriptorTable;
ULONG *oldaddress; //服务函数的原始地址
ULONG *ADDR; //原始存放服务函数的地址
PEPROCESS pEpro;
//他们之间的关系就是在ADDR处存放了oldaddress, *ADDR = oldaddress
NTSTATUS ddkunload(IN PDRIVER_OBJECT pd);
typedef NTSTATUS
(* NTTERMINATEPROCESS )(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
);
NTTERMINATEPROCESS oldnt = NULL;
NTSTATUS
MyNtTerminateProcess(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
);
#pragma INITCODE
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriver,
IN PUNICODE_STRING pRegPath)
{
//_asm int 3;
ULONG *addr,*tablebase;
//_asm int 3
tablebase = (PLONG)KeServiceDescriptorTable->base;
KdPrint(("当前ServiceTableBase地址为%x \n",tablebase));
addr = (PLONG)((CHAR *)tablebase + 4*0x101);
ADDR = addr;
KdPrint(("当前序号NtTerminateProcess地址为%x \n", *addr ));
oldaddress = *addr;
__asm //去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
*addr = MyNtTerminateProcess; //替换为自己的函数地址,
//addr存放服务函数的地址,*addr服务函数的地址。
__asm //恢复页保护
{
mov eax,cr0
or eax,10000h //or eax,not 0FFFEFFFFh
mov cr0,eax
sti
}
pDriver->DriverUnload = ddkunload;
return 1;
}
#pragma PAGECODE
//NTSTATUS ddkunload(IN PDRIVER_OBJECT pDriverObject)
NTSTATUS ddkunload(IN PDRIVER_OBJECT pd)
{
KdPrint(("驱动成功被卸载...OK-----------")); //需要这样一个宏 相当于sprintf,printf
//pd->DeviceObject;
__asm //去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
//memset(ADDR,oldaddress,4);
*ADDR = (ULONG)oldaddress;
__asm //恢复页保护
{
mov eax,cr0
or eax,10000h //or eax,not 0FFFEFFFFh
mov cr0,eax
sti
}
return 1;
}
NTSTATUS
MyNtTerminateProcess(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
)
{
char name[50];
//UNICODE_STRING orl;
//DWORD PID;
//ULONG *orladdr;
NTSTATUS rc; //返回的值
PEPROCESS pEProcess;
//DWORD dwcal;
//_asm int 3;
KdPrint(("MyNtTerminateProcess\n"));
//dwcal = *ADDR;
oldnt = oldaddress;
//RtlInitUnicodeString(&orl, L"NtTerminateProcess");
//orladdr = (ULONG*)MmGetSystemRoutineAddress(&orl);
//oldaddress = orladdr; //存放了原来的服务函数地址,然后再call原来的服务函数地址
//KdPrint(("当前ServiceTableBase地址为MyNtTerminateProcess : %x \n",orladdr));
//ObReferenceObjectByHandle (
// __in HANDLE Handle, //传入对象句柄
// __in ACCESS_MASK DesiredAccess,
// __in_opt POBJECT_TYPE ObjectType, //对象类型
// __in KPROCESSOR_MODE AccessMode,
// __out PVOID *Object, //返回对象体指针
// __out_opt POBJECT_HANDLE_INFORMATION HandleInformation
// )
ObReferenceObjectByHandle(ProcessHandle,
GENERIC_READ,
0,
KernelMode,
&pEProcess,
NULL);
// ObReferenceObjectByHandle(Handle,DesiredAccess,ObjectType,AccessMode,&Process,NULL);
//status = ObReferenceObjectByHandle(ProcessHandle,
// FILE_READ_DATA,0,KernelMode,&process,NULL); //获取进程
KdPrint(("be termited process is %s \n",(char*)pEProcess+0x174));
//strcpy(name, (char *)pEProcess+0x174);
// name = (char *)pEProcess+0x174;
if (strcmp(((char*)pEProcess+0x174),"try.exe") == 0)
{
_asm int 3;
KdPrint(("try.exe"));
}
//if (1)
//{
// //ProcessHandle = NULL; //这个是关键
// rc = STATUS_ACCESS_DENIED; //这个返回值表示拒绝访问
// ObDereferenceObject(pEProcess);
// return rc;
//}
if (pEProcess == PsGetCurrentProcess())
{
KdPrint(("the same\n"));
oldnt(ProcessHandle,ExitStatus);
}
//{//情况一:当前进程不是我们所保护的进程
// //换句话说也就是其他进程试图结束我们所保护的进程,当然不能让他结束
// KdPrint(("[-]进程保护,外部程序试图关闭保护进程\n"));
//rc = STATUS_ACCESS_DENIED;
// return rc;
//ObDereferenceObject(pEProcess);
//_asm call oldaddress //调用原来的函数
oldnt(ProcessHandle,ExitStatus);
}
帮忙看下怎么总是蓝或者异常。。
另外还有几点疑惑
//ObReferenceObjectByHandle (
// __in HANDLE Handle, //传入对象句柄
// __in ACCESS_MASK DesiredAccess,
// __in_opt POBJECT_TYPE ObjectType, //对象类型
// __in KPROCESSOR_MODE AccessMode,
// __out PVOID *Object, //返回对象体指针
// __out_opt POBJECT_HANDLE_INFORMATION HandleInformation
// )
这个函数的第4个参数如果要获得进程的EPROCESS 是不是一定要 *PsProcessType,还是赋值0,我测试了貌似2者都能获取到正确的EPROCESS地址,
2.
//RtlInitUnicodeString(&orl, L"NtTerminateProcess");
//orladdr = (ULONG*)MmGetSystemRoutineAddress(&orl);
//oldaddress = orladdr; //存放了原来的服务函数地址,然后再call原来的服务函数地址
//KdPrint(("当前ServiceTableBase地址为MyNtTerminateProcess : %x \n",orladdr));
这种方式能获取到原始的NtTerminateProcess地址?我测试出来怎么得到的是EPROCESS地址是0,帮忙看看那里有错误
3.如果拒绝结束要保护的进程,那么MYNtTerminateProcess是不用调用原始的NtTerminateProcess,那返回值怎么处理,返回值可以更改,然后传递进来的句柄ProcessHandle这个怎么处理,它是IN OUT,是需要返回的吧,怎么写这一块
赞赏
看原图
赞赏
雪币:
留言: