El ataque de los clones: tecnologías modernas de conducción de bots

"Ahora escribes el programa más difícil de tu vida, que simplemente sumará dos números".
Irina Ryzhova Los


juegos de apuestas inteligentes en línea son un tidbit para los bots. Incluso si los desarrolladores de software de juegos gastan mucho dinero en atrapar bots, como en las salas de póker en línea, por ejemplo, todavía hay una alta probabilidad de tropezar con un "bot inteligente", el juego con el que será uno contra uno. Especialmente si el bot es absolutamente invulnerable ... Porque ningún dinero protegerá el sistema a través del cual pasa mucho dinero.


Fig. 1. Botovody viene


Amenaza oculta


Los juegos de apuestas intelectuales en línea no son seguros. Especialmente inseguros son aquellos en los que gira el dinero real. Su inseguridad se manifiesta principalmente en el hecho de que es imposible saber con certeza con quién estás jugando: con una persona viva o con un bot. En el segundo caso, el juego tendrá un objetivo. En juegos de "interés", - ajedrez y damas en mail.ru, por ejemplo, - los propietarios de juegos en línea miran la botovotirovanie con los dedos. En los juegos multijugador en línea, que en cierta medida cuentan con dinero en vivo, se presta un poco más de atención a la captura de bots. Sin embargo, incluso si el enfoque para suprimir botswood es extremadamente serio, como se hizo, por ejemplo, en las salas de póker en línea, todavía hay una alta probabilidad de tropezar con un bot.

Los desarrolladores de software de póker gastan mucho dinero exponiendo bots, y sin embargo, el botswana de póker en línea está en auge. Porque ningún dinero puede proteger el sistema a través del cual pasa mucho dinero. Botovodov y los receptores de bots, analizando los trucos de los oponentes y tomando las contramedidas apropiadas, ganan alternativamente. Alguien puede pensar que la batalla entre ellos nunca terminará. Sin embargo, existe un esquema seguro de conducción de bots por el que pasan los receptores de bots. Es interesante porque, aunque los "luchadores por la justicia" tengan en sus manos en detalle los códigos fuente comentados del bot, no podrán establecer el hecho de su uso. La implementación de este esquema es un evento costoso, sin embargo, dado que el beneficio potencial es grande, el esquema es bastante relevante.

#

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




: , .En primer lugar, el bot toma fotos del estado actual del juego, ya sea mediante una captura de pantalla o interceptando el tráfico de la red. En segundo lugar, el bot decide qué hacer en esas circunstancias, a veces recurriendo a software de terceros (por ejemplo, en el caso del ajedrez, puede interactuar con algún tipo de motor de ajedrez). Finalmente, en tercer lugar, el bot emula la interacción del usuario con el teclado y el mouse. Además, este ciclo ternario, que los cazadores de bots buscan rastrear y romper, se repite. En consecuencia, la batalla entre botovodov y "luchadores por la justicia" tiene lugar en tres frentes. Esta batalla tiene una historia larga y emocionante, pero nos centraremos solo en su duelo final, en el que los "luchadores por la justicia", frente a un bot absolutamente invulnerable, sufrieron un fiasco incondicional.

La tecnología botánica invulnerable se logra a través de fotografía invisible, análisis invisible y emulación invisible. Es imposible hacer esto en una computadora. En primer lugar, porque el software de póker moderno tiene los elementos de un rootkit.

#

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

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

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

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

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


, .. , .La solución es iniciar el bot no en la estación de trabajo desde la que se juega, sino en una computadora separada: un emulador. Luego, sujeto a tres condiciones paranoicas, el software de póker no tendrá la oportunidad de reconocer el hecho de la emulación: 1) la estación de trabajo y el emulador no deberían poder comunicarse a través de la red; 2) para fotografiar el estado actual del juego, debe usar la salida analógica de la tarjeta de video, conectada a la “computadora de pantalla” usando una tarjeta de captura de video; 3) para emular el teclado y el mouse, debe usar un dispositivo de hardware y software, cuya entrada está conectada a la computadora del emulador y la salida, a dos estaciones de trabajo PS / 2 desde las cuales se juega el juego. Es la salida de video analógico y PS / 2 que el software de póker no sabe que algunos equipos adicionales están conectados a la computadora.



