Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have the following problem:
I try to Kill a Process of a Game from c# code. I always get "access denied"! It has an Anti Hack Shield, i think that's the problem...

But the Window Task Manager can Kill the Process
I checked the PID it is the Same!

So how can i Kill it the same way as the Task Manager do?
Or can i call the Method of the Task Manager?
Maybe i need to change some Parameter before?
I googled a lot and i find something with SeDebugPrivilege I used it but still the same "access denied"

I also found this explanation http://bytes.com/topic/c-sharp/answers/255047-getprocessesbyname-permissions but i dont get in:(



That’s my ways i tried: Run VisualStudio as Administrator
C#
public void KillKal(IntPtr _WindowPointer)
       {
           uint ProcessID;

           GetWindowThreadProcessId(_WindowPointer, out ProcessID);
           try
           {
               Process p = Process.GetProcessById((int)ProcessID);
               //
               //used here the SeDebugPrivilege code from link
               //
               //1. try
               Process.Start(new ProcessStartInfo
               {
                   FileName = "cmd.exe",
                   CreateNoWindow = true,
                   UseShellExecute = false,
                   Arguments = string.Format("/c taskkill /pid {0} /f", ProcessID)
               });
               //2.try
               Process.Start(new ProcessStartInfo
               {
                   FileName = "net.exe",
                   CreateNoWindow = true,
                   UseShellExecute = false,
                   Arguments = string.Format("stop {0}", p.ProcessName)
               });
               //3. try
               Process.Start("cmd", string.Format("/c \"taskkill /f /pid {0}\"", ProcessID));

               //4. try: get exception: access denied
               p.Kill();


                //5. try get exception:Process must exit before requested information can be determined.
                TerminateProcess(p.Handle, (uint)p.ExitCode);
           }
           catch (Exception e)
           {
               MessageBox.Show(e.ToString());
           }
       }

I also tried it with SendMessage close Message

Thanks for Help!

This is the full class...
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices; //dlls
using System.Threading;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms; 

namespace KalLogin_Model
{
    public class KillProcess
    {
     
        [DllImport("user32.dll", SetLastError = true)]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);

        #region test


        [DllImport("kernal32.dll", CharSet = CharSet.Auto)]
        public static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);


        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool OpenProcessToken(IntPtr ProcessHandle,
            UInt32 DesiredAccess, out IntPtr TokenHandle);

        private static uint STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        private static uint STANDARD_RIGHTS_READ = 0x00020000;
        private static uint TOKEN_ASSIGN_PRIMARY = 0x0001;
        private static uint TOKEN_DUPLICATE = 0x0002;
        private static uint TOKEN_IMPERSONATE = 0x0004;
        private static uint TOKEN_QUERY = 0x0008;
        private static uint TOKEN_QUERY_SOURCE = 0x0010;
        private static uint TOKEN_ADJUST_PRIVILEGES = 0x0020;
        private static uint TOKEN_ADJUST_GROUPS = 0x0040;
        private static uint TOKEN_ADJUST_DEFAULT = 0x0080;
        private static uint TOKEN_ADJUST_SESSIONID = 0x0100;
        private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
        private static uint TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
            TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
            TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
            TOKEN_ADJUST_SESSIONID);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr GetCurrentProcess();

        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
            out LUID lpLuid);

        public const string SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege";

        public const string SE_AUDIT_NAME = "SeAuditPrivilege";

        public const string SE_BACKUP_NAME = "SeBackupPrivilege";

        public const string SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege";

        public const string SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege";

        public const string SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege";

        public const string SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege";

        public const string SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege";

        public const string SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege";

        public const string SE_DEBUG_NAME = "SeDebugPrivilege";

        public const string SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege";

        public const string SE_IMPERSONATE_NAME = "SeImpersonatePrivilege";

        public const string SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege";

        public const string SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege";

        public const string SE_INC_WORKING_SET_NAME = "SeIncreaseWorkingSetPrivilege";

        public const string SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege";

        public const string SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege";

        public const string SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege";

        public const string SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege";

        public const string SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege";

        public const string SE_RELABEL_NAME = "SeRelabelPrivilege";

        public const string SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege";

        public const string SE_RESTORE_NAME = "SeRestorePrivilege";

        public const string SE_SECURITY_NAME = "SeSecurityPrivilege";

        public const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";

        public const string SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege";

        public const string SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege";

        public const string SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege";

        public const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";

        public const string SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege";

        public const string SE_TCB_NAME = "SeTcbPrivilege";

        public const string SE_TIME_ZONE_NAME = "SeTimeZonePrivilege";

        public const string SE_TRUSTED_CREDMAN_ACCESS_NAME = "SeTrustedCredManAccessPrivilege";

        public const string SE_UNDOCK_NAME = "SeUndockPrivilege";

        public const string SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege";

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID
        {
            public UInt32 LowPart;
            public Int32 HighPart;
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CloseHandle(IntPtr hHandle);

        public const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001;
        public const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
        public const UInt32 SE_PRIVILEGE_REMOVED = 0x00000004;
        public const UInt32 SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000;

        [StructLayout(LayoutKind.Sequential)]
        public struct TOKEN_PRIVILEGES
        {
            public UInt32 PrivilegeCount;
            public LUID Luid;
            public UInt32 Attributes;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID_AND_ATTRIBUTES
        {
            public LUID Luid;
            public UInt32 Attributes;
        }

        // Use this signature if you do not want the previous state
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
           [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
           ref TOKEN_PRIVILEGES NewState,
           UInt32 Zero,
           IntPtr Null1,
           IntPtr Null2);

        #endregion test
        public KillProcess()
        {

        }
        public void KillKal(IntPtr _WindowPointer)
        {
            uint ProcessID;
            
            GetWindowThreadProcessId(_WindowPointer, out ProcessID);
            try
            {
                #region SeDebugPrivilege 
                IntPtr hToken;
                LUID luidSEDebugNameValue;
                TOKEN_PRIVILEGES tkpPrivileges;

                if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken))
                {
                    Console.WriteLine("OpenProcessToken() failed, error = {0} . SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
                    return;
                }
                else
                {
                    Console.WriteLine("OpenProcessToken() successfully");
                }

                if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, out luidSEDebugNameValue))
                {
                    Console.WriteLine("LookupPrivilegeValue() failed, error = {0} .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
                    CloseHandle(hToken);
                    return;
                }
                else
                {
                    Console.WriteLine("LookupPrivilegeValue() successfully");
                }

                tkpPrivileges.PrivilegeCount = 1;
                tkpPrivileges.Luid = luidSEDebugNameValue;
                tkpPrivileges.Attributes = SE_PRIVILEGE_ENABLED;

                if (!AdjustTokenPrivileges(hToken, false, ref tkpPrivileges, 0, IntPtr.Zero, IntPtr.Zero))
                {
                    Console.WriteLine("LookupPrivilegeValue() failed, error = {0} .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
                }
                else
                {
                    Console.WriteLine("SeDebugPrivilege is now available");
                }


                #regionend SeDebugPrivilege 
                Process p = Process.GetProcessById((int)ProcessID);


                //1. try
                Process.Start(new ProcessStartInfo
                {
                    FileName = "cmd.exe",
                    CreateNoWindow = true,
                    UseShellExecute = false,
                    Arguments = string.Format("/c taskkill /pid {0} /f", ProcessID)
                });
                //2.try
                Process.Start(new ProcessStartInfo
                {
                    FileName = "net.exe",
                    CreateNoWindow = true,
                    UseShellExecute = false,
                    Arguments = string.Format("stop {0}", p.ProcessName)
                });
                //3. try
                Process.Start("cmd", string.Format("/c \"taskkill /f /pid {0}\"", ProcessID));

                //4. try get exception: access denided
                p.Kill();

                //5. try get exception:Process must exit before requested information can be determined.
                TerminateProcess(p.Handle, (uint)p.ExitCode);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }
    }
}
Posted
Updated 2-May-15 0:51am
v2

