As promised, here's the code:
(Uses a RC4 algo from this forum, slightly optimized 4 performance)
Create a (cyphered) keyfile with your logon credentials first, then start the programs with changed user rights.
Code: Select all
Enumeration
#USER_PRIV_GUEST
#USER_PRIV_USER
#USER_PRIV_ADMIN
EndEnumeration
#NERR_SUCCESS = 0
Procedure RC4Cipher(Mem, memLen)
Dim S.w(255)
Dim K.w(255)
RC4Key.s = "YourKeyPhraseHere!"
i = 0 : t = 0 : x = 0 : temp.w = 0 : y.w = 0 : j = 1
keylen = Len(RC4Key)
For i = 0 To 255
S(i) = i
If (j > keylen) : j = 1 : EndIf
K(i) = Asc(Mid(RC4Key, j, 1))
j = j + 1
Next i
j = 0
For i = 0 To 255
j = (j + S(i) + K(i)) & 255
temp = S(i)
S(i) = S(j)
S(j) = temp
Next i
i = 0 : j = 0
For x = 0 To memLen-1
i = (i + 1) & 255
j = (j + S(i)) & 255
temp = S(i)
S(i) = S(j)
S(j) = temp
t = (S(i) + (S(j) & 255)) & 255
y = S(t)
PokeB(Mem+x, PeekB(Mem+x)!y)
Next x
ProcedureReturn Mem
EndProcedure
Procedure.s ShowError()
err = GetLastError_()
If (err)
*memBuffer = AllocateMemory (255)
FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, #Null, err, 0, *memBuffer, 255, #Null)
err$ = PeekS(*memBuffer)
FreeMemory(*memBuffer)
ProcedureReturn err$
EndIf
EndProcedure
Procedure.b IsAdmin()
Result.b = #False
ui3.USER_INFO_3
usr$ = Space(256)
nsize = Len(usr$)
GetUserName_(@usr$, @nsize)
w_usr$ = Space(512)
MultiByteToWideChar_(#CP_ACP, #MB_PRECOMPOSED, @usr$, -1, @w_usr$, Len(w_usr$))
If (NetUserGetInfo_(#Null, @w_usr$, 3, @lpBuf) = #NERR_SUCCESS)
CopyMemory(lpBuf, @ui3, SizeOf(ui3))
If (ui3\usri3_priv = #USER_PRIV_ADMIN) : Result = #True : EndIf
NetApiBufferFree_(lpBuf)
EndIf
ProcedureReturn Result
EndProcedure
Procedure ShowUsage()
dumstr1.s = "2A-RunAs.exe <progname>"+Chr(10)+"Start program with user credentials from keyfile."
dumstr2.s = "2A-RunAs.exe -k <logon> <passwd>"+Chr(10)+"Create keyfile for supplied user credentials."
MessageRequester("2A-RunAs Arguments", dumstr1+Chr(10)+Chr(10)+dumstr2, #PB_MessageRequester_Ok|#MB_ICONINFORMATION)
EndProcedure
Procedure WriteKeyFile(cpass.s, cname.s)
If (cname > "" And cpass > "")
If (CreateFile(1, "2A-RunAs.dat"))
*cypherBuffer = AllocateMemory(516)
strlen = Len(cname)
CopyMemory(@cname, *cypherBuffer, strlen)
RC4Cipher(*cypherBuffer, strlen)
WriteWord(1, strlen)
WriteData(1, *cypherBuffer, strlen)
strlen = Len(cpass)
CopyMemory(@cpass, *cypherBuffer, strlen)
RC4Cipher(*cypherBuffer, strlen)
WriteWord(1, strlen)
WriteData(1, *cypherBuffer, strlen)
CloseFile(1)
FreeMemory(*cypherBuffer)
MessageRequester("2A-RunAs Status", "Keyfile has been generated and saved.", #PB_MessageRequester_Ok|#MB_ICONINFORMATION)
Else
MessageRequester("I/O Problem", "Could not write keyfile!", #PB_MessageRequester_Ok|#MB_ICONERROR)
EndIf
Else
ShowUsage()
EndIf
EndProcedure
Procedure ReadKeyFile(*cname, *cpass)
If (ReadFile(1, "2A-RunAs.dat"))
*cypherBuffer = AllocateMemory(516)
strlen = ReadWord(1)
ReadData(1,*cypherBuffer, strlen)
RC4Cipher(*cypherBuffer, strlen)
CopyMemory(*cypherBuffer, *cname, strlen)
PokeB(*cname+strlen, 0)
strlen = ReadWord(1)
ReadData(1,*cypherBuffer, strlen)
RC4Cipher(*cypherBuffer, strlen)
CopyMemory(*cypherBuffer, *cpass, strlen)
PokeB(*cpass+strlen, 0)
CloseFile(1)
FreeMemory(*cypherBuffer)
Else
MessageRequester("I/O Problem", "Could not read keyfile!", #PB_MessageRequester_Ok|#MB_ICONERROR)
End
EndIf
EndProcedure
Procedure SpawnProcess(cname.s, cpass.s, mycomm.s)
w_cname.s = Space(512)
MultiByteToWideChar_(#CP_ACP, #MB_PRECOMPOSED, @cname, -1, @w_cname, Len(w_cname))
w_cpass.s = Space(512)
MultiByteToWideChar_(#CP_ACP, #MB_PRECOMPOSED, @cpass, -1, @w_cpass, Len(w_cpass))
cdom.s = Space(256)
nsize.w = Len(cdom)
GetComputerName_(@cdom, @nsize)
w_cdom.s = Space(512)
MultiByteToWideChar_(#CP_ACP, #MB_PRECOMPOSED, @cdom, -1, @w_cdom, Len(w_cdom))
w_ccomm.s = Space(512)
MultiByteToWideChar_(#CP_ACP, #MB_PRECOMPOSED, @mycomm, -1, @w_ccomm, Len(w_ccomm))
cpath.s = GetPathPart(mycomm)
w_cpath.s = Space(512)
MultiByteToWideChar_(#CP_ACP, #MB_PRECOMPOSED, @cpath, -1, @w_cpath, Len(w_cpath))
StartInfo.STARTUPINFO
StartInfo\cb = SizeOf(StartInfo)
StartInfo\dwFlags = 0
ProcessInfo.PROCESS_INFORMATION
flags = #CREATE_NEW_CONSOLE|#CREATE_NEW_PROCESS_GROUP|#CREATE_DEFAULT_ERROR_MODE
OpenLibrary(0, "advapi32.dll")
CallFunction(0, "CreateProcessWithLogonW", @w_cname, @w_cdom, @w_cpass, 0, @w_ccomm, #Null, flags, #Null, @w_cpath, @StartInfo, @ProcessInfo)
errstr.s = ShowError()
If (Len(errstr))
MessageRequester("2A-RunAs Error", errstr, #PB_MessageRequester_Ok|#MB_ICONERROR)
EndIf
CloseLibrary(0)
CloseHandle_(ProcessInfo\hThread)
CloseHandle_(ProcessInfo\hProcess)
EndProcedure
progexe.s = Trim(ProgramParameter())
Select LCase(progexe)
Case ""
ShowUsage()
Case "-k"
WriteKeyFile(ProgramParameter(), ProgramParameter()) ;3rd and 2nd parameter (parsed from right to left)
Default
If (GetExtensionPart(progexe) = "")
progexe = progexe + ".exe"
EndIf
If (IsAdmin() = #True)
If (RunProgram(progexe, "", GetPathPart(progexe)) = 0)
MessageRequester("2A-RunAs Error", "Even an admin could not start"+Chr(10)+Chr(10)+progexe , #PB_MessageRequester_Ok|#MB_ICONERROR)
EndIf
Else
cname.s = Space(256)
cpass.s = Space(256)
ReadKeyFile(@cname, @cpass)
SpawnProcess(cname, cpass, progexe)
EndIf
EndSelect
End