11

代码更新,happy unraid 懒人版

 2 years ago
source link: https://www.dosk.win/2022/07/11/dai-ma-geng-xin-happy-unraid-lan-ren-ban/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

代码更新,happy unraid 懒人版

2022/07/11

code

  1. 文章里的讨论仅限于技术交流,如有需要请 购买正版 !!!
  2. 文章里的讨论仅限于技术交流,如有需要请 购买正版 !!
  3. 文章里的讨论仅限于技术交流,如有需要请 购买正版 !
  4. 请勿分发二进制,注意到最近有二进制在流传,和本人无关 !!

UNRAID_UUID 这个变量可以不要了,当然如果测试下来不生效,继续写也是 ok 的

前文回顾:unraid 官方版不修改不用 keymaker 可持续 happy 的方法

由此程序引发的各类后果本人概不承担

编译:gcc -fPIC -shared udev.c -ludev -ldl -o BTRS.key

#define _GNU_SOURCE
#include <dlfcn.h>
#include <fcntl.h>
#include <libudev.h>
#include <netinet/in.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>
#include <unistd.h>

#define RSA void
#define DISK_LABEL "UNRAID"
#define BTRS_FORMAT \
  "regGUID=%s&regTy=%s&regTo=\"%s\"&regTm=%s&regGen=0&regDays=0"

typedef int (*RSA_PUBLIC_DECRYPT_FUNC)(int flen, unsigned char* from,
                                       unsigned char* to, RSA* rsa,
                                       int padding);

static char* unraid_uuid = NULL;
static char* unraid_name = NULL;
static char* unraid_date = NULL;
static char* unraid_version = NULL;
RSA_PUBLIC_DECRYPT_FUNC rsa_public_decrypt;

int get_dev_path(char* buffer, size_t size);
int get_usb_device(char* buffer, size_t size);
int get_serial_string(char* buffer, size_t size);
void read_file(char* buff_ptr, char* base_ptr, char* file_ptr, char* file);

__attribute__((constructor)) void unraid_init() {
  if (!rsa_public_decrypt) {
    rsa_public_decrypt =
        (RSA_PUBLIC_DECRYPT_FUNC)dlsym(RTLD_NEXT, "RSA_public_decrypt");
  }

  if (!unraid_uuid) {
    unraid_uuid = (char*)malloc(1024);
    strcpy(unraid_uuid, "1234-1234-1234-1234567890AB");
    int err = get_serial_string(unraid_uuid, 1024);
    if (err && getenv("UNRAID_UUID")) {
      strcpy(unraid_uuid, getenv("UNRAID_UUID"));
    }
    unraid_name = getenv("UNRAID_NAME");
    unraid_date = getenv("UNRAID_DATE");
    unraid_version = getenv("UNRAID_VERSION");
  }
}

const char* get_self_exe_name(int full) {
  static char buffer[4096] = "";
  readlink("/proc/self/exe", buffer, 4096);
  if (full) {
    return buffer;
  }
  char* ptr = &buffer[strlen(buffer)];
  while (*ptr != '/') --ptr;
  return (ptr + 1);
}

int RSA_public_decrypt(int flen, unsigned char* from, unsigned char* to,
                       RSA* rsa, int padding) {
  if (!strcmp(get_self_exe_name(0), "emhttpd") ||
      !strcmp(get_self_exe_name(0), "shfs")) {
    sprintf(to, BTRS_FORMAT, unraid_uuid, unraid_version, unraid_name,
            unraid_date);
    int len = strlen(to);
    return len;
  } else {
    return rsa_public_decrypt(flen, from, to, rsa, padding);
  }
}

/**** udev stuff ****/
int get_dev_path(char* buffer, size_t size) {
  char link_device[1024];
  char real_device[1024];

  sprintf(link_device, "/dev/disk/by-label/%s", DISK_LABEL);
  char* rv = realpath(link_device, real_device);
  if (!rv) return 2;

  struct udev* udev;
  struct udev_device* dev;
  struct udev_enumerate* enumerate;
  struct udev_list_entry *devices, *dev_list_entry;

  int find = -1;

  udev = udev_new();
  if (!udev) {
    return 1;
  }

  enumerate = udev_enumerate_new(udev);
  if (!enumerate) {
    return 1;
  }

  udev_enumerate_add_match_subsystem(enumerate, "block");
  udev_enumerate_scan_devices(enumerate);

  devices = udev_enumerate_get_list_entry(enumerate);
  if (!devices) {
    return 1;
  }

  udev_list_entry_foreach(dev_list_entry, devices) {
    const char *path, *tmp;
    unsigned long long disk_size = 0;

    path = udev_list_entry_get_name(dev_list_entry);
    dev = udev_device_new_from_syspath(udev, path);

    if (strncmp(udev_device_get_devtype(dev), "partition", 9) != 0 &&
        strncmp(udev_device_get_sysname(dev), "loop", 4) != 0) {
      const char* devnode = udev_device_get_devnode(dev);
      char* ptr = strstr(real_device, devnode);
      if (ptr && ptr == real_device) {  // prefix
        find = 0;
        strcpy(buffer, udev_device_get_devpath(dev));
      }
    }

    udev_device_unref(dev);
  }

  udev_enumerate_unref(enumerate);
  udev_unref(udev);

  return find;
}

int get_usb_device(char* buffer, size_t size) {
  char dev_path[1024];
  if (get_dev_path(dev_path, 1024)) {
    return 2;
  }

  int slash_index[1024];
  int slash_count = 0;
  for (int i = 0; i < strlen(dev_path); ++i) {
    if (dev_path[i] == '/') {
      slash_index[slash_count++] = i;
    }
  }

  int find = -1;
  for (int i = slash_count - 1; i >= 0; --i) {
    char usb_device[1024] = "/sys";
    strcpy(&dev_path[slash_index[i]], "/serial");
    strcat(usb_device, dev_path);
    if (!access(usb_device, F_OK | R_OK)) {
      strcpy(buffer, usb_device);
      buffer[strlen(buffer) - strlen("/serial")] = '\0';
      find = 0;
      break;
    }
  }

  return find;
}

void read_file(char* buff_ptr, char* base_ptr, char* file_ptr, char* file) {
  strcpy(file_ptr, file);
  FILE* fp = fopen(base_ptr, "r");
  fscanf(fp, "%s", buff_ptr);
  fclose(fp);
}

int get_serial_string(char* buffer, size_t size) {
  char usb_device[1024];
  if (get_usb_device(usb_device, 1024)) {
    return 2;
  }

  char* file_ptr = &usb_device[strlen(usb_device)];
  char* buff_ptr = buffer;

  read_file(buff_ptr, usb_device, file_ptr, "/idVendor");
  strcat(buff_ptr, "-");
  buff_ptr += strlen(buff_ptr);

  read_file(buff_ptr, usb_device, file_ptr, "/idProduct");
  strcat(buff_ptr, "-");
  buff_ptr += strlen(buff_ptr);

  char serial_buffer[1024];
  read_file(serial_buffer, usb_device, file_ptr, "/serial");
  strcpy(buff_ptr, serial_buffer);
  *(buff_ptr + 4) = '-';
  strcpy(buff_ptr + 5, &serial_buffer[4]);

  int offset = 'A' - 'a';
  for (int i = 0; i < strlen(buffer); ++i) {
    if (buffer[i] >= 'a' && buffer[i] <= 'z') {
      buffer[i] += offset;
    }
  }

  return 0;
}

int main() {
  char serial[1024];
  int err = get_serial_string(serial, 1024);
  if (!err) {
    printf("SERIAL: %s\n", serial);
  }
  return 0;
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK