Bladeren bron

处理机器码生成算法

lxg 3 jaren geleden
bovenliggende
commit
fe7c16f484
2 gewijzigde bestanden met toevoegingen van 279 en 3 verwijderingen
  1. 1 1
      helper/machineid/id_bsd.go
  2. 278 2
      helper/machineid/id_linux.go

+ 1 - 1
helper/machineid/id_bsd.go

@@ -10,7 +10,7 @@ import (
 func getMachineID() (s string, err error) {
 	paths := []string{
 		"/etc/hostid",
-		"/proc/sys/kernel/random/uuid",
+		"/sys/class/dmi/id/product_uuid",
 	}
 	var (
 		buf []byte

+ 278 - 2
helper/machineid/id_linux.go

@@ -2,13 +2,284 @@
 
 package machineid
 
-import "io/ioutil"
+/*
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef USE_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#ifndef TYPES_H
+#define TYPES_H
+
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef signed short i16;
+typedef unsigned int u32;
+
+#ifdef BIGENDIAN
+typedef struct {
+    u32 h;
+    u32 l;
+} u64;
+#else
+typedef struct {
+    u32 l;
+    u32 h;
+} u64;
+#endif
+
+#ifdef ALIGNMENT_WORKAROUND
+static inline u64 U64(u32 low, u32 high)
+{
+    u64 self;
+
+    self.l = low;
+    self.h = high;
+
+    return self;
+}
+#endif
+
+#ifdef ALIGNMENT_WORKAROUND
+#    ifdef BIGENDIAN
+#    define WORD(x) (u16)((x)[1] + ((x)[0] << 8))
+#    define DWORD(x) (u32)((x)[3] + ((x)[2] << 8) + ((x)[1] << 16) + ((x)[0] << 24))
+#    define QWORD(x) (U64(DWORD(x + 4), DWORD(x)))
+#    else
+#    define WORD(x) (u16)((x)[0] + ((x)[1] << 8))
+#    define DWORD(x) (u32)((x)[0] + ((x)[1] << 8) + ((x)[2] << 16) + ((x)[3] << 24))
+#    define QWORD(x) (U64(DWORD(x), DWORD(x + 4)))
+#    endif
+#else
+#define WORD(x) (u16)(*(const u16 *)(x))
+#define DWORD(x) (u32)(*(const u32 *)(x))
+#define QWORD(x) (*(const u64 *)(x))
+#endif
+
+#endif
+
+struct dmi_header
+{
+        u8 type;
+        u8 length;
+        u16 handle;
+        u8 *data;
+};
+
+static int myread(int fd, u8 *buf, size_t count, const char *prefix)
+{
+    ssize_t r = 1;
+    size_t r2 = 0;
+
+    while (r2 != count && r != 0)
+    {
+        r = read(fd, buf + r2, count - r2);
+        if (r == -1)
+        {
+            if (errno != EINTR)
+            {
+                close(fd);
+                perror(prefix);
+                return -1;
+            }
+        }
+        else
+            r2 += r;
+    }
+
+    if (r2 != count)
+    {
+        close(fd);
+        fprintf(stderr, "%s: Unexpected end of file\n", prefix);
+        return -1;
+    }
+
+    return 0;
+}
+
+int checksum(const u8 *buf, size_t len)
+{
+    u8 sum = 0;
+    size_t a;
+
+    for (a = 0; a < len; a++)
+        sum += buf[a];
+    return (sum == 0);
+}
+
+
+void *mem_chunk(size_t base, size_t len, const char *devmem)
+{
+    void *p;
+    int fd;
+#ifdef USE_MMAP
+    size_t mmoffset;
+    void *mmp;
+#endif
+
+    if ((fd = open(devmem, O_RDONLY)) == -1)
+    {
+        perror(devmem);
+        return NULL;
+    }
+
+    if ((p = malloc(len)) == NULL)
+    {
+        perror("malloc");
+        return NULL;
+    }
+
+#ifdef USE_MMAP
+#ifdef _SC_PAGESIZE
+    mmoffset = base % sysconf(_SC_PAGESIZE);
+#else
+    mmoffset = base % getpagesize();
+#endif
+    mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset);
+    if (mmp == MAP_FAILED)
+        goto try_read;
+
+    memcpy(p, (u8 *)mmp + mmoffset, len);
+
+    if (munmap(mmp, mmoffset + len) == -1)
+    {
+        fprintf(stderr, "%s: ", devmem);
+        perror("munmap");
+    }
+
+    goto out;
+
+#endif
+
+try_read:
+    if (lseek(fd, base, SEEK_SET) == -1)
+    {
+        fprintf(stderr, "%s: ", devmem);
+        perror("lseek");
+        free(p);
+        return NULL;
+    }
+
+    if (myread(fd, p, len, devmem) == -1)
+    {
+        free(p);
+        return NULL;
+    }
+
+out:
+    if (close(fd) == -1)
+        perror(devmem);
+
+    return p;
+}
+
+void to_dmi_header(struct dmi_header *h, u8 *data)
+{
+    h->type = data[0];
+    h->length = data[1];
+    h->handle = WORD(data + 2);
+    h->data = data;
+}
+
+int get_cpuid(char *cpuid)
+{
+    char devmem[10] = "/dev/mem";
+    u16 len;
+    u16 num;
+    size_t fp;
+    u8 *buf=NULL, *nbuf=NULL, *data, *p;
+    int i = 0;
+    if ((buf = mem_chunk(0xF0000, 0x10000, devmem)) == NULL)
+    {
+        free(buf);
+        return 0;
+    }
+
+    for (fp = 0; fp <= 0xFFF0; fp += 16)
+    {
+        if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
+        {
+            len = WORD(buf + fp + 0x16);
+            num = WORD(buf + fp + 0x1C);
+
+            if (!checksum(buf + fp, (buf + fp)[0x05]) || memcmp(buf + fp + 0x10, "_DMI_", 5) != 0 || !checksum(buf + fp + 0x10, 0x0F))
+            {
+                free(buf);
+                return 0;
+            }
+            if ((nbuf = mem_chunk(DWORD(buf + fp + 0x18), len, devmem)) == NULL)
+            {
+                fprintf(stderr, "Table is unreachable, sorry.\n");
+                free(buf);
+                free(nbuf);
+                return 0;
+            }
+            data = nbuf;
+            while (i < num && data+4 <= nbuf + len)
+            {
+                u8 *next;
+                struct dmi_header h;
+
+                to_dmi_header(&h, data);
+
+                if (h.length < 4)
+                {
+                    printf("Invalid entry length (%u). DMI table is "
+                           "broken! Stop.\n\n", (unsigned int)h.length);
+                    free(buf);
+                    free(nbuf);
+                    return 0;
+                }
+
+                next = data + h.length;
+                while (next - nbuf + 1 < len && (next[0] != 0 || next[1] != 0))
+                    next++;
+                next += 2;
+                if (h.type ==4)
+                {
+                    p = h.data + 0x08;
+                    //printf("CPUID:%02X%02X%02X%02X%02X%02X%02X%02X\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+                    sprintf(cpuid, "%02X%02X%02X%02X%02X%02X%02X%02X", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+                    free(buf);
+                    free(nbuf);
+                    return 1;
+                }
+                data = next;
+                i++;
+            }
+            fp += 16;
+        }
+    }
+    free(buf);
+    free(nbuf);
+    return 0;
+}
+*/
+import "C"
+
+import (
+	"encoding/hex"
+	"io/ioutil"
+)
 
 func getMachineID() (s string, err error) {
 	paths := []string{
 		"/var/lib/dbus/machine-id",
 		"/etc/machine-id",
-		"/proc/sys/kernel/random/uuid",
+		"/sys/class/dmi/id/product_uuid",
 	}
 	var (
 		buf []byte
@@ -19,5 +290,10 @@ func getMachineID() (s string, err error) {
 			break
 		}
 	}
+	if s == "" {
+		buf = make([]byte, 16)
+		C.get_cpuid((*C.char)(unsafe.Pointer(&buf[0])))
+		s = hex.EncodeToString(buf)
+	}
 	return
 }