Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Seguridad (https://www.clubdelphi.com/foros/forumdisplay.php?f=36)
-   -   Eliminar ciertos datos de la memoria RAM (https://www.clubdelphi.com/foros/showthread.php?t=41836)

dec 28-03-2007 18:32:58

Hola,

Ya me estoy volviendo loco. Resulta que utilizo el "JvSerialMaker" desde hace cierto tiempo... y me ha dado por comprobar en un antiguo programa que lo utilizaba a ver si era capaz de sacar el número de serie de la memoria... ¡pero no he podido hacerlo!

Y a dios pongo por testigo que ambos programas: tanto el antiguo como el nuevo, utilizan el mismo sistema... eso sí, el antiguo utiliza el "JvSerialMaker" tal cual, y este nuevo utiliza una "adaptación" que le he hecho por mi cuenta... ¡pero los métodos para generar el número de serie y para comprobarlo son prácticamente iguales!

No cambia nada. De hecho la adaptación que he hecho de "JvSerialMaker" se limita a desligarlo de la Jedi VCL (quitando toda referencia a esta) y a retirar las propiedades del componente para quedarme sólo con los dos métodos comentados.

¿Y sin embargo en el programa antiguo no consigo ver el número de serie en la memoria y en el programa nuevo sí? ¡Esto es de locos!

Sé que no es de locos, sino todo lo contrario. Pero yo estoy cansado. Y así me las gasto en estas circustancias... :)

Aquí puede verse la adaptación de "JvSerialMaker" que llevo a cabo; compárese con el "JvSerialMaker" original... yo creo que no hay cambio que justifique que ahora el sistema se haya vuelto "inseguro"...

Código Delphi [-]
unit UGeneradorSeriales;

interface

type
  TGeneradorSeriales = class
  public
    function ObtenerNumeroSerie(numeroBase:integer;
     claveUsuario: string): string;

    function ComprobarNumeroSerie(numeroBase: integer;
     claveUsuario: string; numeroSerie: string): boolean;
  end;

implementation

uses
  SysUtils;

function TGeneradorSeriales.ObtenerNumeroSerie
 (numeroBase: integer; claveUsuario: string): string;
var
  i: integer;
begin
  result := '';
  if (numeroBase <> 0) and (claveUsuario <> '') then
  begin
    i := numeroBase * Length(claveUsuario) + Ord(claveUsuario[1]) * 156;
    result := IntToStr(i);
    i := numeroBase * Ord(claveUsuario[1]) * 452;
    result := Result + IntToStr(i);
    i := numeroBase + (Length(claveUsuario) * Ord(claveUsuario[1])) * 3674;
    result := result + IntToStr(i);
    result := StringReplace(result, '-', '', [rfReplaceAll]);
  end;
end;

function TGeneradorSeriales.ComprobarNumeroSerie(numeroBase: integer;
 claveUsuario: string; numeroSerie: string): boolean;
begin
  if (numeroBase <> 0) and (claveUsuario <> '') then
    result := (numeroSerie = Self.ObtenerNumeroSerie(numeroBase, claveUsuario))
  else
    result := false;
end;

end.

seoane 28-03-2007 18:54:03

Bueno dec, aquí te dejo una función para comprobar el numero de serie pero sin llegar a generarlo en ningún momento. La función para generarlo sigue siendo la misma que pones en el mensaje #40, y puedes usarla tu para generar los números de serie que le mandes a los clientes.
Código Delphi [-]
function GetNum(var Str: String): Integer;
var
  i: Integer;
begin
  Result:= 0;
  while TryStrToInt(Copy(Str,1,1),i) do
  begin
    Result:= (Result * 10) + i;
    Delete(Str,1,1);
  end;
  Delete(Str,1,1);
end;

function CheckSerial(ABase: Integer; AUsername, ASerial: string): Boolean;
var
  A: Integer;
begin
  Result:= FALSE;
  if (ABase <> 0) and (AUserName <> '') then
  begin
    A:= ABase * Length(AUserName) + Ord(AUserName[1]) * 666;
    Result:= GetNum(ASerial) = A;
    A := ABase * Ord(AUserName[1]) * 123;
    Result:= Result and (GetNum(ASerial)= A);
    A := ABase + (Length(AUserName) * Ord(AUserName[1])) * 6613;
    Result:= Result and (GetNum(ASerial) = A);
  end;
end;
Bueno, ahora ya no aparece el numero de serie en la memoria. Ya solo nos tiene que preocupar que nos parchee el programa algún ruso con mucho tiempo libre :D .

Neftali [Germán.Estévez] 28-03-2007 19:06:00

Segun lo que hemos comentado, cambiando un poco la función y añadiendo un parámetro, puedes obtener el número "a trozos".
Revisa este ejemplo.

La de obtener el serial quedaría así:

Código Delphi [-]
function GiveSerial(ABase: Integer; AUserName: string; APart:Integer): string;
const
  RsError = 'Error en los parámetros.';
var
  A: Integer;
begin
  if (ABase <> 0) and (AUserName <> '') then
  begin
    if (APart = 1) then begin
      A := ABase * Length(AUserName) + Ord(AUserName[1]) * 666;
      Result := IntToStr(A);
      Exit;
    end;

    if (APart = 2) then begin
      A := ABase * Ord(AUserName[1]) * 123;
      Result := IntToStr(A);
      Exit;
    end;

    if (APart = 3) then begin
      A := ABase + (Length(AUserName) * Ord(AUserName[1])) * 6613;
      Result := IntToStr(A);
      Exit;
    end;
  end
  else
    Result := RsError;
end;

Y en este caso cambiaríamos la de comprobación por algo así:

Código Delphi [-]
var
  Str, Str2: String;
  i, l1, l2:Integer;
  j1, j2, j3, j4:Integer;
begin

  Str := GiveSerial(123456, Edit1.Text, 1);
  Str2 := Copy(Edit2.Text, 1, Length(Str));

  if (Str <> Str2) then begin
    MessageDlg('SN incorrecto.', mtError, [mbOK], 0);
    Exit;
  end;

  l1 := Length(Str);
  Str := GiveSerial(123456, Edit1.Text, 2);
  Str2 := Copy(Edit2.Text, l1 + 2, Length(Str));

  if ((StrToIntDef(Str, 0) - StrToIntDef(Str2, -99)) <> 0) then begin
    MessageDlg('SN incorrecto.', mtError, [mbOK], 0);
    Exit;
  end;

  l2 := Length(Str);
  Str := GiveSerial(123456, Edit1.Text, 3);
  Str2 := Copy(Edit2.Text, l1 + l2 + 3, Length(Str));

  j1 := StrToIntDef(Str, 0);
  j2 := StrToIntDef(Str2, -99);
  j3 := (j1 DIV j2);
  j4 := (j1 MOD j2);
  if (j3 <> 1) or (j4 <> 0)then begin
    MessageDlg('SN incorrecto.', mtError, [mbOK], 0);
    Exit;
  end;


  MessageDlg('El programa se ha registrado correctamente.', mtInformation, [mbOK], 0);

end;

Es un ejemplo, pero fácilmente puedes generarlizarla un poco más... (lo he escrito sobre la macha y tampoco lo he pensado mucho...).
El número de serie no aparece completo, es más ni siquiera aparecen todos los trozos. Sinceramente creo que es casi imposible que alguien mirando la memoria del programa se le ocurre que 6 números que hay por ahí son parte del número de serie. Si la comprobación la cambias de orden pues mucho menos.

Otro tema es el del Debug; Eso si quieres lo dejamos para otro momento....

dec 28-03-2007 19:20:32

Hola,

Os agradezco a todos vuestro esfuerzo, de verdad. No doy pie con bola y no es culpa vuestra, ni mucho menos. No me encuentro muy bien, a lo que se ve. Supongo que será algo pasajero, puesto que no es la primera vez que me ocurre.

Probando la última solución propuesta por Seoane (no me gusta copiar y pegar, pero, he tenido que hacerlo sin remedio) encuentro el siguiente problema:

(Nótese que el nombre de la función "CheckSerial" es ahora "ComprobarNumeroSerie" pero que no cambia más que esto)

Código Delphi [-]
function TGeneradorSeriales.ComprobarNumeroSerie(numeroBase: integer;
 claveUsuario: string; numeroSerie: string): boolean;
var
  A: Integer;
begin
  Result:= FALSE;
  if (numeroBase <> 0) and (claveUsuario <> '') then
  begin
    A:= numeroBase * Length(claveUsuario) + Ord(claveUsuario[1]) * 666;
    Result:= GetNum(numeroSerie) = A;
    A := numeroBase * Ord(claveUsuario[1]) * 123;
    Result:= Result and (GetNum(numeroSerie) = A);
    A := numeroBase + (Length(claveUsuario) * Ord(claveUsuario[1])) * 6613;
    Result:= Result and (GetNum(numeroSerie) = A);
  end;

  if not Result then
  begin
    ShowMessage(Format('¿Número de serie incorrecto? %s', [numeroSerie]));
  end;

end;

El caso es que incluso proporcionando un código de serie válido este resulta ser "no válido". Por tanto entramos en el "If not Result then...".

He podido comprobar que si no proporcino clave de usuario y sí únicamente el número de serie, entro en el "if not Result then..." y el mensaje muestra efectivamente el número de serie introducido.

Pero si añado la clave de usuario (como tiene que ser) junto con el número de serie, entonces tampoco valida el número (aunque sea correcto) y además el mensaje muestra el número "partido"... no completo...

Esto me supera, probablemente. No he comprobado esto último que comenta Neftalí, puesto que lo acabo de leer. :) Y ya lo que me trae de cabeza es que intente buscar el número de serie en la memoria en antiguos programas en donde hacía uso del mismo sistema... y no aparezca.

