Forum Clubic

Algo pour obtenir l'adresse mac d'un PC [résolu]

Salut à tous!

J’ai besoin de vos lumières sur un point précis…

Voila, je développe des softs en C et j’aurais besoin de protéger l’utilisation d’un soft à un unique poste.

Pour cela, j’ai pensé au départ utiliser les API Windows, notemment celle proposée dans le SDK Windows (SMS_G_System_Disk pour être plus précis) pour récupérer le n° de série du disque dur de la machine.

On compare le n° de série avec celui stocké dans l’exe (pas infaillible mais largement suffisant je pense) et si c’est pas bon, hop, on quitte le prog ou mieux on reboote la machine (ngnak ngnak!!!)

Seuelement, impossible d’utiliser ce fichu SMS_G_System_Disk :confused:

Alors, soit vous savez comment faire, ou peut-être avez vous une solution alternative à me proposer??

Merci par avance de vos conseils éclairés!!

Edit: Bon, pb pour lire le n° de série du disque dur dès qu’on est en RADI, du coup, réorientation vers la récupération de l’adresse mac de la carte réseau présente sur le PC!!

la mac-adress de la carte reseau c unique et avec un peu de chance la carte reseau est integrée a la carte mere

encore plus stricte mac adresse+ip+version os

Oui, effectivement, carte réseau intégrée à la CM!

Mais comment récupérer cette adresse? Y’a une API particulière? Tu l’as déja fait?

je pense qu’on peu le trouver dans une entrée du registre…

ipconfig /all

http://www.codeproject.com/internet/getmac.asp

question conne.

si c’est si simple de protéger un logiciel, pourquoi personne ne le fait ?

les logiciels tres cher sont souvent protegé par adresse mac avec une verif des licence sur reseau… mais c toujours cracable et ça demande de la logistique de hot line lool

Une protection efficace basée sur le matériel, pourquoi pas!
Mais les problèmes se posent en cas de changement du dit matériel.
Dans une application grand publique ce n’est pas possible.

c le principe du dongle

Ce n’est pas pour des applis grand public, mais dans un milieu industriel et pour un seul client (grand groupe). Le seul but est d’éviter un piratage industriel. Pour le pb du changement de matos, comme j’intervient trés régulièrement dur site, c’est pas un pb.

Par contre, ça me gene de passer par VB pour faire ça, je recherche plutôt une solution 100% C ANSI si poss, mais j’ai beau chercher, je trouve pas.

Je continu à chercher, mais si vous avez notamment d’autre soluces, ça m’intéresse. Par exemple, je pensais au S/N du disque dur ou un truc dans le même genre, mais réupérer ces infos relève apparemment du chemin de croix…

pour la mac address :
ben y a les sources de ipconfig…
j’ai pas eu le temps de faire plus qu’une recherche sur google du style ipconfig.c mac addres mais a mon avis on doit pouvoir trouver le module qui lit les mac address pour une NIC…

Mauvaise idée…
Je crois que y a des softs qui permettent de changre l’adresse MAC d’une carte réseau.
Pour le numéro de série de disque dur j’ai pas trouvé. Je connais beaucoup de programme commerciaux qui utilise le numéro de série du disque dur. Je crois que c’est une meilleur idée. Maintenant pour obtenire ce numéro de série, je crains de ne pas beaucoups pouvoir t’aider

changer de mac adresse > spoofing :wink:
on peu le faire avec tout les element de l’ordi :frowning:

Pour le N° série du disque dur, je fais comme ca :

[cpp]
#include <stdio.h>
#include <conio.h>
#include <windows.h>

#define DFP_GET_VERSION 0x00074080
#define DFP_SEND_DRIVE_COMMAND 0x0007c084
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088

#pragma pack(1)
typedef struct _IDEREGS {
BYTE bFeaturesReg;
BYTE bSectorCountReg;
BYTE bSectorNumberReg;
BYTE bCylLowReg;
BYTE bCylHighReg;
BYTE bDriveHeadReg;
BYTE bCommandReg;
BYTE bReserved;
} IDEREGS, *PIDEREGS, *LPIDERE;

