Windows 消息仍然可以在 Windows Vista 中使用!手头的问题是 vista 中称为用户界面特权隔离 (UIPI) 的技术可防止具有较低完整性级别 (IL) 的进程将消息发送到具有高 IL 的进程(例如,Windows 服务具有高 IL 和用户模式应用程序具有中等 IL)。
但是,这可以被绕过,并且可以允许中等 IL 应用程序将 wm 发送到高 IL 进程。
维基百科说得最好:
UIPI 不是安全边界,并不旨在防止所有粉碎攻击。UI 可访问性应用程序可以通过将其“uiAccess”值设置为 TRUE 作为其清单文件的一部分来绕过 UIPI。这要求应用程序位于 Program Files 或 Windows 目录中,并由有效的代码签名机构签名,但这些要求不一定会阻止恶意软件尊重它们。
此外,仍然允许通过某些消息,例如 WM_KEYDOWN,它允许较低的 IL 进程将输入驱动到提升的命令提示符。
最后,函数 ChangeWindowMessageFilter 允许中等 IL 进程(除 Internet Explorer 保护模式外的所有非提升进程)更改高 IL 进程可以从较低 IL 进程接收的消息。这有效地允许绕过 UIPI,
除非从 Internet Explorer 或其子进程之一运行。
Delphi-PRAXIS 的某个人(链接是德语。使用 Google 翻译页面)已经解决了这个问题,并使用 ChangeWindowMessageFilter 发布了他们的代码。我相信他们的问题是 WM_COPYDATA 在他们修改代码以绕过 WM_COPYDATA 的 UIPI 之前无法在 Vista 上运行。
原始链接(德语)
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, uallHook, uallProcess, uallUtil, uallKernel;
type
TfrmMain = class(TForm)
lbl1: TLabel;
tmrSearchCondor: TTimer;
mmo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure tmrSearchCondorTimer(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private-Deklarationen }
fCondorPID : DWord;
fInjected : Boolean;
fDontWork : Boolean;
procedure SearchCondor;
procedure InjectMyFunctions;
procedure UnloadMyFunctions;
function GetDebugPrivileges : Boolean;
procedure WriteText(s : string);
procedure WMNOTIFYCD(var Msg: TWMCopyData); message WM_COPYDATA;
public
{ Public-Deklarationen }
end;
var
frmMain: TfrmMain;
ChangeWindowMessageFilter: function (msg : Cardinal; dwFlag : Word) : BOOL; stdcall;
implementation
{$R *.dfm}
type Tmydata = packed record
datacount: integer;
ind: boolean;
end;
const cCondorApplication = 'notepad.exe';
cinjComFuntionsDLL = 'injComFunctions.dll';
var myData : TMydata;
procedure TfrmMain.WMNOTIFYCD(var Msg: TWMCopyData);
begin
if Msg.CopyDataStruct^.cbData = sizeof(TMydata) then
begin
CopyMemory(@myData,Msg.CopyDataStruct^.lpData,sizeof(TMyData));
WriteText(IntToStr(mydata.datacount))
end;
end;
procedure TfrmMain.WriteText(s : string);
begin
mmo1.Lines.Add(DateTimeToStr(now) + ':> ' + s);
end;
procedure TfrmMain.InjectMyFunctions;
begin
if not fInjected then begin
if InjectLibrary(fCondorPID, PChar(GetExeDirectory + cinjComFuntionsDLL)) then fInjected := True;
end;
end;
procedure TfrmMain.UnloadMyFunctions;
begin
if fInjected then begin
UnloadLibrary(fCondorPID, PChar(GetExeDirectory + cinjComFuntionsDLL));
fInjected := False;
end;
end;
procedure TfrmMain.SearchCondor;
begin
fCondorPID := FindProcess(cCondorApplication);
if fCondorPID <> 0 then begin
lbl1.Caption := 'Notepad is running!';
InjectMyFunctions;
end else begin
lbl1.Caption := 'Notepad isn''t running!';
end;
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
UnloadMyFunctions;
end;
function TfrmMain.GetDebugPrivileges : Boolean;
begin
Result := False;
if not SetDebugPrivilege(SE_PRIVILEGE_ENABLED) then begin
Application.MessageBox('No Debug rights!', 'Error', MB_OK);
end else begin
Result := True;
end;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
@ChangeWindowMessageFilter := GetProcAddress(LoadLibrary('user32.dll'), 'ChangeWindowMessageFilter');
ChangeWindowMessageFilter(WM_COPYDATA, 1);
fInjected := False;
fDontWork := not GetDebugPrivileges;
tmrSearchCondor.Enabled := not fDontWork;
end;
procedure TfrmMain.tmrSearchCondorTimer(Sender: TObject);
begin
tmrSearchCondor.Enabled := False;
SearchCondor;
tmrSearchCondor.Enabled := True;
end;
end.