Three ways to get the MAC address of the network card in the system by "reprint"

Source: Internet
Author: User
Tags snmp sprintf uuid

from:http://blog.csdn.net/zhangting1987/article/details/2732135

The concept of network card address is a bit confusing. Because there are actually two addresses, MAC address and physical address, generally say the network card address I mean the physical address, do not know what others think? Physical address refers to the address of the ROM on the card where the address is stored, the MAC address is the address of the card when it works, in general, the two addresses are the same, So a lot of people are mixed up and don't even know the difference-_-#

When the network card works, an Ethernet frame 60 to 1514 (not including CRC), the frame CRC is the network card automatically added, the preamble is automatically added. The destination address and the source address of the network adapter are driver-added. So actually the network card when working with what address as the work address is entirely determined by the driver:) Therefore, we can completely change the physical address of the network card in the case of the software method to change the work address of the specific network card.

MAC address is generally saved in the registration table, can be modified, so there is a problem:

1th, can be a non-bogey bomb misappropriation of IP,

2nd, can break some garbage encryption software ...

A lot of software is encrypted through the network card address, there are two different. Some of the better things are done by physical address encryption. Some are encrypted by work address. Addresses that are encrypted through work addresses, such as through Guidgen,netbios, are MAC addresses. This method can generally be used to crack. Encryption by physical address is a bit hard to break, but it's not impossible.

Three ways to obtain the MAC address of the network card in the system

The first method uses the Microsoft NetBIOS API. This is a set of commands that provide support for the underlying network through Winsock. The biggest disadvantage of using NetBIOS is that you must have the NetBIOS service installed on your system (this is not a problem if you have file sharing enabled on your Windows network). In addition to this, this method is fast and accurate.

The NetBIOS API includes only one function, which is called NetBIOS. This function uses the network control block structure as a parameter, and this structure tells the function what to do. The structure is defined as follows:

typedef struct _NCB {

UCHAR Ncb_command;

UCHAR Ncb_retcode;

UCHAR Ncb_lsn;

UCHAR Ncb_num;

Puchar Ncb_buffer;

WORD ncb_length;

UCHAR Ncb_callname[ncbnamsz];

UCHAR Ncb_name[ncbnamsz];

UCHAR Ncb_rto;

UCHAR Ncb_sto;

void (CALLBACK *ncb_post) (struct _NCB *);

UCHAR Ncb_lana_num;

UCHAR ncb_cmd_cplt;

#ifdef _win64

UCHAR ncb_reserve[18];

#else

UCHAR NCB_RESERVE[10];

#endif

HANDLE ncb_event;

} NCB, *PNCB;

The focus is on Ncb_command members. This member tells NetBIOS what to do. We use three commands to detect MAC addresses. Their definition in MSDN is as follows:

Command Description:

Ncbenum Windows nt/2000: Enumerates the number of network cards in the system. With this command, the Ncb_buffer member points to the buffer populated by the lana_enum structure.

Ncbenum is not a standard NetBIOS 3.0 command.

Ncbreset Reset the NIC. The network adapter must be reset before accepting the new NCB command.

Ncbastat accepts the status of a local or remote interface card. With this command, the Ncb_buffer member points to the buffer populated by the adapter_status structure, followed by an array of name_buffer structures.

Here are the steps to get your system MAC address:

1 "List all the interface cards.

2 "reset each card to get the correct information.

3 "Query the interface card, get the MAC address and generate a standard colon-delimited format.

Here is the instance source program.

#include <windows.h>

#include <stdlib.h>

#include <stdio.h>

#include <iostream>

#include <string>

using namespace Std;

#define BZERO (Thing,sz) memset (THING,0,SZ)

BOOL Getadapterinfo (int adapter_num, string &mac_addr)

