2008-10-09 11 views
31

मुझे कार्य प्रबंधक में प्रक्रिया को छिपाने की आवश्यकता है। यह इंट्रानेट परिदृश्य के लिए है। तो, सब कुछ वैध है। :)मैं सी # में टास्क मैनेजर में एक प्रक्रिया कैसे छिपा सकता हूं?

कृपया इस मार्ग के साथ जाने में किसी भी कोड (अधिमानतः सी # में) या किसी भी अन्य तकनीक या किसी भी मुद्दे को साझा करने के लिए स्वतंत्र महसूस करें।

Update1: उन में से अधिकांश आदेश कुछ विरासत क्षुधा चलाने के लिए व्यवस्थापक विशेषाधिकार है। तो, सुझाव में से एक यह था कि इसे टास्क मैनेजर में छिपाना था। यदि उपयोगकर्ताओं को प्रक्रिया को मारने से रोकने के लिए अन्य दृष्टिकोण हैं, तो यह बहुत अच्छा होगा।

अद्यतन 2: रूटकिट के संदर्भ को हटा रहा है। किसी भी तरह से यह पोस्ट नकारात्मक दिखता है।

+0

यह एक इंट्रानेट एक वैध परिदृश्य पर कैसे किया जा रहा है? उन्हें व्यवस्थापक निजीकरण न दें ... –

+0

समस्या है। कुछ विरासत ऐप्स का समर्थन करने के लिए अधिकांश उपयोगकर्ताओं के पास व्यवस्थापकीय विशेषाधिकार हैं। –

+14

यदि उपयोगकर्ताओं के पास व्यवस्थापकीय विशेषाधिकार हैं, तो वे मशीन के ओपन, कहानी के अंत हैं। –

उत्तर

42

इसे पूरा करने के लिए कोई समर्थित तरीका नहीं है। प्रक्रिया सूची किसी विशेषाधिकार स्तर पर पढ़ी जा सकती है। यदि आप प्रशासकों से भी प्रक्रिया छिपाने की उम्मीद कर रहे थे, तो यह दोगुना असमर्थित है।

इसे काम करने के लिए, आपको NtQuerySystemInformation पर कॉल को अवरुद्ध करने के लिए कर्नेल मोड रूटकिट लिखना होगा ताकि सिस्टमप्रोसेस सूचना जानकारी कक्षा आपकी छिपी हुई प्रक्रिया को सूचीबद्ध करने में विफल हो।

सिस्टम कॉल को बाधित करना सुरक्षित रूप से करने के लिए बहुत मुश्किल है, और 64 बिट Windows कर्नेल out of their way जाना संभव किया जा रहा से इसे रोकने के लिए: एक पल नीले परदे में syscall तालिका के परिणाम को संशोधित करने की कोशिश कर रहा। यह उन प्लेटफार्मों

Here पर बहुत मुश्किल हो जा रहा है एक रूटकिट कुछ इसी तरह करने की कोशिश करता है (और कई गंभीर समस्या है) इस बात का एक उदाहरण है।

10

मुझे उम्मीद है कि आप सक्षम नहीं होंगे।

अद्यतन: परिदृश्य को देखते हुए, मुझे लगता है कि आप शायद एक अलग व्यवस्थापक खाते के अंतर्गत इसे चलाने बंद सबसे अच्छा हो जाएगा। इससे लोगों को इस तथ्य को सतर्क करने में मदद मिल सकती है कि उन्हें प्रक्रिया को मारना नहीं चाहिए।

+0

मैं आपके बिंदु को समझता हूं। –

4

यदि आपको बस प्रक्रिया को छिपाने की आवश्यकता है और इसे पूरी तरह छिपाना नहीं है, तो आप इसे winlogon.exe या svchost.exe का नाम बदल सकते हैं और इसे उपयोगकर्ताओं द्वारा अनदेखा कर दिया जाएगा। लेकिन सर्जीओ ने उल्लेख किया है कि यह अस्पष्टता से सुरक्षा है और इसे किसी कारण से खराब प्रतिष्ठा मिली है।

उपयोगकर्ताओं को प्रक्रिया को मारने से रोकना एक और कठिनाई है यदि उनके पास उचित विशेषाधिकार हैं। एकमात्र तरीका मुझे पता है कि कई प्रक्रियाएं हैं जो एक-दूसरे को देखते हैं और किसी भी देखी गई प्रक्रिया को पुनरारंभ करते हैं जो मारे जाते हैं। फिर, यह एक छायादार रास्ते नीचे जा रहा है।

+0

मुझे यह कहने से नफरत है, लेकिन चूंकि उपयोगकर्ताओं के पास प्रक्रिया का छेड़छाड़ करने वाले प्रशासनिक विशेषाधिकार हैं, शायद उनकी सर्वश्रेष्ठ शर्त है। सावधान रहें, हालांकि: एंटी-वायरस सॉफ़्टवेयर इसे दुर्भावनापूर्ण व्यवहार के रूप में देख सकता है और केवल प्रोग्राम को अवरुद्ध कर सकता है। –

3

ऐसा करने के लिए कोई आसान या समर्थित तरीका नहीं है। यहां तक ​​कि यदि आपने इसे करने के लिए रूटकिट लिखा है तो वह उस छेद को प्लग करने के लिए किए गए भविष्य के अपडेट द्वारा आसानी से टूटा जा सकता है। मैं फिर से सोचूंगा कि वह ऐसा कुछ है जिसे आप करना चाहते हैं।

64

इसे मारने से रोकने की कोशिश न करें - आप इसे प्रबंधित करने के लिए नहीं जा रहे हैं। इसके बजाय, इसे नियमित रूप से एक webservice के लिए घर पर कॉल करें। जब webservice क्लाइंट को "चुप हो रहा है" नोटिस करता है तो यह मशीन को पिंग कर सकता है कि यह सिर्फ एक रीबूट समस्या है या नहीं, और किसी भी प्रबंधक को (या जो भी) अनुशासन के लिए एक ईमेल भेजता है जिसने प्रक्रिया को मार दिया है।

+4

पहला अच्छा जवाब मैं देख रहा था। –

+0

+100, मैं शुरुआत में ऐसा करना चाहता था जो मूल लेखक करना चाहता था, लेकिन यह एक उत्कृष्ट विचार की तरह लगता है। – Zack

+0

जॉन स्कीट को और अधिक उन्नयन की आवश्यकता है। – pseudocoder

18

आप उन कार्य प्रबंधक से इस प्रक्रिया को मारने से रोकना चाहते हैं, तो आप सिर्फ एक सुरक्षा डिस्क्रिप्टर प्रक्रिया पर हर किसी की पहुंच समाप्त अस्वीकार करने के लिए उपयोग कर सकते हैं।प्रशासक तकनीकी रूप से प्रक्रिया के स्वामित्व और डीएसीएल को रीसेट करके प्रक्रिया को मार सकते हैं, लेकिन टास्क मैनेजर से इन चीजों में से कोई भी करने के लिए कोई इंटरफ़ेस नहीं है। Process Explorer हालांकि एक इंटरफेस हो सकता है।

जब आपकी प्रक्रिया शुरू होती है, तो वर्तमान प्रक्रिया संभाल का उपयोग करके के साथ SetKernelObjectSecurity का उपयोग करें। शून्य एसीएल के साथ एक डीएसीएल सेट करें। यह कार्य प्रबंधक के साथ आपकी प्रक्रिया को समाप्त करने की कोशिश करने वाले सभी लोगों के लिए सभी पहुंच से इंकार कर देगा।

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

दुर्भाग्य से, यह प्रभावी होने के लिए प्रतीत नहीं होता:

यहाँ एक उदाहरण है कि भी इस प्रक्रिया के मालिक बदल जाता है। मैं अभी भी प्रक्रिया को बंद कर सकता हूं (हालांकि सीमित उपयोगकर्ता के रूप में नहीं)। शायद टास्क मैनेजर प्रक्रिया को मारने के लिए स्वामित्व ले रहा है या किसी अन्य विशेषाधिकार का आह्वान कर रहा है? मुझे लगता है कि यह विंडोज के पिछले संस्करणों में काम कर रहा है (मैं 2003 का परीक्षण कर रहा था), लेकिन मुझे गलत हो सकता है।

+0

+10। यह निश्चित रूप से देखने लायक है ... धन्यवाद एक गुच्छा। –

+0

मैंने इसे नमूना ऐप में करने का प्रयास किया है, लेकिन ऐसा कोई प्रभाव नहीं प्रतीत होता है (हालांकि सभी कॉल सफल हुए)। मुझे यह कहने से नफरत है, लेकिन क्या आप कुछ कोड से लिंक कर सकते हैं जो ऐसा करता है? –

+0

मैं एक ही सवाल पूछने वाला था। धन्यवाद स्टीफन। –

6

वैकल्पिक रूप से, आप एक छोटी "चेकर" उपयोगिता लिख ​​सकते हैं जो जांचता है कि ऐप चल रहा है, अगर यह स्वचालित रूप से इसे शुरू नहीं करता है। फिर "चेकर" उपयोगिता की जांच करने के लिए ऐप में कोड जोड़ें जो वही करता है। इस तरह अगर कोई समाप्त हो जाता है, तो दूसरा इसे बैक अप लेता है। मुझे लगता है कि वायरस ऐसा करता है, और ऐसा लगता है कि यह बहुत प्रभावी ढंग से काम करता है।

+0

हाँ। यह संभव है। जांचने वाले सभी के लिए सीपीयू चक्र से बचना चाहता था। –

1

क्या आप बस उपयोगकर्ता से प्रक्रिया को मारने के लिए नहीं कहते हैं? एक ही कंपनी में कर्मचारियों से स्पष्ट रूप से बचपन के व्यवहार के लिए आप इसे कितना समय व्यतीत करेंगे।

+0

उपयोगकर्ताओं को शिक्षित करने के लिए प्रक्रिया की जगह है। मुझे तकनीकी संभावना से इस संभावना को कवर करना होगा। –

3

जैसा ऊपर बताया गया है, सबसे अच्छी विधि 2 कार्य है, एक दूसरे की निगरानी, ​​ मुझे लगता है कि आप सीपीयू को बर्बाद नहीं करना चाहते हैं, इसलिए सबसे अच्छा तरीका उन कार्यों के बीच एक घटना स्थापित करना है जो एक बार ट्रिगर किए जाएंगे बंद कर देता है।

मुझे हुक सेट करने के तरीके पर पूरी तरह से यकीन नहीं है, लेकिन फिर आप थोड़ी देर लूप का उपयोग नहीं करते हैं जो सीपीयू को बर्बाद करता है।

2

क्या आपने एक सेवा लिखने पर देखा है? इस तरह सेवा स्थानीय प्रणाली के रूप में चलती है, और एप्लिकेशन उपयोगकर्ता के संदर्भ में चलता है, और सेवा यह सुनिश्चित कर सकती है कि चीजें अभी भी आवश्यकतानुसार की जा रही हैं, और एप्लिकेशन इस सेवा के लिए एक इंटरफ़ेस है। एप्लिकेशन को मारने के परिणामस्वरूप उपयोगकर्ता को कोई नोटिस, सिस्टम ट्रे आइकन आदि नहीं दिखाई देगा, लेकिन सेवा अभी भी अपना काम कर रही है।

3

ड्राइवर लिखें - आप प्रक्रिया ऑब्जेक्ट एक्सेस अधिसूचना पंजीकृत करने के लिए ObRegisterCallbacks का उपयोग कर सकते हैं। जब DesiredAccess में उन एक्सेस अधिकारों को शामिल किया जाता है जिन्हें आप पसंद नहीं करते हैं, प्रक्रिया प्रक्रिया समाप्त करने या स्मृति को संसाधित करने के लिए लिखने पर STATUS_ACCESS_DENIED लौटें।

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

3

सुनिश्चित नहीं हैं कि क्यों यह नहीं चढ़े, जिस का सुझाव दिया गया अभी तक लेकिन इस साइट पर यहाँ मेरा पहला जवाब। उपयोगकर्ता को प्रक्रिया को मारने से रोकने के बजाय । (रूटकिट हुकिंग की आवश्यकता है।) आप केवल रजिस्ट्री इनपुट के साथ कार्य प्रबंधक को अक्षम करने से अक्षम कर सकते हैं।

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

और 'tasklist.exe',' taskkill.exe 'या 'ProcessMonitor' के बारे में क्या? तो बस कार्य प्रबंधक को रोकने से प्रक्रिया को बंद करने से रोकने का एक अच्छा तरीका नहीं लगता है। – Oliver

+4

आप हमेशा उन लोगों को मारने के लिए अपने आवेदन का उपयोग कर सकते हैं। – Cacoon

2

कई लोग यह जान सकते हैं कि यह कैसे करें, लेकिन बस इसे यहां पोस्ट नहीं किया जाएगा। इंटरनेट पर दुर्भावनापूर्ण कोड पोस्ट करना बहुत खतरनाक है। कौन जानता है कि आप खतरे में हो सकते हैं। कुछ कंप्यूटर इंजीनियर से पूछें। हालांकि मैं आपको कार्यक्रम की संरचना दूंगा।

बस अपने प्रोग्राम के डीएल को explorer.exe में इंजेक्ट करें।

आपकी प्रक्रिया केवल इसलिए दिखाई नहीं देगी क्योंकि यह एक प्रोग्राम के रूप में नहीं चल रहा है लेकिन एक प्रोग्राम में चलाया जा रहा है (एक्सप्लोरर।प्रोग्राम फ़ाइल)। उपयोगकर्ता किसी भी प्रकार के टास्क मैनेजर का उपयोग करने पर भी प्रक्रिया को नहीं देख पाएगा।

0

से स्थायी रूप से हत्या किए जाने की प्रक्रिया को रोकने के लिए, पहली बात यह है प्रक्रिया करता है 'atexit()' कहते हैं और इस प्रक्रिया

+0

जब आप किसी प्रक्रिया को समाप्त करते हैं, atexit को नहीं कहा जाता है (त्वरित प्रयोग के माध्यम से सत्यापित) –

0

शुरू मैं जानता हूँ कि इस सवाल का वर्ष है, लेकिन मैं atexit() फ़ंक्शन के लिए कुछ समय पहले एक डुप्लिकेट प्रश्न का उत्तर दिया जिसमें कुछ अच्छी जानकारी है जो यहां नहीं है इसलिए मैंने सोचा कि मैं इससे लिंक करूंगा। See My answer to the duplicate question. यदि आपका सच्चा लक्ष्य उपयोगकर्ताओं को प्रक्रिया को मारने से रोकने के लिए है, तो मुझे जो कुछ पता है वह बहुत आसानी से काम करने के लिए उपयोग किया जाता है, हालांकि यह थोड़ा हैकिश है और मुझे नहीं पता कि यह अभी भी काम करता है, बस अपने आवेदन lsass को नामित करना है। exe और टास्क मैनेजर एक व्यवस्थापक उपयोगकर्ता को प्रक्रिया बंद करने की इजाजत नहीं देगा। इस विधि के लिए इससे कोई फर्क नहीं पड़ता कि किस उपयोगकर्ता ने प्रक्रिया शुरू की है या जहां निष्पादन योग्य फ़ाइल सिस्टम पर रहता है, ऐसा लगता है कि विंडोज़ सिर्फ यह देखने के लिए जांच करती है कि प्रक्रिया का नाम क्या है या नहीं, इसे समाप्त होने की अनुमति न दें।

अपडेट: मैंने बस विंडोज 7 पर lsass.exe चाल करने की कोशिश की और ऐसा लगता है कि यह तय किया गया है, लेकिन मेरा अनुमान है कि यह अभी भी विंडोज एक्सपी पर काम करता है और यहां तक ​​कि एक्सपी से परे संस्करणों के पहले सर्विस पैक भी हो सकता है। भले ही यह इस लेखन के समय काम नहीं करता है, मैंने सोचा कि मैं इसे एक मजेदार तथ्य के रूप में शामिल करूंगा।

0

मैंने @ क्रिस स्मिथ का जवाब देखा और मैंने इसे सी # में बदलने का फैसला किया।

यहाँ कोड, एक सरल Winform आवेदन के लिए, here से लिया है:
सी # भिन्नता:

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); 
     } 
    } 
} 

एक सीमित उपयोगकर्ता के रूप में यह चलाने के बाद, मैं इसे काम से नहीं मार सकता है प्रबंधक, केवल प्रशासक के रूप में।
मैंने X बटन को व्यवस्थापक के बिना बंद करने में सक्षम होने के लिए छोड़ा लेकिन इसे हटाने के लिए भी संभव है।

परिणाम:

enter image description here

Powershell भिन्नता:

$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 
} 
#> 
संबंधित मुद्दे