Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Temas relacionados > Seguridad
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #21  
Antiguo 27-03-2007
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.325
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por dec
Ahora bien, quedaría entonces cómo comparar el serial del usuario (por partes) con el serial correcto que hemos de generar (también por partes...)
Bueno, como he dicho, esta es una de las primeras cosas a hacer y que evita encontra el serial de forma trivial.

Lo siguiente es evitar comparaciones directas; Simplemente, porque no siempre se necesita encontrar el Serial, a veces basta con "Parchear".

Es decir, si yo no encuentro el Serial, pero veo tres comparaciones que dicen:
Código Delphi [-]
if A!='aasd' then ...
if B!='khgk' then ...
if C!='grfeu' then ...
En este caso optaría por "parchear" los tres != por tres =.

Ya se que el tema se va complicando, pero son cosas que hay que tener en cuenta; La mayoría de sistemas anticopia (serios) ya hechos tienen en cuenta estas cosas y muchas más...
En ese caso a la hora de comparar dos valores, podemos utilizar por ejemplo la resta para saber si da cero, funciones del tipo CHAR y Ord (aplicándolas a los dos) para no comparar los valores exactos, sumar y restar a ambos un valor,...
Aunque desde delphi parece una tontería hacer esto:

Código Delphi [-]
// en lugar de...
if ('A' = Str[1]) then
// usar...
if (char('A') = Char(Str[1])) then

Para el que está revisando el código en ensamblador supone uno o varios saltos, cosa que dificulta mucho a la hora de seguir el código (las llamadas a funciones); Pensad que si se van aplicando diferentes a cada comparación, al final la cosa se hace muy compleja para el que está revisando la pila y los registros.
__________________
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.

Última edición por Neftali [Germán.Estévez] fecha: 27-03-2007 a las 18:30:48.
Responder Con Cita
  #22  
Antiguo 27-03-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 22
ArdiIIa Va por buen camino
Cita:
Empezado por Neftali
Para el que está revisando el código en ensamblador supone uno o varios saltos, cosa que dificulta mucho a la hora de seguir el código (las llamadas a funciones); Pensad que si se van aplicando diferentes a cada comparación, al final la cosa se hace muy compleja para el que está revisando la pila y los registros.
Comenzó el hilo buscando y encontrando una cadena en memória y finalmente acabamos hablando de ingeniería inversa.
Llegados a este punto, creo que el menor de los problemas sería el como ocultar la forma y el modo de como cotejar una clave, dado que llegados a ese nivel y si resulta de interés, el invasor no se iba a preocupar de la clave, sino que se preocuparía de ver cual es el procedimiento que le hace salir del programa (por ejemplo) y que otras alternativas o saltos de programa tiene para que este funcione adecuadamente, para a continuación parchear y a disfrutar.... Creo yo...
__________________
Un poco de tu generosidad puede salvar la vida a un niño. ASÍ DE SENCILLO
Responder Con Cita
  #23  
Antiguo 27-03-2007
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Una pregunta en cuanto al borrado del dato:

¿Qué no puede usarse simplemente una variable global y asignarle otro valor? No hay stack donde quede nada y la variable se ha reescrito.

// Saludos
Responder Con Cita
  #24  
Antiguo 27-03-2007
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.325
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por ArdiIIa
...creo que el menor de los problemas sería el como ocultar la forma y el modo de como cotejar una clave, dado que llegados a ese nivel y si resulta de interés, el invasor no se iba a preocupar de la clave, sino que se preocuparía de ver cual es el procedimiento que le hace salir del programa (por ejemplo) y que otras alternativas o saltos de programa tiene para que este funcione adecuadamente, para a continuación parchear
Bueno, estamos hablando de hacer las dos cosas, evitar que la comparación sea evidente y que esté un único sitio; De ahí que la comparación se haga por partes y no del número completo. Y como segunda parte que esas comparaciones que se hacen por partes no sean evidentes. A nivel de Delphi es un poco más de trabajo (tampoco mucho).
__________________
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.
Responder Con Cita
  #25  
Antiguo 27-03-2007
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.084
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Una vez participé en un proyecto de "seguridad" para evitar que "piratearan" los programas de la empresa donde trabajaba. Tuvimos en cuenta lo que habéis comentado y un montón de cositas más, el proyecto duró 7 meses y éramos 3 personas dedicadas únicamente a eso, en su día tuvo un presupuesto de 60.000 euros. Buscamos información de todos los métodos conocidos hasta la fecha, documentos, libros, consultas a algunos expertos, etc.
Entre nosotros había uno, no era yo, que decía constantemente: "no vale la pena tanto tiempo y dinero en protegerlo, lo mejor es que lo copien y lo usen aunque sea gratis y que no use el de la competencia".
Pues bien, a la semana de sacar el programa, un chaval ruso que además nos envió un gracioso email, publicó un keygen para el programa, que además de ser más simple que nuestro propio programa, era más rápido, pequeño, cómodo y seguro.
Nos quedamos con la boca abierta, nos miramos los unos a los otros y pensamos: "¡¡¡cómo podemos ser tan malos programadores!!!".

Moraleja: sin comentarios
Responder Con Cita
  #26  
Antiguo 27-03-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.561
Poder: 25
egostar Va camino a la fama
Cita:
Empezado por Casimiro Notevi
Una vez participé en un proyecto de "seguridad" para evitar que "piratearan" los programas de la empresa donde trabajaba. Tuvimos en cuenta lo que habéis comentado y un montón de cositas más, el proyecto duró 7 meses y éramos 3 personas dedicadas únicamente a eso, en su día tuvo un presupuesto de 60.000 euros. Buscamos información de todos los métodos conocidos hasta la fecha, documentos, libros, consultas a algunos expertos, etc.
Entre nosotros había uno, no era yo, que decía constantemente: "no vale la pena tanto tiempo y dinero en protegerlo, lo mejor es que lo copien y lo usen aunque sea gratis y que no use el de la competencia".
Pues bien, a la semana de sacar el programa, un chaval ruso que además nos envió un gracioso email, publicó un keygen para el programa, que además de ser más simple que nuestro propio programa, era más rápido, pequeño, cómodo y seguro.
Nos quedamos con la boca abierta, nos miramos los unos a los otros y pensamos: "¡¡¡cómo podemos ser tan malos programadores!!!".

Moraleja: sin comentarios
Yo siempre he pensado que el aliento para pasar las barreras de una protección es que sea lo mas "dificil" posible, y no creo que hayan sido "malos programadores" solo que hubo uno mejor que ustedes.

Aqui en Mexico diriamos, "para chingon, chingon y medio".

Salud OS.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #27  
Antiguo 28-03-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Me voy a meter a cracker. Recordáis la protección de la que hablaba con el md5, esa tan maravillosa, pues con el OllyDbg del que hablaba Neftali me la salte en un momento, el tiempo que me llevo averiguar como guardar los cambios en ese programa endemoniado

La cosa fue tan sencilla como cambiar esto:
Código:
00459BF2  |. E8 4DCAFAFF    CALL <JMP.&kernel32.CompareStringA>
00459BF7  |. 83E8 02        SUB EAX,2
00459BFA  |. 85C0           TEST EAX,EAX
Por esto otro:
Código:
00459BF2  |. E8 4DCAFAFF    CALL <JMP.&kernel32.CompareStringA>
00459BF7     B8 00000000    MOV EAX,0
00459BFC  |. 0F94C0         SETE AL
Y toda mi superproteccion quedo inutilizada .... Lo que hace el aburrimiento
Responder Con Cita
  #28  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.112
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Muchísimas gracias a todos por vuestro interés en el asunto que planteo en este Hilo. Voy a tratar de continuar respondiendo a lo que se ha comentado en mi ausencia.

Román, dices de hacer uso de una variable global en donde se almacenaría el número de serie correcto (generado en el programa) para compararlo con el introducido por el usuario. Acto seguido habría que dar a dicha variable global otro valor. ¿Pero esto funcionaría?

Lo digo porque esta mañana comprobé que el número de serie correcto (insisto, generado en el propio programa) aparecía en la memoria incluso cuando este no era albergado en ninguna variable. O por mejor decir, el algoritmo que construye el número de serie correcto ofrecía su resultado a la propia función ("StrLCopy") encargada de copiarlo a cierta variable... que era ¿liberada? de la memoria acto seguido de utilizarla.

