BSOne.SFC/eCrmHE/EXE_eCrmHeService/SeCrmHeMain.pas

517 lines
16 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

unit SeCrmHeMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs;
const
SERVICE_ACCEPT_SESSIONCHANGE = $00000020;
SERVICE_CONTROL_SESSIONCHANGE = $00000014;
WTS_SESSION_LOGON = 5;
WTS_SESSION_LOGOFF = 6;
WTS_SESSION_LOCK = 7;
WTS_SESSION_UNLOCK = 8;
SHTDN_REASON_MAJOR_SOFTWARE = $00030000;
SHTDN_REASON_MINOR_OTHER = $00000000;
type
TSvcCrmHe = class(TService)
procedure ServicePause(Sender: TService; var Paused: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
procedure ServiceExecute(Sender: TService);
private
{ Private declarations }
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
function CreateEnvironmentBlock(var lpEnvironment: Pointer;
hToken: THandle;
bInherit: BOOL): BOOL; stdcall; external 'userenv.dll';
var
SvcCrmHe: TSvcCrmHe;
implementation
uses
//{$IFDEF DEBUG}
// Tocsg.Trace,
//{$ENDIF}
Tocsg.Trace,Tocsg.Win32, GlobalDefine, Tocsg.Path, Tocsg.Process, Tocsg.Safe, Tocsg.WTS,
Tocsg.Kernel32, Tocsg.Shell, Tocsg.Service, Winapi.WinSvc, Tocsg.Registry;
{$R *.dfm}
function _ExecuteAppAsUser(dwFollowPID: DWORD; sPath, sParam: String; dwVisible: DWORD): TProcessInformation;
type
TOKEN_MANDATORY_LABEL = record
Label_: SID_AND_ATTRIBUTES;
end;
const
DEFWINSTATION = 'WinSta0';
DEFDESKTOP = 'Default';
WINLOGON = 'Winlogon';
SCREENSAVER = 'Screen-Saver';
WHITESPACE = ' '{SPACE}+chr(9){TAB}+chr(10){LF};
DOMUSERSEP = '\';
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
dwCreateFlag: DWORD;
pEnvBlock: Pointer;
hProc, hToken, hNewToken: THandle;
TIL: TOKEN_MANDATORY_LABEL;
begin
ZeroMemory(@Result, SizeOf(Result));
ZeroMemory(@ProcessInfo, SizeOf(TProcessInformation));
ZeroMemory(@TIL, SizeOf(TIL));
hToken := 0;
hNewToken := 0;
if dwFollowPID = 0 then
begin
{$IFDEF DEBUG} TTgTrace.T('_ExecuteAppAsUser() .. FollowPID is null..'); {$ENDIF}
exit;
end;
// hProc := OpenProcess(PROCESS_ALL_ACCESS, false, dwFollowPID);
hProc := OpenProcess(MAXIMUM_ALLOWED, false, dwFollowPID);
if hProc = 0 then
begin
{$IFDEF DEBUG} TTgTrace.T('_ExecuteAppAsUser() .. OpenProcess() - Fail... Error=%d', [GetLastError]); {$ENDIF}
exit;
end;
try
// if OpenProcessToken(hProc, TOKEN_ASSIGN_PRIMARY or TOKEN_DUPLICATE, hToken) then
if OpenProcessToken(hProc, MAXIMUM_ALLOWED, hToken) then
begin
// if DuplicateTokenEx(hToken, TOKEN_ASSIGN_PRIMARY or TOKEN_ALL_ACCESS, nil,
if DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil,
SecurityImpersonation, TokenPrimary, hNewToken) then
begin
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.lpDesktop := DEFWINSTATION + '\' + DEFDESKTOP;
// StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USEPOSITION; // SW_HIDE<44><45><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ű<EFBFBD><C5B0><EFBFBD><EFBFBD> <20>̰<EFBFBD> Ȱ<><C8B0>ȭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD> (<28>뼺 ã<><C3A3>) 15_0521 sunk
StartupInfo.wShowWindow := dwVisible;
dwCreateFlag := NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE;
pEnvBlock := nil;
CreateEnvironmentBlock(pEnvBlock, hNewToken, true);
if pEnvBlock <> nil then
dwCreateFlag := dwCreateFlag or CREATE_UNICODE_ENVIRONMENT;
if CreateProcessAsUserW(hNewToken,
nil,//PWideChar(ExtractFileName(sPath)),
PWideChar(Format('"%s" %s', [sPath, sParam])),
nil,
nil,
false,
dwCreateFlag,
pEnvBlock,
nil,//PWideChar(ExtractFilePath(sPath)),
StartupInfo,
ProcessInfo) then
begin
Result := ProcessInfo;
end else
{$IFDEF DEBUG} TTgTrace.T('_ExecuteAppAsUser() .. CreateProcessAsUserW() - Fail... Error=%d', [GetLastError]); {$ENDIF}
end;
end else
{$IFDEF DEBUG} TTgTrace.T('_ExecuteAppAsUser() .. OpenProcessToken() - Fail... Error=%d', [GetLastError]); {$ENDIF}
finally
if hToken <> 0 then
CLoseHandle(hToken);
if hNewToken <> 0 then
CloseHandle(hNewToken);
if hProc <> 0 then
CloseHandle(hProc);
end;
end;
procedure ForceRebootSystem;
var
hToken: THandle;
tkp: TTokenPrivileges;
ReturnLength: DWORD;
begin
// 1. <20><><EFBFBD><EFBFBD> <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20><>ū<EFBFBD><C5AB> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>غ<EFBFBD>
if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
// 2. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(SeShutdownPrivilege)<29><> LUID ȹ<><C8B9>
LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
// 3. <20><>ū<EFBFBD><C5AB> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
AdjustTokenPrivileges(hToken, False, tkp, 0, nil, ReturnLength);
CloseHandle(hToken);
end;
// 4. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (EWX_FORCE <20>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD>α׷<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
ExitWindowsEx(EWX_REBOOT or EWX_FORCE, SHTDN_REASON_MAJOR_SOFTWARE or SHTDN_REASON_MINOR_OTHER);
end;
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
SvcCrmHe.Controller(CtrlCode);
end;
function TSvcCrmHe.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure TSvcCrmHe.ServiceExecute(Sender: TService);
var
sAPath,
sWPath,
sCurDir,
sRunParam,
sRunAsModule: String;
bExeBeforeSleep: Boolean;
dwExeTerm: DWORD;
// bFailExeTrust: Boolean;
nFailExeTrustCnt: Integer;
processInfo: TProcessInformation;
function ExecuteAgent(dwOwnerPid: DWORD): THandle;//Boolean;
var
t: Integer;
sTrustedInstExe: String;
begin
Result := 0;
if FileExists(sWPath) then
begin
dwExeTerm := GetTickCount;
if not DeleteFile(sWPath) then
begin
SetFileAttributes(PChar(sWPath), FILE_ATTRIBUTE_NORMAL);
DeleteFile(sWPath);
end;
exit;
end else
if dwExeTerm <> 0 then
begin
if (GetTickCount - dwExeTerm) < 10000 then
exit;
dwExeTerm := 0;
end;
if bExeBeforeSleep then
begin
bExeBeforeSleep := false;
Sleep(3000);
end;
sTrustedInstExe := sCurDir + DIR_CONF + EXE_TRUST;
// cmd â<><C3A2> <20><><EFBFBD>Դ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> HEC<45><43><EFBFBD><EFBFBD> <20><><EFBFBD>ſ<EFBFBD>û<EFBFBD><C3BB> 23_1208 13:56:30 kku
if (nFailExeTrustCnt < 3) and FileExists(sTrustedInstExe) then
begin
// -U:[ Option ] Create a process with specified user option.
// Available options:
// T TrustedInstaller
// S System
// C Current User
// E Current User (Elevated)
// P Current Process
// D Current Process (Drop right)
// PS: This is a mandatory parameter.
// -UseCurrentConsole - X <20>ƹ<EFBFBD><C6B9><EFBFBD><EFBFBD><EFBFBD> cmd<6D><64> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ѿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
Inc(nFailExeTrustCnt);
sRunParam := UpperCase(GetRegValueAsString(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services\SvcCrmHe', 'EA'));
if sRunParam = 'ADMIN' then
sRunParam := Format('-U:E -P:E "%s"', [sAPath])
else if sRunParam = 'USER' then
sRunParam := Format('-U:C -P:E "%s"', [sAPath])
else
sRunParam := Format('-U:T -P:E "%s"', [sAPath]);
ExecutePath_hide(sTrustedInstExe, sRunParam);
// ExecutePath_hide(sTrustedInstExe, Format('-U:E -P:E "%s"', [sAPath]));
// t := 0;
// while t < 10 do
// begin
// if MutexExists(MUTEX_AGENT) then
// begin
// nFailExeTrustCnt := 0;
// Result := true;
// exit;
// end;
//
// Sleep(500);
// Inc(t);
// end;
// if _ExecuteAppAsUser(dwOwnerPid, sTrustedInstExe, Format('-U:T -P:E "%s"', [sAPath]), SW_HIDE).dwProcessId <> 0 then
// begin
// {$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s .. Success!!', [sRunAsModule]); {$ENDIF}
// Sleep(2000);
// end else begin
// {$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s .. Fail..... _ExecuteAppAsUser()', [sRunAsModule]); {$ENDIF}
// bFailExeTrust := true;
// end;
end else
begin
// if _ExecuteAppAsUser(dwOwnerPid, sAPath, Format('/wlid %d', [dwOwnerPid]), SW_HIDE).dwProcessId <> 0 then
// if ExecuteApp(sAPath, '', SW_SHOWNORMAL).dwProcessId <> 0 then // Ʈ<><C6AE><EFBFBD><EFBFBD> <20>ȳ<EFBFBD><C8B3><EFBFBD>
processInfo:= _ExecuteAppAsUser(dwOwnerPid, sAPath, '', SW_SHOWNORMAL);
if processInfo.dwProcessId <> 0 then
begin
// t := 0;
// while t < 10 do
// begin
// if MutexExists(MUTEX_AGENT) then
// begin
// nFailExeTrustCnt := 0;
// Result := true;
// exit;
// end;
//
// Sleep(500);
// Inc(t);
// end;
Result:= processInfo.hProcess;
CloseHandle(processInfo.hThread);
// if Result then
// begin
// {$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s .. Success!!', [sRunAsModule]); {$ENDIF}
// Sleep(2000);
// end;
end else begin
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s .. Fail..... _ExecuteAppAsUser()', [sRunAsModule]); {$ENDIF}
end;
end;
// t := 0;
// while t < 6 do
// begin
// if MutexExists(MUTEX_AGENT) then
// begin
// Result := true;
// exit;
// end;
//
// Sleep(500);
// Inc(t);
// end;
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutex .. check timeover .. '); {$ENDIF}
end;
var
PIDList: TProcessIdList;
WTSInfo: TTgWTSSessionInfomation;
dwWinLogonSsId,
dwExecuteAsPid: DWORD;
sAccount: String;
i: Integer;
Mtx: TTgMutex;
processHandle: THandle;
WaitHandles: array[0..1] of THandle;
WaitResult: DWORD;
begin
// bFailExeTrust := false;
nFailExeTrustCnt := 0;
dwExeTerm := 0;
bExeBeforeSleep := false;
Mtx := nil;
if not MutexExists(MUTEX_SERVICE) then
begin
Mtx := TTgMutex.Create(MUTEX_SERVICE);
if Mtx.MutexState <> msCreateOk then
exit;
end;
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. Begin'); {$ENDIF}
Guard(WTSInfo, TTgWTSSessionInfomation.Create);
Guard(PIDList, TProcessIdList.Create);
sCurDir := GetRunExePathDir;
sAPath := sCurDir + EXE_HE;
if not FileExists(sAPath) then
begin
sCurDir := GetProgramFilesDir + DIR_HE;
sAPath := sCurDir + EXE_HE;
end;
{$IFDEF DEBUG} TTgTrace.T('APath="%s"', [sAPath]); {$ENDIF}
sWPath := ExtractFilePath(sAPath) + BYE_ENDSESSION;
try
while not Terminated do
begin
if MutexExists(MUTEX_KILL) then
begin
{$IFDEF DEBUG} TTgTrace.T('Found .. MUTEX_KILL!!'); {$ENDIF}
ServiceThread.Terminate;
exit;
end;
if FileExists(sAPath) then
begin
if not MutexExists(MUTEX_AGENT) then
begin
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext'); {$ENDIF}
// if LoadWinlogonPidInfo then
// continue;
// explorer.exe <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>α׷<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> Ʈ<><C6AE><EFBFBD>̰<EFBFBD> <20>Ȼ<EFBFBD><C8BB>ܼ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>Ȱ<EFBFBD> Ȯ<><C8AE><EFBFBD>ϰ<EFBFBD> <20>õ<EFBFBD><C3B5>Ѵ<EFBFBD> 22_0502 14:21:30 kku
if GetProcessPidByName('explorer.exe') <> 0 then
begin
dwExecuteAsPid := 0;
case GetProcessPidsByName('winlogon.exe', PIDList) of
0 : sRunAsModule := 'explorer.exe';
1 : sRunAsModule := 'winlogon.exe';
else
begin
sRunAsModule := 'winlogon.exe';
WTSInfo.UpdateSessionInfo;
for i := 0 to PIDList.Count - 1 do
if ProcessIdToSessionId(PIDList[i], dwWinLogonSsId) then
begin
sAccount := WTSInfo.GetUserNameBySsid(dwWinLogonSsId);
if (sAccount <> '') and
(UpperCase(sAccount) <> 'SYSTEM') and
(UpperCase(sAccount) <> 'CONSOLE') then
begin
dwExecuteAsPid := PIDList[i];
break;
end;
end;
end;
end;
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s', [sRunAsModule]); {$ENDIF}
// dwExecuteAsPid := GetProcessPidByName('TrustedInstaller.exe');
if dwExecuteAsPid = 0 then
dwExecuteAsPid := GetProcessPidByName(sRunAsModule);
{$IFDEF DEBUG} TTgTrace.T(Format('ServiceExecute() .. dwExecuteAsPid : %d',[DWORD(dwExecuteAsPid)])); {$ENDIF}
if dwExecuteAsPid <> 0 then
processHandle:= ExecuteAgent(dwExecuteAsPid);
end else
bExeBeforeSleep := true;
end
else
begin
var pid: DWORD;
pid:= GetProcessPidByName(sAPath);
if pid <> 0 then
begin
var hProc := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if hProc = 0 then
begin
{$IFDEF DEBUG} TTgTrace.T('ExecuteAgent() .. OpenProcess() - Fail... Error=%d, sAPath:%s', [GetLastError, sAPath]); {$ENDIF}
end
else
begin
{$IFDEF DEBUG} TTgTrace.T('ExecuteAgent() .. OpenProcess() - ok... '); {$ENDIF}
processHandle:= hProc;
end;
end;
end;
end;
{$IFDEF DEBUG} TTgTrace.T(Format('ServiceExecute() .. processHandle : %p',[Pointer(processHandle)])); {$ENDIF}
if processHandle <> 0 then
begin
WaitHandles[0] := ServiceThread.Handle;
WaitHandles[1] := processHandle;
WaitResult := WaitForMultipleObjects(2, @WaitHandles, False, INFINITE);
if WaitResult = WAIT_OBJECT_0 then
begin
//WaitForSingleObject(ServiceThread.Handle, 500);
// Sleep(500);
ServiceThread.ProcessRequests(false);
end
else if WaitResult = WAIT_OBJECT_0 + 1 then
begin
var ExitCode: DWORD;
if GetExitCodeProcess(processHandle, ExitCode) then
begin
if ExitCode = 0 then
begin
// [<5B><>Ȳ A] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ų<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
end
else if ExitCode = 1 then
begin
// [<5B><>Ȳ B] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(1)<29>߰ų<DFB0> ũ<><C5A9><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڵ<EFBFBD>)<29><> <20><><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20>ý<EFBFBD><C3BD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!
ForceRebootSystem;
end;
Sleep(3000);
{$IFDEF DEBUG} TTgTrace.T(Format('ServiceExecute() .. Terminate Process ExitCode : %x',[ExitCode])); {$ENDIF}
CloseHandle(ProcessInfo.hProcess);
processHandle := 0;
end;
end;
end
else
begin
WaitForSingleObject(ServiceThread.Handle, 500);
ServiceThread.ProcessRequests(false);
// bRunLoop := False;
end;
end;
finally
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. End'); {$ENDIF}
if Assigned(PIDList) then FreeAndNil(PIDList);
if Assigned(WTSInfo) then FreeAndNil(WTSInfo);
if Mtx <> nil then
FreeAndNil(Mtx);
if processHandle <> 0 then
CloseHandle(processHandle);
end;
end;
procedure TSvcCrmHe.ServicePause(Sender: TService; var Paused: Boolean);
begin
{$IFDEF DEBUG}
Paused := true;
{$ELSE}
Paused := MutexExists(MUTEX_KILL);
{$ENDIF}
end;
procedure TSvcCrmHe.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
{$IFDEF DEBUG}
Stopped := true;
{$ELSE}
Stopped := MutexExists(MUTEX_KILL);
{$ENDIF}
end;
end.