O sea, que algo he tocado... y ya se sabe que lo que funciona no debe tocarse... ¡qué sé yo!

Bueno. Os agradezco a todos de veras el esfuerzo que ponéis en tratar de echarme una mano, pero, empiezo a pensar que debo tomarme esto mucho más seriamente de lo que soy capaz ahora mismo.

Tampoco corre prisa, supongo. Voy a tratar de tomármelo con más calma a ver qué tal...

Gracias a todos monstruos. :) :D

seoane 28-03-2007 19:32:49

:confused: No entiendo:

Si yo genero un numero de serie con la función que aparece en el mensaje #40. Obtengo esto:
Código:

Base = 1234
Usuario = Domingo
Resultado = 53926-10321176-3149022

Y usando la función que te pase si, yo hago lo siguiente, obtengo TRUE:
Código Delphi [-]
CheckSerial(1234,'Domingo','53926-10321176-3149022');

dec 28-03-2007 19:42:51

Hola,

Vale Seoane.... :D

Sí; acabo de comprobar que funciona el asunto, y que el número de serie correcto no aparece en la memoria... ¡y esto quiere decir que lo he... que lo habéis conseguido! Toca ahora (para interesados) estudiar el código propuesto y saber porqué funciona y porqué antes no funcionaba...

En todo caso parece que el asunto está arreglado... en otro caso volveré a acosaros de nuevo. Gracias por todo. Si no fuera por vosotros probablemente esto me hubiera costado una úlcera (siempre quise decir algo así).

