求取网卡真实物理地址的代码

Hididi 2009-02-11 09:43:18
求取网卡真实物理地址的代码
注意,是真实物理地址,不是注册表里能找到能修改的那种。
...全文
439 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
zcstudio 2009-06-08
  • 打赏
  • 举报
回复
顺便说一句,netbios方案拔了网线,只是读取为空,可以通过程序解决,但macaddr2.htm 方案强的这一点,也被它自己很差的多网卡识别能力和权限报错给抵消掉了。同样都是读注册表中的系统MAC地址,macaddr2.htm 方案还不如netbios方便快捷呢。
zcstudio 2009-06-08
  • 打赏
  • 举报
回复
泼盆凉水,除了楼主验证的两位的代码读出的只是系统MAC,可以在注册表里修改外。
我也验证了unsigned和gzmhero 所指的代码,结论,所读的全都是注册表里的系统MAC,不是网卡真正的物理MAC,这种系统MAC地址,修改注册表就可以轻易骗过,不能用来标识一台计算机。
而且unsigned和gzmhero 所指的代码macaddr2还有极大的缺点,就是对一台计算机上有多个网卡时,当前有效主网卡识别的能力差,无法区分网卡是被禁用还是有效。而且很多情况下读不出来,用管理员权限 仍然报告CreateFile Error code=2.
它唯一比netbios方案强的地方,就是拔了网线,读取功能不受影响,但总体来讲macaddr2.htm 方案,不如netbios方案,而且依旧读的是网卡的注册表中的地址,不是网卡真实物理地址。
希望下次解答问题前自己能先验证一下。

Hididi 2009-02-11
  • 打赏
  • 举报
回复
楼上正解,我也找到了,嘿嘿。

我靠unsigned兄的链接里的关键字找出来的。
gzmhero 2009-02-11
  • 打赏
  • 举报
回复
function GetNetCardMac(NetCardName:string):string;
const
OID_802_3_PERMANENT_ADDRESS :Integer = $01010101;
OID_802_3_CURRENT_ADDRESS :Integer = $01010102;
IOCTL_NDIS_QUERY_GLOBAL_STATS :Integer = $00170002;
var
hDevice: THandle;
inBuf:Integer;
outBuf:array[1..256] of Byte;
BytesReturned:DWORD;
MacAddr:string;
i:integer;
begin
inBuf:=OID_802_3_PERMANENT_ADDRESS;
Result:='';
try
hDevice:=CreateFile(PChar('\\.\'+NetCardName),
GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,nil, OPEN_EXISTING, 0, 0);
if hDevice <> INVALID_HANDLE_VALUE then
begin
if DeviceIoControl(hDevice,IOCTL_NDIS_QUERY_GLOBAL_STATS,@inBuf,4,@outBuf,256,BytesReturned,nil) then
begin
MacAddr:='';
for i:=1 to BytesReturned do
begin
MacAddr:=MacAddr+IntToHex(outbuf[i],2);
end;
Result:= MacAddr;
end;
end;
finally
if not hDevice <> INVALID_HANDLE_VALUE then
CloseHandle(hDevice);
end;
end;


Label1.Caption:=GetNetCardMac('{B593CDAF-7299-411A-8EE9-7D8B631822BB}');

////////////////////////////
NetCardName在注册表中:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\1?....9?等键的下面的ServiceName


僵哥 2009-02-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 Hididi 的回复:]
unsigned兄发的链接应该是正确的,但是看不懂。。。
应该是要直接驱动级别的访问的。
[/Quote]
看这个链接:http://www.pcausa.com/Utilities/macaddr2.htm

代码(C++):http://www.pcausa.com/Utilities/macaddr2/macaddrsdk.exe
Hididi 2009-02-11
  • 打赏
  • 举报
回复
哈哈,楼主都验证过了。
谢谢两位的热心哈,不过你们的代码只能取到注册表里的值。
willflyz 2009-02-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 Hididi 的回复:]
两位的代码,取到的都是注册表里的值,可以随便修改的。
[/Quote]
楼主验证过了吗?注册表是可以改MacID,本地连接属性里面的配置信息也可以改.
如果上面取的不对,那看来只能直接从硬件的地址将值读出了
Hididi 2009-02-11
  • 打赏
  • 举报
回复
unsigned兄发的链接应该是正确的,但是看不懂。。。
应该是要直接驱动级别的访问的。
willflyz 2009-02-11
  • 打赏
  • 举报
回复
有没有高人可以用汇编的方法实现啊?
Hididi 2009-02-11
  • 打赏
  • 举报
