2008-10-09 30 views
31

Tôi có yêu cầu ẩn một quy trình trong Trình quản lý tác vụ. Nó dành cho kịch bản Intranet. Vì vậy, mọi thứ đều hợp pháp. :)Làm cách nào để ẩn một quy trình trong Trình quản lý Tác vụ trong C#?

Vui lòng chia sẻ bất kỳ mã nào bạn có (tốt nhất là trong C#) hoặc bất kỳ kỹ thuật nào khác hoặc bất kỳ vấn đề nào xảy ra với tuyến đường này.

Update1: Hầu hết người dùng có đặc quyền quản trị để chạy một số ứng dụng cũ. Vì vậy, một trong những gợi ý là giấu nó trong trình quản lý tác vụ. Nếu có những cách tiếp cận khác để ngăn chặn người dùng giết chết quá trình, điều đó sẽ rất tuyệt vời.

Update2: Xóa tham chiếu đến rootkit. Bằng cách nào đó làm cho bài đăng này có vẻ tiêu cực.

+0

Làm thế nào là nó đang trên một mạng nội bộ một kịch bản hợp pháp? Không cấp cho họ quyền quản trị ... –

+0

Đó là vấn đề. Hầu hết người dùng đều có đặc quyền quản trị để hỗ trợ một số ứng dụng cũ. –

+14

Nếu người dùng có đặc quyền quản trị viên, họ sẽ sở hữu máy, kết thúc câu chuyện. –

Trả lời

42

Không có cách nào được hỗ trợ để thực hiện việc này. Danh sách quy trình có thể được đọc ở bất kỳ cấp độ đặc quyền nào. Nếu bạn đang hy vọng để ẩn một quá trình từ ngay cả quản trị viên, sau đó điều này là gấp đôi không được hỗ trợ.

Để làm việc này, bạn cần phải viết rootkit chế độ hạt nhân để chặn cuộc gọi đến NtQuerySystemInformation để lớp thông tin SystemProcessInformation không liệt kê quá trình ẩn của bạn.

Chặn cuộc gọi hệ thống rất khó thực hiện một cách an toàn và hạt nhân Windows 64 bit đi out of their way để ngăn không cho điều này xảy ra: cố gắng sửa đổi bảng syscall dẫn đến màn hình xanh ngay lập tức. Sẽ rất khó khăn trên các nền tảng đó

Here là một ví dụ về rootkit cố gắng thực hiện điều gì đó tương tự (và có một số vấn đề nghiêm trọng).

10

Tôi hy vọng rằng bạn sẽ không thể.

Cập nhật: cho trường hợp, tôi nghĩ rằng bạn có thể sẽ chạy tốt nhất nó dưới một tài khoản quản trị khác. Điều đó có thể giúp cảnh báo mọi người về thực tế là họ không nên giết quá trình.

+0

Tôi hiểu ý của bạn. –

4

Nếu bạn chỉ cần che giấu quy trình và không ẩn hoàn toàn quy trình, bạn có thể đổi tên nó thành winlogon.exe hoặc svchost.exe và người dùng có thể sẽ bỏ qua nó. Nhưng như Sergio đã đề cập, đó là an ninh bởi sự tối tăm và nó có một danh tiếng xấu vì một lý do.

Ngăn chặn người dùng giết chết quy trình là một khó khăn khác nếu họ có đặc quyền thích hợp. Phương pháp duy nhất tôi biết là có nhiều quy trình xem nhau và khởi động lại bất kỳ quá trình theo dõi nào bị giết. Một lần nữa, điều này đang đi xuống một con đường râm.

+0

Tôi ghét phải nói điều đó, nhưng vì người dùng có đặc quyền quản trị ngụy trang quá trình này có lẽ là đặt cược tốt nhất của mình. Hãy cảnh giác, mặc dù: phần mềm chống vi-rút có thể coi đây là hành vi nguy hiểm và chỉ chặn chương trình. –

3

Không có cách nào dễ dàng hoặc được hỗ trợ để thực hiện việc này. Ngay cả khi bạn đã viết một rootkit để làm điều đó thì điều đó rất có thể dễ dàng bị phá vỡ bởi một bản cập nhật trong tương lai đã được thực hiện để cắm lỗ đó. Tôi sẽ xem xét lại liệu đó có phải là điều bạn muốn làm không.

64

Đừng cố gắng ngăn chặn việc bị giết - bạn sẽ không quản lý nó. Thay vào đó, hãy thường xuyên gọi điện về nhà cho một dịch vụ web. Khi webservice thông báo một khách hàng "im lặng", nó có thể ping máy để xem đó có phải là vấn đề khởi động lại hay không và gửi email cho người quản lý (hoặc bất kỳ ai) để kỷ luật ai đã giết quá trình.

+4

câu trả lời hay đầu tiên tôi đang tìm kiếm. –

+0

+100, ban đầu tôi đang tìm cách làm những gì tác giả ban đầu muốn làm, nhưng điều này nghe như một ý tưởng tuyệt vời. – Zack

+0

Jon Skeet cần nhiều upvotes hơn. – pseudocoder

18

Nếu bạn muốn ngăn người dùng hủy quá trình từ trình quản lý tác vụ, bạn chỉ có thể sử dụng trình mô tả bảo mật trong quá trình từ chối chấm dứt quyền truy cập vào tất cả mọi người.Quản trị viên về mặt kỹ thuật vẫn có thể giết chết quá trình bằng cách lấy quyền sở hữu của quá trình và đặt lại DACL, nhưng không có giao diện để thực hiện một trong hai việc này từ Trình quản lý tác vụ. Tuy nhiên, Process Explorer có thể có giao diện.

Khi quá trình của bạn bắt đầu, hãy sử dụng SetKernelObjectSecurity với DACL_SECURITY_INFORMATION bằng cách sử dụng trình xử lý hiện tại. Đặt DACL với số không ACL. Điều này sẽ từ chối tất cả quyền truy cập vào tất cả mọi người, kể cả những người đang cố gắng kết thúc quá trình của bạn với trình quản lý tác vụ.

Dưới đây là một ví dụ mà cũng thay đổi chủ sở hữu của quá trình:

SECURITY_DESCRIPTOR sd; 
ACL dacl; 
SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY; 
PSID owner; 

assert(InitializeAcl(&dacl, sizeof dacl, ACL_REVISION)); 

assert(AllocateAndInitializeSid(&ntauth, 1, SECURITY_LOCAL_SYSTEM_RID, 0,0,0,0,0,0,0, &owner)); 

assert(InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)); 

