能力值:
( LV2,RANK:10 )
|
-
-
6 楼
PsGetCurrentProcess返回的是进程结构体,结构体名称是EPROCESS,但这个结构体没有公开,你可以用WINDBG查查这个结构体的
//下面是WINDBG显示的XPSP3 EPROCESS的一部分
kd> dt nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x06c ProcessLock : _EX_PUSH_LOCK
+0x070 CreateTime : _LARGE_INTEGER
+0x078 ExitTime : _LARGE_INTEGER
+0x080 RundownProtect : _EX_RUNDOWN_REF
+0x084 UniqueProcessId : Ptr32 Void
+0x088 ActiveProcessLinks : _LIST_ENTRY
由于没有公开,所以你可以自己定义,然后使用,也可以(ULONG)(PULONG*)((char*)eprocess + 0x84)(XPSP3偏移是0x84)去访问,但兼容性就有些问题了。
当前,XP以上呢,系统提供了一个函数PsGetProcessId,可以从eprocess获取PID的,PsGetProcessId(eprocess)就是进程ID.
一般你用第一种方法PsGetCurrentProcessId就行了
PsGetCurrentProcessId和PsGetProcessId返回的是HANDLE值,但这个值就是PID,如果你不习惯,你可以强制转换为ULONG, ULONG CurrentProcessId = (ULONG)PsGetCurrentProcessId();
至于不起作用,那你查查其他方面的问题。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
能否帮忙看看代码呢?我是新手又急用,不会调试sys,实现的功能是对ZwSetValueKey进行hook达到过滤功能,信任列表是system,lsass.exe,taskmgr.exe,regedit.exe
#include "ntddk.h"
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation, // 0
SystemProcessorInformation, // 1
SystemPerformanceInformation, // 2
SystemTimeOfDayInformation, // 3
SystemNotImplemented1, // 4
SystemProcessesAndThreadsInformation, // 5
SystemCallCounts, // 6
SystemConfigurationInformation, // 7
SystemProcessorTimes, // 8
SystemGlobalFlag, // 9
SystemNotImplemented2, // 10
SystemModuleInformation, // 11
SystemLockInformation, // 12
SystemNotImplemented3, // 13
SystemNotImplemented4, // 14
SystemNotImplemented5, // 15
SystemHandleInformation, // 16
SystemObjectInformation, // 17
SystemPagefileInformation, // 18
SystemInstructionEmulationCounts, // 19
SystemInvalidInfoClass1, // 20
SystemCacheInformation, // 21
SystemPoolTagInformation, // 22
SystemProcessorStatistics, // 23
SystemDpcInformation, // 24
SystemNotImplemented6, // 25
SystemLoadImage, // 26
SystemUnloadImage, // 27
SystemTimeAdjustment, // 28
SystemNotImplemented7, // 29
SystemNotImplemented8, // 30
SystemNotImplemented9, // 31
SystemCrashDumpInformation, // 32
SystemExceptionInformation, // 33
SystemCrashDumpStateInformation, // 34
SystemKernelDebuggerInformation, // 35
SystemContextSwitchInformation, // 36
SystemRegistryQuotaInformation, // 37
SystemLoadAndCallImage, // 38
SystemPrioritySeparation, // 39
SystemNotImplemented10, // 40
SystemNotImplemented11, // 41
SystemInvalidInfoClass2, // 42
SystemInvalidInfoClass3, // 43
SystemTimeZoneInformation, // 44
SystemLookasideInformation, // 45
SystemSetTimeSlipEvent, // 46
SystemCreateSession, // 47
SystemDeleteSession, // 48
SystemInvalidInfoClass4, // 49
SystemRangeStartInformation, // 50
SystemVerifierInformation, // 51
SystemAddVerifier, // 52
SystemSessionProcessesInformation // 53
} SYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_THREAD_INFORMATION {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
LONG State;
LONG WaitReason;
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
SYSTEM_THREAD_INFORMATION Threads[1];
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
#pragma pack(1) //SSDT表的结构
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
PMDL m_MDL;
PVOID *m_Mapped;
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; //变量名是不能变的,因为是从外部导入
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig ) _Orig = (PVOID) InterlockedExchange( (PLONG) &m_Mapped[SYSCALL_INDEX(_Function)], (LONG) _Hook)
NTSYSAPI NTSTATUS NTAPI ZwSetValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
);
typedef NTSTATUS (*ZWSETVALUEKEY)(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
);
NTSTATUS NewZwSetValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
);
ZWSETVALUEKEY OldZwSetValueKey = NULL;
ULONG pid[10] = {0};
int icount = 0;
NTSTATUS Ring0EnumProcess()
{
UNICODE_STRING usMy[4];
UNICODE_STRING usSys;
int comp=0;
int icnt = 0;
ULONG cbBuffer = 0x8000; // 初始化缓冲大小 32kb
PVOID pBuffer = NULL;
NTSTATUS Status;
PSYSTEM_PROCESS_INFORMATION pInfo;
do
{
pBuffer = ExAllocatePool (NonPagedPool, cbBuffer); //分配内存缓冲区
if (pBuffer == NULL) // 如果内存分配失败
return 1;
Status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pBuffer, cbBuffer, NULL);
if (Status == STATUS_INFO_LENGTH_MISMATCH) //如果缓冲区太小
{
ExFreePool(pBuffer); // 释放缓冲区
cbBuffer *= 2; // 增加缓冲区到原来的两倍大小
}
else if (!NT_SUCCESS(Status)) // 如果执行失败
{
ExFreePool(pBuffer); // 释放分配的内存
return 1; //返回1并拖出
}
}
while (Status == STATUS_INFO_LENGTH_MISMATCH);
pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
for (;;)
{
LPWSTR pszProcessName = pInfo->ProcessName.Buffer;
if (pszProcessName == NULL)
pszProcessName = L"NULL"; // 如果获取文件名失败
RtlInitUnicodeString(&(usMy[0]),L"system");
RtlInitUnicodeString(&(usMy[1]),L"lsass.exe");
RtlInitUnicodeString(&(usMy[2]),L"taskmgr.exe");
RtlInitUnicodeString(&(usMy[3]),L"regedit.exe");
RtlInitUnicodeString(&usSys,pszProcessName);
icnt = 0;
for(; icnt < 4; icnt++)
{
if(!RtlCompareUnicodeString(&(usMy[icnt]),&usSys,TRUE))
{
comp = 0;
break;
}
else comp = 1;
}
if (comp==0)
{
pid[icount++]=pInfo->ProcessId;
//KdPrint(("发现要保护的进程\n"));
}
//DbgPrint("pid %d ps %S\n",pInfo->ProcessId,pInfo->ProcessName.Buffer);
if (pInfo->NextEntryDelta == 0)
break;
pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo)+ pInfo->NextEntryDelta);
}
ExFreePool(pBuffer);
return 0;
}
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
PVOID OldFunc = NULL;
HOOK_SYSCALL(ZwSetValueKey, OldZwSetValueKey, OldFunc);
if(m_MDL)
{
MmUnmapLockedPages(m_Mapped, m_MDL);
IoFreeMdl(m_MDL);
}
//KdPrint(("[*]驱动卸载完毕.\n"));
}
NTSTATUS NewZwSetValueKey(IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
)
{
//自己的注册表处理函数
//long lPid = (long)PsGetCurrentProcessId();
//PEPROCESS peProcess = PsGetCurrentProcess();
//if(lPid == pid)
//if((long)peProcess->UniqueProcessId == pid)
//{
// return STATUS_ACCESS_DENIED;
//}
ULONG lPid = (ULONG)PsGetCurrentProcessId();
int i = 0;
for(;i < icount - 1; i++)
{
if(lPid == pid[i])
return OldZwSetValueKey(KeyHandle, ValueName, TitleIndex, Type, Data, DataSize);
}
return STATUS_ACCESS_DENIED;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING theRegistryPath)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
DriverObject->DriverUnload = OnUnload;
m_MDL = MmCreateMdl(NULL,KeServiceDescriptorTable.ServiceTableBase,KeServiceDescriptorTable.NumberOfServices*4);
if(!m_MDL)
{
return STATUS_UNSUCCESSFUL;
}
MmBuildMdlForNonPagedPool(m_MDL);//非分页内存
m_MDL->MdlFlags = m_MDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
m_Mapped = MmMapLockedPages(m_MDL, KernelMode);//锁定
HOOK_SYSCALL(ZwSetValueKey,NewZwSetValueKey,OldZwSetValueKey);
//KdPrint(("[*]驱动程序加载完毕.\n"));
return STATUS_SUCCESS;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
第一,Ring0EnumProcess要调用
第二,调用Ring0EnumProcess前,相关进程要开启,比如你在DriverEntry里调用Ring0EnumProcess,那么在驱动启动前,像Regedit.exe要开着,否则Ring0EnumProcess枚举不到Regedit进程,那么你后边用regedit.exe做实验的时候,就肯定会失败
第三,NewZwSetValueKey里的for(;i < icount - 1; i++),谁告诉你icount减一的呢?这是C基础,for(;i < icount; i++)
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
PsGetProcessImageFileName可以获得进程名,微软没有归档,但导出了,你在你的代码声明一下就可以用了,声明如下
NTKERNELAPI
UCHAR *
PsGetProcessImageFileName(
__in PEPROCESS Process
);
用的时候可以PUCHAR ProcessName = PsGetProcessImageFileName(PsGetCurrentProcess());
ProcessName 就是ANSI的进程名,直接判断即可,不过需要注意的是,这个获得的名称和EXE的文件名有些小区别,就是如果EXE文件名超过15个字节,15个字节后面的将会被截断再作为进程名,这个你自己试试就知道该怎么处理了。
|
能力值:
( LV2,RANK:10 )
|
-
-
18 楼
这样一试,然后就蓝屏了,是不是哪里还有其他要注意的啊?
UCHAR* CurrentExecuteName = PsGetProcessImageFileName(PsGetCurrentProcess());
if(!RtlCompareString(CurrentExecuteName, "system", TRUE)
|| !RtlCompareString(CurrentExecuteName, "lsass.exe", TRUE)
|| !RtlCompareString(CurrentExecuteName, "taskmgr.exe", TRUE)
|| !RtlCompareString(CurrentExecuteName, "setkey.exe", TRUE))
return OldZwSetValueKey(KeyHandle, ValueName, TitleIndex, Type, Data, DataSize);
else return STATUS_ACCESS_DENIED;
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
难道你编译不看warning的么?
编译原则是不允许出现警告的!
!RtlCompareString(CurrentExecuteName, "setkey.exe", TRUE),你看看这个函数的参数是什么类型的,PSTRING,STRING是什么?是个结构体啊,跟你刚才用RtlInitUnicodeString一用,STRING,也是需要RtlInitString的。
|