Newsgroup: it.comp.lang.delphi
Titolo: mxProtector - Parte seconda

Ciao a tutti,
   mi rivolgo, in particolare, a chi ha gia' usato queste librerie ...
Sto implementando una piccola protezione sul programma basata sull' 
hardwareID e ho il seguente problema.
Il programma gira su server e l'applicazione puo' essere lanciata da desktop 
remoto tramite collegamento, oppure sul server stesso.
Ecco il problema, come faccio a prendere l'hardwareID (funzione delle 
librerie mx) del server dal pc remoto ???
Al momento quando lancio il programma da pc remoto, la funzione mi 
restituisce l'harwareID del pc di esecuzione (com'e' ovvio) ma dato che il 
programma e' su server io devo essere in grado di recuperare le informazioni 
del server.
Grazie a tutti
Ciao, Daniele 
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4627 (20091121) __________
The message was checked by ESET NOD32 Antivirus.
http://www.eset.com

Ma questa cosa e' a suo interno o la devi vendere?
A

 Ma questa cosa e' a suo interno o la devi vendere?
E' a strettissimo uso interno, ma sto cercando di andare un po piu' avanti 
di dove sono ora (ogni giorno si impara sempre qualcosa di nuovo).
Alla prossima
Ciao, Daniele
PS : Dimmi che sai come fa :-)) 
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4631 (20091123) __________


 
Non so se puo' fare al caso tuo, ma un idea potrebbe essere,
se il programma è ad uso interno, fare un "WorkAround" di questo tipo:
Fai girare il software la prima volta sul server e salvi in un file 
harwareID e tutte le info del server, dai vari client devi testare se 
esiste il file contenente le varie info del server se lo trovi il 
programma è stato inizializzato ed usi le informazioni che trovi sul 
file, altrimenti o esci oppure lo inizializzi per quel determinato client.
^_Goblin_^
-- 
Ibis et redibis non morieris in bello
http://goblinland.myminicity.com/

 librerie mx) del server dal pc remoto ???
un servizio win32.
A.


Sono due giorni che il mio newsserver è down, pertanto ti rispondo dal
web.
Premesso che queste domande dovresti farle anche a chi ha scritto
mxprotector, io nel desiderio di aiutarti ti suggerisco di cambiare la
gestione delle licenze in questo senso: ogni qualvolta il programma
viene lanciato, cerca l'hardware id della macchina su cui è in
esecuzione (il client) e verifica che sia nella lista della macchine
licenziate all'uso.
Con questa logica di controllo vai a gestire i PC che si connettono a
prescindere dal fatto che il programma sia locale (server) o remoto
(client).
Utilizza una tabella del tuo database per crearti un archivio centrale
sul server di Hardware ID di tutti i client permessi e consultarlo ad
ogni avvio.
Così facendo hai sempre una sola chiave "master" che serve a
registrare la prima volta il programma sul server, il resto dei client
li gestisci tramite quella tabella, così eventualmente puoi anche
segmentare le licenze (5 macchine, 10 macchine, ecc)
Ciao
--
Morde

    mi rivolgo, in particolare, a chi ha gia' usato queste librerie ...
[...]
Premesso che queste domande dovresti farle anche a chi ha scritto 
mxprotector, io nel desiderio di aiutarti ti suggerisco di cambiare la 
gestione delle licenze in questo senso: ogni qualvolta il programma 
viene lanciato, cerca l'hardware id della macchina su cui ï¿œ in 
esecuzione (il client) e verifica che sia nella lista della macchine 
licenziate all'uso.
Con questa logica di controllo vai a gestire i PC che si connettono a 
prescindere dal fatto che il programma sia locale (server) o remoto 
(client).
Utilizza una tabella del tuo database per crearti un archivio centrale 
sul server di Hardware ID di tutti i client permessi e consultarlo ad 
ogni avvio.
Cosï¿œ facendo hai sempre una sola chiave "master" che serve a registrare 
la prima volta il programma sul server, il resto dei client li gestisci 
tramite quella tabella, cosï¿œ eventualmente puoi anche segmentare le 


 altrimenti o esci oppure lo inizializzi per quel determinato client.
