Win 7の下でスーパー管理者が通常権限タスクを作成
3588 ワード
新しいブログに移動しましたhttp://www.raysoftwareクリックしてリンクを開く.cn/?p=49
プロジェクトでは、Win 7の下でスーパー管理者が通常の権限タスクを作成する機能が使用されます.
リソースマネージャのTokenを取得し、このTokenでCreateProcessWithTokenWでタスクを作成するなど、いくつかの方法を試みました.これでいいです.
しかし、現在リソースマネージャまたはその他の一般的な権限のないタスクはどうしますか?CreateTokenは自分でTokenを作ってもいいですが、それらのパラメータは見ると頭が大きいです.
スーパーユーザー方式でタスクマネージャ用メニューの実行を起動してみると、デフォルトで通常の権限タスクが作成され、スーパーユーザー権限でタスクを起動する複素オプションがあります.
WINDBGで追跡してみると.タスクマネージャが呼び出すのはWdcRunTaskAsInteractiveUserという関数である.関数ビットドメインwdc.dllにある.
関数の形式は以下のように分析される.
Delphi宣言:
この関数はパラメータが非常に少なく、簡単です.
最後のパラメータタスクマネージャは39.ビットで識別すべき.39は32 or 4 or 2 or 1であるべきである.
0をあげるならEXEを開くなどは大丈夫だと思っていましたが、MP 3などを開けると失敗します.
IDAでWdcRunTaskAsInteractiveUserを逆コンパイルすると、彼の実装方法は低権限の計画タスクを作成し、計画タスクのRunメソッドを呼び出すことであることがわかりました.
もう一つエピソードがあります.VistaとWindows 7の差は少ないと思います.Windowsバージョン>=6を判断するにはWdcRunTaskAsInteractiveUserを使います.そうしないとShellExecuteExEを呼び出します.
その結果、Vistaにはできません.Vistaにはこの関数がありません.wdc.dll.Vistaのプロセスマネージャもスーパーユーザー権限の下で普通のプロセスを作成できません.ShellExecuteExを簡単に呼び出しただけです.
もちろんVistaの下で私たちは自分で計画タスクを使って普通の権限プロセスタスクを作成することができて、それからRunの.つまり自分でWdcRunTaskAsInteractiveUserを実現します.
私は怠け者で、プロジェクトの中でGetProcAddressがWdcRunTaskAsInteractiveUserを見つけられない限り、私はShellExecuteExを使います.
次に、プロジェクトにカプセル化された実行コードを示します.
プロジェクトでは、Win 7の下でスーパー管理者が通常の権限タスクを作成する機能が使用されます.
リソースマネージャのTokenを取得し、このTokenでCreateProcessWithTokenWでタスクを作成するなど、いくつかの方法を試みました.これでいいです.
しかし、現在リソースマネージャまたはその他の一般的な権限のないタスクはどうしますか?CreateTokenは自分でTokenを作ってもいいですが、それらのパラメータは見ると頭が大きいです.
スーパーユーザー方式でタスクマネージャ用メニューの実行を起動してみると、デフォルトで通常の権限タスクが作成され、スーパーユーザー権限でタスクを起動する複素オプションがあります.
WINDBGで追跡してみると.タスクマネージャが呼び出すのはWdcRunTaskAsInteractiveUserという関数である.関数ビットドメインwdc.dllにある.
関数の形式は以下のように分析される.
Delphi宣言:
function WdcRunTaskAsInteractiveUser ( pwszCmdLine, pwszPath : PWIDECHAR;
dwDummy : DWORD):HResult; stdcall; external 'wdc.dll';
C++宣言:HRESULT WINAPI WdcRunTaskAsInteractiveUser (LPCWSTR pwszCmdLine,
LPCWSTR pwszPath,
DWORD dwDummy);
これはマイクロソフトが公開していない関数です.MSDNもグーグルにも見つかりません.この関数はパラメータが非常に少なく、簡単です.
最後のパラメータタスクマネージャは39.ビットで識別すべき.39は32 or 4 or 2 or 1であるべきである.
0をあげるならEXEを開くなどは大丈夫だと思っていましたが、MP 3などを開けると失敗します.
IDAでWdcRunTaskAsInteractiveUserを逆コンパイルすると、彼の実装方法は低権限の計画タスクを作成し、計画タスクのRunメソッドを呼び出すことであることがわかりました.
もう一つエピソードがあります.VistaとWindows 7の差は少ないと思います.Windowsバージョン>=6を判断するにはWdcRunTaskAsInteractiveUserを使います.そうしないとShellExecuteExEを呼び出します.
その結果、Vistaにはできません.Vistaにはこの関数がありません.wdc.dll.Vistaのプロセスマネージャもスーパーユーザー権限の下で普通のプロセスを作成できません.ShellExecuteExを簡単に呼び出しただけです.
もちろんVistaの下で私たちは自分で計画タスクを使って普通の権限プロセスタスクを作成することができて、それからRunの.つまり自分でWdcRunTaskAsInteractiveUserを実現します.
私は怠け者で、プロジェクトの中でGetProcAddressがWdcRunTaskAsInteractiveUserを見つけられない限り、私はShellExecuteExを使います.
次に、プロジェクトにカプセル化された実行コードを示します.
function RunTaskAsInteractiveUser(cmdLine, Param, dir: String): Boolean;
const
wdc = 'wdc.dll';
type
TWdcRunTaskAsInteractiveUser = function(pwszCmdLine, pwszPath: PWideChar;
dwDummy: DWORD): HResult; stdcall;
var
WdcRunTaskAsInteractiveUser: TWdcRunTaskAsInteractiveUser;
fullname: string;
sei: SHELLEXECUTEINFO;
e: Integer;
hwdc: Cardinal;
begin
Result := False;
SetLength(fullname, Length(cmdLine));
CopyMemory(PChar(fullname), PChar(cmdLine), ByteLength(cmdLine));
// Windows >=6
if Win32MajorVersion >= 6 then
begin
hwdc := GetModuleHandle(wdc);
if hwdc = 0 then
hwdc := LoadLibrary(wdc);
@WdcRunTaskAsInteractiveUser := GetProcAddress(hwdc, 'WdcRunTaskAsInteractiveUser');
// WdcRunTaskAsInteractiveUser Windows7
if Assigned(WdcRunTaskAsInteractiveUser) then
begin
if Length(Param) > 0 then
fullname := format('"%s" %s', [fullname, Param]);
// fullname + ' ' + Param;
// 39 . .TaskMgr 39
// 0 ,EXE , ,MP3
e := WdcRunTaskAsInteractiveUser(PChar(fullname), PChar(dir), 39);
Result := e = S_OK;
end;
end;
// , WdcRunTaskAsInteractiveUser, Vista XP
if not Result then
begin
//
ZeroMemory(@sei, sizeof(sei));
sei.cbSize := sizeof(SHELLEXECUTEINFO);
sei.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_NO_UI;
sei.lpFile := PChar(fullname);
sei.lpVerb := 'Open';// 'runas'
sei.nShow := SW_SHOW;
if Length(Param) > 0 then
sei.lpParameters := PChar(Param)
else
sei.lpParameters := nil;
sei.lpDirectory := PChar(dir);
ShellExecuteEx(@sei);
if sei.hProcess <> 0 then
CloseHandle(sei.hProcess);
end;
end;