¡Muchas gracias! :) :)

PD. Cuando me asegure de que todo está en orden lo referiré de nuevo aquí, no podré evitarlo. Hasta pronto.

Por cierto... el código quedará más o menos de la siguiente forma:

Código Delphi [-]
unit UGeneradorSeriales;

interface

type
  TGeneradorSeriales = class
  public
    function ObtenerNumeroSerie(numeroBase:integer;
     claveUsuario: string): string;

    function ComprobarNumeroSerie(numeroBase: integer;
     claveUsuario: string; numeroSerie: string): boolean;
  end;

implementation

uses
  SysUtils;

// Made in Seoane :P (ClubDelphi.com)
function GetNum(var Str: String): Integer;
var
  i: integer;
begin
  result := 0;
  while TryStrToInt(Copy(Str,1,1),i) do
  begin
    result := (result * 10) + i;
    Delete(Str,1,1);
  end;
  Delete(Str,1,1);
end;

function TGeneradorSeriales.ObtenerNumeroSerie
 (numeroBase: integer; claveUsuario: string): string;
var
  A: integer;
begin
  if (numeroBase <> 0) and (claveUsuario <> '') then
  begin
    A := numeroBase * Length(claveUsuario) + Ord(claveUsuario[1]) * 666;
    result := IntToStr(A) + '-';
    A := numeroBase * Ord(claveUsuario[1]) * 123;
    result := result + IntToStr(A) + '-';
    A := numeroBase + (Length(claveUsuario) * Ord(claveUsuario[1])) * 6613;
    result := result + IntToStr(A);
  end;