Al emular el teclado y el mouse, debe tener en cuenta las circunstancias biométricas y tecnométricas relevantes, que también pueden ser monitoreadas por el software de póker. En cuanto a la biometría, al emular el teclado y el mouse, se debe tener cuidado de emular que los movimientos del cuerpo son similares a la verdad. Debe tenerse en cuenta que, en primer lugar, una persona viva no puede jugar a un ritmo estable durante mucho tiempo inmediatamente en 16 mesas simultáneamente, especialmente en un monitor de ocho pulgadas. En segundo lugar, una persona viva no puede jugar 28 horas al día, 6 días a la semana. Finalmente, en tercer lugar, los movimientos de una persona viva pueden cambiar, dependiendo de cuánto tiempo haya pasado frente a la computadora. Para emular circunstancias biométricas plausibles, necesitará: 1) "PS / 2-sniffer" - loción de software y hardware,que escuchará el flujo de datos enviados por el teclado y el mouse al puerto PS / 2, y guardará todo lo que se escuche en un archivo separado, que posteriormente se utilizará para emular circunstancias biométricas plausibles; 2) una persona viva que realmente jugará al póker en línea durante el tiempo que se planee incluir el bot; sus acciones serán registradas por el "PS / 2-sniffer".

En cuanto a la tecnometría, cada teclado y mouse tiene su propia "escritura a mano" única. Se puede rastrear analizando a un nivel bajo el flujo sin procesar de señales que provienen de ellos a la computadora. Por lo tanto, si varias estaciones de trabajo están involucradas en la conducción de bots a la vez, en preparación para la emulación biométrica, para cada una de ellas es necesario: 1) organizar una intervención telefónica individual, con diferentes teclados y diferentes ratones, 2) plantar diferentes personas para cada estación de trabajo cuyas acciones serán arreglarse con un "sniffer PS / 2". La necesidad del segundo párrafo se debe al hecho de que cada persona usa el mouse y el teclado individualmente. Con suficiente material estadístico extenso, es posible determinar con un grado suficiente de certeza quién está sentado en la computadora, incluso si el usuario no está autenticado.

# -

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


Por lo tanto, se realiza la preparación para la emulación con parámetros biométricos y tecnométricos plausibles. Ahora queda recordar qué teclado y mouse corresponden a qué usuario, y nunca romper esta correspondencia. Ignorar la biometría y la tecnometría o su emulación inverosímil puede conducir al bloqueo de cuentas sin explicación. Sujeto a todas las precauciones, no importa cuán paranoicos puedan parecer, uno puede contar con bots invulnerables.


Elementos del bot invulnerable



Fig. 2. Bot

invulnerable Un bot invulnerable es un complejo de hardware y software que incluye una flota completa de computadoras que resolverán 6 tareas fundamentalmente diferentes. Además de algunas lociones de hardware y software. Además de dos personas vivas, para observar y responder a situaciones de emergencia.

1. Una estación de trabajo (con IP dedicada o PROXY de alta calidad), donde se lanzan 9 salas de póker al mismo tiempo. Debe tener una tarjeta de video con salida de video analógico de alta definición y un monitor grande, porque muchas habitaciones en un monitor pequeño parecen sospechosas. Es económicamente más rentable usar no una estación de trabajo, sino aproximadamente diez a la vez. En este caso, el bot se puede iniciar simultáneamente en 90 habitaciones a la vez.

2. Screener: una computadora poderosa con una tarjeta de captura de video, que se conecta a través de un divisor de video a todas las estaciones de trabajo. La tarea del examinador es reconocer las señales recibidas y traducirlas a una forma estructural. Estos datos se utilizarán posteriormente para 1) escribir en la base de datos, 2) análisis y 3) tomar decisiones para la acción.

