got error 1314 when doing SetTokenInformation - winapi

#include <windows.h>
#include <stdio.h>
#include <Userenv.h>
#include <Wtsapi32.h>
int main() {
DWORD err;
err=GetLastError();
printf( "err001:%d\n",err);
HANDLE hTokenThis = NULL;
HANDLE hTokenDup = NULL;
HANDLE hThisProcess = GetCurrentProcess();
OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);
err=GetLastError();
printf( "err002:%d\n",err);
DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
err=GetLastError();
printf( "err003:%d\n",err);
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
WTSQueryUserToken(dwSessionId, hTokenDup);
//DWORD dwSessionId = 1;
SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD));
err=GetLastError();
printf( "err004:%d\n",err);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "WinSta0\\Default";
LPVOID pEnv = NULL;
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
err=GetLastError();
printf( "err005:%d\n",err);
CreateProcessAsUser(
hTokenDup,
NULL,
(char *)"notepad",
NULL,
NULL,
FALSE,
dwCreationFlag,
pEnv,
NULL,
&si,
&pi);
printf("here we go\n");
err=GetLastError();
printf( "err006:%d\n",err);
return 0;
}
Compile:
gcc -o session.exe session.c c://Windows/System32/kernel32.dll c://Window
s/System32/wtsapi32.dll -lUserenv
Running Result:
session.exe
err001:126
err002:126
err003:126
err004:1314
err005:203
here we go
err006:87
gcc version 4.5.2 (GCC) from mingw.
btw, just ignore the error 126.
My question is :
Why got error 1314?
I want to start a program in the interactive desktop from service by using CreateProcessAsUser without knowing the logon user and password.

