How to get system privilege - c#

I have a C# program that require SeSystemEnvironmentPrivilege to access the UEFI NVRAM.
I found a really long code, that uses Win32 API to get the privilege, but is there a .NET version to get it? In process class, or somewhere else?

If it is really necessary you can use the AdjustTokenPrivileges function.
Something like this:
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
You can get more info here:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa446619%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/aa375728(v=vs.85).aspx#privilege_constants

Related

Any reliable method that provides info about file redirection?

All the C# methods to access a file, e.g. FileInfo(), FileVersionInfo.GetVersionInfo(), FileStream(), etc can be misleading when run in WOW64 mode, i.e. the app is compiled as x86 but run on x64. You can have totally different files with the same name in \Windows\System32\ and \Windows\SysWOW64\, or have no file in \Windows\System32\, but when your code tries to access it in \Windows\System32\ then the file copy in \Windows\SysWOW64\ will be used with no indication that the redirection took place. Is there any method that would indicate such redirection, for any reason (WOW64 or other)? The brute force is to check for WOW64 execution and check the path for \Windows\System32\
but I would prefer the system handle it for me. Also there could be some other special cases.
You can disable file system redirection with Wow64DisableWow64FsRedirection
For example =>
bool bWow64 = false;
IsWow64Process(Process.GetCurrentProcess().Handle, out bWow64);
if (bWow64)
{
IntPtr OldValue = IntPtr.Zero;
bool bRet = Wow64DisableWow64FsRedirection(out OldValue);
}
With :
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool IsWow64Process(IntPtr hProcess, out bool Wow64Process);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool Wow64DisableWow64FsRedirection(out IntPtr OldValue);

View a type within a dll to use in a function used by that Dll

I've got a COM interface dll, and some documentation about the methods within the dll, however from what I can tell with the documentation, the method requires a custom struct be passed in as an out parameter, but the documentation doesn't provide any information about the struct itself.
The function I'm calling from c# is as follows:
API
UINT OpenRequest ([out] PHCOMS phComs,
[in] PCHAR pEndPointName,
[in] UINT fBlockingMode,
[in] UINT fOpenMode,
[in] UINT fDataType,
[in] HINSTANCE hInstance)
My issue is that PHCOMS is a type described in the documentation as:
The address of a variable of type HCOMS. The communications handle to be used by the other API calls, is returned in this variable. If an error occurs this will be NULL.
This function starts by allocating a comms handle (hComs), if
available, to the application. This handle is used for creating a new
connection object. The parameters of this function are assigned to the
relevant members. For this object, a pointer instance is created for
connecting to the interface, as well as the PC Headerpched
interface
I've had a look at various dll inspectors and other posts on SO but can't find anything that helps with how I can actually create a struct that's going to be validly accepted by the function.
I am also unsure if I'm misinterpreting what I need to do - is it possible that I just need to pass a standard handle through to the function or something similar? Is the PHComs type a non custom type that I just can't find info on in google?
Right now I'm attempting to call the function through c# using the DLLImport attribute over an extern function which seems to be ok except that the handle I get back is never valid, which I'm blindly (I've never done something like this before) trying to do like this
[DllImport("MyDll.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern uint OpenRequest(ref SafeProcessHandle hComs, string host, uint fBlockingMode, uint fOpenMode, uint fDataType, SafeProcessHandle hInstance);
static void Main(string[] args)
{
IntPtr h = new IntPtr();
var handle = new SafeProcessHandle(h, true);
uint test = 0;
test = OpenRequest(ref handle, "Host01", 0, 0, 0, handle);
handle.Dispose();
}
Any assistance on how to setup my test properly would help too since I'm blindly guessing about the IntPtr and use of whatever Safe*Handle Classes.
Edit
I've changed it to be like this following Hans' comment:
As you said, there are other methods that use that handle, for example the ConnectRequest added below.
Any suggestion as to what the HInstance parameter refers to? I doubt it's correct that I'm just passing the same handle/IntPtr in again?
The documentation says:
hInstance HINSTANCE Windows programs must pass their instance handle.
[DllImport("MyDll.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern uint OpenRequest(out IntPtr hComs, string host, uint fBlockingMode, uint fOpenMode, uint fDataType, IntPtr hInstance);
[DllImport("MyDll.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern uint ConnectRequest(IntPtr hComs, uint cTimeOut);
static void Main(string[] args)
{
IntPtr hComs = new IntPtr();
uint test_OpenRequest = 0;
test_OpenRequest = OpenRequest(out hComs, "Host01", 0, 0, 0, hComs);
}
Edit 2
[DllImport("WinCom32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern uint OpenRequest(out IntPtr hComs, string host, uint fBlockingMode, uint fOpenMode, uint fDataType, IntPtr hInstance);
static void Main(string[] args)
{
IntPtr hComs = new IntPtr();
uint test_Request = 0;
string hostName = ConfigurationManager.AppSettings["HostName"];
IntPtr hInstance = Marshal.GetHINSTANCE(Assembly.GetEntryAssembly().GetModules()[0]);
test_Request = OpenRequest(out hComs, hostName, 0, 0, 1, hInstance);
Console.WriteLine("Request response value: " + test_Request.ToString());
}
There's a test application I can run that shows that this is supposed to work because it's able to connect to the host, so I've got to be doing something wrong.

c# Calling method using P/Invoke causing AccessViolation Exception

I interfacing with a device using P/Invoke. But I've come stuck at calling the following method:
BOOL __stdcall voGetFirmwareVersion(IN OUT LPTSTR lpVersion, IN OUT DWORD *dwSize);
In my wrapper I have called the method like so:
[DllImport(DLL_LOCATION, CharSet = CharSet.Ansi)]
private static extern Boolean voGetFirmwareVersion(string s, uint d);
I have attempted to change the inputs to Out/Ref and tried adding the [In,Out] attributes but I am constantly getting a AccessViolation Exception. Can anyone point me in the right direction? I've been at this for a couple of hours now and google hasn't been able to put me straight
dwSize is passed by address, so it should be a ref parameter.
BOOL return type must be marshaled if any nonzero value may come as a true value
I am not sure if you really want to use Ansi charset. Try Auto or Unicode.
LPStr and StdCall are not a must, they are the default settings.
So try this:
[DllImport(DLL_LOCATION, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool voGetFirmwareVersion([MarshalAs(UnmanagedType.LPTStr)] string s, ref uint d);

copy a file using UNC and impersonation

I want to use FileInfo and CopyTo to move some files across a network. I have to move the files to a share on a server that has to be accessed using a particular user account. How do I do this - do I have to impersonate that user and then do the copy?
I am using .net 4 and was wondering what the best way accomplish the impersonation is. I've read about using pInvoke and using advapi32.dll, but I was hoping someone could recommend a better way to do this.
Thanks for any thoughts.
EDIT
Thanks for the replies. This is not a service, it is a console app, but it will be run from multiple machines. Is there any advantage to using a mapping over using impersonation, or vice-versa? what is the recommended approach?
I have also considered using a batch file to create the mappings and do the copy, but I wasn't sure how easily it would be to accomplish because the folders to copy from will not always be the same - it will always be within one directory, but the subdirectory name changes.
You don't need impersonation all you have to do is to establish a file mapping using the credentials you want to use. You can accomplish this using either net use as a shell out command or WNetAddConnection2
If you are running as a service, you may need to impersonate. This is not the complete code but the gist of it:
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern unsafe int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref string lpBuffer, int nSize, IntPtr* arguments);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle);
IntPtr token = IntPtr.Zero;
bool isSuccess = LogonUser(username, domain, password, impersonationType, Logon32ProviderDefault, ref token);
if (!isSuccess)
{
RaiseLastError();
}
WindowsIdentity newIdentity = new WindowsIdentity(token);
WindowsImpersonationContext impersonatedUser = newIdentity.Impersonate();
Save the token and then later
CloseHandle(token);

Need to use win32 api to copy files in c# - how do I do this?

I'm trying to copy some files around, and occasionally the lengths of the names exceeds the length that the System.IO.File.Copy method can accept (260 chars according to the exception that is getting thrown)
According to the research I've done, I should be able to use the win32 api's file methods in conjunction with \?\ prepended to paths to get a 32,000 character limit, but I'm not sure witch methods I need to import.
Can someone help me with this? I'm looking for something like (obviously a different function, but you get the idea):
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern SafeFileHandle CreateFileW(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll",
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CopyFile(
[MarshalAs(UnmanagedType.LPWStr)] string lpExistingFileName,
[MarshalAs(UnmanagedType.LPWStr)] string lpNewFileName,
[MarshalAs(UnmanagedType.Bool)] bool bFailIfExists);
http://www.pinvoke.net/default.aspx/kernel32/CopyFile.html
Try using CopyFile.
For PInvoke syntax, you can check pinvoke.net.

Categories