bueno, supongo que bien, en un rato lo posteo. Gracias por responder alzehimer_cerebral
;(para compilar con el masm32)
;
;C:\masm32\bin>ml /c /coff scann.asm
;Microsoft (R) Macro Assembler Version 6.14.8444
;Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
;
; Assembling: scann.asm
;
;C:\masm32\bin>link /SUBSYSTEM:CONSOLE scann.obj
;Microsoft (R) Incremental Linker Version 5.12.8078
;Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
.386
.model flat, stdcall
option casemap:none
includelib \masm32\lib\kernel32.lib
CreateThread PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
GetCommandLineA PROTO
GetStdHandle PROTO :DWORD
lstrlenA PROTO :DWORD
WriteFile PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
CloseHandle PROTO :DWORD
ExitProcess PROTO :DWORD
Sleep PROTO :DWORD
includelib \masm32\lib\ws2_32.lib
WSAStartup PROTO :DWORD,:DWORD
WSACleanup PROTO
socket PROTO :DWORD,:DWORD,:DWORD
closesocket PROTO :DWORD
gethostbyname PROTO :DWORD
htons PROTO :DWORD
connect PROTO :DWORD,:DWORD,:DWORD
.data
Ayuda db "Escaner de puertos by ACHERNAR",13,10
db "scaner <HOST> <puerto-INICIAL> <puerto-FINAL>",13,10,0
numeros db "0123456789"
.data?
SALIDA dd ?
HOST dd ?
INICIAL dd ?
FINAL dd ?
.code
codigo proc
call IniciarWinsock
call ManajadorSalida
call Argumentos
cmp eax,0
jne codigo1
codigo0: lea eax,Ayuda
push eax
call Imprimir
jmp salir
codigo1: mov eax,INICIAL
mov ebx,FINAL
codigo2: push eax
call escanear
cmp eax,ebx
je salir
inc eax
jmp codigo2
salir: mov eax,SALIDA
push eax
call CloseHandle
call TerminarWinsock
push 0
call ExitProcess
ret
codigo endp
;----------------------------------------------------------------------------------------------------
ManajadorSalida proc
;VERIFICADA (FUNCIONA BIEN)
;esta funcion carga en la variable global SALIDA (DWORD)
;el valor del manejador de salida
;la funcion no retorna ningun valor
push eax
push ebx
push ecx
push edx
push edi
push esi
push -11
call GetStdHandle
mov SALIDA,eax
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
ret
ManajadorSalida endp
;----------------------------------------------------------------------------------------------------
Imprimir proc texto:DWORD
;VERIFICADA (FUNCIONA BIEN)
;para llamar a esta funcion tiene que estar cargado
;un manejador de salida en la variable global SALIDA (DWORD)
;la funcion no retorna ningun valor
push eax
push ebx
push ecx
push edx
push edi
push esi
sub esp,4 ;espacio creado para guardar el valor de bytes escritos
mov ebx,esp
push texto
call lstrlenA ;en eax esta la longitud del mensaje a mostrar
push 0 ;overlaped
push ebx ;puntro BytesEscritos
push eax ;bytes a escribir
push texto ;mensaje
push SALIDA ;manejador de salida
call WriteFile
add esp,4 ;acomoda la pila (por el espacio creado antes)
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
ret
Imprimir endp
;----------------------------------------------------------------------------------------------------
escanear proc Parametro:DWORD
push eax
push ebx
push ecx
push edx
push edi
push esi
sub esp,4 ;espacio en la pila para guardar el ThreadID
push esp
push 0
push Parametro
lea eax,VerificarPuerto
push eax
push 0
push 0
call CreateThread
add esp,4
push 1 ;<--- este valor puede modifiarse
call Sleep
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
ret
escanear endp
;----------------------------------------------------------------------------------------------------
Argumentos proc
;esta funcion verifica si hay parametros, y si los hay
;los carga en las variables globales HOST (DWORD), INICIAL(DWORD)
;y FINAL (DWORD)
;en HOST se guarda un puntero a la cadena con el nombre del host
;en INICIAL se guarda el valor del primer puerto a escanear
;en FINAL se guarda el valor del ultimo puerto a escanear
; eax = 1 -->

// eax = 0 -->

