Как поменять идентификационную информацию у SMI флешки

  • 16.04.2019

Внимание! после смены PID - к oscill не будут подходить наши драйверы. Нужны будут другие. Если Вы это забудете - попытки установить oscill на новый ПК будут безуспешными.

PID - Product IDentifier / номер продукта- характеристика USB-устройства, вместе с VID (Vendor IDentifier - номер производителя) однозначно характеризующая это устройство со стороны хоста. По VID/PID устанавливаются и работают драйверы для каждого подключенного устройства.

Осциллографу usb.oscill присвоен уникальный VID+PID, соответственно им поставляются в комплекте (и доступны для загрузки на этом сайте) драйверы для Windows 98, 98SE, ME, 2000, XP, Vista, Seven. Однако, для следующих случаев:

  • использование oscill в ОС Linux (ПО в виртуальной машине) - вариант для FreeBSD
  • подключение oscill к Pocket PC / Windows Mobile через виртуальный COM-порт
  • Windows Seven 64bit с обязательным подписыванием драйверов

может понадобиться применение стандартных драйверов Silabs, для чего придется заменить PID oscill на PID Silabs. Это можно сделать специальной утилитой SetPID :

Рекомендуется изменять PID на EA61, и использовать новую версию ПО и DLL драйвер Silabs v3.X . В этом ПО предусмотрен автоматический и ручной выбор USB драйвера между v2.0 и v3.X. Для ручного выбора нужно сделать: Link-Setup-Port-Driver-V3

Внимание! Смена PID этой утилитой возможна только на ПК под управлением Windows, где уже установлен соответствующий текущему PID драйвер. Иначе, SetPID не увидит oscill . То есть, oscill должен присутствовать в "Диспетчере Устройств" "Панели Управления". Алгоритм:

  1. если уже установлен USB (или VCP) драйвер из этого раздела - утилита setpid покажет PID=840E, и можно сменить PID на generic SILABS;
  2. SetPID потеряет oscill, в Диспетчере Устройств он также исчезнет;
  3. Windows найдет новое устройство, для которого надо скачать стандартный драйвер от Silabs для PID EA60 или для PID EA61
  4. этот драйвер подписан, и с ним должна начать работать оболочка .

Обратная процедура:

  1. после установки стандартного драйвера, утилита SetPID обнаруживает oscill с PID=EA60 или EA61
  2. можно вернуть custom OSCILL PID нажатием соотв.кнопки
  3. SetPID покажет оригинальный PID oscill = 840E

Кроме setpid, для смены PID можно воспользоваться утилитой от Silabs: на этой странице выбрать an144.pdf и an144sw.zip

Примечание: Пользователь Usatenko на форуме опубликовал рецепт смены PID на единственном компьютере с Win7 64

Это основная статья, в которой мы рассмотрим, как классический способ смены данных флешки, так и сравним его с двумя экзотическими, подробно описанными в отдельных статьях.

В них описаны методики смены таких данных, которые нельзя изменить обычным редактированием настроек программы. Короче, применён нестандартный подход к решению задачи.

ВВЕДЕНИЕ

Чем хороши контроллеры SMI , так тем, что их шить совсем не обязательно, чтобы изменить серийный номер и большинство прочей инфы. Это в свою очередь, снижает риски, получения на выходе мёртвой флешки.

Но расслабляться всё равно не надо, использование любого из методов может повлечь, как необходимость дополнительного форматирования, так и зависания. В основном это связанно с глюками некоторых дистрибутивов утилиты SMI MPTool . Так в одной версии, почему-то идентификационная инфа не хочет обновляться, в другой после перебивки серийника, требует форматирования и т.д. Иногда, просто необходимо нащупать полностью совместимый дистрибутив со своей флешкой и уже смело извращаться по полной.

Ниже я разместил небольшую табличку, в которой сделал наглядное сравнение возможностей различных методов изменения идентификационной информации. Как видно из неё, универсального способа нету и комбинация отдельных элементов - это тот самый выход, который напрашивается самим собой.

СРАВНИТЕЛЬНЫЙ АНАЛИЗ МЕТОДИК
СТАНДАРТНЫЙ МЕТОД SMI DEBUG РЕДАКТИРОВАНИЕ ФАЙЛОВ
VID-PID: + + +
Vendor-Product: + + +
Serial Number: + + +
Revision: + +
MP Date: +
ISP Ver: +
PreTest Ver: + +
MP Package No: + +
FlashSet: + +
УРОВЕНЬ СЛОЖНОСТИ: ЛЕГКО СРЕДНИЙ ВЫШЕ СРЕДНЕГО

