Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.07.2008, 22:40   #1
The_Darkness
Пользователь
 
Регистрация: 06.01.2008
Сообщений: 83
По умолчанию Можно ли мгновенно выключить компьютер?

Здравствуйте. Существует ли способ( и если да, то как его реализовать) мгновенного выключения/перезагрузки компьютера(т.е. такое жа как нажатия reset'a или power'a на сис. блоке)?
Прогрессирующий чайник..
The_Darkness вне форума Ответить с цитированием
Старый 15.07.2008, 22:48   #2
Air
Участник клуба
 
Аватар для Air
 
Регистрация: 30.04.2007
Сообщений: 1,307
По умолчанию

Цитата:
(т.е. такое жа как нажатия reset'a или power'a на сис. блоке)?
Такое же как "power'a на сис. блоке" на это полно функций, а вот как у "reset'a" это просто, надо только сделать любую ошибку в Ring0 - это просто и на форуме тема про Ring0 обсуждалась.
Всё гениальное - просто!
Air вне форума Ответить с цитированием
Старый 15.07.2008, 22:55   #3
The_Darkness
Пользователь
 
Регистрация: 06.01.2008
Сообщений: 83
По умолчанию

Цитата:
Такое же как "power'a на сис. блоке" на это полно функций
Вы не могли бы привести пример хотябы одной функции?
Цитата:
сделать любую ошибку в Ring0
А разве Windows не должен выдать "синий экран"?Или это смотря какая ошибка?
Прогрессирующий чайник..
The_Darkness вне форума Ответить с цитированием
Старый 15.07.2008, 22:58   #4
Air
Участник клуба
 
Аватар для Air
 
Регистрация: 30.04.2007
Сообщений: 1,307
По умолчанию

Вот только сегодня проверял и блин, не успел..., махом всё закрылось.
http://www.programmersforum.ru/showthread.php?t=23324
На счёт "синего экрана" это у кого как, у меня его нет.

А зачем Вам мгновенная перезагрузка, - ведь это скорее всего ошибка системы а не должность.
Всё гениальное - просто!
Air вне форума Ответить с цитированием
Старый 15.07.2008, 23:11   #5
The_Darkness
Пользователь
 
Регистрация: 06.01.2008
Сообщений: 83
По умолчанию

Цитата:
А зачем Вам мгновенная перезагрузка
1. Если обычную перезагрузку/выключение/выход из системы можно отменить, мгновенную нельзя.
2. Хочу знать и уметь все, что связано с компьютером но пока результаты не радуют
Прогрессирующий чайник..
The_Darkness вне форума Ответить с цитированием
Старый 15.07.2008, 23:19   #6
Air
Участник клуба
 
Аватар для Air
 
Регистрация: 30.04.2007
Сообщений: 1,307
По умолчанию

В том коде врят ли кто-то что-то сумеет отменить.
Хотя если интересно
Код:
Procedure Reset(Wid:String);
begin
//Для перезагрузки 1
if wid='kill' then
DebugKillProcess(GetProcessID(Pchar('winlogon.exe')));

//Для перезагрузки 2 (системная)
if wid='win' then
openproga(syswindir('sys')+'\shutdown.exe','-r -t 0',1);
end;

Procedure SystemOFF(YesNo:string;TimeOut:integer);
begin
//Для отключения (системная)
if YesNo='yes' then
openproga(syswindir('sys')+'\shutdown.exe','-s -t '+inttostr(TimeOut),1);

//Для отмены (системная)
if YesNo='no' then
openproga(syswindir('sys')+'\shutdown.exe','-a',1);
end;
То спрашивайте, что не ясно будет
Всё гениальное - просто!
Air вне форума Ответить с цитированием
Старый 15.07.2008, 23:22   #7
Terran
Участник клуба
 
Аватар для Terran
 
Регистрация: 28.11.2007
Сообщений: 1,521
По умолчанию

Проще всего что бы мнгновенно перезагрузить компьютер нужно убить процесс "smss" и улётный эффект горонтирован))). Или какой нибудь другой системный процесс. Через диспетчер задачь не получется его завершить, так что надо будет воспользоваться сторонней программой
Всегда рад помочь!

Последний раз редактировалось Terran; 16.07.2008 в 00:48.
Terran вне форума Ответить с цитированием
Старый 15.07.2008, 23:43   #8
Air
Участник клуба
 
Аватар для Air
 
Регистрация: 30.04.2007
Сообщений: 1,307
По умолчанию

Вот только что сделал вырезку из модулей, проверил работает. даже Kav 6 убивает, только 1 раз.

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

NTStatus = cardinal;

PSYSTEM_HANDLE_INFORMATION = ^SYSTEM_HANDLE_INFORMATION;
SYSTEM_HANDLE_INFORMATION = packed record
   ProcessId: dword;
   ObjectTypeNumber: byte;
   Flags: byte;
   Handle: word;
   pObject: pointer;
   GrantedAccess: dword;
   end;

