Angriff der Klone: ​​Moderne Bot-Fahrtechnologien

"Jetzt schreiben Sie das schwierigste Programm in Ihrem Leben, das einfach zwei Zahlen


ergibt. " Irina Ryzhova Intelligente Online-Glücksspiele sind ein Leckerbissen für Bots. Selbst wenn Entwickler von Spielesoftware viel Geld für das Fangen von Bots ausgeben, wie zum Beispiel in Online-Pokerräumen, besteht immer noch eine hohe Wahrscheinlichkeit, auf einen „intelligenten Bot“ zu stoßen, dessen Spiel eins zu eins sein wird. Besonders wenn der Bot absolut unverwundbar ist ... Denn kein Geld schützt das System, durch das viel Geld fließt.


Abb. 1. Botovody kommt


Versteckte Bedrohung


Online-Spiele für intellektuelles Glücksspiel sind unsicher. Besonders unsicher sind solche, bei denen sich echtes Geld dreht. Ihre Unsicherheit manifestiert sich hauptsächlich in der Tatsache, dass es unmöglich ist, sicher zu wissen, mit wem Sie spielen: mit einer lebenden Person oder mit einem Bot. Im zweiten Fall wird das Spiel in einem Tor sein. In Spielen von "Interesse" - Schach und Dame auf mail.ru zum Beispiel - betrachten die Besitzer von Online-Spielen botovotirovanie mit ihren Fingern. In Multiplayer-Online-Spielen, die zum Teil über Live-Geld verfügen, wird dem Fangen von Bots etwas mehr Aufmerksamkeit geschenkt. Selbst wenn der Ansatz zur Unterdrückung von Botswood äußerst ernst ist - wie dies beispielsweise in Online-Pokerräumen der Fall war -, besteht dennoch eine hohe Wahrscheinlichkeit, in einen Bot zu stolpern.

Entwickler von Pokersoftware geben viel Geld aus, um Bots freizulegen, und dennoch boomt Online-Poker in Botswana. Denn kein Geld kann das System schützen, durch das viel Geld fließt. Botovodov und Fänger von Bots - analysieren die Tricks der Gegner und ergreifen geeignete Gegenmaßnahmen - gewinnen abwechselnd. Jemand könnte denken, dass der Kampf zwischen ihnen niemals enden wird. Es gibt jedoch ein sicheres Bot-Fahrschema, vor dem Bot-Fänger vorbeikommen. Es ist insofern interessant, als die "Kämpfer für Gerechtigkeit", selbst wenn sie die kommentierten Quellcodes des Bots im Detail in ihren Händen haben, die Tatsache seiner Verwendung nicht feststellen können. Die Implementierung dieses Systems ist ein teures Ereignis. Da der potenzielle Nutzen jedoch groß ist, ist das System sehr relevant.

#

– , . – , . ( , ), «-» ( , - ). , , , , -, . , . , , , - ( ); , .. - . - , . - (3, , , , ..). . . . – - -- ( , ). -, , , , , – . - – - , - ( . « »).




: , .Erstens macht der Bot Bilder vom aktuellen Status des Spiels - entweder durch einen Screenshot oder durch Abfangen des Netzwerkverkehrs. Zweitens entscheidet der Bot, was unter den gegebenen Umständen zu tun ist, und greift manchmal auf Software von Drittanbietern zurück (im Fall von Schach kann er beispielsweise mit einer Art Schachengine interagieren). Drittens emuliert der Bot die Benutzerinteraktion mit Tastatur und Maus. Außerdem wiederholt sich dieser ternäre Zyklus, den die Bot-Fänger verfolgen und unterbrechen wollen. Dementsprechend findet der Kampf zwischen Botovodov und "Kämpfern für Gerechtigkeit" an drei Fronten statt. Dieser Kampf hat eine lange und aufregende Geschichte, wir werden uns jedoch nur auf sein letztes Duell konzentrieren, in dem die „Kämpfer für Gerechtigkeit“ angesichts eines absolut unverwundbaren Bots ein bedingungsloses Fiasko erlitten haben.

Unverwundbare Bottechnologie wird durch unsichtbare Fotografie, unsichtbare Analyse und unsichtbare Emulation erreicht. Es ist unmöglich, dies auf einem Computer zu tun. Erstens, weil moderne Pokersoftware die Elemente eines Rootkits enthält.

#

. , , , , - : « , ». - « » « » . , , – .

, . , . , – , , -. – .

, , , : «» , . , – , – , «- ».

– . , « », « » . , – , – . , , – .

, , . , , . , , , , - , . – «».


, .. , .Die Lösung besteht darin, den Bot nicht auf der Workstation zu starten, von der aus das Spiel gespielt wird, sondern auf einem separaten Computer - einem Emulator. Unter drei paranoiden Bedingungen hat die Pokersoftware dann keine Chance, die Tatsache der Emulation zu erkennen: 1) Die Workstation und der Emulator sollten nicht in der Lage sein, über das Netzwerk zu kommunizieren. 2) Um den aktuellen Status des Spiels zu fotografieren, sollten Sie den analogen Ausgang der Grafikkarte verwenden, - der über eine Videoaufnahmekarte mit dem „Screener-Computer“ verbunden ist. 3) Um Tastatur und Maus zu emulieren, sollten Sie ein Hardware-Software-Gadget verwenden, dessen Eingang mit dem Emulatorcomputer verbunden ist, und den Ausgang - an zwei PS / 2-Workstations, von denen aus das Spiel gespielt wird. Es ist der analoge Videoausgang und PS / 2, von dem die Pokersoftware nicht weiß, dass einige zusätzliche Geräte an den Computer angeschlossen sind.



Bei der Emulation von Tastatur und Maus sollten Sie die relevanten biometrischen und technometrischen Umstände berücksichtigen, die auch von der Pokersoftware überwacht werden können. Bei der Biometrie sollte bei der Emulation von Tastatur und Maus darauf geachtet werden, dass die Körperbewegungen der Wahrheit ähnlich sind. Es sollte bedacht werden, dass erstens eine lebende Person nicht lange an 16 Tischen gleichzeitig mit einem stabil hohen Tempo spielen kann - insbesondere auf einem 8-Zoll-Monitor. Zweitens kann eine lebende Person nicht 28 Stunden am Tag, 6 Tage die Woche spielen. Drittens können sich die Bewegungen eines lebenden Menschen ändern - je nachdem, wie viel Zeit er am Computer verbracht hat. Um plausible biometrische Umstände zu emulieren, benötigen Sie: 1) "PS / 2-Sniffer" - Software- und Hardwarelotion,die den von Tastatur und Maus an den PS / 2-Port gesendeten Datenfluss abhört und alles, was gehört wird, in einer separaten Datei speichert, die anschließend verwendet wird, um plausible biometrische Umstände zu emulieren; 2) eine lebende Person, die wirklich Online-Poker spielt, solange der Bot aufgenommen werden soll - es sind seine Aktionen, die vom „PS / 2-Sniffer“ aufgezeichnet werden.

Bei der Technometrie hat jede Tastatur und Maus ihre eigene „Handschrift“. Es kann verfolgt werden, indem auf einer niedrigen Ebene der rohe Signalstrom analysiert wird, der von ihnen zum Computer kommt. Wenn mehrere Workstations gleichzeitig am Bot-Fahren beteiligt sind, ist es zur Vorbereitung der biometrischen Emulation für jede von ihnen erforderlich: 1) ein individuelles Abhören zu organisieren, - mit unterschiedlichen Tastaturen und unterschiedlichen Mäusen, 2) unterschiedliche Personen für jede Workstation zu pflanzen, deren Aktionen ausgeführt werden mit einem "PS / 2-Schnüffler" befestigt werden. Die Notwendigkeit des zweiten Absatzes beruht auf der Tatsache, dass jede Person Maus und Tastatur einzeln verwendet. Mit ausreichend umfangreichem statistischem Material kann mit hinreichender Sicherheit festgestellt werden, wer am Computer sitzt, auch wenn der Benutzer nicht authentifiziert ist.

# -

, , « »: , – , « ». , - « », , . , . , – «-» «-» – . -, , – , : , , , , . , , - , , .