{

Reset the NIC so we can query

NCB NCB;

memset (&NCB, 0, sizeof (NCB));

Ncb.ncb_command = Ncbreset;

Ncb.ncb_lana_num = Adapter_num;

if (Netbios (&NCB)! = Nrc_goodret) {

Mac_addr = "Bad (ncbreset):";

Mac_addr + = string (Ncb.ncb_retcode);

return false;

}

Ready to get the state block of the interface card

Bzero (&ncb,sizeof (NCB);

Ncb.ncb_command = Ncbastat;

Ncb.ncb_lana_num = Adapter_num;

strcpy ((char *) ncb.ncb_callname, "*");

struct ASTAT

{

Adapter_status adapt;

Name_buffer namebuff[30];

} Adapter;

Bzero (&adapter,sizeof (Adapter));

Ncb.ncb_buffer = (unsigned char *) &Adapter;

ncb.ncb_length = sizeof (Adapter);

Gets the network card information, and returns the standard colon-delimited format if the NIC works correctly.

if (Netbios (&NCB) = = 0)

{

Char acmac[18];

sprintf (Acmac, "%02x:%02x:%02x:%02x:%02x:%02x",

Int (adapter.adapt.adapter_address[0]),

Int (adapter.adapt.adapter_address[1]),

Int (adapter.adapt.adapter_address[2]),

Int (adapter.adapt.adapter_address[3]),

Int (adapter.adapt.adapter_address[4]),

Int (adapter.adapt.adapter_address[5]));

MAC_ADDR = Acmac;

return true;

}

Else

{

Mac_addr = "Bad (ncbastat):";

Mac_addr + = string (Ncb.ncb_retcode);

return false;

}

}

int main ()

{

Get a list of network cards

Lana_enum adapterlist;

NCB NCB;

memset (&NCB, 0, sizeof (NCB));

Ncb.ncb_command = Ncbenum;

Ncb.ncb_buffer = (unsigned char *) &AdapterList;

ncb.ncb_length = sizeof (adapterlist);

Netbios (&NCB);

Get the address of your local Ethernet card

String mac_addr;

for (int i = 0; i < adapterlist.length-1; ++i)

{

if (Getadapterinfo (Adapterlist.lana, mac_addr))

{

cout << "Adapter" << int (Adapterlist.lana) <<

"´s MAC is" << mac_addr << Endl;

}

Else

{

Cerr << "Failed to get MAC address! Do you "<< Endl;

Cerr << "have the NetBIOS protocol installed?" << Endl;

Break

}

}

return 0;

}

Second method-using the COM GUID API

This method uses the COM API to create a GUID (globally unique identifier) and inherit the MAC address from there. GUIDs are commonly used to identify COM components and other objects in the system. They are computed by the MAC address (which is combined with other things), which is included in the MAC address on the surface. I say ostensibly because the fact is not contained.

I offer this method more as a negative case. You might be able to get a MAC address in this way, but sometimes you just get a random hexadecimal value.

The following example is very simple, needless to say. We use CoCreateGuid to create a GUID and put the last six bytes into the string. They may be MAC addresses, but not necessarily.

#include <windows.h>

#include <iostream>

#include <conio.h>

using namespace Std;

int main ()

{

cout << "MAC address is:";

Requires a UUID to COM. If there is an Ethernet card in the machine,

The last six bytes of the UUID (2-7 bytes of Data4) should be the MAC address of the local Ethernet card.

GUID uuid;

CoCreateGuid (&UUID);

Spit the address out

Char mac_addr[18];

sprintf (mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x",

Uuid. Data4[2],uuid. Data4[3],uuid. DATA4[4],

Uuid. Data4[5],uuid. Data4[6],uuid. DATA4[7]);

cout << mac_addr << Endl;

Getch ();

return 0;

}

Third approach-using the SNMP extension API

The third way I'm going to discuss this is to use the Windows SNMP (Simple Network Management Protocol) extension to get the MAC address. In my experience, this agreement is simple. The code is also straight forward. The basic steps are the same as NetBIOS:

1. Get a list of network cards

2 "Query the type and MAC address of each card

3 "Save current NIC

I don't know much about SNMP personally, but as I've just said, the code is clear.

#include <snmp.h>

#include <conio.h>

#include <stdio.h>

typedef BOOL (WINAPI * psnmpextensioninit) (

In DWORD dwtimezeroreference,

Out HANDLE * hpollfortrapevent,

Out asnobjectidentifier * supportedview);

typedef BOOL (WINAPI * psnmpextensiontrap) (

Out Asnobjectidentifier * Enterprise,

Out Asninteger * generictrap,

Out Asninteger * specifictrap,

Out Asntimeticks * TimeStamp,

Out rfc1157varbindlist * variablebindings);

typedef BOOL (WINAPI * psnmpextensionquery) (

In BYTE RequestType,

In Out rfc1157varbindlist * variablebindings,

Out Asninteger * ErrorStatus,

Out Asninteger * errorindex);

typedef BOOL (WINAPI * Psnmpextensioninitex) (

Out asnobjectidentifier * supportedview);

void Main ()

{

HINSTANCE m_hinst;

Psnmpextensioninit M_init;

Psnmpextensioninitex M_initex;

Psnmpextensionquery M_query;

Psnmpextensiontrap M_trap;

HANDLE pollfortrapevent;

Asnobjectidentifier SupportedView;

UINT oid_ifentrytype[] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 3};

UINT oid_ifentrynum[] = {1, 3, 6, 1, 2, 1, 2, 1};

UINT oid_ipmacentaddr[] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 6};