Es decir, que parece que sólo conque el número de serie sea generado este ya aparecerá completo en la memoria... o eso se deduce de las pruebas que he llevado a cabo, si omitimos el echo de que no llegué a hacer uso de las funciones que propuso el compañero basti más arriba. Tal vez esto último es algo que tendría que comprobar antes de nada.

Seoane, dices de utilizar un "hash", de comparar el "hash" del número de serie con el introducido por el usuario. Y dices que podríamos guardar dicho "hash" incluso en una constante, puesto que, como bien dices, del "hash" no se puede colegir el número de serie. Es cierto, pero, también lo es que no podemos guardar el número de serie correcto como una constante, sencillamente, porque este no es un valor constante: no hay un número de serie correcto para todos y con el que podamos comparar los intentos del usuario.

De hecho el número de serie ha de generarse por el propio programa, a partir de un número base y una clave de usuario. Es decir, un número de serie se "calcula" a partir de la clave de un usuario. Sin conocer esta última no es posible generar el número de serie correspondiente. Entonces, si al cabo hay que generar el número de serie (para luego obtener su "hash"), ¿no estaríamos en el mismo problema en que estamos? Es decir, a partir de que podamos calcular el "hash" de un número de serie quiere decirse que habremos generado dicho número de serie... y ya estará en la memoria... o me equivoco.

Casimiro, dices que acaso no merezca la pena trabajar en estos menesteres, y puede que lleves razón. Es algo que me he planteado también. Liberar el programa, adjuntar incluso su código fuente, y, bueno, que quien quiera pueda realizar una donación o "algo" para que uno (que trabaja en el programa) se vea compensado de algún modo. El problema es este, precisamente: que uno se quiera ver recompensado, es decir, que no se vea así ya. De hecho como digo es una opción más la de liberar el programa, hacer innecesario el uso de ningún número de serie y aquí paz y después que salga el sol por donde salga.

Sin embargo ahora mismo esto que se trata en este Hilo es más bien una especie de reto: se plantea un problema y quiere encontrarse su solución. Independientemente de que en el futuro se quite el problema del medio (y no haya que buscarle solución) lo cierto es que no quisiera evitar el problema... es decir quitarle del medio sin saber antes que al fin y al cabo es algo que tiene solución o soluciones. No digo que tú quieras deshacerte del problema, o no lo digo en ese sentido: creo que sé por dónde vas y ya digo que en cierto modo estoy bastante de acuerdo contigo.

Continúo. Veo que antes de publicar esto Seoane ha conseguido "romper" su propia protección... Aunque no de la misma forma en que yo he propuesto, es decir, según yo aunque comparemos "hashes" el número de serie ha de calcularse en el programa y pasará a poder verse en la memoria con un programa como WinEx. Se verán los "hashes" y no se podrá hacer nada con ellos, de acuerdo, pero también se verá el número de serie, si no estoy metiendo la pata con mi planteamiento, claro está.

Y esto me hace pensar que acaso logre solucionar el problema que me ocupa pero todavía pueda obtenerse un número de serie válido o a lo menos evitar el registro del programa. Probablemente esto sea así. Pero ahora me preocupa cómo quitar el número de serie de la memoria RAM. Si luego hay otros modos o no los hay de saltarse la protección del programa... eso se verá en su momento llegado el caso.

Habéis hablado también (Neftalí mayormente) de que el programa no debería dejar ver a las claras que ha sido o no registrado correctamente. De hecho así es. En el caso del programa que nos ocupa es el usuario quien se encarga de abrir el diálogo para registrarlo. En este diálogo (formulario) el usuario ha de proporcionar su clave de usuario y su número de serie. Si el registro es correcto... no pasa nada, aparentemente. Si es equivocado, tampoco damos al usuario ninguna señal de que el programa no se ha registrado correctamente.

La advertencia de que el programa no está registrado digamos que se produce cuando el usuario ejecuta ciertas acciones. Vale que alguien que sepa de estas cosas puede tratar de localizar el "salto" de dicha advertencia, y quitarla del medio antes de que aparezca. Esto seguramente puede hacerse. También es verdad que yo podría tratar de complicar un poco las cosas. Es decir, en lugar de avisar con una advertencia al usuario de que el programa no está registrado... tal vez podría además hacer que mientras el programa lleva a cabo alguna de sus acciones (o varias de ellas) se compruebe su registro y "salte" en el momento.

