Nota del autor

Si la entrada que estás leyendo carece de imágenes, no se ve el vídeo que teóricamente lleva incrustado o el código fuente mostrado aparece sin formato, podéis conocer los motivos aquí. Poco a poco iré restableciendo la normalidad en el blog.
Este blog es un archivo de los artículos situados previamente en Lobosoft.es y ha dejado de ser actualizado. Las nuevas entradas pueden encontrarse en www.lobosoft.es. Un saludo,
Lobosoft.

jueves, 19 de junio de 2008

Obtener el número de serie del disco duro en .NET

Hace varios años desarrollé una aplicación de escritorio que debía distribuirse de forma controlada, evitando una posible duplicación ilegal del mismo. Como sistema de control incluí en la aplicación una determinada funcionalidad que se basaba en la generación de números de serie vinculados a la unidad de disco duro donde era instalado el programa. Recientemente escribía una entrada sobre la obtención de los números de serie de dispositivos USB, y la forma de usar dicha información para crear una especie de llaves USB "caseras" que permitiesen validar software legal. Tanto una idea como otra son factibles, e incluso una combinación de ambas permitiría obtener una mayor seguridad, siempre teniendo en cuenta que deberían usarse adecuadamente, así como usar algún ofuscador de código, ya que el código objeto permite ser desensamblado, máxime cuando hablamos de código en .NET que, como ya sabemos, se traduce a lenguaje intermedio (IL) del CLR, y es fácil obtener el código fuente asociado al mismo en cualquiera de los lenguajes soportados por .NET (y particularmente, en VB.NET o C#).


El código que presento, por tanto, es el de la obtención del número de serie de un disco duro. Se trata de código en Visual Basic .NET, y se apoya en llamadas a librerías del sistema, en este caso de Kernel32.




[vbnet]Private Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, _

Function HDSerial() As String
Dim sDrv As String, sVolumeName As String, sSysName, SN As String
Dim iSerial, R, i As Int32
sDrv = "C:\" & ControlChars.NullChar
sVolumeName = New String(ControlChars.NullChar, 100)
sSysName = New String(ControlChars.NullChar, 100)
R = GetVolumeInformation(sDrv, sVolumeName, sVolumeName.Length, iSerial, 0, 0, sSysName, sSysName.Length)
SN = iSerial.ToString("X8")
Return SN.Substring(0, 4) & "-" & SN.Substring(4, 4)
End Function
[/vbnet]

Como vemos, obtenemos el valor del número de serie del disco duro mediante una llamada a la función GetVolumeInformation, y recuperando en la variable iSerial el valor de este número de serie. Posteriormente es convertida a Hexadecimal con el método ToString y el formato "X". El número 8 indica el número de valores 0 (cero) significativos a la izquierda del valor, si no llega a los 8 dígitos necesarios.

3 comentarios:

  1. Hola tuviste una muy buena idea para proteger tu sfw yo estoy trantando de hacer lo mismo pero lo que pasa es q en tu codigo le faltan parametros a la funcion GetVolumeInformation o sera q no supe usarla de manera adecuada ?
    pues espero que puedas ayudarme porque soy medio nueva en esto
    muchas gracias !

    ResponderEliminar
  2. Saludos amigo.
    He estado en busca de una aplicacion que me permita identificar el numero de serie del dispositivo fisico. Sin embargo todo lo que encuentro parece que lo que identifica es el volumen en si. Digamos "C:" , "D" etc
    Pero no el disco duro.
    Un ejemplo es que tengo 2 particiones en un disco duro (digamos C y H)
    Las aplicaciones identifican con un mnumero de serie a C y con otro a H, siendo que ambos son el mismo disco duro.
    Utilizando un programa para verificar el estado de los discos duros, podemos observar ke el numero de serie es WD-WCAS821 (referente a la marca del disco que es western digital) y este no cambia en ningun momento independientemente de las unidades que tengamos (C,D,H)... Este es el que me gustaria poder obtener.
    Trato de explicarme lo mas que se pueda.
    Si pudieras ayudarme te lo agradecera muchisimo.

    ResponderEliminar
  3. Estimado Ricardo.

    Entiendo perfectamente lo que buscas, no se trata del número de serie de la partición, establecido durante el formateo de la unidad lógica, sino el físico del disco duro, que debe coincidir para cualquier partición que esté dentro del mismo disco.

    Aunque podría valerte el código que incluyen las entradas relacionadas con este tema que ya hay publicadas en el blog, he creído conveniente incluir una nueva sobre la consulta mediante WMI de características físicas de nuestro sistema. En concreto, utilizando una herramienta que proporciona Microsoft para facilitar el desarrollo de aplicaciones que deban integrar esta funcionalidad.

    Te dejo el enlace de la entrada (que, a su vez, incluye los correspondientes a las otras entradas que te mencionaba). Espero que te sirva de ayuda.

    http://www.lobosoft.es/2009/03/20/wmi-code-creator

    Un cordial saludo.

    ResponderEliminar