3. Analista: una computadora poderosa que funciona según el principio de un servidor meteorológico, pero en lugar de fenómenos naturales acumula todos los datos de póquer posibles. De hecho, hay mucho más información en el póker informático que en el póker en vivo. Pero el problema es que sin software auxiliar es casi imposible rastrearlos. Y el uso de dicho software se detiene de todas las formas posibles: puede obtener una prohibición si lo usa en una estación de trabajo.

4. Espía: cuentas separadas desde las cuales no se juega el juego, sino solo una colección secuencial de toda la información disponible de todas las habitaciones disponibles. Debería haber varios espías, porque si la misma cuenta inicia sesión junto con nuestro juego y cierra la sesión al final, puede arrojar una moneda sistemática en la alcancía de sospechas, y cuando esta alcancía está llena, cerramos la cuenta sin dar ninguna razón. Un "espía" debería funcionar según el mismo principio que una "estación de trabajo". Puede parecer que hay suficiente pantalla de software y emulación de software de un mouse con teclado. Sin embargo, dado que el software de póker se puede unir potencialmente al hardware y a las cuentas de conejos subsiguientes, la detección y la emulación de hardware deben realizarse para un espía, así como para una estación de trabajo.

5. Emulador: una computadora cuyo poder no es fundamental. Está conectado a varios divisores para mouse y teclado. Desde estos divisores, los cables van a las entradas PS / 2 para el mouse y el teclado a cada una de las estaciones de trabajo y espías. Esta computadora recibe comandos del analista y los envía a estaciones de trabajo. Teniendo en cuenta las características de hardware del mouse y el teclado, y las características fisiológicas del comportamiento de la persona que trabaja detrás de ellos (biometría y tecnometría).

6. Dos observadores vivos. Estas ya no son computadoras, es decir, personas vivas. Son necesarios, porque los desarrolladores de software de póker no están dormidos, y en cualquier momento pueden ejecutar alguna prueba única, para identificar los controladores de bot. Una persona no es suficiente, porque puede irse según la necesidad o empolvarse la nariz, y en este momento surgirá una situación de emergencia. Hay situaciones en las que todo se decide por segundos. Por lo tanto, es importante que siempre haya alguien cerca de las máquinas. De modo que cuando el "botón rojo se enciende" (cuando el analista encuentra un comportamiento desconocido), una persona podría decirle qué hacer (escribir algo en el chat o cerrar la ventana). Y en ningún caso puede ir directamente a la estación de trabajo, para no romper el modelo de comportamiento correspondiente del teclado y el mouse.Las acciones deben realizarse solo a través del "puesto de comando".

7. Puesto de mando: una computadora cuyo poder tampoco es fundamental. Solo debe estar conectado al emulador. Esta es precisamente la máquina en la que se sientan dos observadores vivos y a través de la cual, si es necesario, hacen los ajustes necesarios al comportamiento del bot.


Toques finales


Entonces, estos son 7 elementos de un bot invulnerable. Al conectarlos, debe tenerse en cuenta que el analizador, el analista y el emulador intercambian datos a través de la red. La interacción con estaciones de trabajo y espías se lleva a cabo estrictamente a través de la salida analógica de la tarjeta de video y PS / 2. Además, estas computadoras deben estar físicamente separadas de todos los demás. No se puede hablar de comunicación entre ellos a través de la red. Debido a la complejidad de dicho complejo de software y hardware, también es importante tener cuidado de minimizar los errores asociados con el factor humano. Para hacer esto, el emulador, entre otras cosas, se encarga de lanzar todo el software necesario en las estaciones de trabajo y en un espía. Un inspector, un analista y un emulador deben estar en alerta inmediatamente después de encenderse; el software correspondiente simplemente debe estar en el inicio.


Nueva esperanza



Fig. 3. Nueva esperanza

