diff --git a/src/MicroRunTI.sln b/src/MicroRunTI.sln
new file mode 100644
index 0000000..4ac0e1c
--- /dev/null
+++ b/src/MicroRunTI.sln
@@ -0,0 +1,43 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29503.13
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MicroRunTI", "MicroRunTI.vcxproj", "{86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Debug|ARM.ActiveCfg = Debug|ARM
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Debug|ARM.Build.0 = Debug|ARM
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Debug|ARM64.Build.0 = Debug|ARM64
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Debug|Win32.Build.0 = Debug|Win32
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Debug|x64.ActiveCfg = Debug|x64
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Debug|x64.Build.0 = Debug|x64
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Release|ARM.ActiveCfg = Release|ARM
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Release|ARM.Build.0 = Release|ARM
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Release|ARM64.ActiveCfg = Release|ARM64
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Release|ARM64.Build.0 = Release|ARM64
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Release|Win32.ActiveCfg = Release|Win32
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Release|Win32.Build.0 = Release|Win32
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Release|x64.ActiveCfg = Release|x64
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A4A596A2-ACEC-4863-9FCC-71E4E70A0324}
+ EndGlobalSection
+EndGlobal
diff --git a/src/MicroRunTI.vcxproj b/src/MicroRunTI.vcxproj
new file mode 100644
index 0000000..c7615e1
--- /dev/null
+++ b/src/MicroRunTI.vcxproj
@@ -0,0 +1,358 @@
+
+
+
+
+ Debug
+ ARM
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ ARM
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {86EA4DBB-0602-4761-BF35-B3A18EEF2A4A}
+ Win32Proj
+ MicroRunTI
+ MicroRunTI
+
+
+
+ Application
+ true
+ Unicode
+ v142
+
+
+ Application
+ true
+ Unicode
+ v142
+
+
+ Application
+ true
+ Unicode
+ v142
+
+
+ Application
+ true
+ Unicode
+ v142
+
+
+ Application
+ false
+ true
+ Unicode
+ v142
+
+
+ Application
+ false
+ true
+ Unicode
+ v142
+
+
+ Application
+ false
+ true
+ Unicode
+ v142
+
+
+ Application
+ false
+ true
+ Unicode
+ v142
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ false
+
+
+ true
+ false
+
+
+ true
+ false
+
+
+ true
+ false
+
+
+ false
+ true
+
+
+ false
+ true
+
+
+ false
+ true
+
+
+ false
+ true
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ false
+ CompileAsC
+ Default
+
+
+ Windows
+ true
+ main
+ false
+ true
+ userenv.lib;shlwapi.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ false
+ CompileAsC
+ Default
+
+
+ Windows
+ true
+ main
+ false
+ true
+ userenv.lib;shlwapi.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ false
+ CompileAsC
+ Default
+
+
+ Windows
+ true
+ main
+ false
+ true
+ userenv.lib;shlwapi.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ false
+ CompileAsC
+ Default
+
+
+ Windows
+ true
+ main
+ false
+ true
+ userenv.lib;shlwapi.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreaded
+ false
+ CompileAsC
+ Speed
+
+
+ Windows
+ false
+ true
+ true
+ main
+ false
+ true
+ userenv.lib;shlwapi.lib;%(AdditionalDependencies)
+ false
+ RequireAdministrator
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreaded
+ false
+ CompileAsC
+ Speed
+
+
+ Windows
+ false
+ true
+ true
+ main
+ true
+ true
+ userenv.lib;shlwapi.lib;%(AdditionalDependencies)
+ false
+ RequireAdministrator
+
+
+
+
+ Level3
+
+
+ Disabled
+ true
+ false
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreaded
+ false
+ CompileAsC
+ Neither
+
+
+ Windows
+ false
+ true
+ true
+ main
+ true
+ true
+ userenv.lib;shlwapi.lib;%(AdditionalDependencies)
+ false
+ RequireAdministrator
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreaded
+ false
+ CompileAsC
+ Speed
+ true
+
+
+ Windows
+ false
+ true
+ true
+ main
+ false
+ true
+ userenv.lib;shlwapi.lib;%(AdditionalDependencies)
+ false
+ RequireAdministrator
+ true
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..398fc3a
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,189 @@
+#include
+#include
+#include
+
+INT GetProcessIdOfName(WCHAR* name)
+{
+ INT pid = -1;
+
+ PROCESSENTRY32 entry;
+ entry.dwSize = sizeof(PROCESSENTRY32);
+
+ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
+
+ if (Process32First(snapshot, &entry) == TRUE)
+ {
+ while (Process32Next(snapshot, &entry) == TRUE)
+ {
+ if (lstrcmpi(entry.szExeFile, name) == 0)
+ {
+ pid = entry.th32ProcessID;
+ }
+ }
+ }
+
+ CloseHandle(snapshot);
+ return pid;
+}
+
+WCHAR* GetExecutablePath()
+{
+ WCHAR* buf[MAX_PATH];
+
+ GetModuleFileName(NULL, buf, MAX_PATH);
+
+ return buf;
+}
+
+BOOL StartTiService()
+{
+ BOOL wasDisabled = FALSE;
+ QUERY_SERVICE_CONFIG SvcConfig = {0};
+ SC_HANDLE hSvcMgr = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+
+ SC_HANDLE hSvc = OpenService(hSvcMgr, L"TrustedInstaller",
+ SERVICE_CHANGE_CONFIG | SERVICE_QUERY_CONFIG | SERVICE_START);
+
+ UINT dummy = 0;
+ DWORD dwBytesNeeded;
+ LPQUERY_SERVICE_CONFIG lpqscBuf = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LPTR, 4096);
+ if (!QueryServiceConfig(hSvc, lpqscBuf, 4096, &dwBytesNeeded))
+ return FALSE;
+
+ wasDisabled = (SvcConfig.dwStartType == SERVICE_DISABLED);
+
+
+ if (wasDisabled)
+ {
+ if (!ChangeServiceConfig(hSvc, SERVICE_NO_CHANGE,
+ SERVICE_DEMAND_START, SERVICE_NO_CHANGE,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL))
+ return FALSE;
+ }
+
+ StartService(hSvc, 0, NULL);
+
+ if (wasDisabled)
+ {
+ if (!ChangeServiceConfig(hSvc, SERVICE_NO_CHANGE,
+ SERVICE_DISABLED, SERVICE_NO_CHANGE,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL))
+ return FALSE;
+ }
+
+ LocalFree(lpqscBuf);
+ CloseServiceHandle(hSvc);
+ CloseServiceHandle(hSvcMgr);
+
+ return TRUE;
+}
+
+void RunWithToken(WCHAR* procName, WCHAR* path, WCHAR* cmdLine, BOOL forceTokenUseActiveSessionID)
+{
+ WCHAR* ultrabuf = path;
+
+ INT procId = GetProcessIdOfName(procName);
+ if (procId == -1)
+ return;
+
+ HANDLE currProc = GetCurrentProcess();
+ HANDLE hToken;
+
+ if (!OpenProcessToken(currProc, TOKEN_ALL_ACCESS, &hToken))
+ return;
+
+ LUID luid;
+ if (!LookupPrivilegeValue(NULL, L"SeDebugPrivilege", &luid))
+ return;
+
+ TOKEN_PRIVILEGES tp;
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if (!(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL) & (GetLastError() == 0)))
+ return;
+
+ CloseHandle(hToken);
+
+ HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procId);
+ if (!hProc)
+ return;
+
+ HANDLE hTokenToCopyFrom;
+ if (!OpenProcessToken(hProc, TOKEN_DUPLICATE | TOKEN_QUERY, &hTokenToCopyFrom))
+ return;
+
+ HANDLE nhToken;
+ if (!DuplicateTokenEx(hTokenToCopyFrom, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &nhToken))
+ return;
+
+ if (forceTokenUseActiveSessionID)
+ {
+ DWORD SID = WTSGetActiveConsoleSessionId();
+ if (!SetTokenInformation(nhToken, TokenSessionId, &SID, sizeof(DWORD)))
+ return;
+ }
+
+ LPVOID lpEnvironment;
+ if (!CreateEnvironmentBlock(&lpEnvironment, hTokenToCopyFrom, TRUE))
+ return;
+
+ STARTUPINFO si = {0};
+ si.cb = sizeof(STARTUPINFO);
+ si.lpDesktop = L"winsta0\\default";
+ PROCESS_INFORMATION pi = {0};
+
+ if (!CreateProcessWithTokenW(nhToken, LOGON_WITH_PROFILE, path, cmdLine,
+ (NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT),
+ lpEnvironment, NULL, &si, &pi))
+ {
+ if (!CreateProcessAsUser(nhToken, path, cmdLine, NULL, NULL, FALSE,
+ (NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT),
+ lpEnvironment, NULL, &si, &pi))
+ return;
+ }
+
+ CloseHandle(hTokenToCopyFrom);
+ CloseHandle(nhToken);
+ CloseHandle(si.hStdError);
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ DestroyEnvironmentBlock(lpEnvironment);
+}
+
+void main()
+{
+ int argc;
+ WCHAR **argv = CommandLineToArgvW(GetCommandLine(), &argc);
+
+ if(argv)
+ {
+ if(argc >= 0)
+ {
+ BOOL SwitchTI = lstrcmpi(argv[0], L"/STI") == 0;
+ if (!SwitchTI)
+ {
+ if (StartTiService())
+ {
+ WCHAR* path = GetExecutablePath();
+ WCHAR uwu[MAX_PATH];
+ lstrcpy(uwu, path);
+
+ RunWithToken(L"winlogon.exe", uwu, L"/STI", FALSE);
+ }
+ }
+ else
+ {
+ RunWithToken(L"TrustedInstaller.exe", L"cmd.exe", L"", TRUE);
+ }
+
+ }
+
+ LocalFree(argv);
+ }
+
+ ExitProcess(0);
+}
\ No newline at end of file