end;

function TGeneradorSeriales.ComprobarNumeroSerie(numeroBase: integer;
 claveUsuario: string; numeroSerie: string): boolean;
var
  A: integer;
begin
  result := false;
  if (numeroBase <> 0) and (claveUsuario <> '') then
  begin
    A := numeroBase * Length(claveUsuario) + Ord(claveUsuario[1]) * 666;
    result := GetNum(numeroSerie) = A;
    A := numeroBase * Ord(claveUsuario[1]) * 123;
    result := result and (GetNum(numeroSerie) = A);
    A := numeroBase + (Length(claveUsuario) * Ord(claveUsuario[1])) * 6613;
    result := result and (GetNum(numeroSerie) = A);
  end;
end;

end.

mamcx 28-03-2007 19:52:38

A proposito de esto, la mejor guia (en cuanto a ser de facil digestion) de hacer programas anti-crack con Delphi:

http://www.inner-smile.com/nocrack.phtml

;)

dec 28-03-2007 19:56:56

Hola,

Gracias Mario. Echaremos un vistazo. :)

Por cierto Seoane... te vas a partir de la risa... ¡todo va bien, pero mis clientes no podrán llamarse "raro", ni "ramon", ni por supuesto "pepe"!

No te preocupes. Ya trataré de averiguar qué ocurre para que usuarios como "domi", "seoane", "domingo seoane", generen números de serie que luego pueden validarse sin problemas (ni aparecer en memoria), pero, sin embargo, nombres de usuarios como "raro", "ramon", "pepe"... no validen...

Por eso más arriba dije que no me había funcionado... había copiado y pegado bien, pero no me funcionó con el nombre de usuario conque probé... :D :D

Me estoy volviendo loco, me estoy volviendo loco, me estoy volviendo loco, poco a poco, poco a poco... (bis) :D

Edito: Y no es para menos. Ahora resulta que el nombre de usuario "pepe" no valida, pero el número de serie sigue apareciendo en memoria... que da igual, porque no valida, pero aparece... decidme si esto es normal o qué... :D

En todo caso parece que hemos avanzado mucho (gracias Seoane) porque, efectivamente, el usuario "juan" sí valida, pero, si no se introduce un número de serie válido, valga la redundancia, el correcto (generado en el programa) no aparece en memoria.


Bueno. ¡Pues con no vender el programa a nadie que se llame "pepe" o "ramon"! :D :D :D :D

seoane 28-03-2007 20:05:12

Cita:

Empezado por dec
Por cierto Seoane... te vas a partir de la risa... ¡todo va bien, pero mis clientes no podrán llamarse "raro", ni "ramon", ni por supuesto "pepe"!

:D Por que tu lo dices, porque yo hago esto:
Código Delphi [-]
var
  Str: string;
begin
  Str:= GiveSerial(1234,'pepe');
  Writeln(Str);
  Writeln(CheckSerial(1234,'pepe',Str));
  Readln;
end.
Y me valida de maravilla

Al igual que estos otros: raro ,ramon, ...

No sera problema del numero base que estas utilizando ??? :confused:

dec 28-03-2007 20:17:41

Hola,

Estaba leyendo lo que ha enlazado Mario antes... ciertamente interesante.

Seoane... ¡otra vez tienes razón! (yo de ti comenzaría a mirármelo) :)

Era cuestión del número base (de cinco cifras). Cambiando el número base problema resuelto. Aunque no se trata de un programa, sino de varios programas, y por tanto hay implicados varios números base, pero cambiaré todos a cuatro cifras (todos tienen ahora cinco) y probaré a ver...