assert(SetSecurityDescriptorDacl(&sd, TRUE, &dacl, FALSE)); 

assert(SetSecurityDescriptorOwner(&sd, owner, FALSE)); 

assert(SetKernelObjectSecurity(GetCurrentProcess(), DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, &sd)); 

assert(FreeSid(owner) == NULL); 

Thật không may, nó dường như không có hiệu quả. Tôi vẫn có thể đóng quá trình (mặc dù không phải là người dùng hạn chế). Có lẽ Task Manager đang chiếm quyền sở hữu hoặc gọi một số đặc quyền khác để giết quá trình này? Tôi dường như nhớ điều này làm việc trong các phiên bản trước của Windows (tôi đã thử nghiệm 2003), nhưng tôi có thể nhầm lẫn.

+0

+10. Điều này chắc chắn là giá trị nhìn vào ... Cảm ơn một bó. –

+0

Tôi đã cố gắng làm điều này trong một ứng dụng mẫu, nhưng nó dường như không có hiệu lực (mặc dù tất cả các cuộc gọi đã thành công). Tôi ghét phải nói điều đó, nhưng bạn có thể liên kết với một số mã thực hiện điều này không? –

+0

Tôi sắp hỏi cùng một câu hỏi. Cảm ơn Stephen. –

6

Ngoài ra, bạn có thể viết một tiện ích "trình kiểm tra" nhỏ để kiểm tra xem ứng dụng có đang chạy không, nếu nó không tự động chạy ứng dụng. Sau đó, thêm mã vào ứng dụng để kiểm tra tiện ích "trình kiểm tra" thực hiện tương tự. Bằng cách này, nếu người ta chấm dứt, thì người kia bắt đầu lại. Tôi dường như virus làm điều này, và nó có vẻ hoạt động khá hiệu quả.

+0

vâng. có thể. muốn tránh các chu kỳ CPU cho tất cả các kiểm tra đó. –

1

Còn bạn chỉ yêu cầu người dùng không giết quá trình? Bạn sẽ dành bao nhiêu thời gian để thực hiện nó, cho một hành vi rõ ràng là trẻ con từ các nhân viên trong cùng một công ty.

