Heh, well pretty much what could you expect from MSDN Microsoft code, isn't it?
Try this instead.
Code: Select allBOOL Exec(
_In_ LPWSTR lpszCommandLine,
_In_ LPWSTR lpszDirectory,
_In_ DWORD dwSubAuthority,
_In_ BOOL WaitForExit
)
{
BOOL cond = FALSE;
BOOL bResult = FALSE;
HANDLE hToken = NULL, hNewToken = NULL;
SID_IDENTIFIER_AUTHORITY MLAuthority = SECURITY_MANDATORY_LABEL_AUTHORITY;
PSID pIntegritySid = NULL;
TOKEN_MANDATORY_LABEL tml;
PROCESS_INFORMATION pi;
STARTUPINFO si;
do {
bResult = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY |
TOKEN_ADJUST_DEFAULT | TOKEN_ASSIGN_PRIMARY, &hToken);
if (bResult != TRUE) {
break;
}
bResult = DuplicateTokenEx(hToken, 0, NULL, SecurityImpersonation,
TokenPrimary, &hNewToken);
if (bResult != TRUE) {
break;
}
bResult = AllocateAndInitializeSid(&MLAuthority, 1, dwSubAuthority,
0, 0, 0, 0, 0, 0, 0, &pIntegritySid);
if (bResult != TRUE) {
break;
}
RtlSecureZeroMemory(&tml, sizeof(tml));
tml.Label.Attributes = SE_GROUP_INTEGRITY;
tml.Label.Sid = pIntegritySid;
bResult = SetTokenInformation(hNewToken, TokenIntegrityLevel, &tml,
(sizeof(tml) + GetLengthSid(pIntegritySid)));
if (bResult != TRUE) {
break;
}
RtlSecureZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
bResult = CreateProcessAsUser(hNewToken, NULL, lpszCommandLine, NULL, NULL,
FALSE, 0, NULL, lpszDirectory, &si, &pi);
if (bResult) {
if (WaitForExit) {
WaitForSingleObject(pi.hProcess, INFINITE);
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
} while (cond);
if (hToken) {
CloseHandle(hToken);
}
if (hNewToken) {
CloseHandle(hNewToken);
}
if (pIntegritySid) {
FreeSid(pIntegritySid);
}
return bResult;
}
call it as shown, note string params must point to
writable buffers.
Code: Select all WCHAR szParams[MAX_PATH + 1] = L"C:\\windows\\system32\\notepad.exe";
WCHAR szDir[MAX_PATH + 1] = L"c:\\windows";
Exec((LPWSTR)szParams, (LPWSTR)szDir, SECURITY_MANDATORY_LOW_RID, FALSE);
123.png (49.97 KiB) Viewed 470 times