Otra vez gracias. Interesante lo que enlaza Mario, echadle un vistazo si podéis y os sentís interesados en el tema. :)

Gracias otra vez a todos y gracias otra vez Domingo. :)

dec 28-03-2007 21:36:11

Hola,

Bueno. Otra vez yo. Quería que supiérais que ya estoy más tranquilo. Aunque no hago caso ni de la mitad de las cosas que se mencionan en el sitio Web que enlazó antes Mario, al menos el "bug" que tenía el programa que estoy llevando a cabo ya no existe, gracias a todos vosotros.

Es cierto que no tengo ahora mismo ganas de estudiar el código de Domingo Seoane, pero, supongo que cogeré esas ganas de un momento a otro... Por mi parte actualizé ya el programa, me puse en contacto con el usuario que me informó del "bug", le envié los datos de registro del programa (que se los ha ganado) y le agradecí de su útil colaboración.

Bueno. Pues eso. Que ya estoy más tranquilo. ¡Me entran ganas de ponerme a pegar tiros en el Counter Strike!... Por cierto soy "deckiller" y luego estar en "cs.rin.ru". :D

PD. Gracias otra vez a todos. :)

ArdiIIa 29-03-2007 03:10:00

Alguien conoce o ha utilizado Ionwors

Echando un vistazo por Code Projec al final llegué a ese sitio...

dec 29-03-2007 07:52:05

Hola,

Gracias ArdiIIa. Si te interesa el tema no dejes de leer el sitio Web que enlazó Mario más arriba: Anti Cracking FAQ. Creo que ofrece ideas muy curiosas y a tener en cuenta.

También están disponibles libremente los componentes Turbo Power OnGuard. No hize en su momento sino probarlos muy por encima, pero, en fin, la descripción de los componentes es bastante clara:

Cita:

OnGuard is a library to create demo versions of your Borland Delphi & C++Builder applications. Create demo versions that are time-limited, feature-limited, limited to a certain number of uses, or limited to a certain # of concurrent network users.

Casimiro Notevi 29-03-2007 10:05:58

Qué bien vendría una buena traducción de esa página 'Anti Cracking FAQ'

ArdiIIa 29-03-2007 17:53:08

Cita:

Empezado por Casimiro Notevi
Qué bien vendría una buena traducción de esa página 'Anti Cracking FAQ'

Venga Casmimiro, no me digas que no se entiende....

Casimiro Notevi 29-03-2007 20:15:16

Cita:

Empezado por ArdiIIa
Venga Casmimiro, no me digas que no se entiende....

en fin... dije: "una buena traducción" :D

Más o menos se entiende en inglés y en la traducción de google, pero hay "detalles" que muchas veces son los más importantes y que se pierden por culpa de no conocer bien un idioma o por las traducciones automáticas.

Este año no puedo dejarlo pasar sin que me apunte a la escuela de idiomas :rolleyes:

dec 29-03-2007 23:56:50

Hola,

¡Esa es la comunidad! ¡Doscientos traductores peleándose por complacer al compañero Casimiro -entre otros! ¡Yo, yo, yo lo traduzco! ¡No, lo traduzco yo! ¡¡Pa'qué, si ya está traducido!! Anoche que me lo propuse. ¡Jo, que tío! ¡Gracias! ¡Muchas gracias! ¡Gracias amigo! ¡Muchas gracias! ¡Qué onda guey! ¡Sos un genio! ¡Viva, viva el traductor innombrable! ¡Viva! ¡Viva! ¡Viva!

PD. También Casimiro podías apuntarte ya a la escuela de idiomas... :D :D :D

roman 30-03-2007 00:03:13

Nah, está muy largo ese artículo. A ver Casimiro, repite conmigo:

John is a student
My name is Casimiro

:D

// Saludos

dec 30-03-2007 00:13:02

My tailor is rich

:D :D :D :D :D

roman 30-03-2007 00:16:58

Sigamos con la clase:

Linux sucks
Windows rocks
Bill is my friend

:D


La franja horaria es GMT +2. Ahora son las 12:49:04.

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