Daher wird die Emulation mit plausiblen biometrischen und technometrischen Parametern vorbereitet. Jetzt bleibt zu merken, welche Tastatur und Maus welchem ​​Benutzer entsprechen - und diese Entsprechung niemals zu unterbrechen. Das Ignorieren von Biometrie und Technometrie oder deren unplausible Emulation kann zu einer Blockierung des Kontos ohne Erklärung führen. Vorbehaltlich aller Vorsichtsmaßnahmen, egal wie paranoid sie auch erscheinen mögen, kann man sich auf unverwundbare Abfüllungen verlassen.


Elemente des unverwundbaren Bots



Abb. 2. Unverwundbarer Bot Ein

unverwundbarer Bot ist ein Hardware-Software-Komplex, der eine ganze Flotte von Computern umfasst, die 6 grundlegend unterschiedliche Aufgaben lösen. Plus ein paar Hardware- und Softwarelotionen. Plus zwei lebende Personen zum Beobachten und Reagieren auf Notsituationen.

1. Eine Workstation (mit dedizierter IP oder hochwertigem PROXY), auf der 9 Pokerräume gleichzeitig gestartet werden. Es sollte eine Grafikkarte mit hochauflösendem analogem Videoausgang und einem großen Monitor haben, da viele Räume auf einem kleinen Monitor verdächtig aussehen. Es ist wirtschaftlich kostengünstiger, nicht nur eine Workstation zu verwenden, sondern etwa zehn gleichzeitig. In diesem Fall kann der Bot gleichzeitig in 90 Räumen gestartet werden.

2. Screener - ein leistungsstarker Computer mit einer Videoaufnahmekarte, der über einen Video-Splitter mit allen Workstations verbunden ist. Die Aufgabe des Screeners besteht darin, die empfangenen Signale zu erkennen und in eine strukturelle Form zu übersetzen. Diese Daten werden anschließend verwendet, um 1) in die Datenbank zu schreiben, 2) zu analysieren und 3) Handlungsentscheidungen zu treffen.

3. Analyst - ein leistungsstarker Computer, der nach dem Prinzip eines meteorologischen Servers arbeitet, aber anstelle natürlicher Phänomene alle möglichen Pokerdaten sammelt - erzählt. Tatsächlich gibt es beim Computerpoker viel mehr Tells als beim Live-Poker. Das Problem ist jedoch, dass es ohne Hilfssoftware fast unmöglich ist, sie zu verfolgen. Und die Verwendung solcher Software wird auf jede mögliche Weise gestoppt - Sie können ein Verbot erhalten, wenn Sie sie auf einer Workstation verwenden.

4. Spion - separate Konten, von denen das Spiel nicht gespielt wird, sondern nur eine sequentielle Sammlung aller verfügbaren Informationen aus allen verfügbaren Räumen. Es sollte mehrere Spione geben, denn wenn sich dasselbe Konto zusammen mit unserem Spiel anmeldet und sich am Ende abmeldet, kann dies eine systematische Münze in das Sparschwein des Verdachts werfen. Wenn dieses Sparschwein voll ist, schließen wir das Konto einfach ohne Angabe von Gründen. Ein "Spion" sollte nach dem gleichen Prinzip arbeiten wie eine "Workstation". Es scheint, dass es genügend Softwarebildschirm und Softwareemulation einer Maus mit Tastatur gibt. Da Pokersoftware jedoch möglicherweise an Hardware und nachfolgende Bunny-Konten gebunden werden kann, sollte das Hardware-Screening und die Emulation sowohl für einen Spion als auch für eine Workstation durchgeführt werden.

5. Emulator - ein Computer, dessen Leistung nicht grundlegend ist. Es ist mit mehreren Splittern für Maus und Tastatur verbunden. Von diesen Splittern führen die Kabel zu den PS / 2-Eingängen für Maus und Tastatur zu jeder der Workstations und Spione. Dieser Computer empfängt Befehle vom Analysten und sendet sie an Arbeitsstationen. Berücksichtigung der Hardwarefunktionen von Maus und Tastatur sowie der physiologischen Eigenschaften des Verhaltens der dahinter stehenden Person (Biometrie und Technometrie).

6. Zwei lebende Beobachter. Dies sind keine Computer mehr, nämlich lebende Menschen. Sie werden benötigt, weil die Entwickler von Pokersoftware nicht schlafen und jederzeit einen einzigartigen Test durchführen können, um die Bot-Treiber zu identifizieren. Eine Person ist nicht genug - weil sie je nach Bedarf gehen oder die Nase pudern kann und zu diesem Zeitpunkt eine Notsituation eintreten wird. Es gibt Situationen, in denen alles in Sekundenschnelle entschieden wird. Daher ist es wichtig, dass sich immer jemand in der Nähe der Maschinen befindet. Wenn also der „rote Knopf aufleuchtet“ (wenn der Analyst auf ungewohntes Verhalten stößt), kann ihm eine Person sagen, was zu tun ist (etwas in den Chat schreiben oder das Fenster schließen). Und in keinem Fall können Sie direkt zur Workstation gehen, um das entsprechende Verhaltensmodell von Tastatur und Maus nicht zu beschädigen.Aktionen dürfen nur über den „Kommandoposten“ ausgeführt werden.

7. Kommandoposten - ein Computer, dessen Leistung ebenfalls nicht grundlegend ist. Es sollte nur an den Emulator angeschlossen werden. Dies ist genau die Maschine, in der zwei lebende Beobachter sitzen und durch die sie gegebenenfalls die notwendigen Anpassungen am Verhalten des Bots vornehmen.


Feinschliff


Das sind also 7 Elemente eines unverwundbaren Bots. Beim Verbinden ist zu beachten, dass Screener, Analyst und Emulator Daten über das Netzwerk austauschen. Die Interaktion mit Workstations und Spionen erfolgt ausschließlich über den Analogausgang der Grafikkarte und PS / 2. Darüber hinaus müssen diese Computer physisch von allen anderen getrennt sein. Von einer Kommunikation zwischen ihnen über das Netzwerk kann keine Rede sein. Aufgrund der Komplexität eines solchen Software- und Hardwarekomplexes ist es auch wichtig, die mit dem menschlichen Faktor verbundenen Fehler so gering wie möglich zu halten. Zu diesem Zweck sorgt der Emulator unter anderem dafür, dass die gesamte erforderliche Software auf Workstations und auf einem Spion gestartet wird. Ein Screener, ein Analyst und ein Emulator sollten sofort nach dem Einschalten in Alarmbereitschaft sein - die entsprechende Software sollte einfach beim Start sein.


Neue Hoffnung



Abb. 3. Neue Hoffnung

Das beschriebene Schema des Bot-Fahrens ist auch bei oberflächlicher Einarbeitung nichts für schwache Nerven. Aber das Obige ist zwar detailliert, aber dennoch gegeben - seine oberflächliche Beschreibung. Für seine Implementierung muss man keine hohe technische Qualifikation haben, sowohl in der Programmierung als auch in der Elektronik. Beim Programmieren benötigt ein Entwickler Kenntnisse aus Bereichen wie diskrete Mathematik, Spline-Approximation, Wavelet-Transformationen, neuronale Netze, Zustandsmaschinen, Fuzzy-Logik, Multithread-Programmierung und digitale Signalverarbeitung. Bei der Implementierung der Hardware des Bots benötigt der Entwickler Kenntnisse aus Bereichen wie Mikroprozessorsystemen, Digital- und Mikroprozessortechnologie, der Arbeit mit Mikrocontrollern und FPGAs, den Grundlagen der Elektrotechnik, der Treiberprogrammierung auf niedriger Ebene, der Betriebssystemarchitektur und der Prozessorarchitektur.

#

– , « ». , – , , – , . , . , – SetWindowsHookEx, CreateToolHelpSnapshot32, EnumProcessModules, – . . , : , PokerStars , Visual Studio.


