PDA

Ver la Versión Completa : Guardar datos en un ejecutable


cmfab
10-08-2011, 18:37:09
Hola a todos, hoy quisiera hacerles una pregunta interesante. es posible en
un momento de ejecucion de una aplicacion que esta guarde dos variables
por ejemplo de tipo strings dentro del propio ejecutable ?. algo así como
un recurso, pero que esta informacion quede dentro del .exe que no sea
visible al usuario. desde ya mil gracias a todos por sus atenciones

ecfisa
10-08-2011, 18:52:51
Hola cmfab.

Puedo estar equivocado, pero según creo, desde la misma aplicación no es posible ya que el archivo está bloqueado para escritura mientras permanece abierto.


Un saludo.

Edito: Una pregunta, ¿ Por que motivo deseas guardar una cadena de caracteres en el ejecutable ?

genius78
10-08-2011, 19:12:13
Investiga la funcion UpdateResource

ecfisa
10-08-2011, 19:23:34
Investiga la funcion UpdateResource
Hola genius78 y bienvenido a los foros de ClubDelphi.

La función UpdateResource (http://msdn.microsoft.com/en-us/library/ms648049%28v=vs.85%29.aspx) no escribe dentro del propio ejecutable como solicita cmfab, lo hace en los recursos embebidos en él, de todos modos pienso que con Delphi y desde el programa en ejecución no es factible. ( hasta que me demuestren lo contrario... :))

Saludos.

cmfab
10-08-2011, 19:40:57
Hola gracias por las respuestas, pero quiza me sirva ese recurso si esta embebido en el exe. quiere decir que el usuario no puede cambiar esos parametros, es así. podrian indicarme como hacerlo. gracias

ecfisa
10-08-2011, 20:08:19
Hola de nuevo cmfab.

Creo que vas a necesitar mucho más que esa función para solucionar el problema, es el S.O. a quién hay que 'puentear' para lograrlo. Ya que como te dije tu archivo .exe estará bloqueado para escritura mientras permanezca abierto.

Quizá con alguna rutina residente que pudiera tomar una instantánea de tu programa y esperar a que se cierre para adicionar los datos y reescribir el exe, u otro artilugio que desconozco se pueda lograr. (Si el antivirus no empieza a chillar como desquiciado... ;)).

Pero insisto con mi pregunta: ¿ Cuál es el motivo ? Por que seguramente haya un modo más sencillo de hacer lo que buscas.

Un saludo.

oscarac
10-08-2011, 21:20:08
si derrepente lo que buscas es ir guardando informacion al salir del sistema o en el transcurso de su ejecucion podrias utilizar archivos tipo INI o algun archivo de texto donde la informacion que se guarde pueda estar encriptada para que nadie pueda interpretarla

cmfab
10-08-2011, 22:12:48
Gracias a todos en especial a ecfisa. bueno os comento un poco mas. el tema es que no puedo usar archivos ini, ni tablas de una BD por ejemplo, ni el registro.
se que se puede encriptar la informacion para que no se interprete pero lo
que me urge es que no se pueda eliminar, si uso los metodos mencionados
anteriromente el usuario podria eliminar esa informacion. repito lo que necesito es que una vez que yo parapetrice un par de variables tipo strings
el usuario de la aplicacion no pueda eliminar fisicamente estos datos, lo cual no es seguro desde una seccion de un archivo ini, o de un campo de una tabla de la BD.
espero me haya explicado correctamente. gracias a todos

maeyanes
10-08-2011, 22:18:10
Hola...

Si encriptas un archivo INI y aparte le das un nombre raro y lo ocultas, muy difícilmente un usuario promedio le podrá meter mano. También puedes usar el registro de Windows y usar nombres de clave y valores encriptados. El registro de Windows es otro lugar donde los usuarios promedio no meten sus narices. ;)


Saludos...

cmfab
10-08-2011, 22:23:48
Gracias, pregunto y se podrá usar una dll con esas variables y modificarlas
en un momento determinado ?

maeyanes
10-08-2011, 22:30:46
Hola...

Si puedes declarar variables en una DLL y modificarlas en tiempo de ejecución, lo que no podrás hacer es guardar ese valor persistentemente dentro de la misma.

Ya te dimos varias opciones y creo que deberías considerarlas antes de seguir adelante con lo que te propones.

Aquí un hilo que trata casi de lo mismo que preguntas: http://www.clubdelphi.com/foros/showthread.php?t=29039

Y también si te fijas hasta abajo de este mismo hilo verás algunos enlaces a otros temas.



Saludos...

oscarac
10-08-2011, 22:44:43
segun mi humilde opinion intentar grabar datos en un ejecutable es complicarse la vida, alguna vez vi modificar un ejecutable para que en algunos titulos aparezca otra cosa.... pero se hacia a bajo nivel con ensamblador

si quieres guardar datos que no se puedan borrar, existen muchas formas.... archivos include ocultos, registro de windows, archivos alternativos... (si borran uno te queda el otro como backup, etc), las posibilidades son muchas

jose_kira_sk8
10-08-2011, 22:50:29
segun mi humilde opinion intentar grabar datos en un ejecutable es complicarse la vida, alguna vez vi modificar un ejecutable para que en algunos titulos aparezca otra cosa.... pero se hacia a bajo nivel con ensamblador

si quieres guardar datos que no se puedan borrar, existen muchas formas.... archivos include ocultos, registro de windows, archivos alternativos... (si borran uno te queda el otro como backup, etc), las posibilidades son muchas

te doy toda la razón , a mi también me a pasado , es algo muy complicado guardar datos en el ejecutable y casi sin sentido diría , ahí muy pocas excepciones que esto seria viable.