Esto haría las cosas más complicadas al "cracker"... porque en lugar de evitar una advertencia tendría que evitar más de una, y además no sabría, hasta que no lo pudiera comprobar por sí mismo como usuario del programa, cuántas advertencias existen, y dónde existen. Pero en fin, como he dicho, comprendo que alguien con los suficientes conocimientos y la paciencia de rigor conseguiría saltarse las advertencias que se le pusieran por delante: no soy yo mejor que los que diseñan la protección de Windows, por ejemplo, y esta siempre acaba "saltándose" de varias formas además...

Pero me preocupa ahora lo del número de serie. Cómo demonios hacer que un dato que conocemos tras un cálculo en el programa, y que luego utilizamos, sin embargo desaparezca de la memoria, no deje rastro alguno y no pueda ser averiguado, por lo tanto. Esto es lo que me preocupa ahora. Y después de escribir todo esto (aunque estanto un poco dormido aún) sigo pensando en que una posible solución puede ir por donde Neftalí apunta: tal vez generar "trozos" del número de serie, y comparar estos trozos con sus correspondientes pares.

De este modo seguirían viéndose trozos del número de serie correcto en la memoria, pero, ya complicaría el asunto bastante, puesto que a ver cómo y de qué manera se pone uno a "juntar" los trozos a poco que sean unos cuantos... se me hace que el "cracker" tendría entonces que tirar por otro camino y desde luego no podría obtener el número de serie "completo", mondo y lirondo, de la memoria ocupada por el programa.

Bueno. No sé. Digo que lo de partir el número de serie correcto en trozos podría funcionar, pero, lo cierto es que aún no sé cómo llevar a cabo esto. Se admiten ideas y sugerencias y yo por mi parte os mantendré informados en caso de avanzes o retrocesos en este sentido.

Otra vez muchas gracias a todos por vuestro interés. Y disculpad el rollazo.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #29  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.112
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Otra vez yo... acabo de probar con el método que apuntó primero Seoane, añadiéndole la función recursiva que el compañero basti propuso a su vez, pero, que si quieres arroz Catalina... sin utilizar variables, dejándolo en un "buffer" que acto seguido es liberado de la memoria, haciendo uso luego de la función "VamosAContarAlReves"... ¡que si quieres arroz Catalina!

Algún modo ha de haber, digo yo, ¿no?
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #30  
Antiguo 28-03-2007
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
No entendí esto último. ¿Funcionó o no?

// Saludos
Responder Con Cita
  #31  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.112
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

No Román; no me funcionó.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #32  
Antiguo 28-03-2007
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Pues es raro. Yo hice una tímida (e ingenua) prueba así: dado que el problema era que el dato se pasaba al stack al pasar el parámetro, supuse que bastaba llamar una segunda vez al procedimiento con un valor "borrador": Resultado('XXXXXXX'),
pero el condenado pepe seguía ahí. Además de que el pepe entra en un Edit, y ése también contribuye, aún borrando el edit, me parece que pepe sigue ahí.

// Saludos
Responder Con Cita
  #33  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.112
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Pues sí. La verdad es que estoy más perdido que un pavo en un garaje. Alguna forma ha de haber de lograr hacer desaparecer de la memoria el número de serie correcto una vez utilizado por el programa. Pero a mí personalmente no se me ocurre ahora mismo ninguna, y es que todo esto de la pila, el stack, la memoria RAM, etc., etc., es nuevo para mí, lo reconozco, siempre me he movido en otro nivel... para mi mal, probablemente.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #34  
Antiguo 28-03-2007
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.084
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
¿Y por qué no 'escondes' a Pepe?, un xor a nivel de bits, por decir algo, para que no se sepa qué es, quedarán caracteres 'extraños'.
Responder Con Cita
  #35  
Antiguo 28-03-2007
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.325
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por seoane
Recordáis la protección de la que hablaba con el md5, esa tan maravillosa
Bueno, estaba claro que en ese caso (ya que con el MD5 está "peliagudo") la opción era "atacar" la comparación o la constante con el MD5 a comparar si es que estuviera fija.
__________________
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.
Responder Con Cita
  #36  