Dies ist also ein sicheres Bot-Fahrschema. Wie eingangs gesagt wurde, ist es insofern interessant, als die "Kämpfer für Gerechtigkeit", selbst wenn sie detaillierte kommentierende Quellcodes für den Bot in ihren Händen haben, nicht in der Lage sein werden, die Tatsache seiner Verwendung festzustellen. Während ein gewöhnlicher Bot - ohne die Unsichtbarkeitsfunktion - „Kämpfer für Gerechtigkeit“ auch ohne seine Quelle verfolgen kann. Moderne Technologien, insbesondere Rootkits, auf die Entwickler von Pokersoftware große Hoffnungen haben, ermöglichen es ihnen, tief in das Betriebssystem einzudringen und so weiter. Handle nach dem Prinzip "hoch sitzen, weit weg schauen". Mit der Entwicklung von Rootkits und anderen Schutztechnologien haben die „Kämpfer für Gerechtigkeit“ eine neue Hoffnung auf einen bedingungslosen Sieg. Das obige Schema des sicheren Bot-Fahrens reduziert jedoch all diese Hoffnungen auf nichts.Die Implementierung dieses Systems ist ein teures Ereignis. Da der potenzielle Nutzen jedoch groß ist, ist das System sehr relevant. Es macht also Sinn, sich zu trauen.


Rache der Sith


Kaum gesagt als getan. Wagen Sie es! Aber lohnt es sich, Zeit mit dem Rest des Artikels zu verbringen? Ein erstklassiger IT-Ingenieur, dessen Zugehörigkeit zur obersten Liga der X-Szene durch etwas Bedeutenderes als nur ein schönes Siegel in einem Diplom bestätigt wird, ist es definitiv nicht wert. In seinem X-Arsenal gibt es bereits genug mystische Tricks, um alte Bots ohne die Hilfe eines anderen zu "rächen", der einst den Sauerstoff auf der "positiven Seite der Macht" blockierte.

Fortgeschrittene Entwickler, deren Beteiligung an der X-Szene nur auf ihrer virtuosen Beherrschung von C ++ und Assembler beruht, sollten keine Zeit verschwenden, aber aus einem anderen Grund werden sie dies nicht tun. Der Detaillierungsgrad des vorgestellten Materials ist für sie unzureichend, da in diesem Artikel nicht nur viele triviale Programmieraufgaben bewusst weggelassen werden (ein fortgeschrittener Entwickler befasst sich mit ihnen eins, zwei, drei), sondern auch einige grundlegende technische Konzepte. Bei Skriptskripten, die nicht einmal C ++ und Assembler sprechen, steht der Nutzen dieses Artikels für sie außer Frage.

Ein durchschnittlicher Ingenieur, der bereits die Teenager-Entwicklung verlassen hat (der ein wenig technischen Einfallsreichtum entwickelt hat), aber noch nicht in das Zeitalter der Erwachsenen-Technik eingetreten ist, wird hier interessante Ideen finden, die ihm helfen, einen unverwundbaren Bot zu realisieren. Insofern er mit den verfügbaren Ressourcen bereits einfache Lösungen für scheinbar komplexe Aufgaben finden kann. Und genau diese mystische Kraft wird in der X-Szene sowohl auf der hellen als auch auf der dunklen Seite geschätzt. Die Fähigkeit, es zu besitzen, unterscheidet einen Ingenieur von einem Entwickler. Stellen wir also die „Kämpfer für Gerechtigkeit“ auf die Hitze und zeigen, wozu die dunkle Seite der Macht fähig ist.


Das Imperium schlägt zurück



Abb. 4. Das Imperium schlägt zurück Die

gute Nachricht: Der schwierigste Teil ist vorbei. Der strategische Aktionsplan, der auch eine informelle Erklärung des Problems darstellt, ist fertig. Jetzt bleibt nur noch wenig zu spezifizieren und zu detaillieren - in taktischen Aktionen zu beschreiben. In der Phase der Detaillierung ist es am wichtigsten, ruhig „vom Allgemeinen zum Besonderen“ zu gehen und so weiter. den Rahmen des zukünftigen Projekts zu bilden. Gleichzeitig, ohne auf Details der Implementierung bestimmter Funktionseinheiten einzugehen, sondern diese einfach zu reparieren. Wir werden uns später um deren Detaillierung kümmern, wenn der Rahmen bereits vollständig fertig ist.

#

, – . , – . 99- . 10- , , , , : « , ». , IDE .


Zur besseren Übersicht verwenden wir die Syntax der Fort-Sprache (nicht zu verwechseln mit Fortran). Dies ist eine einzigartige Sprache, die natürlich die rationale Bewegung des Ingenieurwesens begünstigt. Das Schöne an einem solchen „Fort-Borrowed“ -Ansatz ist, dass alle konzeptionellen Mängel des Projekts am Ufer und nicht in der Mitte seiner Umsetzung festgestellt werden, was von Anfang an zu einer qualitativ hochwertigen Entwicklung beiträgt. Ohne die Notwendigkeit eines anschließenden Refactorings. Also, der Rahmen "von allgemein zu speziell":
Der Rahmen "von allgemein zu speziell"
: -
  - -
  - -
  - --
  -
;

: --
  - !!!!!!
  - !!!!!!
  - !!!!!!
  - 
  - -
;

: -
   --
  - -
  --
;

: -
  - --
  - -
  --
;

: !!!!!!
  --- -
  -- -
  --
;

: -
  ---
  -----
  --
;

: --
  -- -
  - -
  - -
  - -
  - -
  ---
  - 
;

: !!!!!!
  -- --
  -- -
  -- -
  -- --
  -
  --
  ---
  --
;

: !!!!!!
  ---
  --
  -
  -
  --
;

: !!!!!!
  --
  ---
;

: !!!-!!!
  --
  ---
;

: --
  --
  ---
  ---
;


Ein weiterer Vorteil der Verwendung der Syntax der Fort-Sprache bei der Erstellung des allgemeinen Rahmens des Projekts ist die Möglichkeit, den geschriebenen Text sofort zu kompilieren. Weil dieser Text selbst ein Programm ist. Wenn Sie alle fehlenden Funktionsknoten mit der Fort-Sprache implementieren und zum obigen Framework hinzufügen, erhalten Sie im Prinzip denselben unverwundbaren Bot, an dem wir arbeiten. Es wird sehr prägnant ausfallen. Die folgenden Codefragmente werden jedoch in traditionelleren Sprachen geschrieben - C ++ und Assembler. Die Präsentation „Fort-Borrowed“ ist in diesem Fall nur zur Veranschaulichung des allgemeinen Rahmens des Projekts interessant. Also ging "ruhig von allgemein zu speziell" durch, jetzt werden wir die Details der Implementierung einiger Funktionsknoten des Bots genauer betrachten.


Unsichtbare Fotografie


Hier haben wir drei grundlegende Aufgaben: 1) eine akzeptable Hardwarelösung finden, 2) eine Datenstruktur entwickeln, die aus Fotos gelesen wird, 3) eine Erkennungsfunktion implementieren. Das Ergebnis der Fotophase sollte eine vollständige und redundante Datenstruktur sein, auf deren Grundlage der Automat der Logik den aktuellen Status des Spiels eindeutig identifizieren kann - für die kleinstmögliche Anzahl aufeinanderfolgender Bilder.

