ok , thanks .
now , after walking into the HELP and this FORUM ,i wish to transfer string to the EXE file
EXE -> HOOK DLL
EXE -> IPC MESSAGE
HOOK DLL -> SEND IPC BACK
EXE ->SHOW IPC DATA
Now , i am under XP with DELPHI 7 .
i tried to stay as close as i can to your code .
I Can transfer string , but not PWIDECHAR .
can you help ?
this is the code
The DLL:
***********
please look for : function CreateProcessWCallback
Code: Select all
// ***************************************************************
// HookProcessCreation.dll version: 1.0 · date: 2003-06-15
// -------------------------------------------------------------
// hook all process creation calls and ask for confirmation
// -------------------------------------------------------------
// Copyright (C) 1999 - 2003 http://www.madshi.net, All Rights Reserved
// ***************************************************************
// 2003-06-15 1.0 initial release
library SM1;
{$IMAGEBASE $57800000}
uses Windows, madCodeHook,PsAPI, Classes,sysutils,dialogs
, madRemote, madStrings;
type
TTerminationRequest = record
system : boolean;
process1, process2 : array [0..MAX_PATH] of char;
p:pwidechar;
end;
// this is the information we send to our application
var tr : TTerminationRequest;
session : dword;
// session : dword;
//question,answer:string;
function IsAllowed(appNameA, cmdLineA: pchar; appNameW, cmdLineW: PWideChar) : boolean;
// ask the user whether the current process may execute the specified command line
var arrChA : array [0..MAX_PATH * 3] of char;
arrChW : array [0..500] of wideChar;
pc : pchar;
question : array [0..500] of char;
i1, i2 : integer;
begin
// showMessage(AppNamea);
if not AmSystemProcess then begin
// ask the name of the current process
if GetVersion and $80000000 = 0 then begin
GetModuleFileNameW(0, arrChW, MAX_PATH);
WideToAnsi(arrChW, arrChA);
end else
GetModuleFileNameA(0, arrChA, MAX_PATH);
// we only want the file name
i2 := 0;
for i1 := lstrlenA(arrChA) - 1 downto 0 do
if arrChA[i1] = '\' then begin
i2 := i1 + 1;
break;
end;
lstrcpyA(question, 'May the process ');
lstrcatA(question, @arrChA[i2]);
lstrcatA(question, ' execute the following line?' + #$D#$A + #$D#$A);
// let's get a command line string which we can show to the user
try
if cmdLineA <> nil then begin
pc := pointer(LocalAlloc(LPTR, lstrlenA(cmdLineA) + 1));
lstrcpyA(pc, cmdLineA);
end else
if cmdLineW <> nil then begin
pc := pointer(LocalAlloc(LPTR, lstrlenW(cmdLineW) + 1));
WideToAnsi(cmdLineW, pc)
end else
if appNameA <> nil then begin
pc := pointer(LocalAlloc(LPTR, lstrlenA(appNameA) + 1));
lstrcpyA(pc, appNameA);
end else begin
pc := pointer(LocalAlloc(LPTR, lstrlenW(appNameW) + 1));
WideToAnsi(appNameW, pc);
end;
if lstrlenA(pc) > MAX_PATH then
pc[MAX_PATH] := #0;
lstrcatA(question, pc);
LocalFree(dword(pc));
except
lstrcatA(question, '??? (invalid command line!)');
end;
// finally let's ask the user
if GetVersion and $80000000 = 0 then begin
AnsiToWide(question, arrChW);
//ShowMessage(pc);
//ShowMessage(WideCharToString(arrchw)+','+Md5Hash(WideCharToString(Arrchw)));
// question[2]:='@';
// AnsiToWide(question, arrChW); showMessage(question);
result := MessageBoxW(0, arrChW, 'Question', MB_ICONQUESTION or MB_YESNO or MB_TASKMODAL or MB_TOPMOST) = ID_YES;
end else
result := MessageBoxA(0, question, 'Question', MB_ICONQUESTION or MB_YESNO or MB_TASKMODAL or MB_TOPMOST) = ID_YES;
end else
// let's allow system processes to execute whatever they want
result := true;
end;
// ***************************************************************
var
CreateProcessANext : function (appName, cmdLine: pchar;
processAttr, threadAttr: PSecurityAttributes;
inheritHandles: bool; creationFlags: dword;
environment: pointer; currentDir: pchar;
const startupInfo: TStartupInfo;
var processInfo: TProcessInformation) : bool; stdcall;
CreateProcessWNext : function (appName, cmdLine: pwidechar;
processAttr, threadAttr: PSecurityAttributes;
inheritHandles: bool; creationFlags: dword;
environment: pointer; currentDir: pwidechar;
const startupInfo: TStartupInfo;
var processInfo: TProcessInformation) : bool; stdcall;
WinExecNext : function (cmdLine: pchar; show: dword) : dword; stdcall;
function CreateProcessACallback(appName, cmdLine: pchar;
processAttr, threadAttr: PSecurityAttributes;
inheritHandles: bool; creationFlags: dword;
environment: pointer; currentDir: pchar;
const startupInfo: TStartupInfo;
var processInfo: TProcessInformation) : bool; stdcall;
begin
if not IsAllowed(appName, cmdLine, nil, nil) then begin
// the user doesn't like this CreateProcess call, so we block it
result := false;
SetLastError(ERROR_ACCESS_DENIED);
end else begin
// this CreateProcess call is okay
result := CreateProcessANext(appName, cmdLine, processAttr, threadAttr,
inheritHandles, creationFlags,
environment, currentDir,
startupInfo, processInfo);
// CreateProcess hooks are used very often, so to be sure we renew the hook
RenewHook(@CreateProcessANext);
end;
end;
function CreateProcessWCallback(appName, cmdLine: pwidechar;
processAttr, threadAttr: PSecurityAttributes;
inheritHandles: bool; creationFlags: dword;
environment: pointer; currentDir: pwidechar;
const startupInfo: TStartupInfo;
var processInfo: TProcessInformation) : bool; stdcall;
Var
r :boolean;
s:string;
begin
tr.system := AmSystemProcess;
tr.process1:='123';
tr.process2:='456';
s:=WideCharToString(appname);
tr.p:=cmdLine;
//tr.p:= Pchar(s)+'#0' ;
// tr.p:='122234'+#0 ; //V
//tr.p:=appname+#0 ; //V
//TR.My:=WIDECHARTOSTRING(Appname);
// s:=WIDECHARTOSTRING(Appname);
// s1:=Pchar(s1);
// tr.process1:=s1;
// showMessage('I will send:'+tr.p);
//ProcessIdToFileName(GetCurrentProcess, tr.process1);
//ProcessIdToFileName(GetCurrentProcess, tr.process2);
//AskApplication('abc');
if SendIpcMessage(pchar('HookProcessTermination' + IntToStrEx(session)),
@tr, sizeOf(tr), // our message
@result, sizeOf(result)) // the answer
=true then // ShowMessage('Send ok');
//ShowMessage(Result)
if not IsAllowed(nil, nil, appName, cmdLine) then begin
result := false;
// SetLastError(ERROR_ACCESS_DENIED);
end else begin
result := CreateProcessWNext(appName, cmdLine, processAttr, threadAttr,
inheritHandles, creationFlags,
environment, currentDir,
startupInfo, processInfo);
//ScanApp:=AppName;
RenewHook(@CreateProcessWNext);
end;
end;
function WinExecCallback(cmdLine: pchar; show: dword) : dword; stdcall;
begin
if not IsAllowed(nil, cmdLine, nil, nil) then
result := ERROR_ACCESS_DENIED
else begin
result := WinExecNext(cmdLine, show);
RenewHook(@WinExecNext);
end;
end;
// ***************************************************************
begin
HookAPI('kernel32.dll', 'CreateProcessA', @CreateProcessACallback, @CreateProcessANext);
HookAPI('kernel32.dll', 'CreateProcessW', @CreateProcessWCallback, @CreateProcessWNext);
HookAPI('kernel32.dll', 'WinExec', @WinExecCallback, @WinExecNext );
end.
the EXE main project : Form1 , 2 memo , 1 as log , 1 as memo1
please look for : procedure HandleProcessTerminationRequest
Code: Select all
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls ,
madCodeHook, madStrings, CommDlg;
Const
//dllFileW='HookProcessCreation.dll';
dllFileW='sm1.dll';
type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
Log: TMemo;
Memo1: TMemo;
procedure CheckBox1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
Procedure DoHook;
Procedure DoUnHook;
public
{ Public declarations }
end;
type
// this is the information record which our dll sends us
TTerminationRequest = record
system : boolean;
process1, process2 : array [0..MAX_PATH] of char;
p:pwidechar;
end;
// this is the information we send to our application
Var
T:TTerminationRequest;
// session : dword;
//question,answer:string;
var
Form1: TForm1;
b1,running : boolean;
implementation
{$R *.dfm}
// {$R mad.res}
//{$R needAdminRights.res}
procedure HandleProcessTerminationRequest(name : pchar;
messageBuf : pointer;
messageLen : dword;
answerBuf : pointer;
answerLen : dword); stdcall;
// this function is called by the ipc message whenever our dll contacts us
var s1, s2, s3 : string;
begin
//try
if AmUsingInputDesktop then begin
// our process is running in the current input desktop, so we ask the user
with TTerminationRequest(messageBuf^) do begin
// first extract the file names only
// s1 := ExtractFileName(process1);
// s2 := ExtractFileName(process2);
Form1.Memo1.lines.add(Process1);
Form1.Memo1.lines.add(Process2);
s1:=widechartostring(p); /problem ????
Form1.Memo1.lines.add(s1);
end;
// does the request come from a normal process or from a system process?
{ if system then
s3 := 'system process '
else s3 := 'process ';
s3 := 'May the ' + s3 + s1 + ' terminate the following process?' + #$D#$A + #$D#$A + s2;
end;
// ask the user for confirmation and return the answer to our dll
boolean(answerBuf^) := MessageBox(0, pchar(s3), 'Question...',
MB_ICONQUESTION or MB_YESNO or MB_TOPMOST) = ID_YES;
end else
// our process is *not* running in the current input desktop
// if we would call MessageBox, it would not be visible to the user
// so doing that makes no sense, it could even freeze up the whole OS
boolean(answerBuf^) := true; }
end;
//except on E: Exception do ShowMessage(E.Message+' . '+E.ClassName); END
end;
//dllFileW:PWideChar;
{ dllFileA : array [0..MAX_PATH] of char; // 9x
dllFileW : array [0..MAX_PATH] of wideChar; // nt
}
Procedure Tform1.DoHook;
begin
Log.Lines.Add('Try To Hook...');
// dllFileW:='HookProcessCreation.dll';
b1 := InjectLibraryW(CURRENT_USER, dllFileW);
if b1=true then begin
Log.Lines.Add('Hook Completed...');running:=true;
// timer1.Enabled:=running;
if CreateIpcQueue(pchar('HookProcessTermination' + IntToStr(GetCurrentSessionId)), HandleProcessTerminationRequest) then begin
Log.lines.add('Communication work fine.');
// memo1.Lines.Add(t.process1; )
End;
end
else Log.Lines.Add('Only users with administrator privileges can do this');
end;
Procedure Tform1.DoUnHook;
begin
Application.ProcessMessages;
Log.Lines.Add('Try To UnHook...');
// dllFileW:='HookProcessCreation.dll';
if DestroyIpcQueue(pchar('HookProcessTermination' + IntToStr(GetCurrentSessionId))) then begin
Log.Lines.add('Communication Ended .');
// Application.ProcessMessages;
End;
b1 := UnInjectLibraryW(CURRENT_USER, dllFileW);
if b1=true then begin
Log.Lines.Add('UnHook Completed...');
running:=false;
// timer1.Enabled:=running;
// Application.ProcessMessages;
end
else Log.Lines.Add('Only users with administrator privileges can do this');
//Application.ProcessMessages;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
Case CheckBox1.Checked of
true : begin
DoHook;
end; // of true
false : begin
DoUnHook;
end; // pf false
end; // of case
//InitDllFile;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
//dllFileW:='sm1.dll';
running :=false;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//action:=caNone;
form1.Cursor:=crHourGlass; Application.ProcessMessages ;
Log.Lines.Add('bye bye.');
if running=true then begin DoUnHook; Application.ProcessMessages ;Application.ProcessMessages ;end;
Application.ProcessMessages ;
Sleep(4000);
end;
end.