Windows 7 x64: low IL process msdn example does not work - c++

I want to create process with low integrity level from process with medium integrity level.
I found msdn example: Designing Applications to Run at a Low Integrity Level
But it does not work on my system. Process is created successfully, but message box
"Alpplication failed to initialized properly(0xC0000022 -- STATUS_ACCESS_DENIED) ..."
is appeared. Did anybody meet the same problem?

I ran into this too. The SID used in the example is incorrect. It should be "S-1-16-4096", not "S-1-16-1024".

I have upvoted #dyared's answer because it helped me find the complete answer. I should mention first that I am not specialized in this matter and this is only a summary of my findings.
It seems that the MSDN example does not work with the specified SID string because it specifies an integrity level that is too low. From the Chromium's source code, the S-1-16-1024 SID used in the example is between INTEGRITY_LEVEL_BELOW_LOW and INTEGRITY_LEVEL_UNTRUSTED:
const wchar_t* GetIntegrityLevelString(IntegrityLevel integrity_level) {
switch (integrity_level) {
case INTEGRITY_LEVEL_SYSTEM:
return L"S-1-16-16384";
case INTEGRITY_LEVEL_HIGH:
return L"S-1-16-12288";
case INTEGRITY_LEVEL_MEDIUM:
return L"S-1-16-8192";
case INTEGRITY_LEVEL_MEDIUM_LOW:
return L"S-1-16-6144";
case INTEGRITY_LEVEL_LOW:
return L"S-1-16-4096";
case INTEGRITY_LEVEL_BELOW_LOW:
return L"S-1-16-2048";
case INTEGRITY_LEVEL_UNTRUSTED:
return L"S-1-16-0";
case INTEGRITY_LEVEL_LAST:
return NULL;
}
Furthermore, it seems that the SID S-1-16-4096, suggested by #dyared, is also used when launching Internet Explorer in protected mode, as claimed in Creating a Process in Protected Mode on Windows Vista article on MSDN Blogs.
However, because it was enough to get the example working does not mean it is strict enough for every situation and choosing the appropriate integrity level must be made understanding its implications.

Related

C++ How do we make our application start on computer startup (and of course, after a user signed in)?

How do we make our application start on computer startup (and of course, after the user had signed in)?
And no, I am not making a virus.
Does registry editing sound like a good idea?
My OS is Windows 8.
However, I will try to make my application available for all possible Window OS.
The correct way to do this is simply to add a shortcut to your application's executable to the user's Startup folder. You do not need to (and should not) modify the registry.
Advanced users know how to do this manually already, but it may also be an option you want to provide as part of your installer and/or a configuration dialog in your application.
To do this from C++ code, you will need to do two things:
Retrieve the location of the current user's Startup folder.
This is accomplished by calling the SHGetKnownFolderPath function and specifying the KNOWNFOLDERID of the folder you're interested in. In this case, that would be FOLDERID_Startup.
Sample code:
std::wstring GetStartupFolderPath()
{
PWSTR pszPath;
HRESULT hr = SHGetKnownFolderPath(&FOLDERID_Startup,
0, // no special options required
NULL, // no access token required
&pszPath);
if (SUCCEEDED(hr))
{
// The function succeeded, so copy the returned path to a
// C++ string, free the memory allocated by the function,
// and return the path string.
std::wstring path(pszPath);
CoTaskMemFree(static_cast<LPVOID>(pszPath));
return path;
}
else
{
// The function failed, so handle the error.
// ...
// You might want to throw an exception, or just return an
// empty string here.
throw std::runtime_error("The SHGetKnownFolderPath function failed");
}
}
Note, however, that while SHGetKnownFolderPath is the recommended function to use, it is supported only by Windows Vista and later. If you need to support older versions of the operating system, you'll need to call it dynamically on newer versions where it is available, and otherwise fall back to calling the SHGetFolderPath function. This one takes a different type of identifier, a CSIDL value. The one you want is CSIDL_STARTUP.
Create a shortcut to your application's executable.
This is accomplished using a different set of Shell API functions. I won't bother writing up sample code here because it's all quite well explained on MSDN already: Shell Links
Now you just connect the dots: when you create the shortcut to your application's executable, specify the user's Startup folder as its destination path.
The only other thing to be aware of is that there are actually multiple Startup folders. Each user has one, which is the one we retrieved above using FOLDERID_Startup. About 99% of the time, that's the one you want. Putting a shortcut to your app there will cause it to be launched automatically when that user logs on.
However, there is also a global Startup folder that is shared by all users. This one is identified by FOLDERID_CommonStartup (or CSIDL_COMMON_STARTUP) and requires administrative privileges to add items to. That makes sense, of course, because whatever you put in there is going to launch automatically when any user logs on to the computer. Only administrators can affect global behavior like this. And chances are, your app doesn't need this anyway.
Start menu
Simplest solution is to place .lnk of .bat file into the Start Menu\On startup folder. This is easiest and not too sneaky against the user.
Registry:
Another solution is creating the key in the registry keys:
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run] //All users
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce] //All users once
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run] //Currend user
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce] //Current user once
This is not that transparent - so a bit more agressive against the user.
On windows you can put a shortcut to your application in the Startup folder, or you can implement it as a service.
And that "I am not making a virus" does make you sound guilty... Maybe it is a keylogger? ;)
There are a lot of ways, but they all depend on your OS. For windows take a look at the "Task Schedualer" under "Administrative tools" in the control panel.
Maybe something like this? Note, this code snippet is not written by me.
#include <windows.h>
void Reg() {
::HKEY Handle_Key = 0;
::DWORD Dispoition = 0;
::RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
0,
KEY_ALL_ACCESS,
&Handle_Key );
const unsigned char Path[ MAX_PATH ] = "C:\\Windows\\YourProgramName.exe";
::RegSetValueEx( Handle_Key, "My Directory", 0, 1, Path, sizeof( unsigned char ) );
};
What do you guys think?

