Aplicaciones de consola en VB6

Introducción

Este artículo consiste en aprender a escribir programas de consola en Visual Basic 6. Se verá la forma de crear aplicaciones que corran en modo consola sin mostrar el formulario, se asume que se tienen los siguientes conocimientos:

  • Visual Basic 6.
  • Uso de las Win32 API’s.
  • PE (Portable Executable) Header.

Herramientas Utilizadas

  • Editor Hexadecimal.
  • PE Editor.
  • Visual Basic 6.

Aplicaciones de Consola y la PE Header

El formato PE es basicamente una estructura de datos que encapsula la información necesaria para el cargador de Windows para gestionar el código de un ejecutable.

Dentro de un Ejecutable PE, podemos encontrar una estructura que nos servirá para nuestro fin (Crear ejecutables de consola). La estructura "IMAGE_OPTIONAL_HEADER".

typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
 
WORD    Magic;
BYTE    MajorLinkerVersion;
BYTE    MinorLinkerVersion;
DWORD   SizeOfCode;
DWORD   SizeOfInitializedData;
DWORD   SizeOfUninitializedData;
DWORD   AddressOfEntryPoint;
DWORD   BaseOfCode;
DWORD   BaseOfData;
 
//
// NT additional fields.
//
 
DWORD   ImageBase;
DWORD   SectionAlignment;
DWORD   FileAlignment;
WORD    MajorOperatingSystemVersion;
WORD    MinorOperatingSystemVersion;
WORD    MajorImageVersion;
WORD    MinorImageVersion;
WORD    MajorSubsystemVersion;
WORD    MinorSubsystemVersion;
DWORD   Win32VersionValue;
DWORD   SizeOfImage;
DWORD   SizeOfHeaders;
DWORD   CheckSum;
WORD    Subsystem;
WORD    DllCharacteristics;
DWORD   SizeOfStackReserve;
DWORD   SizeOfStackCommit;
DWORD   SizeOfHeapReserve;
DWORD   SizeOfHeapCommit;
DWORD   LoaderFlags;
DWORD   NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;


De toda esta estructura el único dato que nos interesa es el valor "Subsystem" de 16 bits (2 bytes). Subsystem puede llevar distintos valores, el valor que contienen las aplicaciones GUI es 2 y las consolas tienen el valor 3.

#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.

Por lo tanto modificaremos el valor de los ejecutables que compilemos en Visual Basic, para ello necesitaremos un editor de archivos PE para ubicar el offset del Subsytem y un editor Hexadecimal para modificarlo.

Creando la aplicación de Consola

Haremos algo sencillo, utilizaremos las APIS para manejar la consola y escribiremos en ella "Hello Override – Algoritmatica has you" y el texto cambiará de color a Verde.

Apis necesarias

Private Declare Function FreeConsole Lib "kernel32" () As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
Private Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" (ByVal hConsoleOutput As Long, _
lpBuffer As Any, ByVal nNumberOfCharsToWrite As Long, lpNumberOfCharsWritten As Long, lpReserved As Any) As Long
Private Declare Function SetConsoleTextAttribute Lib "kernel32" (ByVal hConsoleOutput As Long, ByVal _
wAttributes As Long) As Long
Private Declare Function SetConsoleTitle Lib "kernel32" Alias "SetConsoleTitleA" (ByVal lpConsoleTitle _
As String) As Long

Constantes

Private Const STD_OUTPUT_HANDLE = -11&
Private Const FOREGROUND_GREEN = &H2

Código

Private Sub Form_Load()
 Form1.Hide ' Ocultamos el formulario
 Dim hConsoleOut As Long
 hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE) ' Obtenemos el handle de la consola
 If (hConsoleOut) Then
 Dim sTexto As String
 Dim lWritten As Long
 sTexto = "Hello Override - Algorimatica has you!" ' Texto a mostrar en la consola
 SetConsoleTitle ("Algoritmatica.com") ' Cambiamos el titulo de la consola
 SetConsoleTextAttribute hConsoleOut, FOREGROUND_GREEN ' Cambiamos el color de texto de las letras
 ' Mostramos el texto en la consola
 WriteConsole hConsoleOut, ByVal sTexto, Len(sTexto), lWritten, ByVal 0&
 End If
 'Matamos la consola
 CloseHandle hConsoleOut
 FreeConsole
 End ' fin de ejecución
End Sub

Compilando Código

Ahora compilamos nuestro código como lo haríamos de manera normal y generamos nuestro ejecutable, en mi caso lo he llamado test2.exe. Una vez compilado necesitaremos nuestro Editor Pe, en este caso, se ha usado la herramienta "PEview".

Buscando Subsystem

Abrimos nuestro archivo compilado (Test2.exe) en el Peview y expandemos el árbol "IMAGE_NT_HEADERS" y seleccionamos "IMAGE_OPTIONAL_HEADER" ahora del lado derecho buscamos "Subsystem" y encontramos que se encuentra en el offset 0x00000114.

Subsystem offset.jpg

Editando fichero y cambiando el valor de Subsystem

Ahora abriremos nuestro fichero compilado en un editor hexadecimal, se ha usado WinHex. Buscaremos la offset 0x00000114 y vemos que tiene el valor 0x02, modificaremos el valor y colocaremos 0x03 lo que hará que el ejecutable corra en modo Consola.

Cambiando subsystem.GIF

Salvamos el fichero y ahora lo corremos desde el cmd.exe o command.com. El resultado final es:

Consola VB6.jpg

Notas finales

Como nota final, se podría crear una función que escriba en la consola y otra función que espere por entrada de datos algo así como funciones equivalentes en C como son printf y scanf. Con esas dos funciones se podría ya empezar a programar una aplicación en consola


Fuente

Manual "Peering Inside the PE"

Manual Aprenda VB6 como si estuviera en primero

Enlaces Internos

Ciencia de la Información

Crack Informático

Visual_Basic

Microsoft_Visual_Studio

Enlaces Externos

Foro VB

Consolas en VB6