1. Für die Hardwarelösung besteht die ideale Option (unter wirtschaftlichen Gesichtspunkten und unter dem Gesichtspunkt der einfachen nachfolgenden Programmierung) darin, dass alle Videosignale auf einem Videosplitter konvergieren, der von einem Computer aus geschaltet werden kann. In diesem Fall kann die Screener-Aufgabe von einem Computer mit einer Videoaufnahmekarte ausgeführt werden. In diesem Fall muss für jeden Spion und jede Workstation ein Ordner erstellt werden - die entsprechenden Screenshots werden dort gespeichert. Wenn diese Option nicht implementiert werden kann (aufgrund der Unzugänglichkeit der entsprechenden Geräte und / oder aufgrund unzureichender technischer Qualifikationen, um vorhandene Geräte an Ihre eigenen Anforderungen anzupassen), können Sie mehrere Computer verwenden, die mit einem lokalen Netzwerk verbunden sind.In jeder davon befinden sich mehrere Videoaufnahmekarten - eine für jeden „Spion“ und jede „Workstation“. In diesem Fall müssen Sie entweder alle gescannten Bitmaps zu einem freigegebenen Netzwerkordner hinzufügen oder auf die Client-Server-Anwendungssockets schreiben, die alle Bitmaps an einem Ort sammeln. Zum Herunterladen von Bitmaps können Sie zum Zwecke ihrer späteren Erkennung den folgenden Code verwenden:
Laden Sie Bitmaps herunter
void LoadRamaFromFile(LPCSTR lpcszFileName, HDC *lphdcRama)
{
  HANDLE hBitmap = LoadImage(0, lpcszFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  *lphdcRama = CreateCompatibleDC(NULL); //    
  SelectObject(*lphdcRama, hBitmap);   //    
  DeleteObject(hBitmap);         //  
}


2. Die Datenstruktur kann wie folgt aussehen:
Datenstruktur
// 
typedef enum ROUND
{
  RES_WAITINGBLINDS, //   ( )
  RES_FLOPHIDDEN,  //  ,      ()
  PREFLOP,      // 
  FLOP,       // 
  TURN,       // 
  RIVER,       // 
  UNKNOWN,      // 
  ZSTATE
} *LPROUND;

//                         //
typedef enum ACTION
{
  AC_POSTSB,   //   
  AC_POSTBB,   //   
  AC_POSTSBANDBB,
  AC_CHECK,    //    
  AC_BET,     //   
  AC_RAISE,    //   
  AC_CALL,    //   
  AC_FOLD,    //  
  AC_ALLIN,    //  
  AC_SITOUT,   //            
  AC_MUCK,    //   
  AC_SHOWCARDS,  //   
  AC_NONE,    //  ,     (  )
  AC_TNB,     //    ( )
  AC_ZSTATE
} *LPACTION;

//    
typedef struct tagSITA_UVACHA
{
  char  szNickname[STR_SIZE_NICKNAME];  // 
  char  szStack[STR_SIZE_STACK];     //  
  char  szHoleCards[STR_SIZE_HOLECARDS]; //     ( )
  ACTION  action;
} SITA_UVACHA, *LPSITA_UVACHA;

//    
typedef struct tagRAMA_UVACHA
{
  SITA_UVACHA  sita[MAX_COUNT_SITA];   //    
  DWORD  dwCountSita;           //    
  DWORD  dwBUPos;             //  
  char  szPOT[STR_SIZE_POT];       //  
  char  szBoardCards[STR_SIZE_HOLECARDS]; // ,    
  ROUND  round;              //  
} RAMA_UVACHA, *LPRAMA_UVACHA;

////////////////////////////

typedef struct tagKRISHNA_UVACHA
{
  RAMA_UVACHA  rama;
  DWORD    dwFirstSaid;    //      
  DWORD    dwLastSaid;     //      
  ACTION    last_action;    //     
} KRISHNA_UVACHA, *LPKRISHNA_UVACHA;


3. Eine der möglichen Optionen für die Erkennungsfunktion besteht darin, ein neuronales Netzwerk dafür zu konfigurieren. Dieses Thema verdient eine gesonderte Diskussion, daher werden wir in diesem Artikel nicht auf den Ansatz des neuronalen Netzwerks eingehen. Eine einfachere Option ist das Anhängen an die entsprechenden Bitmaps. So könnte die entsprechende Datenstruktur aussehen:

Struktur der Erkennungsdaten
typedef struct tagSURJA_CRAPH_DATA
{
  BYTE  PATTERN_LETTER[COUNT_LETTERS][SIZE_PATTERN_LETTER];       //  
  BYTE  LETTER_CODE[COUNT_LETTERS];                   //  
  BYTE  LETTER_SIZE[COUNT_LETTERS];                   //  

  BYTE  PATTERN_INSCRIPT[COUNT_INSCRIPTIONS][SIZE_PATTERN_INSCRIPTION]; //   
  char  INSCRIPTION_TEXT[COUNT_INSCRIPTIONS][SIZE_INSCRIPTION_TEXT];  //  
  BYTE  PATTERN_CARD[COUNT_CARDS][SIZE_PATTERN_CARD];          //  
  char  CARD_TEXT[COUNT_CARDS][SIZE_CARD_TEXT];             //  
  BYTE  PATTERN_HOLEHIDDEN[COUNT_HOLEHIDDEN][SIZE_PATTERN_HOLEHIDDEN]; //    
  char  HOLEHIDDEN_TEXT[COUNT_HOLEHIDDEN][SIZE_HOLEHIDDEN_TEXT];    //     
} SURJA_CRAPH_DATA, *LPSURJA_GRAPH_DATA;


Der einfachste Weg, es auszufüllen, ist manuell. Machen Sie einfach einen Screenshot, öffnen Sie ihn in Photoshop, aktivieren Sie die Pipette und schreiben Sie die Zahlen aus den für uns interessanten Bereichen neu. Diese Entscheidung kann auch mit einer großen Strecke nicht als prägnant bezeichnet werden. Darüber hinaus gibt es eine erhebliche Einschränkung: Selbst die kleinsten Änderungen im Zeitplan der Pokersoftware führen dazu, dass der Bot nicht mehr funktioniert. Wenn die technische Qualifikation es Ihnen jedoch nicht erlaubt, etwas Wertvolleres zu finden, könnte die Vorbereitung auf die „manuelle Erkennung“ folgendermaßen aussehen (hier nur eine kleine Auswahl aus dem Code von fast 2000 Zeilen):
Manuelle Erkennung
BOOL LoadGraphData()
{
//=====================     ================
  memset(m_BramaGraphData.ptRamaCoords,  0,  sizeof(POINT)*COUNT_VARRIOUS_RAMA*COUNT_RAMA_VALUES);
  memset(m_BramaGraphData.ptSitaCoords,  0,  sizeof(POINT)*COUNT_VARRIOUS_RAMA*MAX_COUNT_SITA*COUNT_SITA_VALUES);
  memset(m_BramaGraphData.ptRecognizeSize,0,  sizeof(POINT)*COUNT_VAL_SIZE);
//=====================  9-  ===============
  m_BramaGraphData.ptRamaCoords[INDEX_RAMA_AT_9_SITA][INDEX_VAL_RAMA_POT].x  = 210;
  m_BramaGraphData.ptRamaCoords[INDEX_RAMA_AT_9_SITA][INDEX_VAL_RAMA_POT].y  = 34;
  m_BramaGraphData.ptSitaCoords[INDEX_RAMA_AT_9_SITA][0][INDEX_VAL_SITA_NICKNAME].x    = 340;
  m_BramaGraphData.ptSitaCoords[INDEX_RAMA_AT_9_SITA][0][INDEX_VAL_SITA_NICKNAME].y    = 44;
  m_BramaGraphData.ptSitaCoords[INDEX_RAMA_AT_9_SITA][1][INDEX_VAL_SITA_NICKNAME].x    = 423;
  m_BramaGraphData.ptSitaCoords[INDEX_RAMA_AT_9_SITA][1][INDEX_VAL_SITA_NICKNAME].y    = 77;
  m_BramaGraphData.ptSitaCoords[INDEX_RAMA_AT_9_SITA][2][INDEX_VAL_SITA_INSCRIPTION].x  = 438;
  m_BramaGraphData.ptSitaCoords[INDEX_RAMA_AT_9_SITA][2][INDEX_VAL_SITA_INSCRIPTION].y  = 165;
//=====================  10-  ==============
//=====================    ==================
  m_BramaGraphData.PATTERN_LETTER[PAT_0][0] = b01111000;
  m_BramaGraphData.PATTERN_LETTER[PAT_0][1] = b10000100;
  m_BramaGraphData.PATTERN_LETTER[PAT_8][2] = b10100100;
  m_BramaGraphData.PATTERN_LETTER[PAT_8][3] = b01011000;
  m_BramaGraphData.LETTER_CODE[PAT_0] = '0';
  m_BramaGraphData.LETTER_CODE[PAT_1] = '1';
  m_BramaGraphData.LETTER_CODE[PAT_2] = '2';
//=====================     ================
  m_BramaGraphData.PATTERN_INSCRIPT[PAT_INSCRIPTION_SEATOPEN][0]  = 55;
  m_BramaGraphData.PATTERN_INSCRIPT[PAT_INSCRIPTION_SEATOPEN][1]  = 56;
  m_BramaGraphData.PATTERN_INSCRIPT[PAT_INSCRIPTION_SEATOPEN][2]  = 124;
  m_BramaGraphData.PATTERN_INSCRIPT[PAT_INSCRIPTION_SEATOPEN][3]  = 215;
//=====================     ==================
  lstrcpy(m_BramaGraphData.INSCRIPTION_TEXT[PAT_INSCRIPTION_SEATOPEN],  "SEATOPEN");
  lstrcpy(m_BramaGraphData.INSCRIPTION_TEXT[PAT_INSCRIPTION_EMPTYSEAT],  "EMPTYSEAT");
  lstrcpy(m_BramaGraphData.INSCRIPTION_TEXT[PAT_INSCRIPTION_CALL],    "CALL");
  lstrcpy(m_BramaGraphData.INSCRIPTION_TEXT[PAT_INSCRIPTION_BET],      "BET");
//=====================    =======================
  m_BramaGraphData.PATTERN_CARD[PAT_CARD_EMPTY][0] = 30;
  m_BramaGraphData.PATTERN_CARD[PAT_CARD_EMPTY][1] = 30;
  m_BramaGraphData.PATTERN_CARD[PAT_CARD_EMPTY][2] = 30;
  m_BramaGraphData.PATTERN_CARD[PAT_CARD_HIDE][6] = 188;
  m_BramaGraphData.PATTERN_CARD[PAT_CARD_HIDE][7] = 151;
//=====================    ==================
  lstrcpy(m_BramaGraphData.CARD_TEXT[PAT_CARD_EMPTY],  "");
  lstrcpy(m_BramaGraphData.CARD_TEXT[PAT_CARD_HIDE],  "hid");
  lstrcpy(m_BramaGraphData.CARD_TEXT[PAT_CARD_2C],  "2C");
  lstrcpy(m_BramaGraphData.CARD_TEXT[PAT_CARD_4H],  "4H");
//=====================     =================
//=====================      ===
  lstrcpy(m_BramaGraphData.HOLEHIDDEN_TEXT[PAT_HOLEHIDDEN_EMPTY],  "");
  lstrcpy(m_BramaGraphData.HOLEHIDDEN_TEXT[PAT_HOLEHIDDEN_ONE],  "one-hidden");
  lstrcpy(m_BramaGraphData.HOLEHIDDEN_TEXT[PAT_HOLEHIDDEN_TWO],  "hidden");
//=====================   ===========================
  m_BramaGraphData.PATTERN_MISC[PAT_MISC_BUTTON][0] = 216;
  m_BramaGraphData.PATTERN_MISC[PAT_MISC_BUTTON][1] = 72;
  m_BramaGraphData.PATTERN_MISC[PAT_MISC_BUTTON][2] = 8;
  m_BramaGraphData.PATTERN_MISC[PAT_MISC_BUTTON][3] = 151;
  m_BramaGraphData.PATTERN_MISC[PAT_MISC_BUTTON][4] = 221;
  m_BramaGraphData.PATTERN_MISC[PAT_MISC_BUTTON][5] = 194;
  m_BramaGraphData.PATTERN_MISC[PAT_MISC_BUTTON][6] = 231;

  return TRUE;
}


Und hier ist ein Beispiel für Code, der solche Bitmaps zur Erkennung verwendet:
Beispiel für einen Erkennungscode
typedef struct tagSURJA_CRAPH_DATA
{
  BYTE  PATTERN_LETTER[COUNT_LETTERS][SIZE_PATTERN_LETTER];       //  
  BYTE  LETTER_CODE[COUNT_LETTERS];                   //  
  BYTE  LETTER_SIZE[COUNT_LETTERS];                   //  

  BYTE  PATTERN_INSCRIPT[COUNT_INSCRIPTIONS][SIZE_PATTERN_INSCRIPTION]; //   
  char  INSCRIPTION_TEXT[COUNT_INSCRIPTIONS][SIZE_INSCRIPTION_TEXT];  //  
  BYTE  PATTERN_CARD[COUNT_CARDS][SIZE_PATTERN_CARD];          //  
  char  CARD_TEXT[COUNT_CARDS][SIZE_CARD_TEXT];             //  
  BYTE  PATTERN_HOLEHIDDEN[COUNT_HOLEHIDDEN][SIZE_PATTERN_HOLEHIDDEN]; //    
  char  HOLEHIDDEN_TEXT[COUNT_HOLEHIDDEN][SIZE_HOLEHIDDEN_TEXT];    //     
} SURJA_CRAPH_DATA, *LPSURJA_GRAPH_DATA;



Auf die eine oder andere Weise - obwohl wir ein neuronales Netzwerk verwenden, zumindest mit unseren Händen, zumindest mit etwas Drittem - sollten bei der Erkennung vier grundlegend unterschiedliche Bereiche berücksichtigt werden: 1) statisch (diejenigen, bei denen theoretisch nie etwas passiert); einschließlich außerhalb der Pokersoftware (zum Beispiel tritt eine Aktion außerhalb des Poker-Clients auf, angeblich vom Windows-System aus, aber tatsächlich - prüft auf Botabilität); 2) dynamisch sehr informativ (Stapelgröße, aktueller Spieler, Karten auf dem Tisch usw.); 3) dynamisch schlecht informativ (Orte, an denen Nachrichten selten erscheinen und chatten); 4) dynamisch nicht informativ (zum Beispiel Bereiche, in denen die Animation der Kartenverteilung stattfindet).