push ebx
push ecx
push edx
push edi
push esi
call GetCommandLineA ;carga en eax la direccion de la linea de comandos
push eax ;guardado en la pila para despues ponerlo en edi
push eax
call lstrlenA
mov ecx,eax ;en ecx esta la longitud de la linea de comandos
pop edi ;en edi esta la direccion de la linea de comandos
mov al," " ;en al esta el caracter a buscar
cld ;edi va a incrementarse durante la busqueda
repne scasb ;repite la busqueda hasta encontrar el caracter o el final
jne Argumentos1 ;si no encontro el caracter " " toma el salto
repe scasb ;sigue la busqueda hasta un caracter distinto a " "
je Argumentos1 ;si encuentra lo buscado toma el salto
dec edi ;edi apunta al inicio de los argumentos
mov eax,edi ;en eax esta la direccion donde comienzan los argumentos
jmp Argumentos2 ;continua para almacenar los valores de los argumentos
Argumentos1: xor eax,eax
jmp Argumentos100
Argumentos2: push eax ;para pasarlo despues a edi (para explorar la cadena)
push eax
call lstrlenA
mov ecx,eax ;en ecx esta la longitud de la cadena con los argumentos
pop edi ;direccion de la cadena con los argumentos
mov HOST,edi ;en HOST esta la direccion del nombre del host
mov al," "
cld
repne scasb ;busca el siguiente " " (separa el 1er argumento del 2do)
jne Argumentos1 ;si no encuentra no hay suficientes argumentos y sale
mov byte ptr[edi-1],0 ;pone un cero al final del primer argumento (nombre del host)
repe scasb ;explora buscando un caracter distinto a " "
je Argumentos1 ;si no encuentra no hay suficientes argumentos y sale
dec edi
mov INICIAL,edi ;en INICIAL esta la direccion de la cadena con el puerto inicial
inc edi
repne scasb ;busca el siguiente " " (separa el 2do argumento del 3ro)
jne Argumentos1 ;si no encuentra no hay suficientes argumentos y sale
mov byte ptr[edi-1],0 ;pone un cero al final del segundo argumento (puerto inicial)
repe scasb ;explora buscando un caracter distinto a " "
je Argumentos1 ;si no encuentra no hay suficientes argumentos y sale
dec edi
mov FINAL,edi ;en FINAL esta la direccion de la cadena con el puerto final
inc edi
repne scasb ;busca el siguiente " " (por si hay alguno al final)
jne Argumentos3 ;si no encuentra no es necesario poner un cero al final
mov byte ptr[edi-1],0 ;pone un cero al final del tercer argumento (puerto final)
Argumentos3: lea eax,INICIAL ;hay que transformar el puerto inicial de texto a numero
push eax
call NumeroPuerto
cmp eax,0
je Argumentos100
lea eax,FINAL ;hay que transformar el puerto final de texto a numero
push eax
call NumeroPuerto
cmp eax,0
je Argumentos100
mov eax,HOST ;hay que transformar el nombre del host a un numero
push eax
call gethostbyname
cmp eax,0
je Argumentos1
mov eax,[eax+12]
mov eax,[eax]
mov eax,[eax]
mov HOST,eax
mov eax,FINAL ;verifica que FINAL no sea menor que INICIAL
mov ebx,INICIAL
cmp ebx,eax
jg Argumentos1
mov eax,1
Argumentos100: pop esi
pop edi
pop edx
pop ecx
pop ebx
ret
Argumentos endp
;----------------------------------------------------------------------------------------------------
NumeroPuerto proc KDNA:DWORD
;KDNA contiene un puntero a un puntero donde esta la cadena con el valor del puerto
;en la direccion KDNA se guarda el valor numerico del puerto
;falta verificar que la cadena no sea alfanumerica.(solo numeros)
push ebx
push ecx
push edx
push edi
push esi
xor edi,edi
mov eax,KDNA
mov eax,[eax]
mov ebx,eax
n0: push ebx
call lstrlenA
cmp eax,0
je n100
cmp eax,5
jg n100
cmp eax,1
je n50
mov ecx,eax
dec ecx
mov eax,1
mov edx,10
n1: mul edx
mov edx,10
loop n1
mov edx,eax
push ebx
call numero
mul edx
add edi,eax
inc ebx
jmp n0
n50: push ebx
call numero
add edi,eax
mov eax,edi
cmp eax,0
je n60
cmp eax,65535
jg n60
mov ebx,KDNA
mov [ebx],eax
mov eax,1
jmp n100
n60: xor eax,eax
n100: pop esi
pop edi
pop edx
pop ecx
pop ebx
ret
NumeroPuerto endp
;----------------------------------------------------------------------------------------------------
numero proc KDNA:DWORD
push ebx
push ecx
push edx
push edi
push esi
xor edi,edi
xor esi,esi
mov ecx,KDNA
lea ebx,numeros
mov al,byte ptr[ecx+edi]
numero1: mov ah,byte ptr[ebx+esi]
cmp al,ah
je numero2
inc esi
jmp numero1
numero2: mov eax,esi
pop esi
pop edi
pop edx
pop ecx
pop ebx
ret
numero endp
;----------------------------------------------------------------------------------------------------
VerificarPuerto proc P:DWORD
push eax
push ebx
push ecx
push edx
push edi
push esi
VerificarPuerto1: push 6
push 1
push 2
call socket
cmp eax,-1
je VerificarPuerto1
push eax
push P
push eax
call Conectar
pop ebx ;socket
push eax
push ebx
call closesocket
pop eax ;resultado de la conexión
cmp eax,1
jne VerificarPuerto100
push 000d0a00h
push 0
mov eax,esp
push eax
push P
call CadenaPuerto
push eax
call Imprimir
pop eax
pop eax
mov eax,1
VerificarPuerto100: pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eaX
ret
VerificarPuerto endp
;----------------------------------------------------------------------------------------------------
CadenaPuerto proc P:DWORD, KDNA:DWORD
push eax
push ebx
push ecx
push edx
push edi
push esi
mov ecx,P
mov esi,1
CadenaPuerto1: mov edx,esi
mov eax,10000
mul edx
cmp eax,ecx
jg CadenaPuerto2
inc esi
jmp CadenaPuerto1
CadenaPuerto2: dec esi
lea eax,numeros
mov al,byte ptr[eax+esi]
mov ebx,KDNA
mov byte ptr[ebx],al
mov eax,10000
mul esi
sub ecx,eax
mov esi,1
CadenaPuerto3: mov edx,esi
mov eax,1000
mul edx
cmp eax,ecx
jg CadenaPuerto4
inc esi
jmp CadenaPuerto3
CadenaPuerto4: dec esi
lea eax,numeros
mov al,byte ptr[eax+esi]
mov ebx,KDNA
mov byte ptr[ebx+1],al
mov eax,1000
mul esi
sub ecx,eax
mov esi,1
CadenaPuerto5: mov edx,esi
mov eax,100
mul edx
cmp eax,ecx
jg CadenaPuerto6
inc esi
jmp CadenaPuerto5
CadenaPuerto6: dec esi
lea eax,numeros
mov al,byte ptr[eax+esi]
mov ebx,KDNA
mov byte ptr[ebx+2],al
mov eax,100
mul esi
sub ecx,eax
mov esi,1
CadenaPuerto7: mov edx,esi
mov eax,10
mul edx
cmp eax,ecx
jg CadenaPuerto8
inc esi
jmp CadenaPuerto7
CadenaPuerto8: dec esi
lea eax,numeros
mov al,byte ptr[eax+esi]
mov ebx,KDNA
mov byte ptr[ebx+3],al
mov eax,10
mul esi
sub ecx,eax
mov esi,1
CadenaPuerto9: mov edx,esi
mov eax,1
mul edx
cmp eax,ecx
jg CadenaPuerto10
inc esi
jmp CadenaPuerto9
CadenaPuerto10: dec esi
lea eax,numeros
mov al,byte ptr[eax+esi]
mov ebx,KDNA
mov byte ptr[ebx+4],al
mov eax,1
mul esi
sub ecx,eax
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
ret
CadenaPuerto endp
;----------------------------------------------------------------------------------------------------
;-------------------------------------------------------------
;--------------------- Funciones Winsock ---------------------
;-------------------------------------------------------------
IniciarWinsock proc
;FUNCIONA BIEN
;eax = 1 -->