回复
两位的代码,取到的都是注册表里的值,可以随便修改的。
gzmhero 2009-02-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gzmhero 的回复:]
function GetAdapterInfo(Lana: Char): String;
var
  Adapter: TAdapterStatus;
  NCB: TNCB;
begin
  FillChar(NCB, SizeOf(NCB), 0);
  NCB.ncb_command := Char(NCBRESET);
  NCB.ncb_lana_num := Lana;
  if Netbios(@NCB) <> Char(NRC_GOODRET) then
  begin
    Result := 'mac not found';
    Exit;
  end;

  FillChar(NCB, SizeOf(NCB), 0);
  NCB.ncb_command := Char(NCBASTAT);
  NCB.ncb_lana_num…
[/Quote]

加上 Use Nb30;
僵哥 2009-02-11
  • 打赏
  • 举报
回复
参考下面的回贴(没有环境测试)
http://www.perlmonks.org/?node_id=639048
hidelphi 2009-02-11
  • 打赏
  • 举报
回复

function GetMACAddress(out MAC: string): WordBool;
var
Lib: Cardinal;
Func: function(GUID: PGUID): Longint; stdcall;
GUID1, GUID2: TGUID;
begin
Result := True;
try
MAC := '';
Lib := 0;
try
begin
Lib := LoadLibrary('rpcrt4.dll');
end
except
begin
//加载失败
end
end;
if Lib <> 0 then
begin
if Win32Platform <> VER_PLATFORM_WIN32_NT then
@Func := GetProcAddress(Lib, 'UuidCreate')
else @Func := GetProcAddress(Lib, 'UuidCreateSequential');
if Assigned(Func) then
begin
if (Func(@GUID1) = 0) and
(Func(@GUID2) = 0) and
(GUID1.D4[2] = GUID2.D4[2]) and
(GUID1.D4[3] = GUID2.D4[3]) and
(GUID1.D4[4] = GUID2.D4[4]) and
(GUID1.D4[5] = GUID2.D4[5]) and
(GUID1.D4[6] = GUID2.D4[6]) and
(GUID1.D4[7] = GUID2.D4[7]) then
begin
MAC :=
IntToHex(GUID1.D4[2], 2) + '-' +
IntToHex(GUID1.D4[3], 2) + '-' +
IntToHex(GUID1.D4[4], 2) + '-' +
IntToHex(GUID1.D4[5], 2) + '-' +
IntToHex(GUID1.D4[6], 2) + '-' +
IntToHex(GUID1.D4[7], 2);
end;
end;
FreeLibrary(Lib);
end;
except
Result := False;
end;
end;
gzmhero 2009-02-11
  • 打赏
  • 举报
回复
function GetAdapterInfo(Lana: Char): String;
var
Adapter: TAdapterStatus;
NCB: TNCB;
begin
FillChar(NCB, SizeOf(NCB), 0);
NCB.ncb_command := Char(NCBRESET);
NCB.ncb_lana_num := Lana;
if Netbios(@NCB) <> Char(NRC_GOODRET) then
begin
Result := 'mac not found';
Exit;
end;

FillChar(NCB, SizeOf(NCB), 0);
NCB.ncb_command := Char(NCBASTAT);
NCB.ncb_lana_num := Lana;
NCB.ncb_callname := '*';

FillChar(Adapter, SizeOf(Adapter), 0);
NCB.ncb_buffer := @Adapter;
NCB.ncb_length := SizeOf(Adapter);
if Netbios(@NCB) <> Char(NRC_GOODRET) then
begin
Result := 'mac not found';
Exit;
end;
Result :=
IntToHex(Byte(Adapter.adapter_address[0]), 2) + '-' +
IntToHex(Byte(Adapter.adapter_address[1]), 2) + '-' +
IntToHex(Byte(Adapter.adapter_address[2]), 2) + '-' +
IntToHex(Byte(Adapter.adapter_address[3]), 2) + '-' +
IntToHex(Byte(Adapter.adapter_address[4]), 2) + '-' +
IntToHex(Byte(Adapter.adapter_address[5]), 2);
end;

function GetMACAddress: string;
var
AdapterList: TLanaEnum;
NCB: TNCB;
begin
FillChar(NCB, SizeOf(NCB), 0);
NCB.ncb_command := Char(NCBENUM);
NCB.ncb_buffer := @AdapterList;
NCB.ncb_length := SizeOf(AdapterList);
Netbios(@NCB);
if Byte(AdapterList.length) > 0 then
Result := GetAdapterInfo(AdapterList.lana[0])
else
Result := 'mac not found';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption:=GetMACAddress;
end;

1,594

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