使用 IOKit 返回 Mac 的序列号返回 4 个额外字符

发布于 2024-12-25 04:59:10 字数 1601 浏览 3 评论 0原文

我正在使用 IOKit 并有以下代码,总体思路是将 platformExpert 密钥传递给这个小型核心基础命令行应用程序,并让它打印解码的字符串。测试用例是“序列号”。下面的代码运行时如下:

./compiled serial-number

几乎可以工作,但会在字符串开头返回序列号的最后 4 个字符,即对于诸如 C12D2JMPDDQX 之类的示例序列,它将返回

DDQXC12D2JMPDDQX

有什么想法吗?

#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>

int main (int argc, const char * argv[]) {
    CFStringRef parameter = CFSTR("serial-number");
    if (argv[1]) {
       parameter = CFStringCreateWithCString(
                                 NULL,
                                 argv[1],
                                 kCFStringEncodingUTF8);
    }

    CFDataRef data;

    io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
    if (platformExpert)
    {
        data = IORegistryEntryCreateCFProperty(platformExpert,
                                               parameter,
                                               kCFAllocatorDefault, 0);
    }

    IOObjectRelease(platformExpert);
    CFIndex bufferLength = CFDataGetLength(data);  
    UInt8 *buffer = malloc(bufferLength);
    CFDataGetBytes(data, CFRangeMake(0,bufferLength), (UInt8*) buffer);
    CFStringRef string = CFStringCreateWithBytes(kCFAllocatorDefault,
                                                 buffer,
                                                 bufferLength,
                                                 kCFStringEncodingUTF8,
                                                 TRUE);
    CFShow(string);
    return 0;
}

I'm playing with IOKit and have the following code, the general idea is to pass a platformExpert key to this small core foundation command line application and have it print the decoded string. The test case is "serial-number". The code below when run like:

./compiled serial-number

Almost works but returns the last 4 characters of the serial number at the beginning of the string i.e. for an example serial such as C12D2JMPDDQX it would return

DDQXC12D2JMPDDQX

Any ideas?

#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>

int main (int argc, const char * argv[]) {
    CFStringRef parameter = CFSTR("serial-number");
    if (argv[1]) {
       parameter = CFStringCreateWithCString(
                                 NULL,
                                 argv[1],
                                 kCFStringEncodingUTF8);
    }

    CFDataRef data;

    io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
    if (platformExpert)
    {
        data = IORegistryEntryCreateCFProperty(platformExpert,
                                               parameter,
                                               kCFAllocatorDefault, 0);
    }

    IOObjectRelease(platformExpert);
    CFIndex bufferLength = CFDataGetLength(data);  
    UInt8 *buffer = malloc(bufferLength);
    CFDataGetBytes(data, CFRangeMake(0,bufferLength), (UInt8*) buffer);
    CFStringRef string = CFStringCreateWithBytes(kCFAllocatorDefault,
                                                 buffer,
                                                 bufferLength,
                                                 kCFStringEncodingUTF8,
                                                 TRUE);
    CFShow(string);
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

↘人皮目录ツ 2025-01-01 04:59:10

更简化的解决方案:

#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>

int main()
{
    CFMutableDictionaryRef matching = IOServiceMatching("IOPlatformExpertDevice");
    io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, matching);
    CFStringRef serialNumber = IORegistryEntryCreateCFProperty(service,
        CFSTR("IOPlatformSerialNumber"), kCFAllocatorDefault, 0);
    const char* str = CFStringGetCStringPtr(serialNumber,kCFStringEncodingMacRoman);
    printf("%s\n", str); //->stdout
    //CFShow(serialNumber); //->stderr
    IOObjectRelease(service);
    return 0;
}

编译:

clang -framework IOKit -framework ApplicationServices cpuid.c -o cpuid

如果您愿意,可以从 github 分叉 ;)

https://github。 com/0infinity/IOPlatformSerialNumber

A more simplified solution:

#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>

int main()
{
    CFMutableDictionaryRef matching = IOServiceMatching("IOPlatformExpertDevice");
    io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, matching);
    CFStringRef serialNumber = IORegistryEntryCreateCFProperty(service,
        CFSTR("IOPlatformSerialNumber"), kCFAllocatorDefault, 0);
    const char* str = CFStringGetCStringPtr(serialNumber,kCFStringEncodingMacRoman);
    printf("%s\n", str); //->stdout
    //CFShow(serialNumber); //->stderr
    IOObjectRelease(service);
    return 0;
}

compile with:

clang -framework IOKit -framework ApplicationServices cpuid.c -o cpuid

Fork from github if you like ;)

https://github.com/0infinity/IOPlatformSerialNumber

邮友 2025-01-01 04:59:10

您可能会误解序列号参数的值。如果我使用ioreg -f -k序列号,我会得到:

<前> <代码> | “序列号”=
| 00000000: 55 51 32 00 00 00 00 00 00 00 00 00 00 XX XX XX XX UQ2......... XXXX
| 00000011:XX XX XX XX 55 51 32 00 00 00 00 00 00 00 00 00 00 XXXXUQ2........................
| 00000022: 00 00 00 00 00 00 00 00 00 ........

(除了重复部分之外,我已经删除了 Mac 的序列号。)

当您显示字符串时,您不会看到空字符,因为它们是空字符。我不知道为什么它看起来像是由空字符分隔的多个字段,但看起来就是这样。

我建议进行进一步的调查,以确保没有关于如何解释这些数据的规范;如果您没有找到任何内容,我将跳过第一轮空值,并获取此后直到下一次空值运行的所有内容。

You may be misinterpreting the value of the serial-number parameter. If I use ioreg -f -k serial-number, I get this:

    |   "serial-number" = 
    |     00000000: 55 51 32 00 00 00 00 00 00 00 00 00 00 XX XX XX XX UQ2..........XXXX
    |     00000011: XX XX XX XX 55 51 32 00 00 00 00 00 00 00 00 00 00 XXXXUQ2..........
    |     00000022: 00 00 00 00 00 00 00 00 00                         .........

(I've X'd out my Mac's serial number except for the repeated part.)

You don't see the null characters when you show the string because, well, they're null characters. I don't know why it has what seems like multiple fields separated by null characters, but that's what it seems to be.

I recommend doing further investigation to make sure there isn't a specification for how this data is supposed to be interpreted; if you don't find anything, I'd skip through the first run of nulls and get everything after that up to the next run of nulls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文