Antiguo 28-03-2007
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.325
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por dec
Alguna forma ha de haber de lograr hacer desaparecer de la memoria el número de serie correcto una vez utilizado por el programa.
¿Y si enfocamos el tema de otra manera?
En lugar de borrarlo, que no aparezca. Tal vez me he perdido algo, pero creo que es posible...

Se trata de hacer el cálculo sin asignar el SN en ningun sitio.
Por ejemplo, este programa; He seguido los pasos (con el WinHex) para encontrar en Serial Correcto en memoria y yo no lo veo.

El procedimiento de cálculo es el siguiente:

Código Delphi [-]
var
  b:Boolean;
  i:Integer;
begin

  if ((Length(Edit2.Text) - Length(Edit1.Text)) < 2) or
     (Length(Edit1.Text) < 4) then begin
    MessageDlg('El número de registro es incorrecto', mtWarning, [mbOK], 0);
    Exit
  end;

  b := True;

  for i := 0 to (Length(Edit1.Text) - 1) do begin
    b := b and (Edit1.Text[i] = Edit2.Text[i]);
  end;

  b := b and (Edit2.Text[i + 1] = 'S');
  b := b and (Edit2.Text[i + 2] = 'N');

  if (b) then begin
    MessageDlg('El registro se ha completado correctamente.', mtInformation, [mbOK], 0);
  end
  else begin
    MessageDlg('El número de registro es incorrecto', mtWarning, [mbOK], 0);
  end;

Como véis es muy "cutre", pero el número correcto no se asigna.
__________________
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.
Responder Con Cita
  #37  
Antiguo 28-03-2007
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.325
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Dista mucho de ser infalible (1) y (2), pero creo que la solución puede ir por aquí.

(1) Comprobación de la longitud. (pepito + palotes); Se pueden ver los registros con los valores 7 y 6 (de ambas longitudes), la resta y la comparación con 2.
(2) Comprobación de caracteres 1 a 1. (1234 + casaca); Se puede ver cómo empieza a comparar "1" y "c" y el salto que nos lleva al mensaje de fallo.

Creo que la idea es buena.
__________________
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.
Responder Con Cita
  #38  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.112
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

No lo cojo Neftalí. En tu anterior ejemplo (que te agradezco) según se ve en el código puede registrarse el programa con el usuario "pepe" y el número de serie "pepeSN". Claro que lo sé porque tengo acceso al código fuente, en esto estamos de acuerdo.

Yo comprendo que ha de haber alguna forma de hacer lo que necesito, puesto que hay programas que me consta no caen en la "trampa" en la que cae el mío. Sin embargo por más que lo intento aún no consigo resultados.

Ten en cuenta que no se trata de comparar el valor "clave de usuario" y "número de serie". Se trata de que a una clave de usuario dada le corresponde un número de serie. El programa se encarga, a partir de la clave de usuario y un número "base", se encarga, digo, de generar el número de serie.

Yo tengo el programa y un generador de números de serie, que es otro programa. Ambos comparten la unidad "GenerarSerial" y en esta unidad hay una clase con dos métodos: "CompararSerials" y "GeneralSerial". Cuando ejecuto el generador lo que estoy haciendo es obtener un número de serie según la clave de un usuario.

El usuario me escribe: "Oyes David, este programa está molón, acabo de ingresarte en tu cuenta 1.000.000 de dólares, espero que sea suficiente para que me envíes un número de serie a nombre de "Pepe Rico".

Yo cojo el Generador e introduzco el número base del programa y la clave de usuario "Pepe Rico". El Generador me genera (toma ya) un número de serie para esa clave y ese número base y yo se lo mando a Pepe Rico: "Hola Pepe, recibido el millón ahí te va el número de serie".

El programa (ya no el Generador de "Serials"), cuando Pepe Rico introduzca su clave de usuario y su número de serie podrá comprobar si este último se corresponde con el que tiene que ser puesto que podrá calcular (como el Generador) el correcto en base al número base y a la clave de usuario introducida.

