(Batch) Es Posible hacer password char en batch? (Pregunta)

Iniciado por maty_16_94, 27 Abril 2009, 11:12 AM

0 Miembros y 1 Visitante están viendo este tema.

Nucleorion

#20
Aunque han pasado años considero que es mejor dejar aqui mi duda y mi contribución.

Los codigos que usaban vbs no me han funcionado. Supongo que tendria que modificar la ruta donde se aloja el bat o algo, ya que me decia que faltaba el archivo .vbs

Como me funcionó el codigo escrito exclusivamente en batch, posteado por maty_16_94 decidí usarlo. Tuve que hacer algunos cambios ya que necesitaba que si se metia la clave se cargase un menu y si no, no. Tambien me pareció oportuno que si se cometia un error al introducir la clave te diese mas oportunidades.

Aunque el codigo funciona hay algo que no entiendo y no me conformo con que funcione, me gustaria entenderlo, jejeje. Y tambien, si he cometido alguna barbaridad, saberlo y corregirla :P

¿Porque se ejecuta la etiqueta reinicio antes de cometer ningun fallo? En un principio iba a duplicar esas lineas pero al meter un pause en la etiqueta reinicio vi que se ejecuta nada mas arrancar. Luego hice el contador de errores y ya puedo mostrar el texto de clave incorrecta, pero me ha quedado esa duda.

Es la primera vez que uso call, supongo que por ahi se me escapa algo.

Tambien me gustaria saber que hace el archivo reply.exe


Código (dos) [Seleccionar]

@echo off
Title Usando Asteriscos en una Clave
::Escrito por Carlos inicialmente

set /a intentos=3
set MensajeIntoduzcaClave="Introduzca la clave de acceso:"

:reinicio
if not exist "reply.exe" (call:reply)
setlocal
set PWL=
set letra=
set/a contador=0
set /a TAM=10
set PASSWORD=1234
call:prompt

:inicio
reply.exe
set letra=%errorlevel%
if [%letra%]==[13] (goto:fin) else (call:ascii %letra%)
goto:eof

:fin
echo.
rem set/p pass=Password <nul
if [%PASSWORD%]==[%PWL%] (
goto:correcta
) else (
goto:incorrecta
)
goto:eof

:correcta
cls
echo.
goto Menu
goto:eof

:incorrecta
echo Clave incorrecta.
if /i 1 leq %intentos% (
set /a intentos=%intentos%-1
echo Numero de intentos restantes=%intentos%
echo Pulsa una tecla para volver a probar.
pause>nul
goto reinicio
) else (
echo Se ha superado el numero de intentos.
pause>nul
exit
)

:ascii
if %1==8 (call:borrar)
if %contador% GEQ %TAM% (goto:inicio)
if %1==48 (set PWL=%PWL%0&goto:contador)
if %1==49 (set PWL=%PWL%1&goto:contador)
if %1==50 (set PWL=%PWL%2&goto:contador)
if %1==51 (set PWL=%PWL%3&goto:contador)
if %1==52 (set PWL=%PWL%4&goto:contador)
if %1==53 (set PWL=%PWL%5&goto:contador)
if %1==54 (set PWL=%PWL%6&goto:contador)
if %1==55 (set PWL=%PWL%7&goto:contador)
if %1==56 (set PWL=%PWL%8&goto:contador)
if %1==57 (set PWL=%PWL%9&goto:contador)
if %1==65 (set PWL=%PWL%A&goto:contador)
if %1==66 (set PWL=%PWL%B&goto:contador)
if %1==67 (set PWL=%PWL%C&goto:contador)
if %1==68 (set PWL=%PWL%D&goto:contador)
if %1==69 (set PWL=%PWL%E&goto:contador)
if %1==70 (set PWL=%PWL%F&goto:contador)
if %1==71 (set PWL=%PWL%G&goto:contador)
if %1==72 (set PWL=%PWL%H&goto:contador)
if %1==73 (set PWL=%PWL%I&goto:contador)
if %1==74 (set PWL=%PWL%J&goto:contador)
if %1==75 (set PWL=%PWL%K&goto:contador)
if %1==76 (set PWL=%PWL%L&goto:contador)
if %1==77 (set PWL=%PWL%M&goto:contador)
if %1==78 (set PWL=%PWL%N&goto:contador)
if %1==79 (set PWL=%PWL%O&goto:contador)
if %1==80 (set PWL=%PWL%P&goto:contador)
if %1==81 (set PWL=%PWL%Q&goto:contador)
if %1==82 (set PWL=%PWL%R&goto:contador)
if %1==83 (set PWL=%PWL%S&goto:contador)
if %1==84 (set PWL=%PWL%T&goto:contador)
if %1==85 (set PWL=%PWL%U&goto:contador)
if %1==86 (set PWL=%PWL%V&goto:contador)
if %1==87 (set PWL=%PWL%W&goto:contador)
if %1==88 (set PWL=%PWL%X&goto:contador)
if %1==89 (set PWL=%PWL%Y&goto:contador)
if %1==90 (set PWL=%PWL%Z&goto:contador)
if %1==97 (set PWL=%PWL%a&goto:contador)
if %1==98 (set PWL=%PWL%b&goto:contador)
if %1==99 (set PWL=%PWL%c&goto:contador)
if %1==100 (set PWL=%PWL%d&goto:contador)
if %1==101 (set PWL=%PWL%e&goto:contador)
if %1==102 (set PWL=%PWL%f&goto:contador)
if %1==103 (set PWL=%PWL%g&goto:contador)
if %1==104 (set PWL=%PWL%h&goto:contador)
if %1==105 (set PWL=%PWL%i&goto:contador)
if %1==106 (set PWL=%PWL%j&goto:contador)
if %1==107 (set PWL=%PWL%k&goto:contador)
if %1==108 (set PWL=%PWL%l&goto:contador)
if %1==109 (set PWL=%PWL%m&goto:contador)
if %1==110 (set PWL=%PWL%n&goto:contador)
if %1==111 (set PWL=%PWL%o&goto:contador)
if %1==112 (set PWL=%PWL%p&goto:contador)
if %1==113 (set PWL=%PWL%q&goto:contador)
if %1==114 (set PWL=%PWL%r&goto:contador)
if %1==115 (set PWL=%PWL%s&goto:contador)
if %1==116 (set PWL=%PWL%t&goto:contador)
if %1==117 (set PWL=%PWL%u&goto:contador)
if %1==118 (set PWL=%PWL%v&goto:contador)
if %1==119 (set PWL=%PWL%w&goto:contador)
if %1==120 (set PWL=%PWL%x&goto:contador)
if %1==121 (set PWL=%PWL%y&goto:contador)
if %1==122 (set PWL=%PWL%z&goto:contador)
goto:inicio

:contador
set/a contador+=1
call:asterisc
goto:inicio

:borrar
if %contador% LEQ 0 (goto:eof)
set/a contador-=1
call:prompt
for /l %%a in (1,1,%contador%) do (call:asterisc)
set PWL=%PWL:~0,-1%
goto:eof

:reply
(
echo n reply.dat
echo e 0000 4D 5A 2E 00 01 00 00 00 02 00 00 10 FF FF F0 FF
echo e 0010 FE FF 00 00 00 01 F0 FF 1C 00 00 00 00 00 00 00
echo e 0020 B4 08 CD 21 3C 00 75 02 CD 21 B4 4C CD 21
echo rcx
echo 002E
echo w0
echo q
echo.
)>reply.dat
type reply.dat|debug>NUL 2>&1
del/f/q/a "REPLY.EXE">NUL 2>&1
ren reply.dat "REPLY.EXE"
goto:eof

:prompt
cls
set/p pass=%MensajeIntoduzcaClave%<nul
goto:eof

:asterisc
set/p pass=*<nul
goto:eof

:Menu
echo.
echo  Menu:
echo.
echo  1. Decir Hola
echo  2. Decir Adios
echo  0. Salir
echo.
set /p var=Elige opcion:
if %var%==1 goto hola
if %var%==2 goto adios
if %var%==0 exit
goto Menu

:hola
echo.
echo Hola
echo.
goto Menu

:adios
echo.
echo Adios
echo.
goto Menu



Zomkar

#21
Antes de nada aclararte que, aunque yo lo uso mucho porque mi dominio de batch supera por mucho mi dominio de otro lenguaje, para cosas como las que quieres hacer batch se queda corto.

Aun asi:

Citar¿Porque se ejecuta la etiqueta reinicio antes de cometer ningun fallo?

Batch se ejecuta linea a linea.

Por eso usar "call" no es buena idea porque se suele hacer:
IF condicion CALL :menu

pero resulta que no estás controlando que si el IF no cumple condicion, no vaya a :menu y entonces a donde va? a la linea siguiente.

En definitiva: lo ideal es controlar si has entrado al IF o al ELSE justo después de un CALL para saber si ha habido errores.
Otra opción es usar las variables llamadas ERRORLEVEL.
Tambien con goto:eof si se habia usado call, regresas a la posicion "original".

Para acabar, siendo que hay trozos de código en VBS, yo quizás probaria a aprender algo más de VBS (saber 1 poco es facil) y hacerlo todo en VBS.

En cuanto a reply.exe creo que se utiliza para leer alguna tecla especial como enter ya que:

Código (dos) [Seleccionar]
:inicio
reply.exe
set letra=%errorlevel%
if [%letra%]==[13] (goto:fin) else (call:ascii %letra%)


Si Errorlevel=13 quiere decir que la letra es la correcta para salir del bucle. Además, creo que sirve para, en función del codigo ASCII que retorne Errorlevel, saber qué letra ha pulsado el usuario. Lo que no sé es si no hay formas más elegantes de hacerlo.

PS: vale, si, hace eso si no me equivoco, buscar en memoria la tecla pulsada y almacenarla, pero con ASM

mas informacion: http://thestarman.pcministry.com/asm/debug/debug.htm#EXE
Si vas a por ellos te llamarán violento.
Si explotas a cientos te verán como un ejemplo.

Nucleorion

Muchisimas gracias, te has explicado genialmente  :D

He programado en muchos lenguajes diferentes, como los patos ya sabes, nadan, corren y vuelan pero no destacan en nada :P

vbs no lo he tocado apenas. La proxima vez que vaya ha hacer algo en dos, pruebo a hacerlo en vbs. Espero que haya mas documentacion ya que es un lenguaje de programacion en si, porque en dos aparte la escueta documentacion casi sin ejemplos de:

http://technet.microsoft.com/en-us/library/bb490873.aspx

Lo demas que he encontrado esta disperso.

Zomkar

Bueno, lo cierto es que en VBS hay más ejemplos que en DOS/Batch, pero también te vas a encontrar con el problema de que las documentaciones están orientadas a quien ya sabe usar las herramientas

Lo ideal, para mi, como con cualquier lenguaje, es aprender leyendo tutoriales, que no sean muy basicos pero que sobretodo usen ejemplos y los conceptos se te queden un poco y cuando quieras hacer un programa sepas por donde tirar.

Por ejemplo tutoriales asi:
http://foro.elhacker.net/scripting/tutorial_vbscript-t229032.0.html

por cierto para DOS hay muchas paginas pero si quieres ejemplos esta esta muy bien:
http://www.robvanderwoude.com/batchcommands.php
Si vas a por ellos te llamarán violento.
Si explotas a cientos te verán como un ejemplo.

Nucleorion

#24
Gracias por los enlaces

Al probarlo en un sistema de 64bits me ha dado error el archivo reply.exe. Imagino que habria que programarlo diferente para 64bits. Creo que he encontrado la manera para detectar que arquitectura de sistema se esta usando con el comando %PROCESSOR_ARCHITECTURE% podria definir si se crea un reply u otro, pero no tengo ni idea de como hacer un reply para 64bits

Zomkar

#25
yo tampoco, si no me equivoco se puede hacer en C:

-leer desde Memoria el valor de la tecla pulsada
-si es Enter devolver ERRORLEVEL 13
-si es retroceso borrar letra
-para el resto de caracteres ascii, devolver su valor en ERRORLEVEL
http://www.ascii-code.com/
(en el batch usan a partir de '0' que es 48 pero puedes hacer más si es que batch los admite)

en realidad se puede hacer todo el codigo en C pero para usarlo con este batch seria eso

compilas el codigo sobre la plataforma que vayas a usar (64) y te olvidas de la parte que crea el archivo.exe si se puede evitar porque para eso hay que saber un poco de ASM por lo menos

PS: si no creas el exe otra vez tendras que conseguir que te funcione y eso quizas no sea posible, prueba con propiedades->compatibilidad
Si vas a por ellos te llamarán violento.
Si explotas a cientos te verán como un ejemplo.