typedef struct _SENDCMDINPARAMS {
DWORD cBufferSize;
IDEREGS irDriveRegs;
BYTE bDriveNumber;
BYTE bReserved[3];
DWORD dwReserved[4];
//BYTE bBuffer[1];
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;

typedef struct _DRIVERSTATUS {
BYTE bDriverError;
BYTE bIDEStatus;
BYTE bReserved[2];
DWORD dwReserved[2];
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;

typedef struct _SENDCMDOUTPARAMS {
DWORD cBufferSize;
DRIVERSTATUS DriverStatus;
BYTE bBuffer[512];
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;

typedef struct _IDSECTOR {
USHORT wGenConfig;
USHORT wNumCyls;
USHORT wReserved;
USHORT wNumHeads;
USHORT wBytesPerTrack;
USHORT wBytesPerSector;
USHORT wSectorsPerTrack;
USHORT wVendorUnique[3];
CHAR sSerialNumber[20];
USHORT wBufferType;
USHORT wBufferSize;
USHORT wECCSize;
CHAR sFirmwareRev[8];
CHAR sModelNumber[40];
USHORT wMoreVendorUnique;
USHORT wDoubleWordIO;
USHORT wCapabilities;
USHORT wReserved1;
USHORT wPIOTiming;
USHORT wDMATiming;
USHORT wBS;
USHORT wNumCurrentCyls;
USHORT wNumCurrentHeads;
USHORT wNumCurrentSectorsPerTrack;
ULONG ulCurrentSectorCapacity;
USHORT wMultSectorStuff;
ULONG ulTotalAddressableSectors;
USHORT wSingleWordDMA;
USHORT wMultiWordDMA;
BYTE bReserved[128];
} IDSECTOR, *PIDSECTOR;

void SwapByteOrder(char *m_lpString, unsigned short m_size)
{
char ch;
int m_counter;
int m_strLen;

m_counter = 0;
m_strLen  = strlen(m_lpString);
for (m_counter; m_counter < m_size; m_counter+=2)
{
	ch = m_lpString[m_counter];
	m_lpString[m_counter] = m_lpString[m_counter+1];
	m_lpString[m_counter+1] = ch;
}

}

int main(char argc, char *argv[])
{
int CurrentDrive;
unsigned long m_bytesRead;
HANDLE m_hDrive;
SENDCMDINPARAMS cmd_InParams;
SENDCMDOUTPARAMS cmd_OutParams;
PIDSECTOR cmd_hdInfos;

CurrentDrive = 0;

m_hDrive = CreateFile("\\\\.\\PhysicalDrive0",GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (m_hDrive == INVALID_HANDLE_VALUE) {    
	printf("CreateFile Erreur\n");
	return -1;
}

ZeroMemory(&amp;cmd_InParams,sizeof(cmd_InParams));
ZeroMemory(&amp;cmd_OutParams,sizeof(cmd_OutParams)); 

if (NULL != m_hDrive)
{
	cmd_InParams.bDriveNumber = CurrentDrive;
	cmd_InParams.cBufferSize  = 512;
	if (CurrentDrive &amp; 1)
		cmd_InParams.irDriveRegs.bDriveHeadReg = 0xb0;
	else
		cmd_InParams.irDriveRegs.bDriveHeadReg = 0xa0;

	cmd_InParams.irDriveRegs.bCommandReg       = 0xec;
	cmd_InParams.irDriveRegs.bSectorCountReg   = 1;
	cmd_InParams.irDriveRegs.bSectorNumberReg  = 1;
	
	m_bytesRead = 0;
	if (!DeviceIoControl(m_hDrive, DFP_RECEIVE_DRIVE_DATA, &amp;cmd_InParams, sizeof(cmd_InParams), &amp;cmd_OutParams, sizeof(cmd_OutParams), &amp;m_bytesRead, 0)){
		printf("DeviceIoControl Erreur");
		Sleep(1500);
		CloseHandle(m_hDrive);
		return -1;
	} 

	if (NULL != m_bytesRead)
	{
		char buf[41];
			
			cmd_hdInfos = (PIDSECTOR)cmd_OutParams.bBuffer;
			memcpy(buf, cmd_hdInfos->sModelNumber,40); 
			buf[40]=0;
			SwapByteOrder(buf, 40); 
			printf("Model              : \t%s\n", buf);

			memcpy(buf, cmd_hdInfos->sFirmwareRev, 8); 
			buf[8]=0;
			SwapByteOrder(buf, 8); 
			printf("Firmware           : \t%s\n", buf);

			memcpy(buf, cmd_hdInfos->sSerialNumber, 20); 
			buf[20]=0;
			SwapByteOrder(buf, 20); 
			printf("Numero de serie    : \t%s\n", buf);

			printf("Taille du disque   : \t%d MO\n", cmd_hdInfos->ulTotalAddressableSectors/2/1024);
			printf("Nombre de pistes   : \t%d   \n", cmd_hdInfos->wNumHeads);
			printf("Secteurs par tetes : \t%d   \n", cmd_hdInfos->wNumCurrentSectorsPerTrack);
			printf("Nombre de cylindre : \t%d   \n", cmd_hdInfos->wNumCurrentCyls);
			printf("Octets ECC         : \t%d   \n", cmd_hdInfos->wECCSize);

	}		

}

getch();
CloseHandle(m_hDrive); 

return 0;

}
[/cpp]

Merci c’est parfait!

Heuu, petit problème, qui semble logique après tout: il semble qu’en utilisant une carte RAID, bah, impossible de récupérer les données des (ou au moins 1) disques durs…

Bizarre car avec mon HD serial ata (RAID donc ?) tout fonctionne.

Alors Karl, tu aurais pas le même genre d’algo mais pour lire une adresse mac??? :wink:

Bon, à force de rechercher sur le net, j’ai fini par trouver des trucs intéressant, notamment en utilisant le protocole ARP…

Juste quelques modifs effectuées (merci le projet de serveur ftp en C…) et j’ai finalement obtenu ce que je voulais!

Si ça intéresse du monde, j’ai developpé 3 parties:

  • Un générateur de clé unique basé sur la mac address du PC (c’est basic mais fonctionnel)
  • Un générateur de code basé sur un système de clé privée (bon, c’est pas du RSA, mais avec ça, j’ai déja pas mal plombé le bordel!!)
  • Une dll qui permet de faire tout ça en automatique.

Bon, le code maintenant (en CVI):
[cpp]
#include <userint.h>
#include <windows.h>
#include <stdio.h>
#include <iphlpapi.h>
#include <winsock.h>
#include <tcpsupp.h>
#include <ansi_c.h>

char TargetPath[512] = {0};

int main(int argc, char *argv[])
{
IPAddr ipAddr;
ULONG pulMac[2];
ULONG ulLen;
int i, j;
char szMac[50] = {0};

PBYTE pbHexMac;
char IPAddress[16] = {0};

// Select IP address
sprintf(IPAddress,“192.168.0.1”);

// Set read IP address to prepare ARP framework
ipAddr = inet_addr (IPAddress);

memset (pulMac, 0xff, sizeof (pulMac));
ulLen = 6;

// Send data with ARP protocol (permits to retrieve mac address)
hr = SendARP (ipAddr, 0, pulMac, &ulLen);

// Ensure ARP frame is successful
if(ulLen == 0)
return -1;

pbHexMac = (PBYTE) pulMac;

// Convert mac address into readable ASCII value
for (i=0;i<ulLen;i++)
{
if(i!=ulLen-1)
sprintf (szMac, “%s%02X:”, szMac,pbHexMac[i])
else
sprintf (szMac, “%s%02X”, szMac,pbHexMac[i]);
}
printf("%s",szMac);

return 0;
}
[/cpp]