// eax = 0 -->

push ebx
push ecx
push edx
push edi
push esi
sub esp,400 ;Creo un espacio de 400 bytes para la estructura WSAData
push esp
push 202h
call WSAStartup
add esp,400 ;Elimino es espacio que reserve en al pila de 400 bytes
cmp eax,0
je IniciarWinsock1 ;si todo salio bien
xor eax,eax ;si algo falló
jmp IniciarWinsock2
IniciarWinsock1: mov eax,1
IniciarWinsock2: pop esi
pop edi
pop edx
pop ecx
pop ebx
ret
IniciarWinsock endp
;-------------------------------------------------------------
TerminarWinsock proc
;FUNCIONA BIEN
;eax = 1 -->

// eax = 0 -->
push ebx
push ecx
push edx
push edi
push esi
call WSACleanup
cmp eax,0
je TerminarWinsock1 ;si todo salió bien
xor eax,eax ;si algo falló
jmp TerminarWinsock2
TerminarWinsock1: mov eax,1
TerminarWinsock2: pop esi
pop edi
pop edx
pop ecx
pop ebx
ret
TerminarWinsock endp
;-------------------------------------------------------------
Conectar proc S:DWORD, PUERTO:DWORD
;FUNCIONA BIEN
;S es el manejador del socket, no un puntero
;DIRECCION es un puntero a una cadena con la direccion del host remoto
;PUERTO es el numero de puerto, no un puntero
;eax = 1 -->

// eax = 0 -->

push ebx
push ecx
push edx
push edi
push esi
mov eax,PUERTO
cmp eax,32767
ja Conectar1
sub eax,65536
Conectar1: push eax
call htons
mov ebx,HOST
sub esp,16
mov ecx,esp
mov word ptr [ecx],2
mov word ptr [ecx+2],ax
mov [ecx+4],ebx
push 16
push ecx
push S
call connect
add esp,16
cmp eax,0
jne Conectar2
mov eax,1
jmp Conectar3
Conectar2: xor eax,eax
Conectar3: pop esi
pop edi
pop edx
pop ecx
pop ebx
ret
Conectar endp
;-------------------------------------------------------------
end codigo