Sprzętowe kliknięcie myszką i uchwyt programu

0

Hej
wiadomo, ze mozna wywolac klikniecie myszka za pomoca programu. Mam jednak pytanie czy da się wykryć w jaki sposób to kliknięcie zostało zrobione? Chodzi mi głównie o wykrycie czy kliknięto myszką za pomocą fizycznej myszy (sprzętu) czy programowo.

Chciałbym też zablokować możliwość umożliwienia zewnętrznym programom przejmowania kontroli nad aplikacją. Chodzi mi np o klikanie w przyciski po złapaniu uchwytu okna. Jest możliwość zablokowania takiego czegoś albo utrudnienia?

pozdrawiam!

0

Na 99% się nie da. Komunikaty będą takie same. Ale możesz np. sprawdzić czy przed kliknięciem położenie myszy było odpowiednio blisko danej kontrolki (programowo najpewniej będzie tylko mouse_event z MOUSEEVENTF_LEFTDOW).

0

z tego co pamiętam to zakładąjac hook można uzyskać taką informację:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644970%28v=vs.85%29.aspx
flags.

proszę o weryfikacje kogoś madrzejszego czy to działa tak jak mysle, że działa D:

0

Chciałbym też zablokować możliwość umożliwienia zewnętrznym programom przejmowania kontroli nad aplikacją. Chodzi mi np o klikanie w przyciski po złapaniu uchwytu okna. Jest możliwość zablokowania takiego czegoś albo utrudnienia?

Jeśli to ma być jakieś zabezpieczenie przed botem to i tak będzie do obejścia, choćby pisząc sterownik fałszywej myszy (z punktu widzenia programu wygląda to jak sprzęt) a w skrajnym przypadku poprzez zbudowanie sprzętowej "myszy" wysyłającej do komputera zaprogramowane sekwencje.

Poza tym osoba niepełnosprawna może się posługiwać jakimś systemem głosowym - więc jego "myszka" będzie czysto programowa, a ty chcesz go blokować.

0