El esquema descrito de conducción de bots, incluso con una familiarización superficial con él, no es para los débiles de corazón. Pero lo anterior se da, aunque detallado, pero aún así, su descripción superficial. Para su implementación, uno no debe tener una calificación técnica considerable, tanto en programación como en electrónica. Al programar, un desarrollador necesitará conocimiento de áreas tales como matemáticas discretas, aproximación de splines, transformaciones wavelet, redes neuronales, máquinas de estado, lógica difusa, programación multiproceso, procesamiento de señal digital. Al implementar el hardware del bot, el desarrollador necesitará conocimientos de áreas tales como sistemas de microprocesador, tecnología digital y microprocesador, trabajar con microcontroladores y FPGA, los conceptos básicos de ingeniería eléctrica, programación de controladores de bajo nivel, arquitectura de sistema operativo y arquitectura de procesador.

#

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


Por lo tanto, este es un esquema de conducción de bots seguro. Como se dijo al principio, es interesante porque, aunque los "luchadores por la justicia" tengan en sus manos códigos de comentarios detallados para el bot, no podrán establecer el hecho de su uso. Mientras que un bot ordinario, sin la función de invisibilidad, los "luchadores por la justicia" pueden rastrear, incluso sin su origen. Las tecnologías modernas, en particular los rootkits, que los desarrolladores de software de póker tienen grandes esperanzas, les permiten profundizar en el sistema operativo, etc. actuar según el principio de "sentarse alto, mirar lejos". Con el desarrollo de rootkits y otras tecnologías de protección, los "luchadores por la justicia" tienen una nueva esperanza de una victoria incondicional. Sin embargo, el esquema anterior de conducción segura de bots reduce todas estas esperanzas a nada.La implementación de este esquema es un evento costoso, sin embargo, dado que el beneficio potencial es grande, el esquema es bastante relevante. Entonces tiene sentido atreverse.


La venganza de los Sith


Apenas dicho que hecho. ¡Atrévete! ¿Pero vale la pena pasar tiempo en el resto del artículo? Un ingeniero informático de primera clase, cuya afiliación a la liga superior de la escena X se confirma con algo más significativo que un simple sello en un diploma, definitivamente no vale la pena. En su arsenal X, ya hay suficientes trucos místicos para "vengar" viejos bots sin la ayuda de otra persona, que una vez bloquearon el oxígeno en el "lado brillante de la fuerza".

Los desarrolladores avanzados, cuya participación en la escena X solo se debe a su virtuoso dominio de C ++ y ensamblador, no deberían perder el tiempo, pero por una razón diferente, no lo harán. El grado de detalle del material presentado es insuficiente para ellos, ya que en este artículo no solo se omiten deliberadamente muchas tareas de programación triviales (un desarrollador avanzado se ocupa de ellas uno, dos, tres), sino también algunos conceptos de ingeniería fundamentales. En cuanto a los scripts de script, que ni siquiera hablan C ++ conversacional y ensamblador, no hay duda de los beneficios de este artículo para ellos.

Sin embargo, un ingeniero promedio, que ya ha dejado el desarrollo adolescente (que ha desarrollado un poco de ingenio ingenieril), pero aún no ha entrado en la era de la ingeniería adulta, encontrará aquí ideas interesantes que lo ayudarán a darse cuenta del bot invulnerable. En la medida en que ya puede encontrar soluciones simples para tareas aparentemente complejas, utilizando los recursos disponibles. Y este es precisamente el poder místico que se valora en la escena X, tanto en el lado claro como en el oscuro. La capacidad de poseerlo es lo que distingue a un ingeniero de un desarrollador. Entonces, establezcamos el calor de los “luchadores por la justicia”, mostrando de lo que es capaz el lado oscuro del poder.


El imperio contraataca



Fig. 4. El Imperio contraataca La

buena noticia: la parte más difícil ha terminado. El plan de acción estratégico, que también es una declaración informal del problema, está listo. Ahora solo queda especificar y detallar ligeramente, describir en acciones tácticas. En la etapa de detalle, lo más importante es caminar con calma "de lo general a lo particular", y así sucesivamente. para formar el marco del futuro proyecto. Al mismo tiempo, sin entrar en detalles de la implementación de unidades funcionales específicas, sino simplemente arreglarlas. Nos ocuparemos de sus detalles más adelante, cuando el marco ya esté completamente listo.