Asnobjectidentifier mib_ifmacentaddr =

{sizeof (OID_IPMACENTADDR) sizeof (UINT), oid_ipmacentaddr};

Asnobjectidentifier Mib_ifentrytype =

{sizeof (Oid_ifentrytype) sizeof (UINT), oid_ifentrytype};

Asnobjectidentifier Mib_ifentrynum =

{sizeof (oid_ifentrynum) sizeof (UINT), oid_ifentrynum};

Rfc1157varbindlist varbindlist;

Rfc1157varbind varbind[2];

Asninteger ErrorStatus;

Asninteger ErrorIndex;

Asnobjectidentifier Mib_null = {0, 0};

int ret;

int dtmp;

int i = 0, j = 0;

BOOL found = false;

Char tempethernet[13];

M_init = NULL;

M_initex = NULL;

M_query = NULL;

M_trap = NULL;

/* Load the SNMP dll and get the instance handle */

M_hinst = LoadLibrary ("Inetmib1.dll");

if (M_hinst < (HINSTANCE) hinstance_error)

{

M_hinst = NULL;

Return

}

M_init =

(Psnmpextensioninit) GetProcAddress (m_hinst, "snmpextensioninit");

M_initex =

(Psnmpextensioninitex) GetProcAddress (M_hinst,

"Snmpextensioninitex");

M_query =

(Psnmpextensionquery) GetProcAddress (M_hinst,

"Snmpextensionquery");

M_trap =

(Psnmpextensiontrap) GetProcAddress (m_hinst, "snmpextensiontrap");

M_init (GetTickCount (), &pollfortrapevent, &supportedview);

/* Initialize the list of variables to receive m_query query results */

Varbindlist.list = Varbind;

Varbind[0].name = Mib_null;

Varbind[1].name = Mib_null;

/* Copy and find the number of entries in the interface table in the OID */

Varbindlist.len = 1; /* Only retrieving one item */

snmp_oidcpy (&varbind[0].name, &mib_ifentrynum);

RET =

M_query (Asn_rfc1157_getnextrequest, &varbindlist, &errorstatus,

&errorindex);

printf ("# of adapters in this system:%in",

Varbind[0].value.asnvalue.number);

Varbindlist.len = 2;

/* iftype-interface type for copy OID */

snmp_oidcpy (&varbind[0].name, &mib_ifentrytype);

/* Copy the OID's ifphysaddress-physical Address */

snmp_oidcpy (&varbind[1].name, &mib_ifmacentaddr);

Do