Nel non sapere cosa fare ... ho adottato una soluzione, che poi e' stata 
anche suggerita da Morde, che prevede la creazione di n registrazioni; se i 
client sono 5, si hanno 5 registrazioni differenti perche' gli harware sono 
diversi.
C'e' un pero' .....
La funzione che restituisce l'hardwareid si basa sull'api 
GetVolumeInformation che pero' *NON* restiuisce il numero seriale di 
fabbricazione dell'hd ma restituisce, solo, il numero di serie dato in 
automatico durante la formattazione.
Quindi, se l'utente formatta e in seguito fornisce un numnero di hardwareid 
diverso, ha ragione !!!!
Per ovviare a questo problema ho trovato questa unit che restituisce il 
numero di serie attribuito all'hd dalla fabbrica ...
HardDiskInfo v.1
http://www.torry.net/quicksearchd.php?String=GetVolumeInformation&Title=No
Grazie,
Ciao, Daniele 
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4633 (20091124) __________


 (client).
In attesa di una risposta ho adottato questa strategia.
Pero', come ho risposto a ^_Goblin_^, mxprotector basa il calcolo della 
registrazione sull'api GetVolumeInformation che restiuisce il numero di 
serie assegnato dal sistema operativo durante una formattazione. Quindi se 
un ipotetico cliente di una ipotetica software house formatta l'hd, telefona 
alla software house chiedendo una nuova regkey con un nuovo hardwareid 
...... non sbaglia ... ha ragione !!!
Quindi anziche' la GetVolumeInformation serve una funzione che restituisca 
il numero di serie dell'hd dao dal costruttore.
E questo non e' cosi' immediato .... perche' tutto quanto si trova sul web 
fa riferimento a sta benedetta GetVolumeInformation.
Cercando e cercando, su torry ho trovato una unit del 2007 che ci da questo 
numero ....
Ecco il link e il nome della unit
http://www.torry.net/quicksearchd.php?String=GetVolumeInformation&Title=No
HarddiskInfo v.1
Per una volta spero di aver dato un'informazione utile ....
Grazie a te e a tutti,
Ciao, Daniele
PS : Meno male che e' solo a scopo personale .... meglio dedicarsi alle 
bionde.... more .... brune .... arfff arfff... 
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4634 (20091124) __________


 Per una volta spero di aver dato un'informazione utile ....
non funziona sotto W7-64 con dischi in raid, e mi sa che non funziona in 
generale con l'uac attivato o da utente non amministratore.
E comunque sia, a parte tutto, qualunque programma puï¿½ essere messo dentro 
una macchina virtuale, attivato, e da lï¿½ distribuito a costo zero in tutto 
il mondo senza bisogno di ulteriori attivazioni, quindi queste protezioni 
sono piuttosto inutili. L'unica sarebbe la chiave hardware, non fosse per i 
costi e per il fatto che comunque si puï¿½ sempre bypassare il lucchetto (non 
c'ï¿½ bisogno di forare la cassaforte per forzarla, basta forzare la 
serratura).
Sandra 

 serratura).