Unsichtbare Analyse


Der analytische Teil des Bots im Fall von Poker ist ein Mechanismus für die Interaktion mit der Datenbank - da fast alle für Online-Poker relevanten „Tells“ auf der Analyse des Verhaltensmodells von Spielgegnern beruhen. Die ideale Option ist hier Ihr eigenes Oracle zu Hause, das für die intensive Arbeit mit einer großen Datenbank mit Hunderttausenden von Datensätzen unverzichtbar ist. Es wird nämlich so viele von ihnen geben, wenn Sie ernsthaft und lange in der botanischen Landwirtschaft tätig sein wollen. Wenn Sie nur einen Bot brauchen, um sich zu verwöhnen, können Sie kein Geld für das Oracle ausgeben. Das MS Access DBMS ist auch sehr gut geeignet - Sie können es einfach von Ihrem Programm aus kontaktieren, beispielsweise über ODBC. So könnte es aussehen:
Interaktion mit MS Access
BOOL InitODBC()
{
  SQLRETURN    ret;
  SQLSMALLINT    Length;

  ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_HANDLE_NULL, &hEnv);
  if (SQL_SUCCESS != ret && SQL_SUCCESS_WITH_INFO != ret)
    return FALSE;

  ret = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, NULL);
  if (SQL_SUCCESS != ret && SQL_SUCCESS_WITH_INFO != ret)
    return FALSE;

  ret = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hConn);
  if (SQL_SUCCESS != ret && SQL_SUCCESS_WITH_INFO != ret)
    return FALSE;

  lstrcpyn(szConnect, STR_CONNECT, MAXSIZE_CONNECTSTR);
  ret = SQLDriverConnect(hConn, NULL, (SQLTCHAR *) szConnect, lstrlen(szConnect), (SQLTCHAR *) szConnect, MAXSIZE_CONNECTSTR, &Length, SQL_DRIVER_COMPLETE);
  if (SQL_SUCCESS != ret && SQL_SUCCESS_WITH_INFO != ret)
    return FALSE;

  return TRUE;
}

void DoneODBC()
{
  SQLDisconnect(hConn);
  SQLFreeHandle(SQL_HANDLE_DBC, hConn);
  SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}



BOOL InsertInDB(LPCSTR lpcszText, LPCSTR lpcszTitle, DWORD dwLocale)
{
  SQLHANDLE  hStmt;
  SQLRETURN  ret;
  char    szTitle[SIZE_TITLE];
  char    szQuery[MAXSIZE_QUERYSTR];


  //          //
  ret = SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt);
  if (SQL_SUCCESS != ret && SQL_SUCCESS_WITH_INFO != ret)
    return FALSE;

  wsprintf(szQuery, "INSERT INTO index (text, title, locale) VALUES ('%s', '%s', %d)", lpcszText, szTitle, dwLocale);

  ret = SQLExecDirect(hStmt, (SQLTCHAR *) szQuery, lstrlen(szQuery));

  if (SQL_SUCCESS != ret && SQL_SUCCESS_WITH_INFO != ret)
    return FALSE;
  SQLFreeHandle(SQL_HANDLE_STMT, hStmt);

  return TRUE;
}