1 solution

You absolutely don't need P/Invoke to kill a process. All you need is the class System.Diagnostics.Process:
https://msdn.microsoft.com/en-us/library/system.diagnostics.process%28v=vs.110%29.aspx[^].

As you can see, you can list all the processes, choose one (but how? doing it by name does not give you 100% guarantee that this is the process you are looking for) and kill it.

You need quite a different thing: permission. Try run your application "as administrator":
http://4sysops.com/archives/vista%E2%80%99s-uac-8-ways-how-to-elevate-an-application-to-run-it-with-administrator-rights[^],
http://www.sevenforums.com/tutorials/11841-run-administrator.html[^].

Or you can create and embed the application manifest which will demand UAC confirmation from the user right away: http://msdn.microsoft.com/en-us/library/bb756929.aspx[^].

But generally, killing some external process by an application is wrong thing, a kind of abuse. It's quite acceptable for some purposes, but cannot be a part of official software product, unless this is some system utility.

[EDIT]

If you cannot close something with Task Manager, chances are, you won't be able to do it in your code. In some cases, stronger utility can help, PsKill:
https://technet.microsoft.com/en-us/sysinternals/bb896683.aspx[^].

I'm not sure you can find its source code (probably not), but, in worst case, you can simply run PsKill using System.Diagnostics.Process.Start(exe, commandLine).

This is part of Sysinternals suite, a must-have to any software developer:
https://technet.microsoft.com/en-us/sysinternals/bb842062[^],
https://technet.microsoft.com/en-us/sysinternals/bb545027[^].

—SA
 
Share this answer
 
v2
Comments
Stefan Erler 1-May-15 11:58am    
First thank you for you Answer!

I don’t know that you mean with P/Invoke, I didn’t use it.
At first I just tried get the Process and then call the Process.Kill(), the other stuff is just from trying to find a way…

I find the process by find the window like this:
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public IntPtr KalGestartet ()
{
return FindWindow("#32770", "KalOnline");
}
and pass the IntPtr to the KillKal Method if it’s not IntPtr.Zero.
And as I say the PID I get is the same as I see in the Task Manager, if I kill this with Task Manager the game is closing. So it should be the same, right?

I Run VisualStudio "as administrator", so the Program also do.

I know you should not do it, but it’s necessary because the game is kind of buggy and you can only close it with Task Manager. That’s why I need this program…

Thank you again.
Sergey Alexandrovich Kryukov 1-May-15 12:06pm    
Yes, you used it [DLLImport] use is called P/Invoke, using Platform Invocation Services. You don't need it.
Please use the class I referenced.

If you cannot close something with Task Manager, chances are, you won't be able to do it in your code. I'll give you another link.

—SA
Sergey Alexandrovich Kryukov 1-May-15 12:10pm    
Please see the update to my answer, after [EDIT].
—SA
Stefan Erler 1-May-15 13:01pm    
Ah ok Thanks now i know what you mean... OK i try this only with System.Diagnostics.Process class. But i think that’s not the problem, but i will try it!

I can kill it with the Task Manager, that’s why i'm not sure why not with Process.Kill.
Thank you for the links i will try every think and let you know tomorrow
[Edit]
When i use psKill in Admin cmd i also get Access denied
Sergey Alexandrovich Kryukov 1-May-15 13:29pm    
The opposite should be correct, too: if you can kill a process with Task Manager, you can kill it with Process.Kill.

If it's so hard to kill the process, even with psKill "As Administrator", I don't know what can be done. I would not use this application at all.

—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900