+0

Quá trình này được thực hiện để giáo dục người dùng. Tôi phải che giấu khả năng này từ góc độ kỹ thuật. –

3

Như mọi người đã đề cập ở trên, phương pháp tốt nhất là 2 nhiệm vụ, theo dõi nhau, Tôi hiểu bạn không muốn lãng phí CPU, vì vậy cách tốt nhất là thiết lập sự kiện giữa các tác vụ sẽ được kích hoạt khi một đóng cửa.

Tôi không hoàn toàn chắc chắn về cách thiết lập móc, nhưng sau đó bạn không sử dụng vòng lặp while làm lãng phí CPU.

2

Bạn đã xem xét việc viết một dịch vụ chưa? Bằng cách này, dịch vụ chạy như hệ thống cục bộ và ứng dụng chạy dưới ngữ cảnh của người dùng và dịch vụ có thể đảm bảo rằng mọi thứ vẫn được thực hiện khi cần và ứng dụng chỉ là giao diện cho dịch vụ này. Giết ứng dụng sẽ chỉ khiến người dùng không nhìn thấy bất kỳ thông báo nào, biểu tượng khay hệ thống, v.v. nhưng dịch vụ vẫn đang thực hiện công việc của mình.

3

Viết trình điều khiển - Bạn có thể sử dụng ObRegisterCallbacks để đăng ký thông báo truy cập đối tượng quy trình. Trả về STATUS_ACCESS_DENIED khi DesiredAccess chứa các quyền truy cập mà bạn không thích, như chấm dứt quá trình hoặc viết để xử lý bộ nhớ.

http://msdn.microsoft.com/en-us/library/windows/hardware/ff558692(v=vs.85).aspx

3

Không chắc chắn tại sao has not này được đề xuất được nêu ra nhưng heres câu trả lời đầu tiên của tôi trên trang web này. thay vì ngăn người dùng hủy quá trình. (Yêu cầu rootkit hooking.) Bạn chỉ có thể vô hiệu hóa trình quản lý tác vụ đang được sử dụng với đầu vào đăng ký.

public static void ToggleTaskManager(bool toggle) 
{ 
    Microsoft.Win32.RegistryKey HKCU = Microsoft.Win32.Registry.LocalMachine; 
    Microsoft.Win32.RegistryKey key = HKCU.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System"); 
    key.SetValue("DisableTaskMgr", toggle ? 0 : 1, Microsoft.Win32.RegistryValueKind.DWord); 
} 
+1

Còn 'tasklist.exe',' taskkill.exe' hoặc 'ProcessMonitor' thì sao? Vì vậy, đơn giản việc ngăn TaskManager có vẻ không phải là cách tốt để ngăn chặn việc đóng một tiến trình. – Oliver

+4

Bạn luôn có thể sử dụng ứng dụng của mình để giết những người đó. – Cacoon

2

Nhiều người có thể biết cách thực hiện, nhưng sẽ không đăng ở đây. Rất nguy hiểm khi đăng mã độc trên internet. Ai biết bạn có thể gặp nguy hiểm. Hãy hỏi một số kỹ sư máy tính. Tuy nhiên, tôi sẽ cung cấp cho bạn cấu trúc của chương trình.

Chỉ cần đưa dll chương trình của bạn vào explorer.exe.

Quy trình của bạn sẽ không hiển thị vì nó không chạy như một chương trình nhưng đang được chạy trong một chương trình (trình thám hiểm.exe). Người dùng sẽ không thấy quy trình ngay cả khi anh ta sử dụng bất kỳ loại trình quản lý tác vụ nào.

0