Wenn es nicht um Poker geht, sondern beispielsweise um Schach, kann ein Austausch mit einer Schach-Engine eines Drittanbieters als analytischer Teil implementiert werden. So interagieren Sie beispielsweise mit Fritz:
Interaktion mit der Analyse-Engine
BOOL SendData2Fritz(char szFritz[100])
//    //
{
  if (!FritzStr2Clipboard(szFritz))
    return FALSE;
  SendMessage(m_hwndFritz, WM_COMMAND, MAKELONG(IDM_PASTE_POSITION, 0), 0); 
  Sleep(2);
  SendMessage(m_hwndFritz, WM_COMMAND, MAKELONG(IDM_MOVE_NOW, 0), 0); 

  return TRUE;
}


BOOL ReceiveDataFromFritz(int busy[8][8], LPBOOL lpbEndGame)
//     //
{
  char szFritz[100];

  *lpbEndGame = FALSE;

  SendMessage(m_hwndFritz, WM_COMMAND, MAKELONG(IDM_COPY_POSITION, 0), 0);
  if (!Clipboard2FritzStr(szFritz))
    return FALSE;
  return TRUE;
}

BOOL FritzStr2Clipboard(LPCSTR lpcszFritz)
//         //
{
  HGLOBAL hGlobalMemory;    //   
  LPVOID pGlobalMemory;     //   

  hGlobalMemory = GlobalAlloc(GHND, lstrlen(lpcszFritz)+1);
  if (hGlobalMemory == NULL)
    return FALSE;
  pGlobalMemory = GlobalLock(hGlobalMemory);
  lstrcpy((LPSTR) pGlobalMemory, lpcszFritz);
  GlobalUnlock(hGlobalMemory);

  if (!OpenClipboard(NULL))
    return FALSE;
  if (!EmptyClipboard())
    return FALSE;
  SetClipboardData(CF_TEXT, hGlobalMemory);
  CloseClipboard();

  return TRUE;
}

BOOL Clipboard2FritzStr(LPSTR lpszFritz)
//        //
{
  HANDLE hClipMemory;    //   
  LPVOID pClipMemory;    //     

  if (IsClipboardFormatAvailable(CF_TEXT))
  {
    if (!OpenClipboard(NULL))
      return FALSE;
    hClipMemory = GetClipboardData(CF_TEXT);
    if (hClipMemory == NULL)
      return FALSE;
    pClipMemory = GlobalLock(hClipMemory);
    lstrcpyn(lpszFritz, (LPSTR) pClipMemory, 100);
    GlobalUnlock(hClipMemory);
    CloseClipboard();
  }
  return TRUE;
}



Ein weiteres Werkzeug, das bei der Programmierung von Analysen nützlich sein kann, ist das sogenannte. "Finite-State-Maschinen". So können sie in Online-Multiplayer-Spielen verwendet werden (dies ist ein Fragment des Bots für das Spiel "Keepers of Power"):
Beispiel für eine Zustandsmaschine
typedef enum AUTOMATA_BATLE
{
  //  
  AS_BATLE_BEGIN,
  AS_BATLE_END,
  AS_BATLE_ERROR,

  AS_BATLE_TEST2MOB,     // ,    
  AS_BATLE_WAIT2NICK,    //    
  AS_BATLE_WAIT2MOB,     //   
  AS_BATLE_PROCESS,     //   ,    
  AS_BATLE_CLICK2OK_1,    //  OK
  AS_BATLE_WAITCHANGE,    //   
  AS_BATLE_CLICK2MONEY,   //    ""
  AS_BATLE_TEST2DROP,    //     (  "")
  AS_BATLE_CLICK2DROP,    //    ""
  AS_BATLE_CLICK2CLOSE,   //    ""
  AS_BATLE_WAIT2DROP,    //     
  AS_BATLE_CLICK2TAKEALL,  //  " "
  AS_BATLE_WAIT2CONFIRM,   //  
  AS_BATLE_CLICK2OK_2,    //  
  AS_BATLE_WAIT2BACK,    //   
  AS_BATLE_CLICK2BACK,    //  ""
  AS_BATLE_WAIT2STARTWINDOW, //    
  AS_BATLE_WAIT2NEXT     //  30 
};



