principalsolucionesentornospaperspaperscontactepapers

Eid0 (E.Sobrino) -Octubre 2001-
http://www.micro-electronica.com
Dedicado a Anna, y tambien a mi amigo Trastu que siempre lo tengo a mi lado (tecnicamente en mis pies) cuando escribo estos articulos.
Greetz: canal #netsearch,#bookwarez
Shoutz: Todas las religiones,naciones, y ideologias injerentes y opresoras. Dejadnos en paz y parad las putas guerras!!

Peace & Hack the World!!

HACKEANDO VISUAL BASIC


Acuerdo de uso

Este texto esta escrito unicamente con fines didacticos. El autor no se hace responsable del mal uso que se pueda dar a esta informacion,ni se hace responsable de los programas que lleve incluidos.
Si el ordenador se te quema, se te borra todo el disco duro o te muerde un perro al ejecutarlos, no reclames al autor.

Introduccion

Visual Basic no es precisamente el lenguaje apropiado para realizar proyectos complejos, ni de calculo intenso, ni multithreading, ni los que manejen datos de alta velocidad,etc.. Pero tiene 2 ventajas respecto a los demas lenguajes:

  1. Las cosas sencillas se hacen muy rapidamente.
  2. Sabe comunicarse muy bien con ese monstruo inmundo que son las interfaces de los objetos COM de OLE. Si bien soy un claro detractor del mundo OLE que quiere imponer Microsoft tengo que reconocer que para la tarea de usar controles para la interfaz de usuario va muy bien ya que en un momento haces los formularios.

Por lo tanto, seria muy interesante poder mezclar programas en C o Assembler que realicen la parte central de los proyectos con partes de Visual Basic que se encarguen de la interfaz de usuario. Si alguna vez habeis leido que esta mezcla se puede hacer de manera oficial, podeis repetir conmigo: MENTIRA!!
Visual Basic es el lenguaje menos abierto de todos los que me he enfrentado...(ver seccion de Historia de Hacks mas abajo)

Lo que MicroSoft si deja hacer es la posibilidad de llamar desde visualbasic a algunas API's de Windows.
Internamente esta caracteristica esta implementada con una chapuzilla donde los strings que se mandan por valor, el visual las copia a un buffer local, las pasa a ANSI y las acaba con un 0 para que sea compatible con las WINAPI, etc..., pero evidentemente estas chapuzas no interesan a programadores como nosotros que queremos una flexibilidad total y ningun veto. Nosotros necesitamos pasar BIDIRECCIONALMENTE todo tipo de datos desde visual basic a nuestras dll's, desde las cuales ya podemos hacer lo que se nos antoje, en nuestro lenguaje preferido (ASM & C).

El objetivo de este articulo es precisamente ese, intercambiar datos (strings, arrays dinamicas, etc...) entre Visual Basic y dll's nuestras realizadas con lenguajes de programacion que no son de juguete.


Breve Historia de hacks con Visual Basic