để ngăn chặn quá trình khỏi bị giết chết vĩnh viễn, có điều đầu tiên quá trình này, không có gì để gọi là 'atexit()' và có atexit) chức năng (bắt đầu quá trình

+0

Khi bạn kết thúc quá trình, atexit không được gọi (được xác minh qua thử nghiệm nhanh) –

0

Tôi biết câu hỏi này là cũ nhưng tôi trả lời một câu hỏi trùng lặp một thời gian trước đây có chứa một số thông tin tốt đẹp ở đó không phải là ở đây vì vậy tôi nghĩ rằng tôi muốn liên kết với nó. See My answer to the duplicate question. Ngoài ra nếu mục tiêu thực sự của bạn là ngăn chặn người dùng giết quá trình thì những gì tôi biết được sử dụng để hoạt động rất dễ dàng, mặc dù đó là một chút hackish và tôi không biết nếu điều này vẫn hoạt động, chỉ đơn giản là tên lsass ứng dụng của bạn. exe và trình quản lý tác vụ sẽ không cho phép ngay cả người dùng quản trị viên đóng quy trình. đối với phương thức này, việc người dùng bắt đầu quá trình hoặc nơi tệp thực thi nằm trên hệ thống tệp là gì, có vẻ như các cửa sổ chỉ kiểm tra xem quá trình có được đặt tên này không cho phép nó kết thúc.

Cập nhật: Tôi chỉ cố gắng thực hiện thủ thuật lsass.exe trên windows 7 và có vẻ như đã được khắc phục, nhưng tôi đoán là nó vẫn hoạt động trên Windows XP và thậm chí cả các gói dịch vụ trước đó của các phiên bản ngoài xp. Mặc dù điều này không còn hoạt động tại thời điểm viết bài này, tôi nghĩ rằng tôi sẽ bao gồm nó như là một thực tế thú vị.

0

Tôi đã thấy câu trả lời @Chris Smith và tôi đã quyết định chuyển đổi thành C#.

Đây là mã, lấy từ here, cho một ứng dụng Winform đơn giản:
C# biến:

using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Drawing; 
    using System.Linq; 
    using System.Runtime.InteropServices; 
    using System.Security.AccessControl; 
    using System.Security.Principal; 
    using System.Text; 
    using System.Threading.Tasks; 
    using System.Windows.Forms; 

namespace Hide2 
{ 
    public partial class Form1 : Form 
    { 
     [DllImport("advapi32.dll", SetLastError = true)] 
     static extern bool GetKernelObjectSecurity(IntPtr Handle, int securityInformation, [Out] byte[] pSecurityDescriptor, 
     uint nLength, out uint lpnLengthNeeded); 

     public static RawSecurityDescriptor GetProcessSecurityDescriptor(IntPtr processHandle) 
     { 
      const int DACL_SECURITY_INFORMATION = 0x00000004; 
      byte[] psd = new byte[0]; 
      uint bufSizeNeeded; 
      // Call with 0 size to obtain the actual size needed in bufSizeNeeded 
      GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, psd, 0, out bufSizeNeeded); 
      if (bufSizeNeeded < 0 || bufSizeNeeded > short.MaxValue) 
       throw new Win32Exception(); 
      // Allocate the required bytes and obtain the DACL 
      if (!GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, 
      psd = new byte[bufSizeNeeded], bufSizeNeeded, out bufSizeNeeded)) 
       throw new Win32Exception(); 
      // Use the RawSecurityDescriptor class from System.Security.AccessControl to parse the bytes: 
      return new RawSecurityDescriptor(psd, 0); 
     } 

     [DllImport("advapi32.dll", SetLastError = true)] 
     static extern bool SetKernelObjectSecurity(IntPtr Handle, int securityInformation, [In] byte[] pSecurityDescriptor); 

     [DllImport("kernel32.dll")] 
     public static extern IntPtr GetCurrentProcess(); 

     [Flags] 
     public enum ProcessAccessRights 
     { 
      PROCESS_CREATE_PROCESS = 0x0080, // Required to create a process. 
      PROCESS_CREATE_THREAD = 0x0002, // Required to create a thread. 
      PROCESS_DUP_HANDLE = 0x0040, // Required to duplicate a handle using DuplicateHandle. 
      PROCESS_QUERY_INFORMATION = 0x0400, // Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob). 
      PROCESS_QUERY_LIMITED_INFORMATION = 0x1000, // Required to retrieve certain information about a process (see QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION. Windows Server 2003 and Windows XP/2000: This access right is not supported. 
      PROCESS_SET_INFORMATION = 0x0200, // Required to set certain information about a process, such as its priority class (see SetPriorityClass). 
      PROCESS_SET_QUOTA = 0x0100, // Required to set memory limits using SetProcessWorkingSetSize. 
      PROCESS_SUSPEND_RESUME = 0x0800, // Required to suspend or resume a process. 
      PROCESS_TERMINATE = 0x0001, // Required to terminate a process using TerminateProcess. 
      PROCESS_VM_OPERATION = 0x0008, // Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory). 
      PROCESS_VM_READ = 0x0010, // Required to read memory in a process using ReadProcessMemory. 
      PROCESS_VM_WRITE = 0x0020, // Required to write to memory in a process using WriteProcessMemory. 
      DELETE = 0x00010000, // Required to delete the object. 
      READ_CONTROL = 0x00020000, // Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right. 
      SYNCHRONIZE = 0x00100000, // The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state. 
      WRITE_DAC = 0x00040000, // Required to modify the DACL in the security descriptor for the object. 
      WRITE_OWNER = 0x00080000, // Required to change the owner in the security descriptor for the object. 
      STANDARD_RIGHTS_REQUIRED = 0x000f0000, 
      PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF),// All possible access rights for a process object. 
     } 
     public static void SetProcessSecurityDescriptor(IntPtr processHandle, RawSecurityDescriptor dacl) 
     { 
      const int DACL_SECURITY_INFORMATION = 0x00000004; 
      byte[] rawsd = new byte[dacl.BinaryLength]; 
      dacl.GetBinaryForm(rawsd, 0); 
      if (!SetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, rawsd)) 
       throw new Win32Exception(); 
     } 

     public Form1() 
     { 
      InitializeComponent(); 

      // Get the current process handle 
      IntPtr hProcess = GetCurrentProcess(); 
      // Read the DACL 
      var dacl = GetProcessSecurityDescriptor(hProcess); 
      // Insert the new ACE 
      dacl.DiscretionaryAcl.InsertAce(
      0, 
      new CommonAce(
      AceFlags.None, 
      AceQualifier.AccessDenied, 
      (int)ProcessAccessRights.PROCESS_ALL_ACCESS, 
      new SecurityIdentifier(WellKnownSidType.WorldSid, null), 
      false, 
      null) 
      ); 
      // Save the DACL 
      SetProcessSecurityDescriptor(hProcess, dacl); 
     } 
    } 
} 

