Link to home
Start Free TrialLog in
Avatar of deshaw
deshawFlag for India

asked on

Identify the windows console type : Normal user or runas window

Hi,

Could anyone please tell me if there is a way to find out the type of console window from where user is running the application. Basically, I want to differentiate between normal console window (cmd.exe) and runas console window (runas /usr:username cmd.exe).

Is there any environment, registry or anything that indicate the current console window is runas console?

I am not sure what are the zones this question eligible for.

Thanks.
ASKER CERTIFIED SOLUTION
Avatar of drilus
drilus

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of deshaw

ASKER

I know using token but there are so many problems with that approach. The token can be generated only in System account but my actuall application is running as normal user. I can also make the token generated process in System using psexe.exe and createprocess but those changes required Admin privileges. So definately generating token is not going to work/not efficient solution for me.
Please let me know if there is any other example you have such as getting parent process(because normal window will have cmd parent and runas window will have runas process parent). I think it also possible with WMI using but I dont know how to do that. If you have any example then it would be great.
Thanks.
Avatar of deshaw

ASKER

I found the way to do this but it is not strong way. I could see for the parent windows title and look for the "running as" string. If Parent windows Title contain "running as" then that window is runas console else not. Could any one suggest strong solution on this.
Thanks.

[DllImport("KERNEL32.dll")]
  public static extern int CreateToolhelp32Snapshot(uint flags, uint processid);
 
  [DllImport("KERNEL32.DLL")]
  public static extern int CloseHandle(int handle);
 
  [DllImport("KERNEL32.DLL")]
  public static extern int Process32Next(int handle, ref ProcessEntry32 pe);
 
  [StructLayout(LayoutKind.Sequential)]
  public struct ProcessEntry32
  {
      public uint dwSize;
      public uint cntUsage;
      public uint th32ProcessID;
      public IntPtr th32DefaultHeapID;
      public uint th32ModuleID;
      public uint cntThreads;
      public uint th32ParentProcessID;
      public int pcPriClassBase;
      public uint dwFlags;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
      public string szExeFile;
  };
 
    public static void FindParentProcess()
    {
        int SnapShot = CreateToolhelp32Snapshot(0x00000002, 0); //2 = SNAPSHOT of all procs 
        try
        {
            ProcessEntry32 pe32 = new ProcessEntry32();
            pe32.dwSize = 296;
            int procid = System.Diagnostics.Process.GetCurrentProcess().Id;
            Console.WriteLine("Current Process: " + System.Diagnostics.Process.GetCurrentProcess().ProcessName.ToString());
            while (Process32Next(SnapShot, ref pe32) != 0)
            {
                string xname = pe32.szExeFile.ToString();
                if (procid == pe32.th32ProcessID)
                {
                    Process pProcess = System.Diagnostics.Process.GetProcessById(Convert.ToInt32(pe32.th32ParentProcessID));
                    Console.WriteLine("Parent Process: " + pProcess.ProcessName.ToString());
                    if (pProcess.MainWindowTitle.ToString().ToLower().IndexOf("running as") > -1)
                    {
                        Console.WriteLine("The parent window is runas console");
                    }
                    else
                    {
                        Console.WriteLine("The parent window isn't runas console");
                    }
                }
            }
 
        }
        catch (Exception ex)
        {
           Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod() + " failed! [Type:" + ex.GetType().ToString() + ", Msg:" + ex.Message + "]");
        }
        finally
        {
            CloseHandle(SnapShot);
        }        
    }

Open in new window

Avatar of drilus
drilus

I have done this through WMI only in Delphi. My code is not ported as I'm new to C#.

I used Win32_Process and called GetOwner.

I have found another article on WMI and GetOwner in C#. Hope it works for you.

http://objectmix.com/csharp/349324-c-win32_process-getowner-remote-machine.html
It looks like you can also you the "LookupAccountSid" API which might be easier than using WMI.
Avatar of deshaw

ASKER

"GetOwner" method will not work because  if user do run as himself then owner of proces will be that user only. In this case we cannot detect whether the window from he is executing process is normal command winow or runas window. See below I did runas my self in two windows but all SIDs and Owner are same so no one solution would work.
 I got this program from http://www.sellsbrothers.com/askthewonk/Secure/HowcanIgetthesecurityprin.htm. I am printing SIDs as well.

C:\>EnumProcessIdentities.exe
cmd running under XXX : S-1-5-21-40860068-2010480466-677931608-49469
cmd running under XXX : S-1-5-21-40860068-2010480466-677931608-49469
cmd running under XXX : S-1-5-21-40860068-2010480466-677931608-49469


Avatar of deshaw

ASKER

One thing we can do here is ignore the case where same user will do runas as him self then we can identify by comparing logged on user and runas user. If they are not same that means it is a runas window console. Is there any simple method to get logged on user? The runas user we can get using Environment.Username.
Thanks.
Avatar of deshaw

ASKER

Thanks for being there.
I found the solution. Putting for someone else as a reference.

RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon");
string loginUser = registryKey.GetValue("DefaultUserName").ToString().ToLower();
if (!loginUser.Equals(Environment.UserName.ToLower()))
{
Console.WriteLine("This is run as window");
return;
}
Avatar of deshaw

ASKER

Your solution was correct and hence accepting. Thanks.

using System.Security.Principal;
 
 
string a;
a = System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
 
MessageBox.Show(a.ToString());

Open in new window

Avatar of deshaw

ASKER

FYI, System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString() wil return the current environment user and it will be same as "Environment.UserDomainName + "\\" + Environment.Username" but logged on user will be different.
When I run the code as a different user using RunAs it reports the user account running the program. Not the system account.
Avatar of deshaw

ASKER

correct that what I am telling.