Bhe se questa e' la direzione del discorso.... tutto, e il contrario di 
tutto, e' opinabile.
Se partiamo dal concetto che qualche hacker ha violato anche la Banca 
d'Italia .... perche' avere i conti correnti, meglio a casa.
Quindi tieni i soldini nel materasso e puo' capitare, com'e' capitato in 
Israele, che la figlia per fare un piacere alla mamma ha cambiato il 
matererasso buttando cosi' un qualcosa come 1 milione di dollari ..... e via 
discorrendo.
Infine, senza polemizzare, credo sia piu' costruttivo per tutti i 
frequentatori del news cercare di dare, nel limite delle proprie 
possibilita' (le mie sono scarse), delle risposte o delle alternative; per 
esempio "quel codice sotto w7 ecc... non funziona, questo si".
Per non finire troppo offtopic, sposto una unit (non e' tanto grande) per 
prendere il numero di serie del primo hd ide del pc (sotto xp sp3, delphi 6 
update 3 funziona)
// Extracting IDE(ATA) disk serial number.
// (c) 2000-2003 Alex Konshin
//               mailto:
akon...@earthlink.net
//               
http://home.earthlink.net/~akonshin/index.htm
//
// 30 Jul 2000 created
// 22 Oct 2003 refactoring
unit IdeSN;
interface
//-------------------------------------------------------------
// Tries to extract the serial number from the first IDE disk that is found 
in the system.
// Returns an empty string if IDE disk is not found.
  function GetIdeSN : String;
//-------------------------------------------------------------
// Tries to extract the serial number from specified IDE disk.
//
// Parameters:
//   ControllerNumber - SCSI port number of the controller.
//   DriveNumber - Device index (0..4).
//
// Raises OSError exception in case of any error during this operation.
//
// Notes:
//  1. The parameter ControllerNumber is ignored on Windows 9x/ME platforms 
and should be 0.
//  2. This function CAN NOT extract SCSI disk serial number.
//
  function GetIdeDiskSerialNumber( ControllerNumber, DriveNumber : Integer ) 
: String;
//=============================================================
implementation
uses
  Windows,
  SysUtils; // only for Win32Platform, SysErrorMessage and class Exception
{$IFDEF VER150}
{$DEFINE VER140}
{$ENDIF}
{$IFNDEF VER140}
procedure RaiseLastOSError;
begin
  RaiseLastWin32Error;
end;
{$ENDIF}
//-------------------------------------------------------------
// Tries to extract the serial number from specified IDE disk.
//
// Parameters:
//   ControllerNumber - SCSI port number of the controller.
//   DriveNumber - SCSI port number of the controller.
// Notes:
//  1. The parameter ControllerNumber is ignored on Windows 9x/ME platforms 
and should be 0.
//  2. This function CAN NOT extract SCSI disk serial number.
//
function GetIdeDiskSerialNumber( ControllerNumber, DriveNumber : Integer ) : 
String;
type
  TSrbIoControl = packed record
    HeaderLength : ULONG;
    Signature    : Array[0..7] of Char;
    Timeout      : ULONG;
    ControlCode  : ULONG;
    ReturnCode   : ULONG;
    Length       : ULONG;
  end;
  SRB_IO_CONTROL = TSrbIoControl;
  PSrbIoControl = ^TSrbIoControl;
  TIDERegs = packed record
    bFeaturesReg     : Byte; // Used for specifying SMART "commands".
    bSectorCountReg  : Byte; // IDE sector count register
    bSectorNumberReg : Byte; // IDE sector number register
    bCylLowReg       : Byte; // IDE low order cylinder value
    bCylHighReg      : Byte; // IDE high order cylinder value
    bDriveHeadReg    : Byte; // IDE drive/head register
    bCommandReg      : Byte; // Actual IDE command.
    bReserved        : Byte; // reserved for future use.  Must be zero.
  end;
  IDEREGS   = TIDERegs;
  PIDERegs  = ^TIDERegs;
  TSendCmdInParams = packed record
    cBufferSize  : DWORD;                // Buffer size in bytes
    irDriveRegs  : TIDERegs;             // Structure with drive register 
values.
    bDriveNumber : Byte;                 // Physical drive number to send 
command to (0,1,2,3).
    bReserved    : Array[0..2] of Byte;  // Reserved for future expansion.
    dwReserved   : Array[0..3] of DWORD; // For future use.
    bBuffer      : Array[0..0] of Byte;  // Input buffer.
  end;
  SENDCMDINPARAMS   = TSendCmdInParams;
  PSendCmdInParams  = ^TSendCmdInParams;
  TIdSector = packed record
    wGenConfig                 : Word;
    wNumCyls                   : Word;
    wReserved                  : Word;
    wNumHeads                  : Word;
    wBytesPerTrack             : Word;
    wBytesPerSector            : Word;
    wSectorsPerTrack           : Word;
    wVendorUnique              : Array[0..2] of Word;
    sSerialNumber              : Array[0..19] of Char;
    wBufferType                : Word;
    wBufferSize                : Word;
    wECCSize                   : Word;
    sFirmwareRev               : Array[0..7] of Char;
    sModelNumber               : Array[0..39] of Char;
    wMoreVendorUnique          : Word;
    wDoubleWordIO              : Word;
    wCapabilities              : Word;
    wReserved1                 : Word;
    wPIOTiming                 : Word;
    wDMATiming                 : Word;
    wBS                        : Word;
    wNumCurrentCyls            : Word;
    wNumCurrentHeads           : Word;
    wNumCurrentSectorsPerTrack : Word;
    ulCurrentSectorCapacity    : ULONG;
    wMultSectorStuff           : Word;
    ulTotalAddressableSectors  : ULONG;
    wSingleWordDMA             : Word;
    wMultiWordDMA              : Word;
    bReserved                  : Array[0..127] of Byte;
  end;
  PIdSector = ^TIdSector;
const
  IDE_ID_FUNCTION = $EC;
  IDENTIFY_BUFFER_SIZE       = 512;
  DFP_RECEIVE_DRIVE_DATA        = $0007c088;
  IOCTL_SCSI_MINIPORT           = $0004d008;
  IOCTL_SCSI_MINIPORT_IDENTIFY  = $001b0501;
  DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;
  BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize;
  W9xBufferSize = IDENTIFY_BUFFER_SIZE+16;
var
  hDevice : THandle;
  cbBytesReturned : DWORD;
  s : String;
  pInData : PSendCmdInParams;
  pOutData : Pointer; // PSendCmdInParams;
  Buffer : Array[0..BufferSize-1] of Byte;
  srbControl : TSrbIoControl absolute Buffer;
  procedure ChangeByteOrder( var Data; Size : Integer );
  var ptr : PChar;
      i : Integer;
      c : Char;
  begin
    ptr := @Data;
    for i := 0 to (Size shr 1)-1 do
    begin
      c := ptr^;
      ptr^ := (ptr+1)^;
      (ptr+1)^ := c;
      Inc(ptr,2);
    end;
  end;
begin
  Result := '';
  FillChar(Buffer,BufferSize,#0);
  if Win32Platform=VER_PLATFORM_WIN32_NT then
    begin // Windows NT, Windows 2000
      Str(ControllerNumber,s);
      // Get SCSI port handle
      hDevice := CreateFile(
        PChar('\\.\Scsi'+s+':'),
        GENERIC_READ or GENERIC_WRITE,
        FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );
      if hDevice=INVALID_HANDLE_VALUE then RaiseLastOSError;
      try
        srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
        System.Move('SCSIDISK',srbControl.Signature,8);
        srbControl.Timeout      := 2;
        srbControl.Length       := DataSize;
        srbControl.ControlCode  := IOCTL_SCSI_MINIPORT_IDENTIFY;
        pInData := PSendCmdInParams(PChar(@Buffer)+SizeOf(SRB_IO_CONTROL));
        pOutData := pInData;
        with pInData^ do
        begin
          cBufferSize  := IDENTIFY_BUFFER_SIZE;
          bDriveNumber := DriveNumber;
          with irDriveRegs do
          begin
            bFeaturesReg     := 0;
            bSectorCountReg  := 1;
            bSectorNumberReg := 1;
            bCylLowReg       := 0;
            bCylHighReg      := 0;
            bDriveHeadReg    := $A0 or ((DriveNumber and 1) shl 4);
            bCommandReg      := IDE_ID_FUNCTION;
          end;
        end;
        if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT, @Buffer, 
BufferSize, @Buffer, BufferSize, cbBytesReturned, nil ) then 
RaiseLastOSError;
      finally
        CloseHandle(hDevice);
      end;
    end
  else
    begin // Windows 95 OSR2, Windows 98
      hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 );
      if hDevice=INVALID_HANDLE_VALUE then RaiseLastOSError;
      try
        pInData := PSendCmdInParams(@Buffer);
        pOutData := PChar(@pInData^.bBuffer);
        with pInData^ do
        begin
          cBufferSize  := IDENTIFY_BUFFER_SIZE;
          bDriveNumber := DriveNumber;
          with irDriveRegs do
          begin
            bFeaturesReg     := 0;
            bSectorCountReg  := 1;
            bSectorNumberReg := 1;
            bCylLowReg       := 0;
            bCylHighReg      := 0;
            bDriveHeadReg    := $A0 or ((DriveNumber and 1) shl 4);
            bCommandReg      := IDE_ID_FUNCTION;
          end;
        end;
        if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, pInData, 
SizeOf(TSendCmdInParams)-1, pOutData, W9xBufferSize, cbBytesReturned, nil ) 
then RaiseLastOSError;
      finally
        CloseHandle(hDevice);
      end;
    end;
  with PIdSector(PChar(pOutData)+16)^ do
  begin
    ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));
    SetString(Result,sSerialNumber,SizeOf(sSerialNumber));
  end;
  Result := Trim(Result);
end;
//-------------------------------------------------------------
function GetIdeSN : String;
var
  iController, iDrive, maxController : Integer;
begin
  Result := '';
  maxController := 15;
  if Win32Platform<>VER_PLATFORM_WIN32_NT then maxController := 0;
  for iController := 0 to maxController do
  begin
    for iDrive := 0 to 4 do
    begin
      try
        Result := GetIdeDiskSerialNumber(iController,iDrive);
        if Result<>'' then Exit;
      except
        // ignore exceptions
      end;
    end;
  end;
end;
end.
Per farmi perdonare il tono che poteva sembrare polemico (ma non lo e') ecco 
qui:
Get Hard Drive Serial Number 
http://www.diskserialnumber.com/
Key Features of HardDriveInfo.DLL
  a.. Supports to get hard disk serial number.
  b.. Supports to get parameters like Model Number, Firmware Revision 
Number, Cylinders, Heads, Sectors Per Track, Bytes Per Sector etc.
  c.. Support reading several physics hard disks.
  d.. Development languages like Delphi, C++ Builder, VC, C#, VB, 
VB.NET
, 
PowerBuilder, Visual Foxpro, Microsoft VBA, Clarion are supported.
  e.. Do not require administrator rights in Win NT/2000/XP.
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Pero' costa $29.......
Ciao e alla prossima, Daniele


 librerie mx) del server dal pc remoto ???