Error 1314 is "A required privilege is not held by the client".
From the WTSQueryUserToken() docs (http://msdn.microsoft.com/en-us/library/aa383840.aspx):
To call this function successfully, the calling application must be running within the context of the LocalSystem account and have the SE_TCB_NAME privilege
Also your call to WTSQueryUserToken() should look like:
WTSQueryUserToken(dwSessionId, &hTokenDup);
And you'll need appropriate privileges for SetTokenInformation() enabled as well.
Bottom line is that you're trying to do something that Windows reserves for highly privileged processes, so you'll need to make sure your process is configured to run appropriately (maybe as a service that talks to a regular non-privileged process for user interaction).

Related

Why isn't this code executing a hello world executable

Why isn't this code running my hello world c executable
#include <windows.h>
#include <string>
int main()
{
// path for hello world compiled program
std::string app_path = "C:\\Users\\test\\Desktop\\a.exe";
BOOL inherit_handles = true;
PROCESS_INFORMATION pi;
STARTUPINFO si;
CreateProcessA(app_path.c_str(),
NULL,
NULL,
NULL,
inherit_handles,
CREATE_NEW_CONSOLE|CREATE_PROTECTED_PROCESS|DETACHED_PROCESS,
0,
NULL,
&si,
&pi);
return 0;
}
I am clueless to why not output is given, even when I use > out.txt, although I do see some cpu usage spikes in process hacker
I also tried to use calc.exe instead of a.exe but this also didn't help
STARTUPINFO needs to be initialized:
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
Don't inherit handles unless you need to.
Don't use CREATE_PROTECTED_PROCESS.
Don't use DETACHED_PROCESS unless you want to hide stdout.
Check the return value of CreateProcess!

GetThreadSelectorEntry throwing ERROR_NOT_SUPPORTED for x64 App

I trying to write a very simple app to debug a Win32 64-bit app. My end goal is to get the TIB and PEB of the remote thread, but for some reason the way I did this on 32-bit app is not working for 64-bit ones (Aside from looking at Esp vs Rsp and checking SegFs vs SegGs). The code I'm trying to use is here:
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
int main(int argc, char *argv[]){
LDT_ENTRY entry;
DWORD pid;
HANDLE hThread;
HANDLE hSnapshot;
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL;
if(argc < 2){
printf("Usage: %s PID\n", argv[0]);
exit(1);
}
pid = atoi(argv[1]);
THREADENTRY32 te32;
te32.dwSize = sizeof(te32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
while(Thread32Next(hSnapshot, &te32)){
if(pid == te32.th32OwnerProcessID){
hThread = OpenThread(THREAD_ALL_ACCESS, 0, te32.th32ThreadID);
if(!hThread)
exit(1);
if(SuspendThread(hThread) == (DWORD) -1)
exit(1);
if(!GetThreadContext(hThread, &context))
exit(1);
printf("Rsp = 0x%x\n", context.Rsp);
if(!GetThreadSelectorEntry(hThread, context.SegGs, &entry)){
LPSTR buff = NULL;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buff, 0, NULL);
printf("Error: %s\n", buff); //ERROR_NOT_SUPPORTED 50 0x32 The request is not supported.
LocalFree(buff);
exit(1);
}
}
}
CloseHandle(hSnapshot);
return 0;
}
but it's always throwing an error at "GetThreadSelectorEntry". The error code that's thrown is ERROR_NOT_SUPPORTED: The request is not supported.
I am not able to understand why it's not supported. Does anyone know why?
[EDIT]
Okay GetThreadSelectorEntry is not available to x86_64 processes, does anyone know how I can get the TIB/PEB addresses of a remote process?

Visual C - Win32 APP - how to use system call with system() without opening a command prompt window?

I am new to VC++
I build a simple Win32 Application via default templet.
when i run it it shows a normal window with a menubar.
I added a system call that does a curl operation in InitInstance function:
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
//EDITED THIS WILL CREATE A FILE.HTML
system("curl www.google.co.in > file.html");
return TRUE;
}
all works fine.
But the problem is when ever i call system it opens in console window.
I want it to be a hidden process that does not shows that command prompt window..
help me with this.
The system function always shows a console window. If you want a hidden console window, you need to call CreateProcess directly. You can then ask for a DETACHED_PROCESS which runs without a console. Note that CreateProcess does not wait for the process to exit, so you will need to perform the wait yourself.
I put code in separate function, with url and filename as parameters.
#include <tchar.h>
#include <windows.h>
BOOL DownloadWithoutConsole(TCHAR* pszURI, TCHAR* pszFileName)
{
//here we will calculate our command line length in bytes
DWORD dwLen = (lstrlen(pszURI) + lstrlen(pszFileName) + 20)*sizeof(TCHAR);
//memory allocation for the command line
TCHAR* pszCmdLine = (TCHAR*)HeapAlloc(GetProcessHeap(), 0, dwLen);
ZeroMemory(pszCmdLine, dwLen);
//making command line
_stprintf_s(pszCmdLine,dwLen/sizeof(TCHAR), TEXT("cmd /c curl %s > %s"), pszURI, pszFileName);
//preparing arguments for CreateProcess
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
//creating new process
BOOL bResult = CreateProcess(NULL, pszCmdLine, NULL, NULL, FALSE, CREATE_NO_WINDOW,
NULL, NULL, &si, &pi);
if(bResult)
{
//waiting for process termination
WaitForSingleObject(pi.hProcess, INFINITE);
//cleanup
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
//freeing memory
HeapFree(GetProcessHeap(), 0, pszCmdLine);
return(bResult);
}
int __cdecl _tmain(void)
{
DownloadWithoutConsole(TEXT("stackoverflow.com"), TEXT("test.txt"));
return(0);
}
Set nCmdShow to SW_HIDE(0) (ShowWindow). This way u will run it without he cmd prompt

How to execute another program from a Visual C++ Application

I am doing a software project with Visual Studio Professional 2010.
In the form that I am making, I would like to put a link to open Microsoft Paint. How can I execute another application (MSPaint) from mine?
Call ShellExecute() passing open as the verb and mspaint.exe as the filename.
ShellExecute(
MainFormWindowHandle,
"open",
"mspaint.exe",
NULL,
NULL,
SW_SHOW
);
My contribution a complete example:
Go to Visual Studio, create a new Win32 C++ Project (not console), and paste the following code in the source file will appear:
// Win32Project1.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "Win32Project1.h"
#include "shellapi.h"
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
ShellExecuteA ( NULL, "open",
"your.exe",
"your params",
"working dir", SW_SHOW);
return TRUE;
}
Myself I contribute the following code which can be used in Windows
#include <iostream>
#include<Windows.h>
using namespace std;
int main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD dwProcessId = 0;
DWORD dwThreadId = 0;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
bool bCreateProcess = NULL;
bCreateProcess = CreateProcess((Location of Paint path),0,0,0,0,0,0,0,&si, pi);
//Instead of 0 NULL can also be used
if (bCreateProcess == FALSE)
cout << " Creation Process Failed ";
else
cout << " Process Executedd ";
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}