ЧЕРЕЗ ПРОШИВАЛЬЩИК SMI MPTOOL

Как я уже написал в введении, шить совсем не обязательно для решения задачи смены данных. Достаточно на первой странице настроек в правой части оставить активными галочки Write CID и Download ISP .

И даже больше, для старой модели SM3252C , можно вообще оставить только одну птичку Write CID .

Полная же перепрошивка достигается путём дополнительного включения опций: Pretest и Format(FAT32) .

Отдельно рассмотрим Serial Number , т.к. он наиболее сложный, а уже потом все прочие параметры.

СЕРИЙНОГО НОМЕРА

При первом знакомстве может показаться что благодаря ручной правке, можно устанавливать длину серийника SMI -флешки ниже 13-символов , заложенных в производственную утилиту SMIMPTool . Но как такового нижнего ограничения в 13 байт не существует в приложении, не смотря на имеющийся параметр SN Length .

Сначала выставляем значение параметра Serial Number , определяющего способ формирования:
13-32 Bytes (стандартное значение, из-под которого и следует редактировать его)
Random SN (случайные символы)
NO Serial (отсутствует серийник)
NO Update Serial (оставить прежнее значение)

Если хотите жестко задать определённый серийный номер, то просто укажите его в графе Serial Mask .

Символ # в серийном номере, значит произвольное значение, используется при генерации серийника в режимах Random SN и 13-32 Bytes .

SN Length : значение длины, от 13 до 32 символов . Без опции Chk SN Len , жестко контролирующей длину указанного серийника, параметр SN Length ограничивает ваши аппетиты лишь по максимальной длине.

Serial Mask – маска по которой формируется серийник. Каждая последующая флешка будет иметь отличный от предыдущей номер, идущий от значения Begin Serial до End Serial меняя символы под знаком решетки (# ).
Begin Serial – начальное значение, для первой флешки.
End Serial – конечное значение.

Рассмотрим пример генерации номера на примере режима Random SN :
Задаём Serial Mask = AA #USBDEVRU ###################
Получаем такой серийный номер: AA ZUSBDEVRU 0ORFR1BYNRB7UBY317E

Т.е. символы AA и USBDEVRU остались, остальные произвольно сменились.

ВСЕГО ОСТАЛЬНОГО

Объяснять процедуру изменения VID-PID , REV , VENDOR-PRODUCT нету особого смысла, лишь коротко поясню где что. Будем называть элементы SMI MPTool так, как это принято в приложении ChipGenius .

VID и PID и без меня понятно, вбиваем свои значения, если это того требуется.

(название в SMI MPTool ) = ChipGenius )

USB Vendor Str = Device Vendor
USB Product Str = Device Name

Inquiry Vendor = Manufacturer
Inquiry Product = Product Model

bcdDevice – это ревизия (Revision ), задаётся одно и тоже значение для Device Revision и Product Revision . При использовании других методов, можно менять их отдельно и поэтому в таблице я поставил МИНУС в соответствующей графе.

ЧЕРЕЗ SMI REFIXINFO

Является компактным портативным инструментом, который идеально подходит совсем неподготовленным юзерам.

Достаточно активировать снизу птички тех параметров, которые следует изменить и затем перебить их в верхней части программы.

К сожалению утилита устаревшая и несовместима с актуальными чипами. Предположительно работает с моделями не старше SMI SM3257AA , который с конца 2000-ых годов, днём с огнём не сыщешь.

К тому же не позволяет сменить серинный номер устройства, а это вполне существенный недостаток. Позволяет модифицировать следующие параметры: VID , PID , Device Vendor , Device Name , Device Revision , Manufacturer и Product Model .

ЧЕРЕЗ ПРОШИВАЛЬЩИК DYNA MPTOOL

Имеет куча особенностей и заковырок, советую обходить утилиты стороной по возможности.

Для тех, кто как-то запорол флешку и хочет прошить её уже с нужными данными, покажу на скринах соответствующие пункты настроек программы.

: OpenCard Config:

: Device Config:

Учитывая то, что с DYNA -шитыми флешками вообще много проблем, лучшее для них решение будет ручное редактирование данных через .

ЧЕРЕЗ SMI QCTOOL

Есть ещё такой вариант как использование утилиты SMI QCTool I1027 , но это всё же слишком экзотический вариант.

Точно сказать не могу с какими моделями чипов совместима эта утилита, но уж точно мало с какими и все они старые. Например, совместима с моей флешкой на SMI SM3252C .

Рассматривать в данном материале вопрос применения приложения SMIQCTool мы не будем и вам не советую с ним связываться. Скажу лишь, что в графы Vendor , Product , Label находящиеся в главном окне утилиты, нужно вбить значения вашей флешки, чтобы она не выдавала красным цветом ошибки типа: Label error , SCSI Vendor error и SCSI Product error .