Cuando pense en hacer esta combinacion en mis proyectos, crei que ya estaria todo inventado. Solo hacia falta algun libro de algun guru de visual basic... Llego a mis oidos que uno de los gurus mas conocidos era Bruce McKiney y que habia escrito el libro Hardcore Visual Basic de Microsoft Press. Le eche un vistazo (esta gratis en el msdn), el libro estaba escrito basandose en el Visual Basic 5, era la segunda edicion, y este tio hacia los hacks con las instrucciones(indocumentadas) y API's:

  • Rtlmemcpy (winapi)-->aliased a CopyMemory
  • Strptr
  • Varptr
  • ObjPtr

    Buscando por internet una libreria typedef de todas las winapis que habia realizado el autor y que yo os recomiendo encarecidamente (WIN.TLB), fue muy grande mi sorpresa cuando leo una nota de ultima hora en la web del autor, cagandose en Microsoft y su puta madre. Resumiendo Bruce McKiney ponia que ya no iba a usar nunca mas Visual Basic por que con la version Visual Basic 6 que Microsoft acababa de sacar no compilaba ninguno de sus programa e incluso veia imposible solucionarlo en un plazo razonable.
    Con eso dejaba en el tintero la tercera edicion de su libro y pedia perdon a aquellos lectores que habian usado sus tecnicas para comunicarse con el WinAPI, ya que se iban a quedar mas colgaos que un murcielago haciendo puenting.

    EL MUNDO DE LAS IDEAS (zen)

    Asi las cosas, la situacion pintaba mal para conseguir mis objetivos, ya me veia haciendo toda la interfaz de usuario en C, con 500 ventanas, y millones de mensajitos de ventana y toda la parafernalia...

    Pero primero hay que utilizar el ultimo y mas valorado recurso, vamos a buscar a zen, con un Martini con Vodka (solo vale vodka ruso) en la mano, inspiro profundamente y me relajo,miro por la ventana, el cielo esta encapotado con una increible tonalidad de grises, sonidos procedentes de animales de la granja comienzan a llegar a mis oidos... * (ver nota)

    Con todo ese armamento pesado, zen se me aparece en poco rato...

    Bruce Mackiney, como otros gurus se equivocan hackeando Visual Basic con Visual Basic!! Visual Basic no es para hackear, visual basic es para dibujar pantallitas. Visual Basic hay que hackearlo desde fuera!! Si quieres hackear utiliza ASM, incluso C, pero no vb. Las cabilaciones continuan, no consigo imaginarme al compilador del visual manejando strings HLSTR, y mas tarde, cuando alguna cabeza pensante de Microsoft decide cambiar el formato interno de los string a BSTR cambiar todo el compilador. No. Eso no es posible. Visual Basic ha de estar aislado de la implementacion interna de strings y muchas otras cosas. Hay que hackear visual basic sin ayuda de instrucciones indocumentadas. No quiero utilizar argumentos por valor para que el visual basic me engañe, quiero unicamente direcciones reales, lo quiero todo transparente....

    Lo mejor es ver por mi mismo como funciona un programita simple de visual basic a nivel de codigo maquina.

    COMIENZA EL ASEDIO

    Generamos un programita minimo en Visual Basic 6, le llamamos test.frm. Compilamos y generamos un exe.

    Miramos los imports con pedump de Matt Pietrek (gracias Matt):

    c:\>pedump test.exe
    imports:
    MSVBVM60.DLL


    Si!
    Hemos encontrado la materia Gris del Visual Basic, se puede decir que el visual basic es esta dll.
    Ahora vemos que funciones exporta esta DLL.

    c:\>pedump /e MSVBVM60

    Vemos que exporta todas las funciones propias del basic y empezamos a ver funciones interesantes como estas:

    __vbastrcopy
    __vbastrmove
    __vbAryCopy
    Putmemh
    Putmemstr
    __vbastr2vec
    __vbastrarytoansi
    __vbastrcat
    --vbastrcmp

    Hemos encontrado el cerebro pensante que controla los strings y demas estructuras!! El compilador de visual basic no gestiona los strings dinamicos, todo esto, lo hace la dll.


    STRINGS DINAMICOS

    Vamos a profundizar un poquito mas:

    Creamos un form en visual con un boton que cuando se pulsa solo hace lo siguiente: Sub boton_click()
    Dim hola as string
    hola="Esto es una prueba"
    End Sub

    Compilamos, generamos un exe,pillamos un debugger de Kernel (SoftIce) y hacemos: BPX __vbastrcopy

    Ejecutamos el programa,pulsamos el boton del formulario, y el debugger salta.
    Hacemos peek&poke, vemos como los procedures hacen handles de SEH de tipo 2, modificando el TIB y por ultimo descubrimos como se traduce en asm la instruccion hola="esto es una prueba":

    mov ecx, direccion de variable hola en pila (es un puntero)
    mov edx, puntero a cadena en formato UNICODE de "esto es una prueba"
    call MSVBVM60!__vbastrcopy

    ASI DE FACIL!, no se preocupa de formatos, ni de si hay que alocar mas memoria en el buffer dinamico de hola, ni nada de nada. De todo esto se preocupa __vbastrcopy. El proggy solo se ha de preocupar de poner una cadena en formato UNICODE y acabarla en 0, y de meterle al api la direccion real de la variable hola.
    Si desensamblamos la funcion vemos que usa el formato de intercambio de datos (calling convention) fastcall, es decir, los argumentos se pasan a la libreria por registro (esto denota lo mucho que usa esta funcion el compilador).

    Bueno pues nosotros haremos lo mismo!!! En nuestros proggys de C y ASM que se comuniquen con el visual basic, utilizaremos la funcion __vbastrcopy de la dll del visual. Asi de sencillo! Y si quieren cambiar de formato interno en la siguiente version del visual, no habra que modificar NADA! tan solo atacar a la dll que venga con el nuevo visual (MSVBVMXX.DLL). Lo unico a destacar es que si el prog. principal del proyecto esta en C, hay que tener en cuenta que en esta funcion los argumentos son pasados por registro, y por lo tanto habra que echar mano del inline assembler del c (esto no hace falta si nuestro compilador de C entiende el calling convention _fastcall).

    ARRAYS DINAMICOS Y ESTRUCTURAS

    En este momento sabemos pasar de manera bidireccional entre el visual basic y el resto del mundo: floats, integers y demas, ya que la conversion es directa. Tambien sabemos pasar Strings que es lo que hemos visto antes. Ahora faltaria saber pasar el tipo de variables que mas se utiliza en estos tiempos, los arrays dinamicos.

    Modifico el programa test, creo un modulo y le pongo:

    Type estructura
    hola1 as long
    hola2 as long
    end type

    Y en el procedure del boton del formulario meto:

    redim hola() as estructura
    redim hola(100)
    dim kk as string
    kk="Esta cadena hara saltar el debugger"
    hola(1).hola1=1
    hola(1).hola2=2

    Le meto el debugger de kernel, y veo como la cosa se ha complicado algo. Pero nada que no se pueda dislumbrar...
    Tras inspeccionar el codigo maquina veo que:

    Un array es un puntero a una pequeña estructura donde se guardan todos los Metadatos del array (longitud, etc...)
    Esta estructura es como sigue:

    01 00 ?? ?? ?? ?? ?? ??  ?? ?? ?? ?? XX XX XX XX


    const................................puntero a buffer con
    .....................................todos los datos propios del array

    XX XX XX XX 00 00 00 00  ?? ?? ?? ?? ?? ?? ?? ??


    longitud....offset
    del array...(siempre 0?)
    en lineas


    Ejemplos Avanzados de Funcionamiento

    En un proyecto que estaba realizando me encontre con una dificultad:

    Mi programa ODBCgway de seguridad de comunicaciones de bases de datos hecha en C, tiene una funcion que devuelve los datos de una llamada SQL, con el handicap que cuando esta funcion es llamada no sabes cuantos datos vas a obtener. En C se podria alocar un buffer dinamicamente en la misma funcion pero ya sabemos lo que le gustan los punteros al visual basic... Tendriamos que utilizar rtlmemcpy desde visual basic y empezar a mangonear la memoria de la forma que hemos decidido que NO tenemos que hacer.

    Solucion

    La solucion es ir a jugar el partido al campo del Visual Basic, nada de alocar memoria en C ni nada por el estilo.
    Solo haremos lo que el compilador de Visual Basic haria internamente.
    Con esto podemos dilucidar que es perfectamente posible pasar desde visual basic un array dinamico con 0 elementos a la funcion C. Desde C pillamos ese array y lo dimensionamos siempre que queramos con la api __Redim de MSVBVMX0.DLL, y la llenamos de los datos que vamos obteniendo. No hay que devolver nada, cuando la funcion vuelva y el visual basic retome el control, su array ya estara dimensionada y llena de datos.

    Como veis esta tecnica se puede aplicar a todo tipo de situaciones y lenguajes del mundo de Windows. Por ejemplo alguien puede necesitar saber como pasar datos variant, personalmente no los utilizo ya que son mas lentos, pero la tecnica para descubrir su estructura es exactamente la misma que he tilizado para analizar los string, y los arrays.

    Espero que esto os sirva tanto como me ha servido a mi...


    Podeis mandarme vuestros comentarios y criticas a eid0@micro-electronica.com.

    Eid0 (E.Sobrino)
    http://www.micro-electronica.com

    * Parrafo entendible solo para aquellos que conozcan los geniales essays de +ORC.