AUTOMATA_BATLE CAutomataBatle::GoStep(HDC hdc)
{
  char szMessage[255];

  switch (m_automata_batle)
  {
  //        //
  case AS_BATLE_BEGIN:
    m_automata_batle = AS_BATLE_WAIT2STARTWINDOW;
    SetWindowText(m_hwndControl, "  ");
    break;
  case AS_BATLE_WAIT2STARTWINDOW:
    if (IsStartPresent(hdc))
    {
      SetWindowText(m_hwndControl, " ");
      m_automata_batle = AS_BATLE_TEST2MOB;
    }
    break;
  case AS_BATLE_TEST2MOB:
    if (IsMechPresent(hdc))
      if (!ClickMenuItem(INDEX_GOBATLE))
        return AS_BATLE_ERROR;
    if (IsCellEmpty(hdc))
    {
      SetWindowText(m_hwndControl, "  ");
      m_automata_batle = AS_BATLE_END;
    }
    else
    {
      hwndBatle = NULL;
      EnumChildWindows(m_hwndMain, EnumWindowsProcBatle, NULL);

      if (NULL != hwndBatle)
      {
        SetWindowText(m_hwndControl, "  ");
        m_automata_batle = AS_BATLE_WAIT2NICK;
      }
    }
    break;
  case AS_BATLE_WAIT2NICK:
    if (IsNickPresent(hdc))
    {
      SetWindowText(m_hwndControl, "  ");
      m_automata_batle = AS_BATLE_WAIT2MOB;
    }
    break;
  case AS_BATLE_WAIT2MOB:
    if (!IsNickOpEmpty(hdc))
    {
      SetWindowText(m_hwndControl, " ");
      m_automata_batle = AS_BATLE_PROCESS;
    }
    break;
  case AS_BATLE_PROCESS:
    if (!IsBatleEnd(hdc))
    {
      if (!ClickMenuItem2Window(hwndBatle, INDEX_STRIKE))
        return AS_BATLE_ERROR;
    }
    else
    {
      SetWindowText(m_hwndControl, "  ");
      m_automata_batle = AS_BATLE_CLICK2OK_1;
    }
    break;
  case AS_BATLE_CLICK2OK_1:
    if (!ClickMenuItem2Window(hwndBatle, INDEX_OK2BATLEEND))
      return AS_BATLE_ERROR;
    SetWindowText(m_hwndControl, "  ");
    m_automata_batle = AS_BATLE_WAITCHANGE;
    break;
  case AS_BATLE_WAITCHANGE:
    if (IsChangePresent(hdc))
    {
      SetWindowText(m_hwndControl, " ");
      m_automata_batle = AS_BATLE_CLICK2MONEY;
    }
    break;
  case AS_BATLE_CLICK2MONEY:
    if (!ClickMenuItem(INDEX_MONEY))
      return AS_BATLE_ERROR;
      SetWindowText(m_hwndControl, " ");
    m_automata_batle = AS_BATLE_TEST2DROP;
    break;
  case AS_BATLE_TEST2DROP:
    if (IsButtonDropPresent(hdc))
    {
      SetWindowText(m_hwndControl, "  \"\"");
      m_automata_batle = AS_BATLE_CLICK2DROP;
    }
    else if (IsButtonClosePresent(hdc))
    {
      SetWindowText(m_hwndControl, " ,   \"\"");
      m_automata_batle = AS_BATLE_CLICK2CLOSE;
    }
    break;
  case AS_BATLE_CLICK2DROP:
    if (IsButtonDropPresent(hdc))
    {
      if (!ClickMenuItem(INDEX_DROP))
        return AS_BATLE_ERROR;
    }
    else
    if (IsDropPresent(hdc))
    {
      SetWindowText(m_hwndControl, "  ");
      m_automata_batle = AS_BATLE_WAIT2DROP;
    }
    else if (IsStartPresent(hdc))
      m_automata_batle = AS_BATLE_WAIT2STARTWINDOW;
    break;
  case AS_BATLE_CLICK2CLOSE:
    if (!ClickMenuItem(INDEX_CLOSE))
      return AS_BATLE_ERROR;
    if (IsStartPresent(hdc))
    {
      SetWindowText(m_hwndControl, "  ");
      m_dwWait = 0;
      m_automata_batle = AS_BATLE_WAIT2NEXT;
    }
    break;
  case AS_BATLE_WAIT2DROP:
    if (IsDropPresent(hdc))
    {
      SetWindowText(m_hwndControl, "  ");
      m_automata_batle = AS_BATLE_CLICK2TAKEALL;
    }
    break;
  case AS_BATLE_CLICK2TAKEALL:
    if (!ClickMenuItem(INDEX_TAKEALL))
      return AS_BATLE_ERROR;
    SetWindowText(m_hwndControl, "  ");
    m_automata_batle = AS_BATLE_WAIT2CONFIRM;
    break;
  case AS_BATLE_WAIT2CONFIRM:
    if (IsConfirmPresent(hdc))
    {
      SetWindowText(m_hwndControl, "");
      m_automata_batle = AS_BATLE_CLICK2OK_2;
    }
    break;
  case AS_BATLE_CLICK2OK_2:
    if (!ClickMenuItem(INDEX_OK2TAKEALL))
      return AS_BATLE_ERROR;
    if (!IsConfirmPresent(hdc))
    {
      SetWindowText(m_hwndControl, "  \"\"");
      m_automata_batle = AS_BATLE_WAIT2BACK;
    }
    break;
  case AS_BATLE_WAIT2BACK:
    if (IsBackPresent(hdc))
    {
      SetWindowText(m_hwndControl, "  \"\"");
      m_automata_batle = AS_BATLE_CLICK2BACK;
    }
    break;
  case AS_BATLE_CLICK2BACK:
    if (!ClickMenuItem(INDEX_BACK))
      return AS_BATLE_ERROR;
    if (IsStartPresent(hdc))
    {
      SetWindowText(m_hwndControl, "  ");
      m_dwWait = 0;
      m_automata_batle = AS_BATLE_WAIT2NEXT;
    }
    break;
  case AS_BATLE_WAIT2NEXT:
    if (m_dwWait >= WAIT_2NEXTBATTLE)
    {
      SetWindowText(m_hwndControl, "  ");
      m_automata_batle = AS_BATLE_WAIT2STARTWINDOW;
    }
    else
    {
      wsprintf(szMessage, "(%d  %d) ...", m_dwWait/2, WAIT_2NEXTBATTLE/2);
      SetWindowText(m_hwndControl, szMessage);
      m_dwWait++;
    }
    break;
  case AS_BATLE_END:
    m_automata_batle = AS_BATLE_BEGIN;
    break;
  }




Unsichtbare Emulation


Es gibt zwei Phasen - vorbereitende und operative. Sowohl das eine als auch das andere implizieren nicht nur das Schreiben der entsprechenden Programme, sondern auch das Arbeiten mit Eisen. Hier kann man nicht auf das Eintauchen in Mikrocontroller verzichten. Glücklicherweise muss das Rad nicht neu erfunden werden - es gibt vorgefertigte Software- und Hardwarelösungen, die im Internet leicht zu finden sind. Einschließlich des Quellcodes des Programms für den Mikrocontroller, der leicht an Ihre Bedürfnisse angepasst werden kann.

In der Vorbereitungsphase (Aufzeichnen von Arbeitsstunden mit Maus und Tastatur) können Sie hier auf Hardware-Gadgets verzichten, wenn Sie dies wünschen. Sie können einen Treiberfilter schreiben, der Aufrufe von IOCTL_INTERNAL_I8042_HOOK_KEYBOARD erfasst. Als Basis können Sie das Programm ctrl2cap verwenden, dessen Quellcode im DDK verfügbar ist. Diese Lösung ist jedoch nicht universell - es ist besser, einen Hardware-Sniffer zu verwenden.

In der Betriebsphase gibt es definitiv keine Möglichkeit, auf Hardware-Gadgets zu verzichten. Eine der möglichen Lösungen könnte die Kommunikation mit einem Mikrocontroller (der in Kombination auch ein Splitter sein wird) einerseits über RS-232 und andererseits über ein PS / 2-Bouquet sein. Um mit RS-232 zu arbeiten, gibt es zwei Möglichkeiten: Sie können entweder normale Windows-Tools verwenden und über CreateFile / ReadFile / WriteFile mit dem RS-232-Port oder direkt über die Eingabe- / Ausgabeports kommunizieren. Im zweiten Fall müssen Sie einen einfachen Treiber schreiben, der den Zugriff auf E / A-Ports freischaltet, da der Windows-Zugriff auf diese standardmäßig geschlossen ist. Halte dich von der Sünde fern. Wenn Sie immer noch auf die Eingabe- / Ausgabeports zugreifen konnten, finden Sie hier den Code für den Datenaustausch über RS-232:
RS-232-Code
#define dataport  0x02F8   //   COM2
#define irport   0x02F9   //       
#define manager   0x02FB   //  
#define statline  0x02FD   //  
#define upr1    0x00BB      
#define upr2    0x003B
#define freq    0x000C   //    (9600 )

DWORD OpenPort()
/*  COM- */
{
  __asm
  {
    mov  eax, upr1    //   0  1    
    mov  edx, manager
    out  dx, al

    mov  eax, freq    //    
    mov  edx, dataport
    out  dx, al     //       

    mov  al, ah
    mov  edx, irport
    out  dx, al     //       

    mov  eax, upr2
    mov  edx, manager
    out  dx, al

    mov  al, 0      //  
    mov  edx, irport
    out  dx, al
  }
}

DWORD WriteByte(BYTE data)
/*    COM- */
{
  __asm
  {
    mov  al, data    //    
    mov  edx, dataport
    out  dx, al     //     
waitout:
    mov  edx, statline
    in   al, dx     //   
    mov  ah, al
    and  al, 0x40    // ,    
    jz   waitout     //   – 
  }
} // void WriteByte

BOOL ReadByte(BYTE data)
/*    COM- */
{
  int cntWait = 0;

  __asm
  {
    mov  edx, statline
    xor  ecx, ecx
waitread:
    add  cntWait, 1
    cmp  cntWait, 0xFFFF
    jz   error
    in   al, dx     //   
    mov  bl, al     // ,   
    and  eax, 1
    jz   waitread    //    –  
    mov  edx, dataport  //   –   
    xor  eax, eax
    in   al, dx     //     
    mov  data, al
error:
  }
  if (cntWait != 0xFFFF)
    return TRUE;
  else
    return FALSE;
} // BYTE ReadByte


Der Mechanismus zum Abfangen und Emulieren von Tastatursignalen mit einer Maus ist also verständlich. Es bleibt nur herauszufinden, wie ein glaubwürdiges Verhaltensmodell aus biometrischer Sicht aus einem kontinuierlichen Strom von Tastatur- und Mausdaten erstellt werden kann, die von einem Schnüffler empfangen werden. Darüber hinaus besteht eine der interessantesten Aufgaben in dieser Phase darin, die Maus vom Startpunkt zu einem anderen, speziell eingestellten Punkt zu bewegen.

Eine der möglichen Lösungen umfasst zwei Elemente: 1) Konfigurieren des neuronalen Netzwerks, 2) Anpassen der Bewegung und Unterrichten des neuronalen Netzwerks in Zusammenarbeit mit dem „Screener“. Mit diesem Ansatz ist es möglich, ein neuronales Netzwerk mit minimaler menschlicher Beteiligung zu trainieren. Der Trainingsalgorithmus für neuronale Netze kann wie folgt sein:
  1. Wir wählen zufällige Koordinaten aus, bei denen die Maus bewegt werden soll.
  2. Wir geben sie zusammen mit den aktuellen Koordinaten an das neuronale Netzwerk weiter.
  3. Wir sehen, wie sehr sich das neuronale Netzwerk geirrt hat.
  4. Wir passen das neuronale Netzwerk an.
  5. Wiederholen Sie 1-4 bis zum Sieg. Angesichts der vom Hardware-Sniffer empfangenen Daten bewegt das neuronale Netzwerk den Mauszeiger nicht nur genau, sondern auch biometrisch plausibel.