#

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


Para mayor claridad, utilizaremos la sintaxis del lenguaje Fort (que no debe confundirse con Fortran). Este es un lenguaje único que favorece naturalmente el movimiento racional de la ingeniería. La belleza de este enfoque de "fuerte prestado" es que todos los defectos conceptuales del proyecto se revelan incluso en la costa, y no en el medio de su implementación, lo que desde el principio contribuye a un desarrollo de alta calidad. Sin la necesidad de una refactorización posterior. Entonces, el marco "de general a particular":
El marco "de lo general a lo particular"
: -
  - -
  - -
  - --
  -
;

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

: -
   --
  - -
  --
;

: -
  - --
  - -
  --
;

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

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

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

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

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

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

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

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


Otra ventaja de utilizar la sintaxis del lenguaje Fort al elaborar el marco general del proyecto es la capacidad de compilar inmediatamente el texto escrito. Porque este texto es en sí mismo un programa. En principio, si implementa todos los nodos funcionales que faltan utilizando el lenguaje Fort y los agrega al marco anterior, obtendrá el mismo bot invulnerable en el que estamos trabajando. Resultará muy concisamente. Sin embargo, los fragmentos de código a continuación se escribirán en lenguajes más tradicionales: C ++ y ensamblador. La presentación "fuerte-prestada" en este caso es interesante solo con fines ilustrativos del marco general del proyecto. Entonces, "tranquilamente de general a particular" pasó, ahora consideraremos con más detalle los detalles de la implementación de algunos nodos funcionales del bot.


Fotografía invisible


Aquí tenemos tres tareas fundamentales: 1) encontrar una solución de hardware aceptable, 2) desarrollar una estructura de datos que se leerá de las fotos, 3) implementar una función de reconocimiento. El resultado de la fase de fotografía debe ser una estructura de datos completa y redundante, en base a la cual el autómata de la lógica puede identificar de forma única el estado actual del juego, para el menor número posible de disparos consecutivos.

1. En cuanto a la solución de hardware, la opción ideal (desde un punto de vista económico y desde el punto de vista de la facilidad de la programación posterior) es que todas las señales de video converjan en un divisor de video, que podría cambiarse desde una computadora. En este caso, la tarea de selección puede ser realizada por una computadora con una tarjeta de captura de video. Para cada espía y estación de trabajo en este caso, será necesario crear una carpeta; las capturas de pantalla correspondientes se guardarán allí. Si esta opción no se puede implementar (debido a la inaccesibilidad del equipo apropiado y / o debido a calificaciones técnicas insuficientes para adaptar el equipo existente a sus propias necesidades), puede usar varias computadoras conectadas a una red local,en cada una de las cuales habrá varias tarjetas de captura de video, una para cada "espía" y "estación de trabajo". En este caso, deberá agregar todos los mapas de bits escaneados a una carpeta de red compartida o escribir en los sockets de aplicaciones cliente-servidor, que recopilarán todos los mapas de bits en un solo lugar. Para descargar mapas de bits, para su posterior reconocimiento, puede usar el siguiente código:
Descargar mapas de bits
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. En cuanto a la estructura de datos, puede ser la siguiente:
Estructura de datos
// 
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. Una de las opciones posibles para la función de reconocimiento es configurar una red neuronal para esto. Este tema merece una discusión por separado, por lo tanto, no hablaremos sobre el enfoque de red neuronal en este artículo. Una opción más simple es adjuntar a los mapas de bits correspondientes. Así es como se vería la estructura de datos correspondiente:

Estructura de datos de reconocimiento
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;