mysle ze najprosciej bedzie po prostu sprawdzic czy myszka jest w zasiegu np przycisku. To proste jest

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1MouseLeave(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button1MouseEnter(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    myszka: boolean;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if myszka then caption := 'yo'
  else caption := 'grrr';
end;

procedure TForm1.Button1MouseEnter(Sender: TObject);
begin
  myszka := true;
end;

procedure TForm1.Button1MouseLeave(Sender: TObject);
begin
  myszka := false;
end;

end.

Jesli w twojej wersji Delphi nie ma tych zdarzen, to mozesz zrobic je sam uzywajac tego http://msdn.microsoft.com/en-us/library/windows/desktop/ms645604%28v=vs.85%29.aspx

0
m_Lesiu napisał(a):

z tego co pamiętam to zakładąjac hook można uzyskać taką informację:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644970%28v=vs.85%29.aspx
flags.

Tak na szybko, rzeczywiście flags się zmienia, kod w Lazarusie

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Windows, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, LCLProc, StdCtrls;

const WH_MOUSE_LL = 14;

type
  tagMSLLHOOKSTRUCT = record
     pt: TPoint;
     mouseData: DWord;
     flags: DWord;
     time: DWord;
     dwExtraInfo: PDWord;
  end;
  TMSLLHOOKSTRUCT = tagMSLLHOOKSTRUCT;
  PMSLLHOOKSTRUCT = ^TMSLLHOOKSTRUCT;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Enter(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  private
  public
  end;

var
  Form1: TForm1;
  hhm: HHOOK;

implementation

{$R *.lfm}

function HookCallBack(nCode :Longint; awParam: WParam; alParam:LParam): Longint; stdcall;
var
   lPar: PMSLLHOOKSTRUCT;
begin
 if awParam = WM_LBUTTONDBLCLK then Form1.Label1.Caption := 'WM_LBUTTONDBLCLK';
 if awParam = WM_LButtonDOWN   then Form1.Label1.Caption := 'WM_LButtonDOWN';
 if awParam = WM_LButtonUP     then Form1.Label1.Caption := 'WM_LButtonUP';
 if awParam = WM_RButtonDOWN   then Form1.Label1.Caption := 'WM_RButtonDOWN';
 if awParam = WM_RButtonUP     then Form1.Label1.Caption := 'WM_RButtonUP';
 if awParam = WM_MOUSEMOVE     then Form1.Label1.Caption := 'WM_MOUSEMOVE';
 if awParam = WM_MOUSEWHEEL    then Form1.Label1.Caption := 'WM_MOUSEWHEEL';
 lPar := PMSLLHOOKSTRUCT(alParam);
 Form1.Label2.Caption:=IntToStr(lPar^.pt.X)+':'+IntToStr(lPar^.pt.Y)+#13#10+
                       IntToStr(lPar^.flags)+#13#10+
                       IntToStr(lPar^.mouseData)+#13#10+
                       IntToStr(lPar^.time);

 Result:=CallNextHookEx(0, nCode, awParam, alParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  hhm:=SetWindowsHookEx(WH_MOUSE_LL, @HookCallBack, Hinstance, 0);
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, 100, 100, 0, 0);
 Application.ProcessMessages;
 sleep(1000);
 Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, 100, 100, 0, 0);
end;

end.    
0

Dzięki chłopaki popracuje nad Waszymi rozwiązaniami :)

Faktycznie chciałem zrobić zabezpieczenie przed botami. Zrobiłem gierke (warcaby) na Indy po sieci i chciałbym pobawić się w zwalczanie botów żeby przeciwnik nie mógł oszukiwać.
Możecie podsunąć jakieś pomysły oprócz tych, które zaproponowałem, jeżeli macie?

1

Sprawdzanie poprawności ruchów powinno odbywać się po stronie serwera, klient powinien tylko wyświetlać stan gry (planszy) i pytać serwer czy może wykonać dany ruch danym pionkiem a serwer zezwalać lub nie. Co ma tutaj wspólnego klikanie myszką z zabezpieczeniami? Gdybym miał pisać bota do twojej gry ingerowałbym w ruch sieciowy całkowicie eliminując używanie twojego klienta. Problemem byłoby raczej wyposażenie takiego bota w sztuczną inteligencję a sama komunikacja to kwestia podsłuchania i spreparowania ruchu sieciowego.

0

Co byś nie robił i tak da się to obejść. Nawet potężne gry jak np Diablo III z milionowymi budżetami nie są odporne na boty. Mogą uprzykrzyć życie ale całkowicie odporne nie są. Dla przykładu systemy oparte o GameGuard mogą zostać oszukane poprzez drobną wstawkę w asemblerze (w delphi oczywiście). Byłem świadkiem gdzie żywcem zmieniane są adresy w pamięci oszukując tym samym aplikację i robiąc przycisk dostępny gdy nie ma odpowiedniej licencji itd. Uwierz mi, że choćbyś nie wiem jak kombinował i tak znajdzie się ktoś kto to obejdzie.

0

W linku poniżej znajdziesz pdfa z opisem co potrafi i jak jest zbudowany Hackshield:
http://www.speedyshare.com/v7NhQ/AhnLab-HackShield-2.0-Programming-Guide-en.pdf

Niestety, ale bez przejścia w tryb jądra systemu (kernel mode) nie da się stworzyć w miarę dobrego systemu ochrony przed cheatami/botami. Choćbyś zastosował najlepsze zabezpieczenia dostępne z trybu użytkownika (user mode) to i tak dość łatwo będzie można je obejść korzystając ze sterowników działających w jądrze systemu. Właściwie jedyne co daje jako takie szanse na sukces to zastosowanie skomplikowanej kontroli integralności klienta i własny najlepiej dynamiczny system szyfrowania wszystkich plików i komunikacji z serwerem.

Jeśli robisz to tylko dla zabawy to istnieje pewien w miarę prosty trik pozwalający na ochronę własnej aplikacji w trybie użytkownika. Polega on na wczytaniu własnej dllki do każdego uruchomionego procesu, a następnie shookowaniu różnych funkcji np. NtOpenProcess / NtCreateThread / SetWindowsHookEx w zależności przed czym chcesz się chronić. Kontrolując parametry przekazywane do shookowanych funkcji możesz łatwo wykryć czy dany proces próbuje manipulować chronionym programem.

Samo załadowanie dllki do wszystkich procesów jest bardzo proste, bo wystarczy skorzystać z klucza w rejestrze:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows - AppInit_DLLs

Reszta to hookowanie funkcji i filtrowanie parametrów, ale to jest bardzo obszerny i dobrze opisany temat:
http://www.codeproject.com/Articles/2082/API-hooking-revealed
http://nagareshwar.securityxploded.com/2014/03/20/code-injection-and-api-hooking-techniques/

Gotowce:
https://code.google.com/p/delphi-detours-library/
http://www.ic0de.org/archive/index.php/t-10009.html

0

AhnLab HacksShield być może nie jest idealny, ale ma bardzo potężną "moc" zapytania o wybrany obszar pamięci u klienta. Klient nie wie co zostanie sprawdzone to serwer pyta np. czy prędkość poruszania zmieniła się z 45 na 180 i napisanie emulatora symulującego odpowiedzi na takie pytanie jest niemal niemożliwe. Oczywiście istnieje możliwość zrobienia zrzutu pamięci i odszukiwania pamięci gry gdy klient jest w stanie "stabilnym", ale np. jeśli serwer wyśle do klienta, że użył speeda, wartość zmienia się na 80 a klient dalej odsyła 45 to po takiej akcji HS wykrywa niedopasowanie. Gdyby ktoś chciał pisać emulator musiałby uwzględniać takie rzeczy a jest to tak trudne, że wiąże się z nakładem pracy przewyższającym napisanie klienta od nowa. HS przez wyżej wyjaśnioną opcję implikuje to, że pominięcie całkowicie HS'a jest niemożliwe. Z drugiej jednak strony ownerzy gier nie korzystają z tej opcji bo jest dość trudna w implementacji (osobiście nie spotkałem się z tak zaawansowanym wykorzystaniem możliwości HS'a)

PS nie wiedziałem, że aż tyle osób nie dość, że wie co to HS to jeszcze ma jako takie pojęcie co dzieje się pod maską, może się z tego rozkręcić niezła dyskusja ;)
PS2 napiszcie na jakich grach zdobywacie doświadczenie. Moim źródłem jest KalOnline

1 użytkowników online, w tym zalogowanych: 0, gości: 1