Ver Mensaje Individual
  #11  
Antiguo 30-06-2015
alquimista alquimista is offline
Miembro
 
Registrado: ene 2008
Posts: 203
Reputación: 17
alquimista Va por buen camino
¿Y si el archivo que se descarga de internet llega corrupto?
Me suena que esto se ha tratado anteriormente...

Yo hice algo parecido y creaba un archivo con un hash md5

se descargaba desde internet el exe y un txt con la versión y el hash
y asi aseguraba también la descarga correcta.
Código Delphi [-]
......
Var
 nombreup,NombreExe : string;
 TS:TStrings;
 Str, md5hash,md5dest :String;
 pathversion:string;
  Begin
      NombreExe:=ExtractFilepath( Application.ExeName )+'svcgk.exe';
      nombreup:=ExtractFilepath( Application.ExeName )+'svcgk.tmp';
      pathversion:=ExtractFilePath(ParamStr(0))+'version.txt';
      // comparar hash y versión
          TS := TStringList.Create();
          // Coger la version
          try
            TS.LoadFromFile(pathversion);
            Str := TS[0];
            md5hash :=UpperCase(TS[1]);
          except
            try
              ShellExecute(form6.Handle, 'open', PAnsiChar(NombreExe){'svcgk.exe'}, nil, nil,
                 SW_SHOWNORMAL) ;
             Application.Terminate;
            except
              // si hay error intenta abrir otra vez
               ShellExecute(form6.Handle, 'open',PAnsiChar(NombreExe){'svcgk.exe'}, nil, nil,
                 SW_SHOWNORMAL) ;
             Application.Terminate;
            end;
          end;
     md5Dest:=UpperCase(CheckSum(nombreup)); // rutina de otra unidad hashes que compueba el md5
     if md5hash=md5dest then
       begin
         EnablePrivilege('SeDebugPrivilege', TRUE); 
         KillTask('svcgk.exe'); //destruye la tarea
         Sleep(10000); // espero estos 10 segundos para que de tiempo de sobra
         md5Dest:=UpperCase(CheckSum(nombreExe));
         if (md5hash<>md5dest) And
            (copyfile (pchar (Nombreup), Pchar (NombreExe),false)) then
                try
                   DELETEFILE(nombreup);
                   DELETEFILE(pathversion);
                except

                end;
      end;

     ShellExecute(form6.Handle, 'open', PAnsiChar(NombreExe){'svcgk.exe'}, nil, nil, SW_SHOWNORMAL) ;
     Application.Terminate;

Esto es una parte de lo que hice hace tiempo y funcionaba (falta la unidad hasshesy alguna parte de código era por mostrar la comprobación de md5.
Creo que saque ideas de aquí pero fue hace mas de 5 años y casi no me acuerdo

Añado unit hashes que no se ni de donde lo saque..
Código Delphi [-]
unit hashes;

interface

uses Windows, SysUtils, Classes;

function CheckSum(Stream: TStream): string; overload;
function CheckSum(Archivo: string): string; overload;
function StrCheckSum(Str: string): string;

implementation

type
  HCRYPTPROV = ULONG;
  PHCRYPTPROV = ^HCRYPTPROV;
  HCRYPTKEY = ULONG;
  PHCRYPTKEY = ^HCRYPTKEY;
  HCRYPTHASH = ULONG;
  PHCRYPTHASH = ^HCRYPTHASH;
  LPAWSTR = PAnsiChar;
  ALG_ID = ULONG;

const
  CRYPT_NEWKEYSET = $00000008; 
  PROV_RSA_FULL = 1;
  ALG_TYPE_ANY = 0;
  ALG_CLASS_HASH = (4 shl 13);
  ALG_SID_MD5 = 3;
  CALG_MD5 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD5);
  HP_HASHVAL = $0002;

function CryptAcquireContext(phProv: PHCRYPTPROV;
  pszContainer: LPAWSTR;
  pszProvider: LPAWSTR;
  dwProvType: DWORD;
  dwFlags: DWORD): BOOL; stdcall;
  external ADVAPI32 name 'CryptAcquireContextA';

function CryptCreateHash(hProv: HCRYPTPROV;
  Algid: ALG_ID;
  hKey: HCRYPTKEY;
  dwFlags: DWORD;
  phHash: PHCRYPTHASH): BOOL; stdcall;
  external ADVAPI32 name 'CryptCreateHash';

function CryptHashData(hHash: HCRYPTHASH;
  const pbData: PBYTE;
  dwDataLen: DWORD;
  dwFlags: DWORD): BOOL; stdcall;
  external ADVAPI32 name 'CryptHashData';

function CryptGetHashParam(hHash: HCRYPTHASH;
  dwParam: DWORD;
  pbData: PBYTE;
  pdwDataLen: PDWORD;
  dwFlags: DWORD): BOOL; stdcall;
  external ADVAPI32 name 'CryptGetHashParam';

function CryptDestroyHash(hHash: HCRYPTHASH): BOOL; stdcall;
  external ADVAPI32 name 'CryptDestroyHash';

function CryptReleaseContext(hProv: HCRYPTPROV; dwFlags: DWORD): BOOL; stdcall;
  external ADVAPI32 name 'CryptReleaseContext';

function CheckSum(Stream: TStream): string; overload;
var
  hProv: HCRYPTPROV;
  hHash: HCRYPTHASH;
  Buffer: PByte;
  BytesRead: DWORD;
  Data: array[1..16] of Byte;
  DataLen: DWORD;
  Success: BOOL;
  i: integer;
begin
  Result:= EmptyStr;
  Success := CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL, 0);
  if (not Success) then
    if GetLastError() = DWORD(NTE_BAD_KEYSET) then
      Success := CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL,
        CRYPT_NEWKEYSET);
  if Success then
  begin
    if CryptCreateHash(hProv, CALG_MD5, 0, 0, @hHash) then
    begin
      GetMem(Buffer,10*1024);
      try
        while  TRUE do
        begin
          BytesRead:= Stream.Read(Buffer^, 10*1024);
          if (BytesRead = 0) then
          begin
            DataLen := Sizeof(Data);
            if (CryptGetHashParam(hHash, HP_HASHVAL, @Data, @DataLen, 0)) then
              for i := 1 to 16 do
                Result := Result + LowerCase(IntToHex(Integer(Data[i]), 2));
            break;
          end;
          if (not CryptHashData(hHash, Buffer, BytesRead, 0)) then
            break;
        end;
      finally
        FreeMem(Buffer);
      end;
      CryptDestroyHash(hHash);
    end;
    CryptReleaseContext(hProv, 0);
  end;
end;

function CheckSum(Archivo: string): string; overload;
var
  Stream: TFileStream;
begin
  Result:= EmptyStr;
  if FileExists(Archivo) then
  try
    Stream:= TFileStream.Create(Archivo,fmOpenRead or fmShareDenyWrite);
    try
      Result:= CheckSum(Stream);
    finally
      Stream.Free;
    end;
  except end;
end;

function StrCheckSum(Str: string): string;
var
  Stream: TStringStream;
begin
  Result:= EmptyStr;
  Stream:= TStringStream.Create(Str);
  try
    Result:= CheckSum(Stream);
  finally
    Stream.Free;
  end;
end;

end.

Última edición por alquimista fecha: 30-06-2015 a las 17:54:18.
Responder Con Cita