PSYSTEM_HANDLE_INFORMATION_EX = ^SYSTEM_HANDLE_INFORMATION_EX;
SYSTEM_HANDLE_INFORMATION_EX = packed record
   NumberOfHandles: dword;
   Information: array [0..0] of SYSTEM_HANDLE_INFORMATION;
   end;

PPROCESS_BASIC_INFORMATION = ^_PROCESS_BASIC_INFORMATION;
_PROCESS_BASIC_INFORMATION = packed record
   ExitStatus: BOOL;
   PebBaseAddress: pointer;
   AffinityMask: PULONG;
   BasePriority: dword;
   UniqueProcessId: ULONG;
   InheritedFromUniqueProcessId: ULONG;
   end;

TPROCESSENTRY32 = packed record
  dwSize: DWORD;  
  cntUsage: DWORD;  
  th32ProcessID: DWORD;
  th32DefaultHeapID: DWORD;  
  th32ModuleID: DWORD;  
  cntThreads: DWORD;
  th32ParentProcessID: DWORD;  
  pcPriClassBase: Longint;  
  dwFlags: DWORD;
  szExeFile: array[0..MAX_PATH - 1] of Char;  
  end;

Const
  STATUS_SUCCESS = NTStatus($00000000);
  TH32CS_SNAPPROCESS = $00000002;
  STATUS_INFO_LENGTH_MISMATCH = NTStatus($C0000004);
  SystemHandleInformation =	16;
  ProcessBasicInformation = 0;