La forma más fácil de completarlo es manual. Simplemente tome una captura de pantalla, ábrala en Photoshop, active la herramienta Cuentagotas y vuelva a escribir los números de las áreas que nos interesan. Esta decisión no se puede llamar concisa incluso con un gran estiramiento. Además, tiene una limitación importante: incluso los cambios más pequeños en la programación del software de póker harán que el bot deje de funcionar. Sin embargo, si la calificación técnica no le permite llegar a algo que valga la pena, entonces esto es lo que podría parecer la preparación para el "reconocimiento manual" (aquí hay solo una pequeña selección del código de casi 2000 líneas):
Reconocimiento manual
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;
}


Y aquí hay un ejemplo de código que usa tales mapas de bits para el reconocimiento:
Ejemplo de código de reconocimiento
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;



De una forma u otra, a pesar de que usamos una red neuronal, al menos con nuestras manos, al menos con algo tercero, en reconocimiento, cuatro áreas fundamentalmente diferentes deben tenerse en cuenta: 1) estática (aquellas donde, según la teoría, nunca sucede nada); incluyendo externo al software de póker (por ejemplo, algún tipo de acción surge fuera del cliente de póker, supuestamente desde el sistema Windows, pero de hecho, verifica la botabilidad); 2) dinámico altamente informativo (tamaño de la pila, jugador actual, cartas sobre la mesa, etc.); 3) dinámico poco informativo (lugares donde los mensajes rara vez aparecen y chatean); 4) dinámica no informativa (por ejemplo, áreas en las que se produce la animación de la distribución de tarjetas).


Análisis invisible


La parte analítica del bot, en el caso del póker, es un mecanismo para interactuar con la base de datos, ya que casi todos los "avisos" relevantes para el póker en línea se basan en el análisis del modelo de comportamiento de los oponentes del juego. La opción ideal aquí es su propio Oracle local, que es indispensable en el trabajo intensivo con una gran base de datos que incluye cientos de miles de registros. Es decir, habrá muchos de ellos si planea dedicarse a la agricultura botánica en serio y durante mucho tiempo. Si solo necesita un bot para disfrutar, entonces no puede gastar dinero en el Oracle. MS Access DBMS también es bastante adecuado: puede contactarlo fácilmente desde su programa, por ejemplo, a través de ODBC. Así es como podría verse:
Interacción con 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;
}


Si no se trata de póker, sino de ajedrez, por ejemplo, se puede implementar un intercambio con un motor de ajedrez de terceros como parte analítica. Por ejemplo, aquí se explica cómo interactuar con Fritz:
Interacción con el motor analítico.
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;
}



Otra herramienta que puede ser útil para programar análisis es la llamada. "Máquinas de estados finitos". Así es como se pueden usar en juegos multijugador en línea (este es un fragmento del bot para el juego "Keepers of Power"):
Ejemplo de máquina de estado
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;
  }




Emulación invisible


Hay dos etapas: preparatoria y operativa. Tanto uno como el otro implican no solo escribir los programas apropiados, sino también trabajar con hierro. Aquí no puede prescindir de la inmersión en microcontroladores. Afortunadamente, no hay necesidad de reinventar la rueda: hay soluciones de software y hardware listas para usar que se pueden encontrar fácilmente en Internet. Incluyendo el código fuente del programa para el microcontrolador, que puede adaptarse fácilmente a sus necesidades.

En cuanto a la etapa preparatoria (grabación de horas de trabajo con el mouse y el teclado), aquí, si lo desea, puede prescindir de los dispositivos de hardware. Puede escribir un filtro de controlador que capture las llamadas a IOCTL_INTERNAL_I8042_HOOK_KEYBOARD. Puede tomar el programa ctrl2cap como base, cuyos códigos fuente están disponibles en el DDK. Sin embargo, esta solución no es universal: es mejor usar un sniffer de hardware.