Ну и приведу пару скриншотов настроек утилиты, а дальше уже сами, если захотите.

Для детального рассмотрения вашей проблемы по смене серийника или любого другого параметра, перейдите пожалуйста на – .

  • Ненормальное программирование ,
  • Программирование
  • В этой статье мы попытаемся создать модуль ядра, способный изменить PID уже запущенного процесса в ОС Linux, а так же поэкспериментировать с процессами, получившими измененный PID.


    Предупреждение : смена PID - нестандартный процесс, и при определенных обстоятельствах может привести к панике ядра.

    Наш тестовый модуль будет реализовывать символьное устройство /dev/test, при чтении с которого процессу будет изменен PID. За пример реализации символьного устройства спасибо статье. Полный код модуля приведен в конце статьи. Конечно, самым правильным решением было добавить системный вызов в само ядро, однако это потребует перекомпиляцию ядра.

    Окружение

    Все действия по тестированию модуля выполнялись в виртуальной машине VirtualBox с 64 битным дистрибутивомLInux и версией ядра 4.14.4-1. Связь с машиной осуществлялась с помощью SSH.

    Попытка #1 простое решение

    Пару слов о current : переменная current указывает на структуру task_struct с описанием процесса в ядре(PID, UID, GID, cmdline, namespaces и т.д)

    Первой идеей было просто поменять параметр current->pid из модуля ядра на нужный.

    Static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { printk("PID: %d.\n",current->pid); current->pid = 1; printk("new PID: %d.\n",current->pid); , }
    Для проверки работоспособности модуля я написал программу на C++:

    #include #include #include int main() { std::cout << "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >> str; std::cout << "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
    Загрузим модуль коммандой insmod, создадим /dev/test и попробуем.

    # ./a.out My parent PID 293 My PID 782 My new PID 782
    PID не изменился. Возможно, это не единственное место, где указывается PID.

    Попытка #2 дополнительные поля PID

    Если не current->pid является идентификатором процесса, то что является? Быстрый просмотр кода getpid() навел на структуру task_struct , описывающую процесс Linux и файл pid.c в исходном коде ядра. Нужная функция - __task_pid_nr_ns. В коде функции встречается обращение task->pids.pid, этот параметр мы и изменим

    Компилируем, пробуем

    Так как тестировал я по SSH, мне удалось получить вывод программы до падения ядра:

    My parent PID 293 My PID 1689 My new PID 1689
    Первый результат, уже что-то. Но PID все равно не изменился.

    Попытка #3 не экспортируемые символы ядра

    Более внимательное изучение pid.c дало функцию, которая делает то, что нам нужно
    static void __change_pid(struct task_struct *task, enum pid_type type,
    struct pid *new)
    Функция принимает задачу, для которой надо изменить PID, тип PID и, собственно, новый PID. Созданием нового PID занимается функция
    struct pid *alloc_pid(struct pid_namespace *ns)

    Эта функция принимает только пространство имен, в котором будет находиться новый PID, это пространство можно получить с помощью task_active_pid_ns .
    Но есть одна проблема: эти символы ядра не экспортируются ядром и не могут использоваться в модулях. В решении этой проблемы мне помогла замечательная . Код функции find_sym взят оттуда.

    Static asmlinkage void (*change_pidR)(struct task_struct *task, enum pid_type type, struct pid *pid); static asmlinkage struct pid* (*alloc_pidR)(struct pid_namespace *ns); static int __init test_init(void) { printk(KERN_ALERT "TEST driver loaded!\n"); change_pidR = find_sym("change_pid"); alloc_pidR = find_sym("alloc_pid"); ... } static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { printk("PID: %d.\n",current->pid); struct pid* newpid; newpid = alloc_pidR(task_active_pid_ns(current)); change_pidR(current,PIDTYPE_PID,newpid); printk("new PID: %d.\n",current->pid); ... }
    Комплируем, запускаем

    My parent PID 299 My PID 750 My new PID 751
    PID изменен! Ядро автоматически выделило нашей программе свободный PID. Но можно ли использовать PID, который занял другой процесс, например PID 1? Добавим после аллокации код

    Newpid->numbers.nr = 1;
    Комплируем, запускаем

    My parent PID 314 My PID 1172 My new PID 1
    Получаем настоящий PID 1!

    Bash выдал ошибку, из-за которой не будет работать переключение задач по комманде %n, но все остальные функции работают отлично.

    Интересные особенности процессов с измененным PID

    PID 0: войти нельзя выйти

    Вернемся к коду и изменим PID на 0.

    Newpid->numbers.nr = 0;
    Комплируем, запускаем

    My parent PID284 My PID 1517 My new PID 0
    Выходит PID 0 не такой и особенный? Радуемся, пишм exit и…

    Ядро падает! Ядро определило нашу задачу как IDLE TASK и, увидев завершение, просто упало. Видимо, перед завершением наша программа должна вернуть себе «нормальный» PID.

    Процесс-невидимка

    Вернемся к коду и выставим PID, гарантированно не занятый
    newpid->numbers.nr = 12345;

    Комплируем, запускаем

    My parent PID296 My PID 735 My new PID 12345
    Посмотрим, что находится в /proc

    1 148 19 224 288 37 79 86 93 consoles fb kcore locks partitions swaps version 10 149 2 226 29 4 8 87 acpi cpuinfo filesystems key-users meminfo sched_debug sys vmallocinfo 102 15 20 23 290 5 80 88 asound crypto fs keys misc schedstat sysrq-trigger vmstat 11 16 208 24 291 6 81 89 buddyinfo devices interrupts kmsg modules scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup mounts self thread-self 13 176 210 26 3 737 83 90 cgroups dma ioports kpagecount mtrr slabinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg pagetypeinfo stat uptime
    Как видим /proc не определяет наш процесс, даже если мы заняли свободный PID. Предыдущего PID тоже нет в /proc, и это весьма странно. Возможно, мы находимся в другом пространстве имен и поэтому не видны основному /proc. Смонтируем новый /proc, и посмотрим что там

    1 14 18 210 25 291 738 81 9 bus devices fs key-users locks pagetypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats interrupts keys meminfo partitions stat tty 102 149 19 222 27 30 76 83 92 cmdline dma iomem kmsg misc sched_debug swaps uptime 11 15 2 224 28 37 78 84 93 config.gz driver ioports kpagecgroup modules schedstat sys version 12 16 20 226 288 4 79 85 acpi consoles execdomains irq kpagecount mounts scsi sysrq-trigger vmallocinfo 13 17 208 23 29 6 8 86 asound cpuinfo fb kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo crypto filesystems kcore loadavg net slabinfo thread-self zoneinfo
    По прежнему нашего процесса нет, а значит мы в обычном пространстве имен. Проверим

    Ps -e | grep bash
    296 pts/0 00:00:00 bash

    Только один bash, с которого мы и запускали программу. Ни предыдущего PID, ни текущего в списке нет.



    В этой статье мы попытаемся создать модуль ядра, способный изменить PID уже запущенного процесса в ОС Linux, а так же поэкспериментировать с процессами, получившими измененный PID.


    Предупреждение : смена PID - нестандартный процесс, и при определенных обстоятельствах может привести к панике ядра.

    Наш тестовый модуль будет реализовывать символьное устройство /dev/test, при чтении с которого процессу будет изменен PID. За пример реализации символьного устройства спасибо этой статье. Полный код модуля приведен в конце статьи. Конечно, самым правильным решением было добавить системный вызов в само ядро, однако это потребует перекомпиляцию ядра.

    Окружение

    Все действия по тестированию модуля выполнялись в виртуальной машине VirtualBox с 64 битным дистрибутивомLInux и версией ядра 4.14.4-1. Связь с машиной осуществлялась с помощью SSH.

    Попытка #1 простое решение

    Пару слов о current : переменная current указывает на структуру task_struct с описанием процесса в ядре(PID, UID, GID, cmdline, namespaces и т.д)

    Первой идеей было просто поменять параметр current->pid из модуля ядра на нужный.

    Static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { printk("PID: %d.\n",current->pid); current->pid = 1; printk("new PID: %d.\n",current->pid); , }
    Для проверки работоспособности модуля я написал программу на C++:

    #include #include #include int main() { std::cout << "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >> str; std::cout << "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
    Загрузим модуль коммандой insmod, создадим /dev/test и попробуем.

    # ./a.out My parent PID 293 My PID 782 My new PID 782
    PID не изменился. Возможно, это не единственное место, где указывается PID.

    Попытка #2 дополнительные поля PID

    Если не current->pid является идентификатором процесса, то что является? Быстрый просмотр кода getpid() навел на структуру task_struct , описывающую процесс Linux и файл pid.c в исходном коде ядра. Нужная функция - __task_pid_nr_ns. В коде функции встречается обращение task->pids.pid, этот параметр мы и изменим

    Компилируем, пробуем

    Так как тестировал я по SSH, мне удалось получить вывод программы до падения ядра:

    My parent PID 293 My PID 1689 My new PID 1689
    Первый результат, уже что-то. Но PID все равно не изменился.

    Попытка #3 не экспортируемые символы ядра

    Более внимательное изучение pid.c дало функцию, которая делает то, что нам нужно
    static void __change_pid(struct task_struct *task, enum pid_type type,
    struct pid *new)
    Функция принимает задачу, для которой надо изменить PID, тип PID и, собственно, новый PID. Созданием нового PID занимается функция
    struct pid *alloc_pid(struct pid_namespace *ns)

    Эта функция принимает только пространство имен, в котором будет находиться новый PID, это пространство можно получить с помощью task_active_pid_ns .
    Но есть одна проблема: эти символы ядра не экспортируются ядром и не могут использоваться в модулях. В решении этой проблемы мне помогла замечательная . Код функции find_sym взят оттуда.

    Static asmlinkage void (*change_pidR)(struct task_struct *task, enum pid_type type, struct pid *pid); static asmlinkage struct pid* (*alloc_pidR)(struct pid_namespace *ns); static int __init test_init(void) { printk(KERN_ALERT "TEST driver loaded!\n"); change_pidR = find_sym("change_pid"); alloc_pidR = find_sym("alloc_pid"); ... } static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { printk("PID: %d.\n",current->pid); struct pid* newpid; newpid = alloc_pidR(task_active_pid_ns(current)); change_pidR(current,PIDTYPE_PID,newpid); printk("new PID: %d.\n",current->pid); ... }
    Комплируем, запускаем

    My parent PID 299 My PID 750 My new PID 751
    PID изменен! Ядро автоматически выделило нашей программе свободный PID. Но можно ли использовать PID, который занял другой процесс, например PID 1? Добавим после аллокации код

    Newpid->numbers.nr = 1;
    Комплируем, запускаем

    My parent PID 314 My PID 1172 My new PID 1
    Получаем настоящий PID 1!

    Bash выдал ошибку, из-за которой не будет работать переключение задач по комманде %n, но все остальные функции работают отлично.

    Интересные особенности процессов с измененным PID

    PID 0: войти нельзя выйти

    Вернемся к коду и изменим PID на 0.

    Newpid->numbers.nr = 0;
    Комплируем, запускаем

    My parent PID284 My PID 1517 My new PID 0
    Выходит PID 0 не такой и особенный? Радуемся, пишм exit и…

    Ядро падает! Ядро определило нашу задачу как IDLE TASK и, увидев завершение, просто упало. Видимо, перед завершением наша программа должна вернуть себе «нормальный» PID.

    Процесс-невидимка

    Вернемся к коду и выставим PID, гарантированно не занятый
    newpid->numbers.nr = 12345;

    Комплируем, запускаем

    My parent PID296 My PID 735 My new PID 12345
    Посмотрим, что находится в /proc

    1 148 19 224 288 37 79 86 93 consoles fb kcore locks partitions swaps version 10 149 2 226 29 4 8 87 acpi cpuinfo filesystems key-users meminfo sched_debug sys vmallocinfo 102 15 20 23 290 5 80 88 asound crypto fs keys misc schedstat sysrq-trigger vmstat 11 16 208 24 291 6 81 89 buddyinfo devices interrupts kmsg modules scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup mounts self thread-self 13 176 210 26 3 737 83 90 cgroups dma ioports kpagecount mtrr slabinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg pagetypeinfo stat uptime
    Как видим /proc не определяет наш процесс, даже если мы заняли свободный PID. Предыдущего PID тоже нет в /proc, и это весьма странно. Возможно, мы находимся в другом пространстве имен и поэтому не видны основному /proc. Смонтируем новый /proc, и посмотрим что там

    1 14 18 210 25 291 738 81 9 bus devices fs key-users locks pagetypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats interrupts keys meminfo partitions stat tty 102 149 19 222 27 30 76 83 92 cmdline dma iomem kmsg misc sched_debug swaps uptime 11 15 2 224 28 37 78 84 93 config.gz driver ioports kpagecgroup modules schedstat sys version 12 16 20 226 288 4 79 85 acpi consoles execdomains irq kpagecount mounts scsi sysrq-trigger vmallocinfo 13 17 208 23 29 6 8 86 asound cpuinfo fb kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo crypto filesystems kcore loadavg net slabinfo thread-self zoneinfo
    По прежнему нашего процесса нет, а значит мы в обычном пространстве имен. Проверим

    Ps -e | grep bash
    296 pts/0 00:00:00 bash

    Только один bash, с которого мы и запускали программу. Ни предыдущего PID, ни текущего в списке нет.