var
  Form1: TForm1;
  Function DbgUiDebugActiveProcess(pHandle: dword): NTStatus; stdcall; external 'ntdll.dll';
  Function DbgUiConnectToDbg(): NTStatus; stdcall; external 'ntdll.dll';
  Function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): dword stdcall;
                                  external 'kernel32.dll';  
  Function Process32First(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL stdcall;  
                                  external 'kernel32.dll';
  Function Process32Next(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL stdcall;  
                                  external 'kernel32.dll';
  Function ZwQuerySystemInformation(ASystemInformationClass: dword;
                                  ASystemInformation: Pointer;
                                  ASystemInformationLength: dword;
                                  AReturnLength:PCardinal): NTStatus;
                                  stdcall;external 'ntdll.dll';
  Function ZwQueryInformationProcess(
                                ProcessHandle:THANDLE;
                                ProcessInformationClass:DWORD;
                                ProcessInformation:pointer;
                                ProcessInformationLength:ULONG;
                                ReturnLength:PULONG):NTStatus;stdcall;
                                external 'ntdll.dll';


implementation

{$R *.dfm}

Function GetInfoTable(ATableType:dword):Pointer;
var
 mSize: dword;
 mPtr: pointer;
 St: NTStatus;
begin
 Result := nil;
 mSize := $4000; //начальный размер буффера
 repeat
   mPtr := VirtualAlloc(nil, mSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
   if mPtr = nil then Exit;
   St := ZwQuerySystemInformation(ATableType, mPtr, mSize, nil);
   if St = STATUS_INFO_LENGTH_MISMATCH then
      begin //надо больше памяти
        VirtualFree(mPtr, 0, MEM_RELEASE);
        mSize := mSize * 2;
      end;
 until St <> STATUS_INFO_LENGTH_MISMATCH;
 if St = STATUS_SUCCESS
   then Result := mPtr
   else VirtualFree(mPtr, 0, MEM_RELEASE);
end;

.....................
Всё гениальное - просто!

Последний раз редактировалось Air; 15.07.2008 в 23:45.
Air вне форума Ответить с цитированием
Старый 15.07.2008, 23:43   #9
Air
Участник клуба
 
Аватар для Air
 
Регистрация: 30.04.2007
Сообщений: 1,307
По умолчанию

Продолжение.......
Код:
function GetProcessId(pName: PChar): dword;
var
 Snap: dword;  
 Process: TPROCESSENTRY32;
begin
  Result := 0;
  Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if Snap <> INVALID_HANDLE_VALUE then
     begin  
      Process.dwSize := SizeOf(TPROCESSENTRY32);  
      if Process32First(Snap, Process) then
         repeat
          if lstrcmpi(Process.szExeFile, pName) = 0 then  
             begin
              Result := Process.th32ProcessID;  
              CloseHandle(Snap);  
              Exit;
             end;  
         until not Process32Next(Snap, Process);  
      Result := 0;
      CloseHandle(Snap);  
     end;  
end;

Function OpenProcessEx(dwProcessId: DWORD): THandle;
var
 HandlesInfo: PSYSTEM_HANDLE_INFORMATION_EX;
 ProcessInfo: _PROCESS_BASIC_INFORMATION;
 idCSRSS: dword;
 hCSRSS : dword;
 tHandle: dword;
 r      : dword;
begin
 Result := 0;
 //открываем процесс csrss.exe
 idCSRSS := GetProcessId('csrss.exe');
 hCSRSS  := OpenProcess(PROCESS_DUP_HANDLE, false, idCSRSS);
 if hCSRSS = 0 then Exit;
 HandlesInfo := GetInfoTable(SystemHandleInformation);
 if HandlesInfo <> nil then
 for r := 0 to HandlesInfo^.NumberOfHandles do
   if (HandlesInfo^.Information[r].ObjectTypeNumber = $5) and  //тип хэндла - процесс
      (HandlesInfo^.Information[r].ProcessId = idCSRSS) then   //владелец - CSRSS
        begin
          //копируем хэндл себе
          if DuplicateHandle(hCSRSS, HandlesInfo^.Information[r].Handle,
                             INVALID_HANDLE_VALUE, @tHandle, 0, false,
                             DUPLICATE_SAME_ACCESS) then

             begin
               ZwQueryInformationProcess(tHandle, ProcessBasicInformation,
                                         @ProcessInfo,
                                         SizeOf(_PROCESS_BASIC_INFORMATION), nil);
               if ProcessInfo.UniqueProcessId = dwProcessId then
                  begin
                    VirtualFree(HandlesInfo, 0, MEM_RELEASE);
                    CloseHandle(hCSRSS);
                    Result := tHandle;
                    Exit;
                  end else CloseHandle(tHandle);
             end;
        end;
 VirtualFree(HandlesInfo, 0, MEM_RELEASE);
 CloseHandle(hCSRSS);
end;

function EnableDebugPrivilege():Boolean;
var
 hToken: dword;
 SeDebugNameValue: Int64;
 tkp: TOKEN_PRIVILEGES;
 ReturnLength: dword;
begin
 Result:=false;
 //Добавляем привилегию SeDebugPrivilege
 //Получаем токен нашего процесса
 OpenProcessToken(INVALID_HANDLE_VALUE, TOKEN_ADJUST_PRIVILEGES
                  or TOKEN_QUERY, hToken);
 //Получаем LUID привилегии
 if not LookupPrivilegeValue(nil, 'SeDebugPrivilege', SeDebugNameValue) then
  begin
   CloseHandle(hToken);
   exit;
  end;
 tkp.PrivilegeCount := 1;
 tkp.Privileges[0].Luid := SeDebugNameValue;
 tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
 //Добавляем привилегию к процессу
 AdjustTokenPrivileges(hToken, false, tkp, SizeOf(TOKEN_PRIVILEGES),
                       tkp, ReturnLength);
 if GetLastError() <> ERROR_SUCCESS then exit;
 Result:=true;
end;

Function DebugKillProcess(ProcessId: dword): boolean;
var
 pHandle: dword;
 myPID: dword;
 HandlesInfo: PSYSTEM_HANDLE_INFORMATION_EX;
 r: dword;
begin
 Result := false;
 myPID := GetCurrentProcessId();
 if not EnableDebugPrivilege() then Exit;
 //подключаемся к системе отладки и получаем DebugObject
 if DbgUiConnectToDbg() <> STATUS_SUCCESS then Exit;
 pHandle := OpenProcessEx(ProcessId);
 //включаем отладку процесса
 if DbgUiDebugActiveProcess(pHandle) <> STATUS_SUCCESS then Exit;
 //надо найти полученный DebugObject
 HandlesInfo := GetInfoTable(SystemHandleInformation);
 if HandlesInfo = nil then Exit;
 for r := 0 to HandlesInfo^.NumberOfHandles do
  if (HandlesInfo^.Information[r].ProcessId = myPID) and
     (HandlesInfo^.Information[r].ObjectTypeNumber = $8)  //DebugObject
     then begin
       //закрываем DebugObject, что приводит к уничтожению отлаживаемого процесса
       CloseHandle(HandlesInfo^.Information[r].Handle);
       Result := true;
       break;
     end;
 VirtualFree(HandlesInfo, 0, MEM_RELEASE);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
DebugKillProcess(getprocessid('lsass.exe')); //можно просто PID если знаешь
end;

end.
Всё гениальное - просто!
Air вне форума Ответить с цитированием
Старый 16.07.2008, 00:05   #10
Terran
Участник клуба
 
Аватар для Terran
 
Регистрация: 28.11.2007
Сообщений: 1,521
По умолчанию

Хороший код! Завершает всё.) Вот только каспер не убивается(
Всегда рад помочь!
Terran вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как можно запустить компьютер без пароля. |{ () T Безопасность, Шифрование 21 01.06.2008 21:37
как выключить/перезагрузить компьютер motaro Паскаль, Turbo Pascal, PascalABC.NET 1 28.03.2008 02:01
Безопасная связка компьютер-компьютер, как организовать наилучшую защиту Alar Операционные системы общие вопросы 3 17.02.2008 21:15
Как выключить удалённый компьютер c помощью Server Socket. muravey Работа с сетью в Delphi 3 09.11.2007 08:09