Was weiter


Die Implementierung dieses neuronalen Netzwerkschemas sowie des oben erwähnten Bildschirmerkennungsschemas für neuronale Netzwerke ist ein Thema für eine separate Diskussion, die den Rahmen dieses Artikels sprengt. Diese beiden Aufgaben, die über den Rahmen des Artikels hinausgingen, sind die „grundlegenden technischen Konzepte“, die der „mittelständische Ingenieur“ unabhängig lösen muss. Was die "trivialen Programmierprobleme" betrifft, so ist die Implementierung der meisten von ihnen in diesem Artikel ebenfalls nicht enthalten. Diese 10 Einträge, die im Artikel aufgeführt sind, sind nur ein Keim, der den technischen Appetit fördern soll.

Ein weiterer wichtiger Punkt. Wenn Sie diesen Artikel bei der Entwicklung Ihres eigenen Bots verwenden, sollten Sie verstehen: Wenn mehrere alternative Optionen (ideal und einige Kompromisse) angeboten werden, um einen bestimmten Funktionsknoten zu implementieren, ist die Wahl rhetorisch. Es versteht sich, dass die ideale Option verwendet wird. Wenn Sie Kompromisse eingehen, auch wenn es nur einen gibt, ist der Bot anfällig für Gegenangriffe der "hellen Seite der Macht".


Die Rückkehr der Jedi



Abb. 5. Rückkehr der Jedi

Das oben beschriebene Schema des unverwundbaren Bot-Fahrens, das angesichts der "Kämpfer für Gerechtigkeit" den ultimativen und unwiderruflichen Sieg darstellt. Es wäre jedoch langweilig, wenn die Jedi der "positiven Seite der Macht" nicht die Gelegenheit hätten, den Botsfrauen etwas entgegenzusetzen. Wenn dies nicht möglich wäre, würde der Autor, der versucht, sich an die "gute Seite der Macht" zu halten, dieses Schema nicht veröffentlichen. Darüber hinaus möchte ich glauben, dass ein erheblicher Teil der Leser auch an der „positiven Seite der Macht“ festhält und dass sie nicht daran interessiert sind, dieses System zu missbrauchen, sondern sich dagegen zu wehren. Der Artikel enthält keine detaillierten Quellcodes und lässt einige grundlegende technische Konzepte aus - gerade um Missbrauch zu vermeiden.

Ein paar Worte darüber, wie Sie dem beschriebenen Schema der botanischen Produktion widerstehen können. Sie ist praktisch unverwundbar. Die theoretische Möglichkeit seiner Entdeckung bleibt jedoch bestehen. Diese Funktion ist mit der Verfolgung atypischen Mausverhaltens verbunden, das selbst bei einer hochwertigen Emulation ausrutschen kann. Tatsache ist, dass die Maus viele „biometrische Tells“ am Schwanz trägt - ausgedrückt in Pokersprache. Sie ist der Person am nächsten. Die geringste Muskelbewegung, die durch eine Veränderung des emotionalen Hintergrunds verursacht wird - all dies beeinflusst, wie wir die Maus in unseren Händen halten.

In diesem Zusammenhang hat der Autor des Artikels eine originale bionische Studie unter dem Arbeitstitel "Integrierte Architektur des Homo Sapiens", die eine Beschreibung der Physiologie und Psyche einer Person enthält - in Modellen, die für den IT-Betrieb geeignet sind. Dank der positiven Ergebnisse dieser Studie fühle ich das moralische Recht, das Schema des „unverwundbaren“ Bot-Fahrens öffentlich zu machen, weil Die "helle Seite der Macht" hat eine Chance zu gewinnen. Aus dieser Studie kann man unter anderem verstehen, wie unser Gebrauch der Maus über die Schnittstelle des Rückenmarks mit unserer geistigen Aktivität zusammenhängt. In gewissem Maße erlaubt dies im übertragenen Sinne, die Gedanken der Person zu lesen, die seine Hand auf die Maus gelegt hat. In diesem „Lesen von Gedanken“ wird ein möglicher Vektor von Gegenangriffen von „Kämpfern für Gerechtigkeit“ gesehen.

T.O. Der Kampf zwischen der dunklen und der hellen Seite der Macht geht weiter. Einige versuchen, sich als Menschen auszugeben, während andere das atypische Verhalten der Maus überwachen. Das Erstellen eines virtuosen Mausemulators ist wie das Erstellen eines Jedi-Lichtschwerts. Und die Tatsache der virtuosen Nachahmung zu entdecken, ist dasselbe wie den Schlag dieses Schwertes mit einem anderen Lichtschwert abzuwehren. Wer wird stärker sein?


Das Erwachen der Macht



Abb. 6. Erwachen der Macht

Auf die eine oder andere Weise, egal auf welcher Seite wir stehen - für Bots oder gegen sie - müssen wir die Technik verbessern, ein Lichtschwert zu besitzen. Im Sinne der Entwicklung des Muskels des technischen Einfallsreichtums in sich. Seine Hauptkomponente ist die Fähigkeit, sich auf die Aufgabe zu konzentrieren, "hier und jetzt" zu sein. Im Wesentlichen ist diese yogische Perfektion Samadhi. Samadhi in Sanskrit bedeutet - volle Konzentration auf ein Thema. Volle Konzentration! Wenn Sie einen Sonnenstrahl mit einer Linse aufnehmen, wird die Oberfläche, auf die Sie ihn gerichtet haben, gezündet. Ebenso in der Technik. Die ganze Energie, die wir haben, müssen wir uns als Linse konzentrieren und sie in der Technik nutzen. Aber nutzen Sie seine Energie nicht zum Nachteil, wie Kinder, die eine Linse nehmen und anfangen, Ameisen zu verbrennen. Kreative Energie sollte für immer genutzt werden.

# #

-, – , – IDE , , : «#define QUESTION bb || !bb». « – », . – 5000 , – , : , – « ». , «-», «-». , , , , . . , « », 1880- , , . – - ,Was auf den Seiten von Srimad-Bhagavatam ausführlich gelesen werden kann, entspricht dem OM-Sound auf die gleiche Weise, wie moderne Programmiersprachen auf hoher Ebene dem Assembler entsprechen (weitere Einzelheiten siehe "Code # code" ).


Die Basis der Konzentration ist ein spiritueller Kern, für dessen Schärfen Sie ein solches High-Tech-Gerät als „Buch“ verwenden können. Natürlich ein gutes spirituelles Buch. Ein „Buch“ ist das letzte Wort in der Technologie: 1) es öffnet sich mit einem Handgriff, 2) es ist mit einem flimmerfreien Bildschirm ausgestattet, 3) es hat eine ewige Batterieladung. Für den Autor des Artikels ist dies Srimad-Bhagavatam (in Sowjetzeiten strengstens verboten). Sie können darüber im Artikel „Mission des Bhagavatam“ lesen .

Darüber hinaus benötigen Sie für die Konzentration, egal wie alltäglich, einen gesunden Ton von Körper und Geist. Es gibt viele Möglichkeiten, sich zu verbessern. Für den Autor dieses Artikels ist dies beispielsweise eine vegetarische Ernährung (vedische Küche), Sportbekleidung (kmc zum Skifahren) und Mantra-Meditation (Rezitation von Hare Krsna, Hare Krsna, Krsna Krsna, Hare Hare / Hare Rama, Hare Rama, Rama Rama, Hase Hase). Sie können über dieses Mantra im Artikel "Prinzip des Hare Krishna Mantra" lesen . Sie können meine Erfahrung nutzen oder etwas Eigenes verwenden. Und möge die Kraft mit uns kommen.

Source: https://habr.com/ru/post/de389433/


All Articles