Sau khi chạy nó như là một người dùng hạn chế, tôi không thể giết nó từ nhiệm vụ người quản lý, chỉ với tư cách là quản trị viên.
Tôi đã rời nút X để có thể đóng nó mà không có quản trị viên nhưng cũng có thể xóa nó.

Kết quả:

enter image description here

Powershell biến:

$source = @" 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Runtime.InteropServices; 
using System.Security.AccessControl; 
using System.Security.Principal; 

namespace Hide2 
{ 
    public class myForm 
    { 
     [DllImport("advapi32.dll", SetLastError = true)] 
     static extern bool GetKernelObjectSecurity(IntPtr Handle, int securityInformation, [Out] byte[] pSecurityDescriptor, 
     uint nLength, out uint lpnLengthNeeded); 

     public static RawSecurityDescriptor GetProcessSecurityDescriptor(IntPtr processHandle) 
     { 
      const int DACL_SECURITY_INFORMATION = 0x00000004; 
      byte[] psd = new byte[0]; 
      uint bufSizeNeeded; 
      // Call with 0 size to obtain the actual size needed in bufSizeNeeded 
      GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, psd, 0, out bufSizeNeeded); 
      if (bufSizeNeeded < 0 || bufSizeNeeded > short.MaxValue) 
       throw new Win32Exception(); 
      // Allocate the required bytes and obtain the DACL 
      if (!GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, 
      psd = new byte[bufSizeNeeded], bufSizeNeeded, out bufSizeNeeded)) 
       throw new Win32Exception(); 
      // Use the RawSecurityDescriptor class from System.Security.AccessControl to parse the bytes: 
      return new RawSecurityDescriptor(psd, 0); 
     } 

     [DllImport("advapi32.dll", SetLastError = true)] 
     static extern bool SetKernelObjectSecurity(IntPtr Handle, int securityInformation, [In] byte[] pSecurityDescriptor); 

     [DllImport("kernel32.dll")] 
     public static extern IntPtr GetCurrentProcess(); 

     [Flags] 
     public enum ProcessAccessRights 
     { 
      PROCESS_CREATE_PROCESS = 0x0080, // Required to create a process. 
      PROCESS_CREATE_THREAD = 0x0002, // Required to create a thread. 
      PROCESS_DUP_HANDLE = 0x0040, // Required to duplicate a handle using DuplicateHandle. 
      PROCESS_QUERY_INFORMATION = 0x0400, // Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob). 
      PROCESS_QUERY_LIMITED_INFORMATION = 0x1000, // Required to retrieve certain information about a process (see QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION. Windows Server 2003 and Windows XP/2000: This access right is not supported. 
      PROCESS_SET_INFORMATION = 0x0200, // Required to set certain information about a process, such as its priority class (see SetPriorityClass). 
      PROCESS_SET_QUOTA = 0x0100, // Required to set memory limits using SetProcessWorkingSetSize. 
      PROCESS_SUSPEND_RESUME = 0x0800, // Required to suspend or resume a process. 
      PROCESS_TERMINATE = 0x0001, // Required to terminate a process using TerminateProcess. 
      PROCESS_VM_OPERATION = 0x0008, // Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory). 
      PROCESS_VM_READ = 0x0010, // Required to read memory in a process using ReadProcessMemory. 
      PROCESS_VM_WRITE = 0x0020, // Required to write to memory in a process using WriteProcessMemory. 
      DELETE = 0x00010000, // Required to delete the object. 
      READ_CONTROL = 0x00020000, // Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right. 
      SYNCHRONIZE = 0x00100000, // The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state. 
      WRITE_DAC = 0x00040000, // Required to modify the DACL in the security descriptor for the object. 
      WRITE_OWNER = 0x00080000, // Required to change the owner in the security descriptor for the object. 
      STANDARD_RIGHTS_REQUIRED = 0x000f0000, 
      PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF),// All possible access rights for a process object. 
     } 
     public static void SetProcessSecurityDescriptor(IntPtr processHandle, RawSecurityDescriptor dacl) 
     { 
      const int DACL_SECURITY_INFORMATION = 0x00000004; 
      byte[] rawsd = new byte[dacl.BinaryLength]; 
      dacl.GetBinaryForm(rawsd, 0); 
      if (!SetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, rawsd)) 
       throw new Win32Exception(); 
     } 

     public static void ProtectMyProcess() 
     { 
      // Get the current process handle 
      IntPtr hProcess = GetCurrentProcess(); 
      // Read the DACL 
      var dacl = GetProcessSecurityDescriptor(hProcess); 
      // Insert the new ACE 
      dacl.DiscretionaryAcl.InsertAce(
      0, 
      new CommonAce(
      AceFlags.None, 
      AceQualifier.AccessDenied, 
      (int)ProcessAccessRights.PROCESS_ALL_ACCESS, 
      new SecurityIdentifier(WellKnownSidType.WorldSid, null), 
      false, 
      null) 
      ); 
      // Save the DACL 
      SetProcessSecurityDescriptor(hProcess, dacl); 

     } 
    } 
} 
"@ 