Hai provato ad immaginare un sistema diverso? Se ti è possibile 
scomporre l'applicazione in un modulo server (quello che si interfaccia 
al DBMS) ed uno client (interfaccia utente), potresti proteggere solo il 
primo (installato sul server) perchè tanto il secondo senza il primo non 
servirebbe a nulla..
A quel punto potresti dilettarti con piacevolezze tipo num. max di 
client simultanei, client web-based scritti anche in altri linguaggi, 
versioni base-professional-enterprise dell'applicativo...
Spero di non averti confuso le idee ancora di più :-)

 // Extracting IDE(ATA) disk serial number.
e se il disco ï¿½ SATA (oggi sono tutti SATA, ormai) ?
Sandra 

 e se il disco � SATA (oggi sono tutti SATA, ormai) ?
C'e' sempre la famosa dll per 29$
Ottima la discussione, ma credo che siamo finiti un po troppo off topic !!!
Un saluto, Daniele


 C'e' sempre la famosa dll per 29$
non c'ï¿½ niente di piï¿½ facilmente craccabile (o, ancor meglio, sostituibile) 
di una dll, con buona pace delle protezioni.
Sandra 

 di una dll, con buona pace delle protezioni.
Alla base del mio ragionamento, che non ï¿œ stato capito fino in fondo, ï¿œ 
il fatto che oggi come oggi essendo *tutto* craccabile ï¿œ inutile 
sprecare energie per inventarsi meccanismi e giri "alla turca" per 
recuperare o nascondere certe info del sistema..
Il sistema di protezione da me suggerito ha lo scopo di *controllare* 
le richieste di codici di registrazione, per avere un monitoraggio su 
ogni cliente.
Il resto poi lo deve fare il backoffice chiedendosi: ï¿œ uno affidabile? 
ha sempre pagato? perchï¿œ ha chiesto 5 codici di sblocco se ha due 
client in ufficio?
Questi miei ragionamenti nascono direttamente dall'esperienza.
Mi piace ricordare a tal proposito un episodio successo un'era 
informatica fa: ai tempi vendevamo un gestionale scritto in GWBasic, 
windows 3.1 non era ancora arrivato e si vendevano macchine olivetti 
con un mega di RAM, e compagnia bella :-)
Bene, in questo epico scenario, capitï¿œ che un cliente ci chiese la 
chiave di registrazione per ben 4 volte in un mese.. e la scusa era "ho 
preso un virus, ho dovuto riformattare". Fu allora che mettemmo un 
meccanismo di protezione che si attivava solo se veniva riconosciuto un 
hardware diverso dal precedente (ricavato dal codice di registrazione).
E cosï¿œ scoprimmo che il cliente stava rivendendo sottobanco a sua volta 
il nostro gestionale e ci chiedeva i codici per i computer dei suoi 
amici: e questa storia venne chiusa dallo studio legale, spolpandosi 
per bene il disonesto.
Quindi, la morale della favole ï¿œ che non serve metter in piedi un 
meccanismo super raffinato anti cracking, basta solo seguire bene il 
cliente..
ciao
-- 
Morde

Comunque, trovo discutibile perdere tempo sulla protezione di un
progetto, ovvero di un prodotto software ad uno interno, quando
secondo me ci saranno n funzionalita' migliorie etc richieste dagli
utenti.
Se lo fai per tuo aggiornamento professionale ci sono cose molto piu
interessanti, e sopratutto, utili, da studiare e approfondire.
A.

Ciao,

Concordo ....
Mi riservo di approfondire questo argomento in un momento piu' favorevole di 
questo.
Grazie a tutti per l'ottima discussione ...
Ciao,
Daniele 
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4639 (20091126) __________


 sostituibile) di una dll, con buona pace delle protezioni.
Questa dll restituisce solo il numero di serie dell'hd ....
Alla prossima discussione ...
Ciao, Daniele
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4639 (20091126) __________


 6 update 3 funziona)
[cut]
Come gi� detto da altri, tale unit in alcuni casi non funziona sotto win 7 - 
vista....
Andrea