Neftali [Germán.Estévez]
11-08-2011, 09:23:52
Si te decides a llevarlo a cabo, ten en cuenta que es probable que la mayoría de los antivirus que existen te den una alarma cuando se intente modificar un ejecutable. Digamos que es una cosas considerada como "sospechosa".

cmfab
11-08-2011, 13:15:57
Gracias a todos por sus respuestas y tiempo

un gran saludo

ecfisa
11-08-2011, 21:19:35
Hola.

Por si fuera de utilidad, hice un ejemplo simple que guarda cifrado el numero de serie lógico del disco en el registro y luego lo recupera:

...

uses Registry;

(* Escribe serial en registro *)
procedure WriteRegKey(const ARootKey: HKEY; const AKey, Valor, NSer: string);
begin
with TRegistry.Create(KEY_WRITE) do
try
RootKey := ARootKey;
if not OpenKey(AKey, True) then
raise Exception.Create('Error escribiendo el registro')
else
begin
WriteString(Valor, NSer);
CloseKey;
end
finally
Free
end
end;

(* Devuelve serial almacenado en registro *)
function ReadRegKey(const ARootKey: HKEY; const AKey, Valor: string): string;
begin
with TRegistry.Create do
try
RootKey := ARootKey;
if not OpenKey(AKey, False) then
raise Exception.Create('Error leyendo el registro')
else
begin
ReadString(Result);
CloseKey
end
finally
Free
end
end;

(* Obtiene el número serial del disco *)
function HDSerial(const lpRootPathName: PChar): string;
var
lpMaximumComponentLength: DWORD;
lpFileSystemFlags: DWORD;
lpVolumeSerialNumber: DWORD;
lpVolumeNameBuffer: array[0..MAX_PATH] of Char;
begin
GetVolumeInformation(PChar(lpRootPathName),
@lpVolumeNameBuffer,
SizeOf(lpVolumeNameBuffer),
@lpVolumeSerialNumber,
lpMaximumComponentLength,
lpFileSystemFlags, nil, 0);
Result := IntToHex(HiWord(lpVolumeSerialNumber),4) +
IntToHex(LoWord(lpVolumeSerialNumber),4);
end;

(* rutina trivial de cifrado *)
procedure Cifrar(var Valor: string);
var
i: integer;
begin
for i:= 1 to Length(Valor) do
Valor[i]:= Chr(((Ord(Valor[i]) xor 172)xor 15));
end;

(* Ejemplo de uso *)
procedure TForm1.Button1Click(Sender: TObject);
const
VALOR_KEY = '\Software\Microsoft\Windows\CurrentVersion';
var
NSer: string;
begin
NSer:= HDSerial('C:\'); // Obtener serial
Label1.Caption:='Serial Original: ' + NSer; // Mostrar
Cifrar(NSer); // Cifrarlo
// Escribir serial cifrado en el registro
//'NombreConfuso' es cualquiera que no se vislumbre como protección.
WriteRegKey(HKEY_LOCAL_MACHINE,VALOR_KEY,'NombreConfuso',NSer);
// Leer el serial almacenado en el registro
NSer:= ReadRegKey(HKEY_LOCAL_MACHINE,VALOR_KEY,'NombreConfuso');
Label2.Caption:='Serial Cifrado: ' + NSer; // Lo que se ve en el registro
Cifrar(NSer); // Descifrarlo
Label3.Caption:= 'Serial Restaurado: '+Nser;// Mostrarlo
end;

Como es sólo un ejemplo la rutina de cifrado no es ninguna maravilla ;), pero se puede cambiar por la que sea.

Espero que sirva como base para mejorarlo a gusto

Un saludo.

arriolar
23-04-2016, 19:45:39
Hola, ya se que es tarde pero le puede servir a otros. Dentro del ejecutable no se puede, pero si a continuacion de el.

Hace tiempo hice una pequeña aplicacion tipo Libreta de Direcciones para llevar en el usb, tener en la Pc o en la nube, los datos los guardaba en un archivo independiente. Al pasarselo a amigos se quejaban que no les abria, por que no sabian que hacia falta copiar la BD tambien.

Asi que por deporte me propuse obtener esto con un unico archivo que contuviese la BD y el ejecutable, que funcionase trasparente al usuario y guardase los cambios efectuados a la BD.

La "Danza" a grosso modo es la siguente:
Creamos el ejecutable y la BD, con otro programa le anexamos a continuacion la BD al programa.

El ejecutable acepta parametros y segun estos actua de distintos modos:

Sin parametros el programa compara una variable que definimos en tiempo de diseño cuyo valor es el tamaño real del ejecutable.

En caso de ser su tamaño mayor asume que contiene en si a la BD, se abre a si mismo en modo lectura y guarda una copia de si mismo con otro nombre (ya veremos luego por que), extrae la BD, llama a ejecutar su copia pasandole como parametro su propia ruta y nombre.

La copia al recibir el parametro ya sabe que es la copia y no el original, el usuario trabaja normal y al momento de cerrarse usa el parametro para borrar el original, se copia a si mismo con el nombre del original y le anexa a continuacion la BD, invoca al programa original con el parametro LIMPIAR y se cierra.

El programa al recibir el parametro LIMPIAR borra la copia, la BD y se cierra.

Este programa lo realice en C++ Con CBuilder5, use rutinas de manejo de archivos binarios (fOpen,fSeek etc)
Recientemente lo hice en Linux con Lazarus y me ahorre las rutinas dichas tirando del comando dd (DiskDump) que es muy potente, tambien le añadi cifrado fuerte a la BD ya que almacena usuarios y contraseñas.

Casimiro Notevi
23-04-2016, 19:56:42
Hola, bienvenido y gracias por contar tu historia.
No olvides, como todos los nuevos en clubdelphi, leer nuestra guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php), gracias :)