En cuanto a la fase operativa, definitivamente no hay forma de prescindir de los dispositivos de hardware. Una de las posibles soluciones podría ser la comunicación con un dispositivo microcontrolador (que también será un divisor en combinación) por un lado a través de RS-232 y, por otro lado, a través de un ramo PS / 2. Para trabajar con RS-232, hay dos opciones: puede usar herramientas regulares de Windows y comunicarse a través de CreateFile / ReadFile / WriteFile con el puerto RS-232, o directamente a través de los puertos de entrada / salida. En el segundo caso, deberá escribir un controlador simple que desbloquee el acceso a los puertos de E / S, porque de forma predeterminada en Windows el acceso a ellos está cerrado. Mantente alejado del pecado. Si aún logró acceder a los puertos de entrada / salida, aquí está el código para intercambiar datos a través de RS-232:
Código RS-232
#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


Por lo tanto, el mecanismo para interceptar y emular las señales del teclado con un mouse es comprensible, solo queda descubrir cómo crear un modelo de comportamiento creíble desde el punto de vista de la biometría a partir de un flujo continuo de datos de teclado y mouse recibidos de un sniffer. Además, una de las tareas más interesantes en esta etapa es cómo mover el mouse desde el punto de partida a otro, específicamente establecido.

Una de las posibles soluciones incluye dos elementos: 1) configurar la red neuronal, 2) ajustar el movimiento y enseñar a la red neuronal a trabajar en conjunto con el "filtro". Con este enfoque, es posible entrenar una red neuronal con una participación humana mínima. El algoritmo de entrenamiento de la red neuronal puede ser el siguiente:
  1. Seleccionamos coordenadas aleatorias donde se debe mover el mouse.
  2. Los alimentamos junto con las coordenadas actuales a la red neuronal.
  3. Observamos cuánto se equivocó la red neuronal.
  4. Ajustamos la red neuronal.
  5. Repita 1-4 hasta la victoria. Teniendo en cuenta los datos recibidos del rastreador de hardware, la red neuronal no solo mueve con precisión el cursor del mouse, sino que también lo hace de manera biométrica plausible.



Que sigue


La implementación de este esquema de red neuronal, así como el esquema de reconocimiento de pantalla de red neuronal mencionado anteriormente, es un tema para una discusión separada que está más allá del alcance de este artículo. Estas dos tareas que fueron más allá del alcance del artículo son los mismos "conceptos fundamentales de ingeniería" que el "ingeniero intermedio" está invitado a resolver de forma independiente. En cuanto a los "problemas de programación triviales", la implementación de la mayoría de ellos tampoco está incluida en este artículo. Esos 10 listados que se enumeran en el artículo son solo una semilla, diseñados para ayudar a fomentar el apetito de ingeniería.

Otro punto importante. Al utilizar este artículo al desarrollar su propio bot, debe comprender: cuando se ofrecen varias opciones alternativas (ideal y algo de compromiso) para implementar un nodo funcional particular, la elección es retórica. Se entiende que se utilizará la opción ideal. Si haces compromisos, aunque solo sea uno, entonces el bot será vulnerable a los contraataques del "lado positivo de la fuerza".


El regreso de los Jedi



Fig. 5. Regreso de los Jedi

Entonces, el esquema de conducción invulnerable de bots descrito anteriormente, que ante los "luchadores por la justicia" - afirma ser la victoria definitiva e irrevocable. Sin embargo, sería aburrido si los Jedi del "lado brillante del poder" no tuvieran la oportunidad de oponerse a las mujeres bots. Además, si esto no fuera posible, el autor, al tratar de adherirse al "lado positivo de la fuerza", no publicaría este esquema. Además, quiero creer que una parte importante de los lectores también se adhiere al "lado positivo de la fuerza" y su interés no está en el abuso de este esquema, sino en cómo resistirlo. El artículo no proporciona códigos fuente detallados y omite algunos conceptos fundamentales de ingeniería, precisamente para evitar abusos.

Algunas palabras sobre cómo puede resistir el esquema descrito de producción botánica. Ella es prácticamente invulnerable. Sin embargo, la posibilidad teórica de su descubrimiento permanece. Esta característica está asociada con el seguimiento del comportamiento atípico del mouse que puede deslizarse, incluso en el caso de una emulación de alta calidad. El hecho es que el mouse lleva muchos "biométricos" en su cola, expresados ​​en lenguaje de póker. Ella es la más cercana a la persona. El más mínimo movimiento muscular causado por un cambio en el fondo emocional: todo esto afecta la forma en que mantenemos el mouse en nuestras manos.

