// залепа
Function MessageProc(code : integer; wParam : word;
lParam : longint) : longint; stdcall;
begin
CallNextHookEx(0, Code, wParam, lparam);
Result := 0;
end;
Procedure SetGlobalHookProc();
begin
SetWindowsHookEx(WH_GETMESSAGE, @MessageProc, HInstance, 0);
Sleep(INFINITE);
end;
//
Procedure SetGlobalHook();
var
hMutex: dword;
TrId: dword;
begin
hMutex := CreateMutex(nil, false, 'AdvareHook');
if GetLastError = 0 then
CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else
CloseHandle(hMutex);
end;
Перехватить API! (Хуки)
Не могу понять зачем нужно вот это:
Код:
hMutex := CreateMutex(nil, false, 'AdvareHook');
Зачем создавать какой-то Mutex???
if GetLastError = 0 then
Если не было ошибки, то создать поток...
CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else
Иначе кончаем Mutex...
CloseHandle(hMutex);
Зачем нужен Mutex и что это такое???
По идее для перехвата нужно только это (а в NewMessageBoxExW мы просто обрабатываем вызов API-функции MessageBoxEx):
Код:
function NewMessageBoxExW(hWnd: HWND; lpText, lpCaption: PWideChar;
uType: UINT; wLanguageId: Word): Integer; stdcall;
var
AdText: PWideChar;
NewText: PWideChar;
NewLen: dword;
begin
AdText := GetRandomString();
NewLen := (lstrlenw(AdText) + lstrlenw(lpText)) * SizeOf(WideChar) + 20;
GetMem(NewText, NewLen);
lstrcpyw(NewText, lpText);
lstrcatw(NewText, #10#13#10#13);
lstrcatw(NewText, AdText);
FreeMem(AdText);
Result := TrueMessageBoxExW(hWnd, NewText, lpCaption, uType, wLanguageId);
FreeMem(NewText);
end;
Procedure SetHook();
var
hUser32: dword;
Bytes: dword;
begin
hUser32 := GetModuleHandle('user32.dll');
MbwAdr := GetProcAddress(hUser32, 'MessageBoxExW');
MbaAdr := GetProcAddress(hUser32, 'MessageBoxExA');
ReadProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, @OldMbw, SizeOf(OldCode), Bytes);
ReadProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, @OldMba, SizeOf(OldCode), Bytes);
JmpMbw.PuhsOp := $68;
JmpMbw.PushArg := @NewMessageBoxExW;
JmpMbw.RetOp := $C3;
JmpMba.PuhsOp := $68;
JmpMba.PushArg := @NewMessageBoxExA;
JmpMba.RetOp := $C3;
WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, @JmpMbw, SizeOf(far_jmp), Bytes);
WriteProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, @JmpMba, SizeOf(far_jmp), Bytes);
end;
uType: UINT; wLanguageId: Word): Integer; stdcall;
var
AdText: PWideChar;
NewText: PWideChar;
NewLen: dword;
begin
AdText := GetRandomString();
NewLen := (lstrlenw(AdText) + lstrlenw(lpText)) * SizeOf(WideChar) + 20;
GetMem(NewText, NewLen);
lstrcpyw(NewText, lpText);
lstrcatw(NewText, #10#13#10#13);
lstrcatw(NewText, AdText);
FreeMem(AdText);
Result := TrueMessageBoxExW(hWnd, NewText, lpCaption, uType, wLanguageId);
FreeMem(NewText);
end;
Procedure SetHook();
var
hUser32: dword;
Bytes: dword;
begin
hUser32 := GetModuleHandle('user32.dll');
MbwAdr := GetProcAddress(hUser32, 'MessageBoxExW');
MbaAdr := GetProcAddress(hUser32, 'MessageBoxExA');
ReadProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, @OldMbw, SizeOf(OldCode), Bytes);
ReadProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, @OldMba, SizeOf(OldCode), Bytes);
JmpMbw.PuhsOp := $68;
JmpMbw.PushArg := @NewMessageBoxExW;
JmpMbw.RetOp := $C3;
JmpMba.PuhsOp := $68;
JmpMba.PushArg := @NewMessageBoxExA;
JmpMba.RetOp := $C3;
WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, @JmpMbw, SizeOf(far_jmp), Bytes);
WriteProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, @JmpMba, SizeOf(far_jmp), Bytes);
end;
А что ещё надо?
это для того чтобы ставить перехват только один раз, то есть если этот объект уже создан то повторное его создание будет вести к ошибке и как следствие повторная установка хука будет исключена
это для того чтобы ставить перехват только один раз, то есть если этот объект уже создан то повторное его создание будет вести к ошибке и как следствие повторная установка хука будет исключена
[/quote]
Это чтобы другое приложение не поставило HOOK на ту же функцию? Короче, как бы ЖМОТСКОЕ приложение получается...
А без этого Mutex'а можно обойтись???
И что это такое?
[quote=Meatcoins]Это чтобы другое приложение не поставило HOOK на ту же функцию?[/quote]
Нет - чтобы это же приложение не установило один и тот же хук повторно.
Цитата: HexEdit
Нет - чтобы это же приложение не установило один и тот же хук повторно.
А зачем для локальных с т.з. приложения операций использовать глобальный механизм?
Моё мнение: мьютекс здесь совершенно не нужен.
Цитата: Green
А зачем для локальных с т.з. приложения операций использовать глобальный механизм?
Моё мнение: мьютекс здесь совершенно не нужен.
Моё мнение: мьютекс здесь совершенно не нужен.
Хм... А какие локальные операции при перехвате? Или я чет не так понял?
Неаккуратно написанный код приводит к ошибке его восприятия.
Короче, в приведенном тобой коде мьютекс лочит создание треда установки хука другими экземплярами данного приложения.
Чтож в такой постановке глобальный объек синхронизации, возможно, нужен.
[/quote]
А понятно. Есть программы, которые проверяют запущена ли их вторая копия или нет, если запущена, то повторно они не запускаются - и тут аналогично, как я понимаю.
Я сейчас как раз пытаюсь перевести с Delphi на свой любимый Assembler - что-то не прёт пока! Также с Delphi разбираюсь - всё упрощаю - суть надо понять, а там попрёт!
мьютексы в данном примере, то что надо!!!!!
Восновном именно мьютектсами это и проверяется. Ты прав.