Add-Type -TypeDefinition $Source -Language CSharp 

[ScriptBlock]$scriptNewForm = { 
    Add-Type -AssemblyName System.Windows.Forms 

    $Form = New-Object system.Windows.Forms.Form 
    $Form.Text = "PowerShell form" 
    $Form.TopMost = $true 
    $Form.Width = 303 
    $Form.Height = 274 

    [void]$Form.ShowDialog() 
    $Form.Dispose() 
} 



$SleepTimer = 200 
$MaxResultTime = 120 
$MaxThreads = 3 

$ISS = [system.management.automation.runspaces.initialsessionstate]::CreateDefault() 
$RunspacePool = [runspacefactory]::CreateRunspacePool(1, $MaxThreads, $ISS, $Host) 
$RunspacePool.Open() 

$Jobs = @() 

$PowershellThread = [powershell]::Create().AddScript($scriptNewForm) 
$PowershellThread.RunspacePool = $RunspacePool 
$Handle = $PowershellThread.BeginInvoke() 
$Job = "" | Select-Object Handle, Thread, object 
$Job.Handle = $Handle 
$Job.Thread = $PowershellThread 
$Job.Object = $computer 
$Jobs += $Job 

[Hide2.myForm]::ProtectMyProcess() 

<# 
ForEach ($Job in $Jobs){ 
    $Job.Thread.EndInvoke($Job.Handle) 
    $Job.Thread.Dispose() 
    $Job.Thread = $Null 
    $Job.Handle = $Null 
} 
#> 
Các vấn đề liên quan