Detecting modifier keys held down during startup in OS/X (or Windows)?

I've searched here and not found any question that really covers this.
I have a cross-platform Windows-OS/X application in which I'd like to be able to detect whether modifier keys like shift or control are being held down while the application starts up.
We'd like to do this to allow the application to start up without reading its preferences file, in case that somehow gets corrupted (we saw in testing a prefs bug, now fixed, that made the window size 0 by 0, for example).
We're using the excellent and comprehensive cross-platform C++ library named Juce. Unfortunately, Juce's master tells me that he believes this is impossible on OS/X at least since you only get keyboard events and there is no way to read the state of the keys unless something changes.
Is this true? Or is there some way around this? I'm almost sure I've used Mac programs that used this mechanism to bypass their preferences.
Or... stepping up one level... is there another solution to providing the functionality of "run the program but don't read the prefs file" other than "holding a key down while launching the program"? This is consumer software so we can't expect too much from the user.
The final solution will end up being a cross-platform one so hints on the Windows side will also be appreciated.
Thanks, and be well! I'll report in with progress on my end.
Works on Mac (Objective-C):
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSUInteger theFlags = [NSEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
if(theFlags & NSShiftKeyMask) NSLog(#"Shift down!");
if(theFlags & NSControlKeyMask) NSLog(#"Control down!");
if(theFlags & NSCommandKeyMask) NSLog(#"Command down!");
if(theFlags & NSAlternateKeyMask) NSLog(#"Alternate down!");
if(theFlags & NSFunctionKeyMask) NSLog(#"Function down!");
}
The first answer is fine, but in case for some reason you'd like to avoid Objective-C, you can use the Carbon framework:
UInt32 flags = GetCurrentKeyModifiers();
if ( (flags & optionKey) != 0)
{...}

Why using "SND_SYNC" in a "QueueUserWorkItem" bad?

Larry Osterman writes about a real error found in Microsoft's code, the offending code is
static DWORD WINAPI _PlayBeep(__in void* pv)
{
UNREFERENCED_PARAMETER(pv);
PlaySound(L".Default"NULL, SND_SYNC | SND_ALIAS);
return 0;
}
LRESULT WndProc(...)
{
:
:
case WM_KEYDOWN:
if (!_AcceptInputKeys(wParam, lParam))
{
QueueUserWorkItem(_PlayBeep, NULL, 0);
}
break;
}
and Larry asks:
Given the simplicity of the code
above, to get the answer right, it’s
not enough to say what’s wrong with
the code (the problem should be
blindingly obvious). You also need to
be able to explain why this is so bad
(in other words, what breaks when you
do this).
The best answer is terse in the comments is not enough,
David's VERY close to what's going
wrong - now think about the context of
the application.
Can someone please explain fully what's happening when this code runs?
Read the answer page, it's got a very detailed explanation
http://blogs.msdn.com/b/larryosterman/archive/2009/06/29/what-s-wrong-with-this-code-part-26-the-answer.aspx
Basically, don't use QueueUserWorkItem for long-running work items because this can cause thread exhaustion in your process, or even deadlock in a very hard to debug way if you wait for work items to complete on a (necessarily) finite-sized thread pool. Same goes for the .Net equivalent of this API ThreadPool.QueueUserWorkItem btw.
In this specific case, the workitem trigger ("press the down key") and the resulting thread workitem ("sound a sync beep") are very unbalanced, so that if user holds down or repeatedly hits his/her down key, the process will quickly hit fatal issues.

How to terminate a program when it crashes? (which should just fail a unit test instead of getting stuck forever)

Our unit tests fire off child processes, and sometimes these child processes crash. When this happens, a Windows Error Reporting dialog pops up, and the process stays alive until this is manually dismissed. This of course prevents the unit tests from ever terminating.
How can this be avoided?
Here's an example dialog in Win7 with the usual settings:
If I disable the AeDebug registry key, the JIT debugging option goes away:
If I disable checking for solutions (the only thing I seem to have control over via the control panel), it looks like this, but still appears and still stops the program from dying until the user presses something. WerAddExcludedApplication is documented to also have this effect.
A summary from the answers by jdehaan and Eric Brown, as well as this question (see also this question):
N.B. These solutions may affect other error reporting as well, e.g. failure to load a DLL or open a file.
Option 1: Disable globally
Works globally on the entire user account or machine, which can be both a benefit and a drawback.
Set [HKLM|HKCU]\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI to 1.
More info: WER settings.
Option 2: Disable for the application
Requires modification to the crashing program, described in documentation as best practice, unsuitable for a library function.
Call SetErrorMode: SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX); (or with SEM_FAILCRITICALERRORS). More info: Disabling the program crash dialog (explains the odd arrangement of calls).
Option 2a: Disable for a function:
Requires modification to the crashing program, requires Windows 7/2008 R2 (desktop apps only) or higher, described in documenation as preferred to SetErrorMode, suitable for a thread-safe library function.
Call and reset SetThreadErrorMode:
DWORD OldThreadErrorMode = 0;
SetThreadErrorMode(SEM_FAILCRITICALERRORS,& OldThreadErrorMode);
…
SetThreadErrorMode (z_OldThreadErrorMode, NULL);
More info: not much available?
Option 3: Specify a handler
Requires modification to the crashing program.
Use SetUnhandledExceptionFilter to set your own structured exception handler that simply exits, probably with reporting and possibly an attempt at clean-up.
Option 4: Catch as an exception
Requires modification to the crashing program. For .NET applications only.
Wrap all code into a global try/catch block. Specify the HandleProcessCorruptedStateExceptionsAttribute and possibly also the SecurityCriticalAttribute on the method catching the exceptions. More info: Handling corrupted state exceptions
Note: this might not catch crashes caused by the Managed Debugging Assistants; if so, these also need to be disabled in the application.
Option 5: Stop the reporting process
Works globally on the entire user account, but only for a controlled duration.
Kill the Windows Error Reporting process whenever it shows up:
var werKiller = new Thread(() =>
{
while (true)
{
foreach (var proc in Process.GetProcessesByName("WerFault"))
proc.Kill();
Thread.Sleep(3000);
}
});
werKiller.IsBackground = true;
werKiller.Start();
This is still not completely bullet-proof though, because a console application may crash via a different error message, apparently displayed by an internal function called NtRaiseHardError:
The only solution is to catch all exceptions at a very high level (for each thread) and terminate the application properly (or perform another action).
This is the only way to prevent the exception from escaping your app and activating WER.
Addition:
If the exception is something you do not except to happen you can use an AssertNoThrow(NUnit) or alike in another Unit Test framework to enclose the code firing the child processes. This way you would also get it into your Unit test report. This is in my opinion the cleanest possible solution I can think of.
Addition2:
As the comments below show, I was mistaken: you cannot always catch the asynchronous exceptions, it depends on what the environment allows. In .NET some exceptions are prevented from being caught, what makes my idea worthless in this case...
For .NET: There are complicated workarounds involving the use of AppDomains, leading to an unload of an AppDomain instead of a crash of the whole application. Too bad...
http://www.bluebytesoftware.com/blog/PermaLink,guid,223970c3-e1cc-4b09-9d61-99e8c5fae470.aspx
http://www.develop.com/media/pdfs/developments_archive/AppDomains.pdf
EDIT:
I finally got it. With .NET 4.0 You can add the HandleProcessCorruptedStateExceptions attribute from System.Runtime.ExceptionServices to the method containing the try/catch block. This really worked! Maybe not recommended but works.
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.ExceptionServices;
namespace ExceptionCatching
{
public class Test
{
public void StackOverflow()
{
StackOverflow();
}
public void CustomException()
{
throw new Exception();
}
public unsafe void AccessViolation()
{
byte b = *(byte*)(8762765876);
}
}
class Program
{
[HandleProcessCorruptedStateExceptions]
static void Main(string[] args)
{
Test test = new Test();
try {
//test.StackOverflow();
test.AccessViolation();
//test.CustomException();
}
catch
{
Console.WriteLine("Caught.");
}
Console.WriteLine("End of program");
}
}
}
Try setting
HKCU\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI
to 1. (You can also set the same key in HKLM, but you need admin privs to do that.)
This should prevent WER from showing any UI.

C++, OLE, Excel Automation: EAccessviolation at 00000800

I am writing an background service application that has to automatically read data from Excel 2003 files. But no matter what I try, the method OlePropertyGet() always results in an EAccessViolation error while trying to read from address "00000800".
The error always occurs at the last line of this code snippet, and seems independent of what parameter the method receives:
Variant excel, workbooks;
try
{
excel = GetActiveOleObject("Excel.Application");
}
catch(...)
{
excel = CreateOleObject("Excel.Application");
}
workbooks = excel.OlePropertyGet("Workbooks");
I've done some extensive google search on this, but found nothing that's even remotely helpful, only this forum thread where someone has the same issue, but doesn't give any information about the cause or solution (it's somewhat funny that at one point the author mentions he knows the cause, but doesn't say what it is!).
I'm open to any ideas as to what is causing this and how to solve this problem, but also alternative approaches to Excel OLE automation.
My guess is its a null pointer issue..
It looks like neither GetActiveOleObject() nor CreateOleObject() worked.
Try checkign the validity of 'excel' before calling OlePropertyGet.
And I guess you should make sure you have Excel installed.
You can use Visual Studio Tools for Office (see http://msdn.microsoft.com/en-us/library/d2tx7z6d.aspx).
Or you can use ATL support to instantiate the object model provided by office.
Your code may not be able to resolve "Excel.Application" successfully, leading to a null pointer. It uses a registry lookup with that string to identify Excel. It sounds like you're missing that registry entry.
I use such code to determine validity of created objects(in C++ Builder):
Varaint excel = GetActiveOleObject("Excel.Application");
TAutoDriver<IDispatch> dispatcher;
dispatcher.Bind(excel, false);
if (dispatcher.IsBound())
{
Variant workbooks = excel.OlePropertyGet("Workbooks");
}