gcc/g++ gives me error "CreateProcess: No such file or directory"

-edit- it seems to be a problem with path and not being able to find its bin/ folder. Even though the g++ is in that bin directory.
I am trying to launch g++ on windows in my app but i get the error below. How do i fix it? side note i can do g++ dummy.cpp in the prompt with no problem.
args -o file.exe -x c++ -
stdout
: CreateProcess: No such file or directory
-edit- my code is...
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
#include <ios>
#include <iostream>
#include <fstream>
#include <sstream>
#include <exception>
#include <string>
#include <deque>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
string gcc_bin="E:/dev/external/MinGW/bin/g++.exe";
string gcc_folder="E:/dev/external/MinGW/bin/";
int launch_gcc(ostringstream&o);
int main(){
ostringstream osz;
osz << "#include <cstdio>" << endl << "int main(){ printf(\"hello\"); } return 4; }";
{
launch_gcc(osz);
}
return 0;
}
void ErrorExit(PTSTR);
int launch_gcc(ostringstream&o)
{
char buf2[4096];
char buf[4096];
ExpandEnvironmentStrings("%PATH%", buf, 4095);
OutputDebugString(buf);
sprintf(buf2, "PATH=%s;%s;\0\0", gcc_folder.c_str(), buf);
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInformation;
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
HANDLE g_hChildStd_ERR_Rd = NULL;
HANDLE g_hChildStd_ERR_Wr = NULL;
HANDLE g_hInputFile = NULL;
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
ErrorExit(TEXT("StdoutRd CreatePipe"));
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stdout SetHandleInformation"));
if ( ! CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr, 0) )
ErrorExit(TEXT("StderrRd CreatePipe"));
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stderr SetHandleInformation"));
if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
ErrorExit(TEXT("Stdin CreatePipe"));
if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stdin SetHandleInformation"));
ZeroMemory( &startupInfo, sizeof(STARTUPINFO) );
startupInfo.cb = sizeof(STARTUPINFOA);
startupInfo.hStdError = g_hChildStd_OUT_Wr;
startupInfo.hStdOutput = g_hChildStd_ERR_Wr;
startupInfo.hStdInput = g_hChildStd_IN_Rd;
startupInfo.dwFlags |= STARTF_USESTDHANDLES;
ZeroMemory( &processInformation, sizeof(PROCESS_INFORMATION) );
bool bSuccess = CreateProcess(
gcc_bin.c_str(),
" -o \"c:/dev/src/git/myprj/theout.exe\" -x c++ -",
0,
0,
1,
NORMAL_PRIORITY_CLASS,
0,//buf2,
0,//gcc_folder.c_str(),
&startupInfo,
&processInformation
);
if ( ! bSuccess )
ErrorExit(TEXT("CreateProcess"));
else
{
// Close handles to the child process and its primary thread.
// Some applications might keep these handles to monitor the status
// of the child process, for example.
CloseHandle(processInformation.hProcess);
CloseHandle(processInformation.hThread);
}
{
DWORD dwRead, dwWritten;
BOOL bSuccess = FALSE;
auto sz=o.str();
bSuccess = WriteFile(g_hChildStd_IN_Wr, sz.c_str(), sz.size(), &dwWritten, NULL);
//if ( ! bSuccess ) break;
if ( ! CloseHandle(g_hChildStd_IN_Wr) )
ErrorExit(TEXT("StdInWr CloseHandle"));
}
#define BUFSIZE 1024*4
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
chBuf[0]=0;
if (!CloseHandle(g_hChildStd_OUT_Wr))
ErrorExit(TEXT("StdOutWr CloseHandle"));
for (;;)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
if( ! bSuccess || dwRead == 0 ) break;
bSuccess = WriteFile(hParentStdOut, chBuf,
dwRead, &dwWritten, NULL);
chBuf[dwWritten]=0;
if (! bSuccess ){
printf("%s", chBuf);
break;
}
}
}
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdErr = GetStdHandle(STD_ERROR_HANDLE);
if (!CloseHandle(g_hChildStd_ERR_Wr))
ErrorExit(TEXT("StdOutWr CloseHandle"));
for (;;)
{
bSuccess = ReadFile( g_hChildStd_ERR_Rd, chBuf, BUFSIZE, &dwRead, NULL);
if( ! bSuccess || dwRead == 0 ) break;
bSuccess = WriteFile(hParentStdErr, chBuf,
dwRead, &dwWritten, NULL);
chBuf[dwWritten]=0;
if (! bSuccess ){
printf("%s", chBuf);
break;
}
}
auto a=1;
}
return 0;
}
void ErrorExit(PTSTR lpszFunction)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(1);
}
Try to add the path to g++ compiler into PATH environment variable:
TCHAR *path;
TCHAR *newpath;
DWORD dwSize = GetEnvironmentVariable(TEXT("PATH"), NULL, 0);
path = new TCHAR[dwSize];
GetEnvironmentVariable(TEXT("PATH"), path, dwSize);
dwSize += MAX_PATH;
newpath = new TCHAR[dwSize];
_tcscpy_s(newpath, dwSize, TEXT("E:\\dev\\external\\MinGW\\bin;"));
_tcscat_s(newpath, dwSize, path);
SetEnvironmentVariable(TEXT("PATH"), newpath);
delete[] path;
delete[] newpath;
At this point environment block of your process contains PATH variable that includes the path to g++ compiler. Note: this does not affect user's environment.
You can use char instead of TCHAR, and strcpy, strcat. This way will work in both cases: with Unicode enabled and without Unicode support.
It is very likely that double instances of the compiler exist on the system.
If so, try the following for experiment so that the one under current path could run for the source compile:
D:\cmn_dev\mingw64\bin>.\g++ HelloGcc.cpp -o Hello.exe
Hope this could be of help. Regards.
Which GCC for windows are you using? MinGW, Cygwin, something else?
Have you tried logging in and out again as indicated in this question? CreateProcess: No such file or directory
On Windows, GCC needs its bin directory to be on the PATH, it won't look in the directory of its own binary. Try putting something like
wchar_t buf[4096];
ExpandEnvironmentStringsW(L"%PATH%", buf, 4095);
OutputDebugStringW(buf);
into your program before the call to g++ to make sure the directory is on the path for your program's environment (if you're not running your program in a debugger, use wprintf instead)
Watch out if you tried to install GCC on a path with a space character in it, both MinGW and Cygwin warn against this.
I have had the same issue and got it resolved after adding the "C:\MinGW\msys\1.0\bin" to the PATH system variable.
Use Sysinternals ProcessMonitor (http://technet.microsoft.com/en-us/sysinternals/bb896645) to trace the system calls that are issued by your code (CreateFile, CreateProcess, Registry queries) along with their success and return value. This also shows all different attempts to find the executable which is not found by your code - most times this makes it obvious, which mistake (e.g. typo, escaping, white-space in path etc.) caused the code not to find the g++ executable.
Use Sysinternals ProcessMonitor like BertNase said. What you do is find the .exe name that is doing the compiling under the Process Name column, like gcc.exe. Then look in the Result column and anything that is not a SUCCESS check it out. I think what you are looking for is a NAME NOT FOUND result though.
I had this same problem and did what I just mentioned above, I found that gcc.exe was getting a NAME NOT FOUND result for cc1obj.exe. So I made an educated guess and went into my MinGW folder under \libexec\gcc\mingw32\4.5.0 (the version number might not be the same for you) and made a copy of cc1.exe then renamed it as cc1obj.exe. And wala, that fixed the problem.
You probably aren't missing the same file but it sounds like following this process will fix it.
I got a problem yesterday with a program not being able to handle a path like this:
<some stuff>;%ProgramFiles%\path\to\bins;<some other stuff>
I replaced it with :
<some stuff>;C:\Program Files\path\to\bins;<some other stuff>
and it worked. You might want to check this out
The error you get say that the function of gcc "CreateProcess" try to access some file and can't find it.
Obviously if gcc catch the error, it's running, so nothing wrong with your PATH.
However gcc can't find a program or a library needed for the compilation. It's a strange error that I know on mingw32. My best advice will be to re-installed mingw32. You may have change some file use by the program.
I have also faced the problem while setting up Atom. But later I found out that my MinGW was copied from Codeblocks folder. Reinstalling the packages through official MinGW installer and adding the directory path (for my case C:\MinGW\bin) in
Advance System Settings>Environment Variables > Path
solved the problem for me
Old thread but who knows it can help.
For me, I replaced the complete path with the location of the compiler.
So:
set path="< folder that contains the compiler>"
I think that maybe the current path has some elements in it that are not parsed properly by the compiler (no double quotes, no spaces, etc)

Resources