En este sentido, el autor del artículo tiene un estudio biónico original, bajo el título de trabajo "Arquitectura integrada del Homo Sapiens", que incluye una descripción de la fisiología y la psique de una persona, en modelos adecuados para la operación de TI. Gracias a los resultados positivos de este estudio, siento el derecho moral de hacer público el esquema de conducción de bots "invulnerable", porque el "lado positivo del poder" tiene la oportunidad de ganar. De este estudio, entre otras cosas, uno puede entender cómo nuestro uso del mouse, a través de la interfaz de la médula espinal, está relacionado con nuestra actividad mental. Hasta cierto punto, esto permite, en sentido figurado, leer los pensamientos de la persona que puso su mano sobre el mouse. Es en esta "lectura de pensamientos" que se ve un posible vector de contraataques de "luchadores por la justicia".

T.O. La batalla entre los lados oscuros y claros de la fuerza continúa. Algunos intentan fingir ser personas, mientras que otros controlan el comportamiento atípico del mouse. Crear un emulador virtuoso de mouse es como crear un sable láser Jedi. Y descubrir el hecho de la emulación virtuosa es lo mismo que repeler el golpe de esta espada con otro sable de luz. Entonces, ¿quién será más fuerte?


El despertar del poder.



Fig. 6. Despertar del poder

De una forma u otra, sin importar el lado que tomemos, para los bots o en contra de ellos, necesitamos mejorar la técnica de poseer un sable de luz. En el sentido de desarrollar el músculo del ingenio ingenieril en uno mismo. Su componente principal es la capacidad de concentrarse en la tarea, estar "aquí y ahora". Esencialmente, esta perfección yóguica es samadhi. Samadhi en sánscrito significa: concentración total en un tema. Concentración completa! Si levanta un rayo solar con una lente, entonces se enciende la superficie a la que apuntó. Del mismo modo, en ingeniería. Toda la energía que tenemos, debemos concentrarnos como una lente y usarla en ingeniería. Pero no use su energía en detrimento, como los niños que toman lentes y comienzan a quemar hormigas. La energía creativa debe usarse para bien.

# #

-, – , – IDE , , : «#define QUESTION bb || !bb». « – », . – 5000 , – , : , – « ». , «-», «-». , , , , . . , « », 1880- , , . – - ,lo que se puede leer en detalle en las páginas del Srimad-Bhagavatam, que corresponde al sonido OM de la misma manera que los lenguajes de programación modernos de alto nivel corresponden al ensamblador (para más detalles, consulte "Código # código" ).


La base de la concentración es un núcleo espiritual, para agudizar el cual puede utilizar un dispositivo de alta tecnología como un "libro". Buen libro espiritual, por supuesto. Un "libro" es la última palabra en tecnología: 1) se abre con un movimiento de la muñeca, 2) está equipado con una pantalla sin parpadeo, 3) tiene una carga de batería eterna. Para el autor del artículo, este es el Srimad-Bhagavatam (estrictamente prohibido en la época soviética). Puede leer sobre esto en el artículo "Misión del Bhagavatam" .

Además, para concentrarse, no importa cuán común sea, necesita un tono saludable del cuerpo y el espíritu. Hay muchas formas de tonificar. Para el autor de este artículo, por ejemplo, esta es una dieta vegetariana (cocina védica), ropa deportiva (kmc para esquiar) y meditación mantra (recitación de Hare Krsna, Hare Krsna, Krsna Krsna, Hare Hare / Hare Rama, Hare Rama, Rama Rama, Liebre Liebre). Puedes leer sobre este mantra en el artículo "Principio del mantra Hare Krishna" . Puedes usar mi experiencia, o usar algo propio. Y que la fuerza venga con nosotros.

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


All Articles