{

/* Submit the query, and the results will be loaded into varbindlist.

It can be expected that the number of calls to the loop is equal to the number of interface cards in the system */

RET =

M_query (Asn_rfc1157_getnextrequest, &varbindlist, &errorstatus,

&errorindex);

if (!ret)

ret = 1;

Else

/* Confirm the correct return type */

ret = snmp_oidncmp (&varbind[0].name, &mib_ifentrytype,

Mib_ifentrytype.idlength);

if (!ret) {

j + +;

dTMP = Varbind[0].value.asnvalue.number;

printf ("Interface #%i Type:%in", J, dTMP);

/* Type 6 describes Ethernet interfaces */

if (dtmp = = 6)

{

/* Confirm that we have obtained the address here */

RET =

SNMP_OIDNCMP (&varbind[1].name, &MIB_IFMACENTADDR,

Mib_ifmacentaddr.idlength);

if ((!ret) && (varbind[1].value.asnvalue.address.stream! = NULL))

{

if ((varbind[1].value.asnvalue.address.stream[0] = = 0x44)

&& (varbind[1].value.asnvalue.address.stream[1] = = 0x45)

&& (varbind[1].value.asnvalue.address.stream[2] = = 0x53)

&& (varbind[1].value.asnvalue.address.stream[3] = = 0x54)

&& (varbind[1].value.asnvalue.address.stream[4] = = 0x00))

{

/* Ignore all Dial-up network interface cards */

printf ("Interface #%i is a DUN adaptern", j);

Continue

}

if ((varbind[1].value.asnvalue.address.stream[0] = = 0x00)

&& (varbind[1].value.asnvalue.address.stream[1] = = 0x00)

&& (varbind[1].value.asnvalue.address.stream[2] = = 0x00)

&& (varbind[1].value.asnvalue.address.stream[3] = = 0x00)

&& (varbind[1].value.asnvalue.address.stream[4] = = 0x00)

&& (varbind[1].value.asnvalue.address.stream[5] = = 0x00))

{

/* Ignore the null address returned by the other network interface card */

printf ("Interface #%i is a NULL addressn", j);

Continue

}

sprintf (tempethernet, "%02x%02x%02x%02x%02x%02x",

Varbind[1].value.asnvalue.address.stream[0],

VARBIND[1].VALUE.ASNVALUE.ADDRESS.STREAM[1],

VARBIND[1].VALUE.ASNVALUE.ADDRESS.STREAM[2],

VARBIND[1].VALUE.ASNVALUE.ADDRESS.STREAM[3],

VARBIND[1].VALUE.ASNVALUE.ADDRESS.STREAM[4],

VARBIND[1].VALUE.ASNVALUE.ADDRESS.STREAM[5]);

printf ("MAC Address of Interface #%i:%sn", J, Tempethernet);}

}

}

} while (!ret); /* ERROR termination occurs. */

Getch ();

FreeLibrary (m_hinst);

/* Unbind */

Snmp_freevarbind (&varbind[0]);

Snmp_freevarbind (&varbind[1]);

}

The method to get the physical address is different for different NIC, but it is the operation IO port, the specific address of the port depends on the specification of the specific chip. Encryption software to get the physical address, you can not use this method. In general, it is in the nuclear mentality with ndisrequest to get. Here is a method for applying a layer.

To pull the ndisrequest, it will be far away, or stop it ...

As described in the NDIS specification, the NIC driver supports the Ioctl_ndis_query_stats interface:

The parameters are as follows:

Oid_802_3_permanent_address: Physical Address

Oid_802_3_current_address:mac Address

So we got the method.

First, look at the registry, find a network card has a few pieces, what is the device name.

Specific location and OS related, 2000 under Hlm/software/microsoft/windows nt/current version/networkcards. Then CreateFile (devicename,...) Note that you want to use linkname, so

Also add "////.//device//".

Then DeviceIoControl (Hmac,ioctl_ndis_query_stats,

Oid_802_3_permanent_address/oid_802_3_current_address ...)

The specific situation can be see under the DDK

Oid_802_3_current_address entry.

So we got the MAC address and the physical address.

--------------------------------------------------------------------------------

about how to modify the MAC address, there is not much to speak of the necessary, anyway, and the registry, the following post a little bit how to modify the network card physical address things:

can be read or modified directly from the EEPROM (e.g. 8029AS using the 93C46 chip)

But the chip of the NIC is different, the reading obtains the way different.

such as reading 8029AS of the EEPROM of the Mac offset 0001h; actual address i/o+01

The Mac is deposited in the address 1h,2h,3h of the EEPROM;

such as reading 8139C (L) of the EEPROM (93C46) in the offset 0050h; actual i/o+0x50

Mac stored in EEPROM, ADDRESS 7h,8h,9h;

The system actually uses the Mac placed in the 8139chin register, the offset address is in 0000h,0001h,0002h,0003h,0004h,0005h

Three ways to get the MAC address of the network card in the system by "reprint"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.