uses TlHelp32;

 

 

 

 

// NT Privileges 상수
// 지금 당장 필요한 건 SE_DEBUG_NAME 밖엔 없지만..

const
  SE_CREATE_TOKEN_NAME = 'SeCreateTokenPrivilege';
  SE_ASSIGNPRIMARYTOKEN_NAME = 'SeAssignPrimaryTokenPrivilege';
  SE_LOCK_MEMORY_NAME = 'SeLockMemoryPrivilege';
  SE_INCREASE_QUOTA_NAME = 'SeIncreaseQuotaPrivilege';
  SE_UNSOLICITED_INPUT_NAME = 'SeUnsolicitedInputPrivilege';
  SE_MACHINE_ACCOUNT_NAME = 'SeMachineAccountPrivilege';
  SE_TCB_NAME = 'SeTcbPrivilege';
  SE_SECURITY_NAME = 'SeSecurityPrivilege';
  SE_TAKE_OWNERSHIP_NAME = 'SeTakeOwnershipPrivilege';
  SE_LOAD_DRIVER_NAME = 'SeLoadDriverPrivilege';
  SE_SYSTEM_PROFILE_NAME = 'SeSystemProfilePrivilege';
  SE_SYSTEMTIME_NAME = 'SeSystemtimePrivilege';
  SE_PROF_SINGLE_PROCESS_NAME = 'SeProfileSingleProcessPrivilege';
  SE_INC_BASE_PRIORITY_NAME = 'SeIncreaseBasePriorityPrivilege';
  SE_CREATE_PAGEFILE_NAME = 'SeCreatePagefilePrivilege';
  SE_CREATE_PERMANENT_NAME = 'SeCreatePermanentPrivilege';
  SE_BACKUP_NAME = 'SeBackupPrivilege';
  SE_RESTORE_NAME = 'SeRestorePrivilege';
  SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
  SE_DEBUG_NAME = 'SeDebugPrivilege';
  SE_AUDIT_NAME = 'SeAuditPrivilege';
  SE_SYSTEM_ENVIRONMENT_NAME = 'SeSystemEnvironmentPrivilege';
  SE_CHANGE_NOTIFY_NAME = 'SeChangeNotifyPrivilege';
  SE_REMOTE_SHUTDOWN_NAME = 'SeRemoteShutdownPrivilege';
  SE_UNDOCK_NAME = 'SeUndockPrivilege';
  SE_SYNC_AGENT_NAME = 'SeSyncAgentPrivilege';
  SE_ENABLE_DELEGATION_NAME = 'SeEnableDelegationPrivilege';
  SE_MANAGE_VOLUME_NAME = 'SeManageVolumePrivilege';

 

 

 

 

 

 

// 권한 얻기-해제
//
http://support.microsoft.com/kb/q131065/  => 델파이로 포팅함 [2008.07.23, 백충덕]
// 그러므로 오류가 있을 수도 있음...-_-;
// _____________________________________________________________________________
function SetPrivilege(hToken: THandle; Privilege: LPCTSTR; bEnablePrivilege: Boolean): Boolean;
var
  tp: TOKEN_PRIVILEGES;
  luid: TLargeInteger;
  tpPrevious: TOKEN_PRIVILEGES;
  cbPrevious: DWORD;
  dwWritten: DWORD;

 

begin
  Result:=False;

 

  cbPrevious:=sizeof(TOKEN_PRIVILEGES);

  if not LookupPrivilegeValue(nil, Privilege, luid) then exit;

 

  tp.PrivilegeCount:=1;
  tp.Privileges[0].Luid:=luid;
  tp.Privileges[0].Attributes:=0;

 

  AdjustTokenPrivileges(hToken, False, tp, sizeof(TOKEN_PRIVILEGES), tpPrevious, cbPrevious);
  if GetLastError<>ERROR_SUCCESS then exit;

 

  tpPrevious.PrivilegeCount:=1;
  tpPrevious.Privileges[0].Luid:=luid;

 

  if bEnablePrivilege then begin
    tpPrevious.Privileges[0].Attributes:=tpPrevious.Privileges[0].Attributes or (SE_PRIVILEGE_ENABLED);
  end
  else begin

    tpPrevious.Privileges[0].Attributes:=tpPrevious.Privileges[0].Attributes xor (SE_PRIVILEGE_ENABLED and tpPrevious.Privileges[0].Attributes);
  end;

 

  AdjustTokenPrivileges(hToken, False, tpPrevious, cbPrevious, nil, dwWritten);
  if GetLastError<>ERROR_SUCCESS then exit;

 

  Result:=True;
end;

 

 

 

 

 

 

 

// 프로세스 리스트를 다 뒤지다가 이름이 일치하면 PID 반환 [2008.07.23, 백충덕]
// _____________________________________________________________________________
function GetProcessIdByName(const ProcName: String): DWORD;
var
  Process32: TProcessEntry32;
  SHandle:   THandle;
  Next:      BOOL;


begin
  Result:=0;

 

  Process32.dwSize := SizeOf(TProcessEntry32);
  SHandle          := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);

 

  if Process32First(SHandle, Process32) then begin
    repeat
      Next := Process32Next(SHandle, Process32);
      if AnsiCompareText(Process32.szExeFile, Trim(ProcName))=0 then begin
        Result:=Process32.th32ProcessID;
        break;
      end;
    until not Next;
  end;
  CloseHandle(SHandle);
end;

 

 

 

 

 

 

 

 

 

// 디버그 권한을 얻어서 OpenProcess 시도   [2008.07.23, 백충덕]
// 역시
http://support.microsoft.com/kb/q131065/ 에 있는 main 함수를 적절하게...-_-;
// _____________________________________________________________________________
procedure TForm1.Button1Click(Sender: TObject);

const 프로세스이름 = 'calc.exe';
var
  hProcess: THandle;
  hToken: THandle;
  ProcID: DWORD;

 

begin
  if not
OpenThreadToken(GetCurrentThread, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, False, hToken) then begin
    if
GetLastError=ERROR_NO_TOKEN then begin
      if not
ImpersonateSelf(SecurityImpersonation) then begin
        Memo1.Lines.Add('[Error] ImpersonateSelf');
        Exit;
      end;

 

      if not OpenThreadToken(GetCurrentThread, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, False, hToken) then begin
        Memo1.Lines.Add('[Error] OpenThreadToken');
        Exit;
      end;
    end
    else begin
      Memo1.Lines.add('[Error] OpenThreadToken GetLastError<>ERROR_NO_TOKEN');
      Exit;
    end;
  end;

 

  // 디버그 권한 얻기
  if not SetPrivilege(hToken, SE_DEBUG_NAME, True) then begin
    Memo1.Lines.Add('[Error] SetPrivilege');
    CloseHandle(hToken);
    Exit;
  end;

 

  // ProcessID 를 가져옴
  ProcID:=GetProcessIdByName(프로세스이름);

  Memo1.Lines.Add('ProcessID: '+IntToStr(ProcID));

 

  // OpenProcess 시도
  hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, ProcID);
  if hProcess=0 then begin
    Memo1.Lines.Add('[Error] OpenProcess');
    Memo1.Lines.Add(IntToStr(GetLastError));
    Exit;
  end
  else
Memo1.lines.Add('OpenProcess 성공');

 

  // 디버그 권한 해제(?)
  SetPrivilege(hToken, SE_DEBUG_NAME, False);

 

  CloseHandle(hToken);
  CloseHandle(hProcess);
end;








Posted by bloodguy
,