How to run Exe at a user level from a higher level

I would like the process to always run at the user level. Or when it is launched by the installer (custom, not msi), which runs both at the administrator level and when the user logs in. Looking back, I'm not sure if this is possible.

+4
source share
5 answers

Everyone is always looking to get around in a different way. Anyhoo, this project code should help.

+1
source

Assuming you know which user you want to run and get your password, CreateProcessWithLogonW Function will do this.

+1
source

There are many hacker ways to do this (use taskcheduler, inject into explorer.exe, etc.)

The only way to get the correct user (the one that started your program before raising UAC (it may not be the same user as the session owner / "login" / "session owner")) is that the installer starts two instances of itself , one โ€œexternalโ€ instance that is not promoted, it basically just starts another instance, starting with ShellExecute [Ex] using the verb runas. When the time comes to start the mid / low process, the elevated instance using some form of IPC tells the external instance to start a new process.

This is a pain in the neck for implementation, I would only recommend not having a launch flag at the end of your installer.

+1
source

The easiest way is to have 2 processes. One of them is a regular user, and he starts the advanced / administration process. The administration process can then use IPC to ask the normal user process to do something.

If you do not have a normal user process, Raymond Chen documents:

Moving from an unselected process to an elevated process is easy. You can start the process with elevation to pass the verb runas to ShellExecute or ShellExecuteEx.

Going the other way is harder. Firstly, it is very difficult to execute a marker in order to properly remove nature. And, among other things, even if you can do this, it is not, because the user cannot have a different user.

The solution here is to return to Explorer and ask Explorer to run the program for you. Since Explorer works as the original non-powered user, the program (in this case, a web browser) will work like Bob. This is also important if the handler for the file you want to open is launched as an internal extension of the process, and not as a separate process, because in this case the attempt to unelevate will be meaningless, because the first place in the process of creating a new process. (And if the file handler tries to contact an existing unrestored copy of itself, everything may fail due to UIPI.)

Well, I know that Small programs should not have motivation, but I could not help myself. Enough jabber. Let write the code. (Remember that in "Small Programs" there is little or no error checking because they roll.)

#define STRICT #include <windows.h> #include <shldisp.h> #include <shlobj.h> #include <exdisp.h> #include <atlbase.h> #include <stdlib.h> void FindDesktopFolderView(REFIID riid, void **ppv) { CComPtr<IShellWindows> spShellWindows; spShellWindows.CoCreateInstance(CLSID_ShellWindows); CComVariant vtLoc(CSIDL_DESKTOP); CComVariant vtEmpty; long lhwnd; CComPtr<IDispatch> spdisp; spShellWindows->FindWindowSW( &vtLoc, &vtEmpty, SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &spdisp); CComPtr<IShellBrowser> spBrowser; CComQIPtr<IServiceProvider>(spdisp)-> QueryService(SID_STopLevelBrowser, IID_PPV_ARGS(&spBrowser)); CComPtr<IShellView> spView; spBrowser->QueryActiveShellView(&spView); spView->QueryInterface(riid, ppv); } void GetDesktopAutomationObject(REFIID riid, void **ppv) { CComPtr<IShellView> spsv; FindDesktopFolderView(IID_PPV_ARGS(&spsv)); CComPtr<IDispatch> spdispView; spsv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&spdispView)); spdispView->QueryInterface(riid, ppv); } 

The GetDesktopAutomationObject function finds the view of the desktop folder, and then queries the send object for the view. Then we return this dispatch object in the form requested by the caller. This send object is ShellFolderView, and for the C ++ interface it is IShellFolderViewDual, so most callres will request this interface, but if you are a masochist, you can skip the dual interface and talk directly to IDispatch.

 void ShellExecuteFromExplorer( PCWSTR pszFile, PCWSTR pszParameters = nullptr, PCWSTR pszDirectory = nullptr, PCWSTR pszOperation = nullptr, int nShowCmd = SW_SHOWNORMAL) { CComPtr<IShellFolderViewDual> spFolderView; GetDesktopAutomationObject(IID_PPV_ARGS(&spFolderView)); CComPtr<IDispatch> spdispShell; spFolderView->get_Application(&spdispShell); CComQIPtr<IShellDispatch2>(spdispShell) ->ShellExecute(CComBSTR(pszFile), CComVariant(pszParameters ? pszParameters : L""), CComVariant(pszDirectory ? pszDirectory : L""), CComVariant(pszOperation ? pszOperation : L""), CComVariant(nShowCmd)); } 

The ShellExecuteFromExplorer function begins by retrieving the desktop folder automation object. We use the desktop not because it is especially significant, but because we know that it will always be there.

As in the desktop folder view, the ShellFolderView object is not interesting to us. This is interesting for us, because the object is in the process that hosts the desktop (which is the main Explorer process). From the ShellFolderView, we request the Application property so that we can move on to the main Shell.Application object, which has the IShellDispatch interface (and its extensions IShellDispatch2 via IShellDispatch6) as its C ++ interfaces. And it is this method of IShellDispatch2 :: ShellExecute that we really need.

And we call IShellDispatch2 :: ShellExecute with the appropriate parameters. Note that the parameters of IShellDispatch2 :: ShellExecute are in a different order from the parameters to ShellExecute!

Well, let it be inside a small program.

 int __cdecl wmain(int argc, wchar_t **argv) { if (argc < 2) return 0; CCoInitialize init; ShellExecuteFromExplorer( argv[1], argc >= 3 ? argv[2] : L"", argc >= 4 ? argv[3] : L"", argc >= 5 ? argv[4] : L"", argc >= 6 ? _wtoi(argv[5]) : SW_SHOWNORMAL); return 0; } 

A program takes a mandatory command line argument that must be executed, whether it be a program or a document or a URL. Optional parameters are the parameters of the thing being done, the current directory to use, the operation being performed, and the way the window opens.

Open an elevated command prompt, and then run this program in various ways.

  • scratch http://www.msn.com/
    Open the unleaded web page in a custom web browser.
  • scratch cmd.exe "C: \ Users" "3
    Open a command prompt without change in C: \ Users, maximized.
  • scratch C: \ Path \ To \ Image.bmp "" "" change
    Change the bitmap in the unleaded image editor.
+1
source

similar to what Bill said, you can also use the CreateProcessAsUser () API to do this.

  • First use LogonUser () and get the access token for the user who needs to complete the process. Here, if the user belongs to the group of administrators (then you will receive a separation token if you pass LOGON_FLAG as LOGON32_LOGON_INTERACTIVE). Therefore, if you need an increased administrator token, pass the flag as LOGON32_LOGON_BATCH.
  • Using the token obtained above, you can call CreateProcessAsUser (), passing the command line and parameters.
0
source

All Articles