Hasta ahí bien. Todo es correcto. ¿Todo? No. Porque que el Generador deje en memoria el número de serie correcto no importa. De hecho tiene que ofrecerme ese número de serie correcto, tiene que dejarme "copiarlo" (de hecho se muestra en un "TEdit") para que yo pueda mandárselo a Pepe Rico que para eso pagó el millón de rupias.

Ahora bien, el programa, el de Pepe Rico, no el Generador, no debe (y no lo hace) mostrar el número de serie correcto al usuario... ¡pero este se queda en la memoria! Y tal vez Pepe Rico no, pero algún otro usuario conseguirá el número de serie correcto a poco que eche un vistazo...

Lo último que he probado ha sido el "CheckSum", el "hash" del número de serie, pero es que no salimos del problema: Yo puedo comparar el "CheckSum" del número de serie del usuario y del correcto, pero si puedo hacer esto último es porque he generado el número de serie correcto, y, según parece, a poco que esto se haga y se haga donde se haga ya aparecerá en memoria... irremediablemente.

Tal vez es que el planteamiento es el equivocado. Ya digo que todo mi "sistema de generación y comprobación de números de serie" se basa en el código del componente "TJvSerialMaker" de la Jedi VCL. Pero entonces es que todo programa que haga uso de este componente está comprometido en lo dicho: mostrará el número de serie correcto en la memoria.

Tal vez sea esto y no tenga remedio porque es un mal planteamiento o no está lo suficientemente pensado o simplemente es algo sencillo, de andar por casa, puesto que a Pepe Rico probablemente no mirará la memoria RAM ni sabrá siquiera que algo así existe y se puede mirar...

¡Arrggggggggggggggggggggg!
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #39  
Antiguo 28-03-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Si no es mucho preguntar, como generas el numero de serie. Puede que el problema resida ahí. Podríamos intentar crear un algoritmo, una sola función, que permita comprobar el numero de serie dejando la memoria limpia.

En resumen, muestranos el algoritmo
Responder Con Cita
  #40  
Antiguo 28-03-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.112
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Ningún problema Seoane... es de dominio público... ya digo. Extraído de la unidad "JvSerialMaker.pas" de la Jedi Library. De hecho copiaré aquí los dos métodos principales... el que genera números de serie y el que compara un número de serie con el "correcto" (generado)...

Código Delphi [-]
function TJvSerialMaker.GiveSerial(ABase: Integer; AUserName: string): string;
var
  A: Integer;
begin
  if (ABase <> 0) and (AUserName <> '') then
  begin
    A := ABase * Length(AUserName) + Ord(AUserName[1]) * 666;
    Result := IntToStr(A) + '-';
    A := ABase * Ord(AUserName[1]) * 123;
    Result := Result + IntToStr(A) + '-';
    A := ABase + (Length(AUserName) * Ord(AUserName[1])) * 6613;
    Result := Result + IntToStr(A);
  end
  else
    Result := RsError;
end;

function TJvSerialMaker.SerialIsCorrect(ABase: Integer; AUserName: string; Serial: string): Boolean;
begin
  if (AUserName <> '') and (ABase <> 0) then
    Result := Serial = GiveSerial(ABase, AUserName)
  else
    Result := False;
end;

Como se ve se parte de un número "base" que ha de ser constante tanto en el programa generador de números de serie como en el programa a "proteger"... Ambos programas, pues, comparten el código anterior. A partir del número base y de una clave de usuario, como puede verse el primer método genera un número de serie: justamente el que corresponde a la clave de usuario + número base.

Así se consigue que tanto el programa generador de números de serie como el programa a "proteger" puedan obtener de una clave de usuario un número de serie, el mismo que ha de compararse con el que el usuario introduzca. Todo esto funciona correctamente, si no fuera porque el número de serie correcto (y justo el cuando se genera en el primer método) queda en la memoria.

Y es en el primer método donde queda el número en memoria, porque puede verse que en el método el número de serie se va generando "a trocitos", que al cabo son unidos: pues bien, en la memoria aparecen todos los trocitos... e incluso el resultado final: el número de serie correcto para cualquier clave de usuario introducida.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 28-03-2007 a las 18:17:37.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

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


La franja horaria es GMT +2. Ahora son las 07:30:14.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi