![]() |
![]() |
| Paypal | FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
|||||||
| Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Buscar | Temas de Hoy | Marcar Foros Como Leídos |
![]() |
|
|
Herramientas | Buscar en Tema | Desplegado |
|
|
|
#1
|
||||
|
||||
|
Hola,
Lamento molestar otra vez... Seoane... he intentado implementar el código (y la idea... dentro de mis posibilidades) en el programa de marras y el asunto no ha funcionado: sigue viéndose en la memoria RAM lo que no debía verse. Y entonces me he preguntado cómo es posible si he probado tu ejemplo y yo mismo he dicho que me había funcionado... pero lo he vuelto a probar y el asunto no funciona Seoane... y ahora no sé si es que no nos ponemos de acuerdo (sin duda por culpa mía) acerca de lo que hay que quitar y lo que no... En tu ejemplo, en todo caso (se "compruebe" o no se "compruebe") que el usuario escribió "Pepe"... este sigue apareciendo en la memoria RAM... ¿tú cómo lo ves? ![]() Gracias en todo caso. PD. Es verdad Román que acaso he proporcionado información de cierta relevancia a alguien... pero no era mi intención: no le dí importancia en ese sentido. No sé si porque doy por supuesto que al final lo explicado no va a servir... si al cabo se consigue eliminar de la memoria RAM el valor de que tratamos. |
|
#2
|
||||
|
||||
|
Si aparece no sera por culpa de la función "Comprobar" sino por culpa de la función "Resultado" que al manipular strings nos provoca el problema. Lo ideal es utilizar solo variables que podamos borrar, ya que delphi aunque libera la memoria que ocupan, no se preocupa de borrar lo que contienen.
Aquí el problema es como planteas la protección, comparar lo que entra el usuario con un valor fijo y devolver un boolean no es muy buen sistema de protección. Funciona, y para un usuario "normal" seria suficiente (1), pero si ya nos encontramos con un "listo" la cosa falla. Saltarse una protección de este tipo es tan fácil como parchear el programa para que la función "Comprobar" siempre devuelva TRUE. Así ya podemos llamar a la función mil veces en nuestro código que la protección ha quedado desactivada. Pero supongamos que el listo no lo es tanto, y no sabe ensamblador, pero conoce el programa WinHex y prueba a "pescar" en la memoria la posible clave. Pues como la incluyamos como constante en nuestro exe ya estamos vendidos, es mas ni siquiera le haría falta leer la RAM, con solo leer el ejecutable la podría encontrar. Por eso la clave debe generarse durante la ejecución, y utilizarse durante todo el proceso (generación y comprobación) variables que luego podamos borrar. Y lo mas importante, que el listo no sepa ensamblador para que no nos desmonte todo usando lo del párrafo anterior Si de verdad quieres proteger la aplicación (mas tarde o mas temprano caen todas) tendrías que irte a algo mas "profesional". Lo primero un antidebugger, para evitar que usen un debugger. Luego podemos encriptar parte del código del programa y utilizar como clave la clave del producto, de esta manera si la clave no es correcta no hay manera de obtener el código. Y por ultimo un buen rootkit para vacilarlos nosotros antes de que nos intenten vacilar ellos (Parece una broma, pero recordemos a Sony y alguno mas)Como ves, si empiezas a preocuparte por lo que van a hacer los "listos" puedes terminar paranoico. Así que si verdaderamente es importante, una llave hardware y no se hable mas. (1) Para mi también seria suficiente, con tantos programas OpenSource como hay, no pienso perder el tiempo buscando claves. |
|
#3
|
|||
|
|||
|
Hola, he visto este hilo y me parece interesante. Creo que tanto 'Pepe' como la fecha pueden aparecer en el volcado de memoria del programa de Seoane por dos razones, espero no equivocarme.
'Pepe' está escrito de manera estática en la función Resultado, por lo tanto no hay manera de quitarlo de la memoria. Esto no sería un problema para tu aplicación, ya que la clave del cliente no estaría escrita en el código de la aplicación. El otro problema que veo es la pila del programa, cuando se hace la siguiente llamada:
El valor 'Pepe'+DateToStr(Time) se copia en la pila de llamadas de la aplicación, y permanecerá ahi hasta que otras llamadas sobreescriban estos datos en la pila. Puedes comprobarlo de la manera siguiente: En el código de Seoane haces una implementación de StrLCopy, algo así de manera que uses esta función en vez de la original de delphi. Pones un punto de ruptura dentro de la función, vas a la ventana "Call Stack". Ahí verás el valor tanto de 'Pepe' como la fecha. La solución, creo que podría ser una llamada a una función recursiva, justo después de la llamada a StrLCopy, para que sobreescriba la pila. La función debe ser llamada las veces que hagan falta para borrar los datos de la pila. Algo así:
Última edición por basti fecha: 27-03-2007 a las 15:02:22. |
|
#4
|
||||
|
||||
|
Ingenioso método de borrar la pila Basti
Entonces ya tenemos los 3 pasos: no usar constantes, borrar las variables y borrar la pila. |
|
#5
|
||||
|
||||
|
Hola,
Gracias a todos, de verdad. Estaba a punto de escribir esto porque me parecía haber encontrado una posible solución, pero, me quedo corto al lado vuestro. Como dices Seoane el problema está en manipular variables en la función "Resultado". Si no lo hacemos, es decir, si "calculamos" el resultado ya dentro de la función "StrLCopy" entonces desaparece el problema. Es decir, que puedo decir que el problema está resuelto gracias a vosotros. Acabo de comprobarlo y volverlo a comprobar. Dices Seoane que dejar el Serial como constante no es buena idea... pero no se hace así. Lo que se tiene como constante es un número "base". Con este número base y la clave del usuario se genera un "Serial", pero esto se hace con cierto algoritmo (luego más sobre esto) que no puede conocerse así como así. Ahora bien. Parece (y digo parece porque he hecho pruebas pero tengo que hacer alguna más aún) que conseguimos hacer desaparecer el "Serial" correcto de la memoria RAM. Ahora lo que me deja perplejo es el tema de la pila... ¿ya no basta con la memoria RAM? ¿Acaso puede buscarse el "Serial" en la pila incluso cuando digo que ya no aparece en la memoria RAM? Definitivamente me queda mucho más por aprender de lo que aprenderé nunca. Para quien esté interesado, estoy utilizando una clase para todo esto que está basada en el componente "JvSerialMaker" de la Jedi Library. Evidentemente ya sabéis que este componente "deja" en la memoria RAM el número de serie que genera y puede comprobar... En fin voy a asegurarme con más pruebas de que el número de serie no aparece en la memoria RAM y luego acaso me ponga con el tema de la pila que apunta el compañero basti (gracias basti). Pero estoy de acuerdo con Seoane... probablemente estas cosas habría que tomarlas bastante más en serio de lo que estoy dispuesto a hacer para evitar que alguien "piratee" un programa como se empeñe en hacerlo... |
|
#6
|
||||
|
||||
|
Veo que habéis avanzado en el tema mientras yo escribía, o mejor dicho, me enrollaba...
![]() ![]() Cita:
__________________
Germán Estévez => Web/Blog Guía de estilo, Guía alternativa Utiliza TAG's en tus mensajes. Contactar con el Clubdelphi ![]() P.D: Más tiempo dedicado a la pregunta=Mejores respuestas. |
|
#7
|
||||
|
||||
|
Hola,
Muchas gracias Neftalí. Gracias a todos. ![]() Yo me doy cuenta de lo poco que sé de todo esto... ¡me pierdo enseguida! Y como me pierda no me encuentro. ¡¿Pues no resulta ahora que tras haber comprobado con estos ojos que se han de comer la tierra, me pongo a implementar el asunto en el programa de marras y todo sigue igual?! Igual. El número de serie correcto aparece en memoria. Pero ahora el número no está en ninguna variable como antes. Yo no sé si estoy comprendiendo lo que hablamos, porque, ahora mismo el número de serie "se calcula" dentro de la propia función "StrLCopy"... Es decir, que pasa a la variable "destino" de la función "StrLCopy", directamente, variable que luego es destruída tal como Seoane ha explicado... No sé. ¿Acaso me queda entonces por hacer lo que apunta el compañero basti? ¿No basta entonces con liberar dicha variable (única que llega a contener el número de serie correcto)? No sé... voy a probar a ver... ![]() Y en todo caso pelear con lo que menciona Neftalí: pero me temo que voy a dar unos cuantos palos de ciego... ¡Ay! ![]() |
|
#8
|
||||
|
||||
|
Hola,
Yo de nuevo. ![]() Oyes Neftalí... ¿sabes que lo de comprobar el número de serie por partes puede acaso ser una solución? Pero no se me ocurre cómo... de momento... y puede que nunca. ![]() El caso es que, efectivamente, ni siquiera quitando del medio la función "Resultado", es decir, comparando el número de serie del usuario con la cadena resultante del cálculo del número de serie... es decir, comparando una variable con "un valor" (no una variable) que se conforma en el momento... aun así el número de serie, o sea el "valor" queda en la memoria... Así que como no sea partiendo el número de serie, de modo que quede... pero irreconocible, pudiera ser una buena opción. Ahora toca averiguar cómo demonios hago esto, porque no se me ocurre... no sé... ![]() |
![]() |
| Herramientas | Buscar en Tema |
| Desplegado | |
|
|
Temas Similares
|
||||
| Tema | Autor | Foro | Respuestas | Último mensaje |
| eliminar datos con dbgrid | UREÑA | Conexión con bases de datos | 20 | 30-03-2007 23:41:32 |
| Eliminar Datos eficientemente | k_rito | Conexión con bases de datos | 5 | 27-11-2006 00:44:45 |
| Cómo obtener ciertos datos de los archivos ejecutables y librerías | StartKill | Varios | 1 | 14-08-2006 23:10:01 |
| Eliminar del memoria los querys | Aura | OOP | 4 | 01-04-2004 17:40:40 |
| Eliminar datos de una tabla DBF | vicvil | Tablas planas | 4 | 16-05-2003 21:17:46 |
|