В конце прошлого года я купил паяльную станцию, уже успевшую получить ярлык «народная». Её достоинства: удобные жала-картриджи T12, приличная мощность (до 72W в теории), быстрый нагрев (единицы секунд), невысокая цена. (Подробнее ознакомиться со станцией можно в этом шикарном обзоре)
Купил я самую последнюю версию hardware 2.1s, и немного расстроился, увидев что прошивка старая. Разумеется руки зачесались обновить. Зная что «сердцем» паяльной станции является STM32F103C8 (популярный микропроцессор ARM Cortex-M3 производства STMicroelectronics) — тем интереснее было покопаться, т.к. я когда-то уже моргал светодиодом на STM32F4Discovery.
Тут же были припаяны 4 провода SWD интерфейса, подключен программатор, залита прошивка.
И… Станция потребовала активацию!
Чтобы было понятнее, расскажу пару слов о разработчике этой станции. Вся информация почерпнута из интернета (и, частично, из самой прошивки). Железо и прошивку разработал некий китайский товарищ ZhongGuoxin (38827251@qq.com) приблизительно в 2014 году. Разработка активно шла в закрытой группе какого-то китайского форума. Видимо понимая тщётность попыток защитить разработку от клонирования своими «земляками», он сделал защиту в прошивке. Прошивка распространялась в виде бинарных модулей, и её мог залить в свежеспаянный клон любой желающий.
Почему именно так? Ведь есть гораздо более надёжные схемы, с распространением уже прошитых МК и обновлением зашифрованными BLOB-ами. Не знаю. Видимо тонкий баланс между затратами времени, удобством, популярностью и доходом. При старте прошивка генерирует коды ID1 и ID2, которые автор обменивает на ключ активации RG1 и RG2 за символическую сумму в 9 юаней (~80 рублей).
Но как можно защитить прошивку, если злоумышленник имеет к ней доступ? Сейчас узнаем.
К сожалению, моих кодов активации, честно купленных вместе с устройством, мне не досталось. Забегая вперед скажу, что помимо обновления затребовать эти коды может перепайка микропроцессора (если пожгли ему ноги) или замена EEPROM. И такие случаи уже были неоднократно.
Т.к. владею своим экземпляром я правомерно, то в полном соответствии с ст. 1280 ГК РФ, могу «осуществлять действия, необходимые для функционирования программы»
Первый блин комом
Прошивка была загружена в IDA. Очень быстро найдено место где вводится код активации. Чтобы убедиться что я на верном пути — я пропатчил аргумент у функции, которую назвал DisplayString. Залил пропатченную версию. Не стартует!
Ну ничего страшного, наверное неверно понял назначение функции. Откатываю изменения. Патчу выводимый текст. Не стартует!
Тааак. Есть проверка целостности. Нужен отладчик. И мы её поймаем аппаратной точкой останова! В качестве отладчиков перебрал несколько вариантов, остановился на связке IDA gdb + OpenOCD. Сам по себе отладчик в IDA неудобен и глюковат, но возможность интерактивно редактировать дизасм прямо в отладчике перевесила.
Запускаю OpenOCD, ставлю watchpoint на чтение изменённых байт кода. Запускаю. Ватчпоинт не срабатывает… Как же так? Ведь проверка целостности 100% присутствует!
И вот тут я заинтересовался по-настоящему.
Исследуем данные
Полный размер прошивки 75512 байт. Это довольно много. Код от данных для нас уже отделила IDA. Получилось 48128 байт кода и 27384 байта данных, без учёта маленьких пятен локальных данных, расположенных в коде между функциями — особенность ARM Thumb.
Теперь неплохо бы понять что эти данные означают.
Самое простое — текстовые данные. Названия пунктов меню, жал, копирайты. Их оказалось больше 6кб. Среди текстов меню попались байты, очень похожие на 32 битные адреса в сегменте FLASH. По этим адресам располагались объемные подпрограммы, содержащие в себе вызовы ранее найденной DisplayString. Значит это обработчики пунктов меню. Приличный объём кода опознан.
Продолжаем. Раз экран станции монохромный — логично предположить что графические данные будут представлены в битовом (монохромном) виде. Вспомнив детство с ZX-Spectrum — было решено отображать байты столбцами: так я в 90е искал графику в играх, она заметно отличалась от данных и кода.
Была написана программка viewbin на питоне. Для удобства каждый блок в 256 байт отделён от соседнего. Всего в одном столбце по вертикали располагается ровно килобайт (4 блока). Следующий столбец относится к следующему килобайту.
В правой части хорошо заметны графические закорючки. Но в картинки они складываются плохо. А если наклонить голову вправо? Сначала можно заметить шрифт 8*16 (x*y): первые 8 байт образуют верхнюю половину символа, вторые — его нижнюю половину.
Остальные символы строятся по тому же приципу. Большой шрифт имеет размер 16*32, глифы иероглифов 16*16
Плюс есть ещё несколько служебных символов (значок цельсия, термометр, стрелка, чекбоксы). Суммарно почти 16 кб занято графикой.
Итого из 27 кб данных удалось сходу распознать 22 кб. Неплохо.
Перейдём к коду — 48 килобайт тугого THUMB кода. Он действительно весьма компактный. Например часто встречающаяся операция v1 & (~v2) это всего одна инструкция «BTC».
Что такое ARM Cortex M3
МК, помимо ARM ядра, содержит кучу периферийных модулей. Всё это хозяйство управляется регистрами, отображёнными на память. Этих регистров тысячи. Они объёдинены в группы по функциональному признаку, каждая группа выровнена.
Плюс т.н. BitBanding — когда доступ к слову (32 bit) означает атомарные установку или сброс единственного бита. Нетрудно прикинуть, что один 32 разрядный регистр займёт 128 байт в области BitBand. Итого регистры занимают совершенно сумасшедший размер адресного пространства.
Работа с периферией заключается в записи или чтении этих регистров. Существует библиотека CMSIS от ARM, прикрывающая голые регистры тонким слоем СИ-шного кода и сопутствующие ей библиотеки от производителей (STM32F10x_StdPeriph_Driver в нашем случае) для периферии.
Из Си кода работа с периферией выглядит как изменение именованного регистра периферии.
В ассемблере же эта работа выглядит как несколько уровней косвенной адресации. Обычных регистров CPU. Достали r1 из r2, по нему другой r0, а потом ещё раз r0 по смещению 0x0C. Что это — неясно совершенно.
Исследуем код
После ввода регистрационного кода вызывается несколько функций. Очищается экран. Выводится надпись (на китайском!). После чего вызывается ещё несколько функций. Сверяются два значения. И выводится либо одно, либо другое сообщение (на китайском!). После чего станция виснет.
Предположив что это и есть проверка кода я заменил условие. Ничего не изменилось. Поставил точки останова на вызываемых функциях и их внутренностях. Они вызываются из большого числа мест совершенно с разыми аргументами.
Понятнее не стало. Возвращаемся к началу. Так почему же не сработал WatchPoint подсчёта контроля целостности?
Я догадывался что причина в DMA (Direct Memory Access) контроллере. Тем более что STM32 имеет аппаратный модуль подсчёта CRC — даёшь ему задачу, и он сам читает байты из памяти через DMA, инкрементирует адрес, и считает контрольную сумму. Достаточно лишь дождаться окончания выполнения и прочитать результат из регистра.
Но чтобы исследовать работу с периферией надо корректно определить все регистры по их номерам. Регистров тысячи, их числовая форма скрыта от программиста слоем библиотечного кода. В дизассемблере нашёл константу — поищи что это за регистр. Заниматься прыжками datasheet-дизассемблер мне быстро наскучило. И я написал питон-скрипт для IDA (ссылка на GitHub), который генерирует основную массу регистров. А заодно определяет таблицу векторов прерываний, даёт имена обработчикам, оформляет точку старта и создаёт сегмент SRAM.
Стало чуточку понятнее.
Чтобы восстановить логику работы я предпочитаю начинать с маленьких функций. Они легче для понимания, а полезные ещё и часто используются.
Функции, использующие много битовой арифметики, были определены как Floating Point с помощью «грубой силы»: указатель команд ставился на начало функции. В регистры заносилось HEX представление плавающей точки (например числа «100.0» и «30.0»). (Ссылка на удобный Online конвертер). Результат функции конвертировался обратно в плавающий вид. Если на выходе имеем что-то осмысленное, типа «70.0» или «3.3333» — то смело можем давать имя. Оказалось что часть функций работает с float, часть c double.
Мне очень повезло, и для работы с периферией автор использовал стандартую библиотеку, СИ-код сопоставлялся с дизассемблером идеально.
Споткнулся я на нескольких noreturn функциях, на входе в которые lr указывал «вникуда», имея значение 0xFFFFFFFF, а стек был заполнен странными константами навроде 0x12121212, 0x09090909. Гугл настаивал что это FreeRTOS (Что?!
Операционная система реального времени в… ПАЯЛЬНИКЕ?).
Но вот с исходниками бинарный код сопоставить не получилось. Я проверил 10 версий, от 10.0.0 (2018) до 3.2.4 (2005). Везде сходство было лишь поверхностным. Поэтому ограничился именованием таких фукнций как TaskXXXXX, а общий код, который передавал им управление, как TaskCreate.
Исследуем работу периферии или Автоматизация отладки
Среди опознанных функции стандартной библиотеки оказались DMAInit, DMACmd, DMAGetCurrentDataCounter. Проблема заключалась в том, что вызывались они слишком уж много и часто. А я ленивый.
Поэтому я написал питон API для работы с функциями OpenOCD: Ссылка на GitHub. Команды шлются OpenOCD серверу по telnet протоколу. В качестве примера использования в каталоге «examples/dbgbot» лежит код робота, речь о котором пойдёт ниже.
На основе этого API я сделал робота, исследующего вызовы DMA. Робот реагирует на инициализацию DMA операции в функции DMA_Init. Протоколирует адреса периферии, памяти, направление передачи, количество и размер передаваемых элементов, а так же опциональный признак автоинкремента адресов источника и приёмника.
Но кроме этого я хотел видеть получаемые данные. Например если запрошен рассчёт CRC — то хочу знать что именно там посчиталось. Для этого необходимо пройти всю цепочку вызовов: Init -> Command «enable» -> Wait. Т.е. нужна машина состояний. Которая динамически устанавливает и снимает точки останова в зависимости положения между состояниями.
Для Wait надо ждать когда обнулится аппаратный счётчик. (Ещё есть сигнализация прерываниями, но это не наш случай.) Ждать надо продолжая исполнять команды, т.к. JTAG отладка полностью останавливает ядро микропроцессора.
Проблема оказалась в том, что автор не заморачивался с ожиданием, если давал DMA команду на небольшой объём данных — к тому моменту когда они ему становились нужны чип уже всё сделает. Для меня же это решение означало что я не могу надеяться на вызов DMAGetCurrentDataCounter для отслеживания окончания передачи. И когда этими данными начнут пользоваться я тоже не знал — если получать их слишком поздно они уже могут быть испорчены работой остального кода.
Поэтому пришлось применить эвристику: если размер передачи > 32 байт — будет использована явная проверка. Иначе после выдачи команды на трансфер я пошагово исполню столько инструкций, сколько байт запрошено на передачу.
Это не единственный «хак» — изучив весь код ожиданий, я пришёл к выводу, что он всегда занимает 4 байта после вызова DMAGetCurrentDataCounter.
Поэтому после первого срабатывания этой точки останова — получаем адрес возврата и переставляем точку останова на 4 байта за ним. Ожидание завершено!
??? DMA LR:0x08000abf P:0x4001244c *(00000000) (=>) M:0x20000224 [0x000f] P2.M2+
-------------------------------------------------------------------------------------
MasterCRCtoRAM
M2M DMA LR:0x08002e81 P:0x080125bc *(145eac33) (=>) M:0x200000f0 [0x0002] P2+M2+
-------------------------------------------------------------------------------------
MasterCRCtoRAM
M2M DMA LR:0x08002e81 P:0x080125bc *(145eac33) (=>) M:0x20000020 [0x0002] P2+M2+
-------------------------------------------------------------------------------------
Calc_CRC_0_Wrap (Begin)
M2M DMA LR:0x08005001 P:0x200000f0 *(145eac33) (=>) M:0x20000010 [0x0002] P2+M2+
-------------------------------------------------------------------------------------
Calc_CRC_0
CRC DMA LR:0x080050d3 P:0x40023008 (<=) M:0x2000085c *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08005127 P:0x40023000 (<=) M:0x20000010 *(145eac33) [0x0002] P4.M4.
CRC DMA LR:0x08005127 P:0x40023000 (<=) M:0x20000010 *(145eac33) [0x0002] P4.M4.
CRC DMA LR:0x08005177 P:0x40023000 *(abb10a5e) (=>) M:0x20000010 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
Calc_CRC_0_Wrap (End)
M2M DMA LR:0x08005043 P:0x200000f0 *(145eac33) (=>) M:0x20000014 [0x0002] P2+M2+
-------------------------------------------------------------------------------------
Calc_CRC_1
CRC DMA LR:0x08005203 P:0x40023008 (<=) M:0x20000804 *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08005257 P:0x40023000 (<=) M:0x20000014 *(145eac33) [0x0006] P4.M4.
CRC DMA LR:0x08005257 P:0x40023000 (<=) M:0x20000014 *(145eac33) [0x0006] P4.M4.
CRC DMA LR:0x08005257 P:0x40023000 (<=) M:0x20000014 *(145eac33) [0x0006] P4.M4.
CRC DMA LR:0x080052a7 P:0x40023000 *(4859bef2) (=>) M:0x20000014 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
Calc_CRC_2
CRC DMA LR:0x08002359 P:0x40023008 (<=) M:0x20000954 *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x080023ad P:0x40023000 (<=) M:0x08000000 [0x496f] P4.M4+
CRC DMA LR:0x08002411 P:0x40023000 (<=) M:0x080125c0 [0x3690] P4.M4+
CRC DMA LR:0x08002463 P:0x40023000 *(145eac33) (=>) M:0x2000001c [0x0001] P4.M4.
CRC DMA LR:0x080024b5 P:0x40023000 *(145eac33) (=>) M:0x20000958 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
Calc_CRC_3
CRC DMA LR:0x08002f07 P:0x40023008 (<=) M:0x2000095c *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08002f5d P:0x40023000 (<=) M:0x08000000 [0x496f] P4.M4+
CRC DMA LR:0x08002fbf P:0x40023000 (<=) M:0x080125c0 [0x3690] P4.M4+
CRC DMA LR:0x08003011 P:0x40023000 *(145eac33) (=>) M:0x20000030 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
Calc_CRC_4
CRC DMA LR:0x08002c17 P:0x40023008 (<=) M:0x20000854 *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08002c6b P:0x40023000 (<=) M:0x20000030 *(145eac33) [0x0002] P4.M4.
CRC DMA LR:0x08002c6b P:0x40023000 (<=) M:0x20000030 *(145eac33) [0x0002] P4.M4.
CRC DMA LR:0x08002cbb P:0x40023000 *(abb10a5e) (=>) M:0x20000030 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
Calc_CRC_5
CRC DMA LR:0x080030bb P:0x40023008 (<=) M:0x2000095c *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08003111 P:0x40023000 (<=) M:0x08000000 [0x496f] P4.M4+
CRC DMA LR:0x08003173 P:0x40023000 (<=) M:0x080125c0 [0x3690] P4.M4+
CRC DMA LR:0x080031c5 P:0x40023000 *(145eac33) (=>) M:0x20000034 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
Calc_CRC_6
CRC DMA LR:0x08002d47 P:0x40023008 (<=) M:0x200007fc *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08002d9b P:0x40023000 (<=) M:0x20000034 *(145eac33) [0x0006] P4.M4.
CRC DMA LR:0x08002d9b P:0x40023000 (<=) M:0x20000034 *(145eac33) [0x0006] P4.M4.
CRC DMA LR:0x08002d9b P:0x40023000 (<=) M:0x20000034 *(145eac33) [0x0006] P4.M4.
CRC DMA LR:0x08002deb P:0x40023000 *(4859bef2) (=>) M:0x20000034 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
Calc_CRC_2
CRC DMA LR:0x08002359 P:0x40023008 (<=) M:0x20000c64 *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x080023ad P:0x40023000 (<=) M:0x08000000 [0x496f] P4.M4+
CRC DMA LR:0x08002411 P:0x40023000 (<=) M:0x080125c0 [0x3690] P4.M4+
CRC DMA LR:0x08002463 P:0x40023000 *(145eac33) (=>) M:0x2000001c [0x0001] P4.M4.
CRC DMA LR:0x080024b5 P:0x40023000 *(145eac33) (=>) M:0x20000c68 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
Calc_CRC_7
CRC DMA LR:0x08007a7d P:0x40023008 (<=) M:0x200008a0 *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08007acd P:0x40023000 (<=) M:0x200000fc *(abcdfedc) [0x0076] P4.M4.
CRC DMA LR:0x08007acd P:0x40023000 (<=) M:0x200000fc *(abcdfedc) [0x0076] P4.M4.
CRC DMA LR:0x08007b1f P:0x40023000 *(80a34f2a) (=>) M:0x200000fc [0x0001] P4.M4.
-------------------------------------------------------------------------------------
DMACopyWord_0
M2M DMA LR:0x08002b09 P:0x200000fc *(80a34f2a) (=>) M:0x20000000 [0x0002] P2+M2+
-------------------------------------------------------------------------------------
DMACopyWord_1
M2M DMA LR:0x08002b91 P:0x200000fc *(80a34f2a) (=>) M:0x200000f4 [0x0002] P2+M2+
-------------------------------------------------------------------------------------
Get_DesignID_0
M2M DMA LR:0x080029f3 P:0x1ffff7e8 (=>) M:0x200021c0 [0x0006] P2+M2+
0x200021c0 56 ff 76 06 51 80 48 54 | 38 18 10 87 V.v.Q.HT8 ...
-------------------------------------------------------------------------------------
DMACopyWord_2
M2M DMA LR:0x08002a7f P:0x20000000 *(80a34f2a) (=>) M:0x200001b0 [0x0002] P2+M2+
-------------------------------------------------------------------------------------
Get_DesignID_1
M2M DMA LR:0x08001c61 P:0x1ffff7e8 (=>) M:0x20002dc0 [0x0006] P2+M2+
0x20002dc0 56 ff 76 06 51 80 48 54 | 38 18 10 87 V.v.Q.HT8 ...
M2M DMA LR:0x08001cc5 P:0x200001b0 *(80a34f2a) (=>) M:0x20002db8 [0x0002] P2+M2+
-------------------------------------------------------------------------------------
Calc_CRC_7_Wrap (Begin)
M2M DMA LR:0x08001d99 P:0x200030b8 *(5a92dc90) (=>) M:0x200030c4 [0x0002] P2+M2+
M2M DMA LR:0x08001dd5 P:0x0800f4bb (=>) M:0x20003098 [0x0010] P2+M2+
0x20003090 | 00 04 04 44 c4 4f 44 44 . ..D.ODD
0x200030a0 c4 24 24 2f b4 24 04 04 | 00 40 44 24 24 15 0c 04 .$$/.$... @D$$...
0x200030b0 fe 04 0c 15 24 24 44 40 | ....$$D@
M2M DMA LR:0x08001e2f P:0x0800f4fb (=>) M:0x20003098 [0x000e] P2+M2+
0x20003090 | 00 10 60 02 8c 00 00 fe . .`.....
0x200030a0 92 92 92 92 92 fe 00 00 | 00 04 04 7e 01 40 7e 42 ......... ..~.@~B
0x200030b0 42 7e 42 7e | B~B~
-------------------------------------------------------------------------------------
Calc_CRC_7
CRC DMA LR:0x08007a7d P:0x40023008 (<=) M:0x20002f84 *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08007acd P:0x40023000 (<=) M:0x200030c8 *(a7894d6e) [0x0076] P4.M4.
CRC DMA LR:0x08007acd P:0x40023000 (<=) M:0x200030c8 *(a7894d6e) [0x0076] P4.M4.
CRC DMA LR:0x08007b1f P:0x40023000 *(fab893e0) (=>) M:0x200030c8 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
Calc_CRC_7_Wrap (End)
M2M DMA LR:0x08001e81 P:0x200030c8 *(fab893e0) (=>) M:0x200000f8 [0x0002] P2+M2+
M2M DMA LR:0x08001ebd P:0x200030c8 *(fab893e0) (=>) M:0x200030bc [0x0002] P2+M2+
-------------------------------------------------------------------------------------
DMACopy_32bytes_0
M2M DMA LR:0x08001b73 P:0x0800f4bb (=>) M:0x20002778 [0x0010] P2+M2+
0x20002770 | 00 04 04 44 c4 4f 44 44 . ..D.ODD
0x20002780 c4 24 24 2f b4 24 04 04 | 00 40 44 24 24 15 0c 04 .$$/.$... @D$$...
0x20002790 fe 04 0c 15 24 24 44 40 | ....$$D@
-------------------------------------------------------------------------------------
DMACopy_32bytes_1
M2M DMA LR:0x08001be7 P:0x0800f4fb (=>) M:0x20002778 [0x0010] P2+M2+
0x20002770 | 00 10 60 02 8c 00 00 fe . .`.....
0x20002780 92 92 92 92 92 fe 00 00 | 00 04 04 7e 01 40 7e 42 ......... ..~.@~B
0x20002790 42 7e 42 7e 42 42 7e 40 | B~B~BB~@
-------------------------------------------------------------------------------------
Calc_CRC_7
CRC DMA LR:0x08007a7d P:0x40023008 (<=) M:0x200026bc *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08007acd P:0x40023000 (<=) M:0x200027a4 *(a7894d6e) [0x0076] P4.M4.
CRC DMA LR:0x08007acd P:0x40023000 (<=) M:0x200027a4 *(a7894d6e) [0x0076] P4.M4.
CRC DMA LR:0x08007b1f P:0x40023000 *(fab893e0) (=>) M:0x200027a4 [0x0001] P4.M4.
-------------------------------------------------------------------------------------
DMACopy_32bytes_0
M2M DMA LR:0x08001b73 P:0x0800f4bb (=>) M:0x20002a80 [0x0010] P2+M2+
0x20002a80 00 04 04 44 c4 4f 44 44 | c4 24 24 2f b4 24 04 04 ...D.ODD. $$/.$..
0x20002a90 00 40 44 24 24 15 0c 04 | fe 04 0c 15 24 24 44 40 .@D$$.... ...$$D@
-------------------------------------------------------------------------------------
DMACopy_32bytes_1
M2M DMA LR:0x08001be7 P:0x0800f4fb (=>) M:0x20002a80 [0x0010] P2+M2+
0x20002a80 00 10 60 02 8c 00 00 fe 92 | 92 92 92 92 fe 00 00 ..`...... .......
0x20002a90 00 04 04 7e 01 40 7e 42 42 | 7e 42 7e 42 42 7e 40 ...~.@~BB ~B~BB~@
-------------------------------------------------------------------------------------
Calc_CRC_7
CRC DMA LR:0x08007a7d P:0x40023008 (<=) M:0x200029c4 *(00000001) [0x0001] P4.M4.
CRC DMA LR:0x08007acd P:0x40023000 (<=) M:0x20002aac *(a7894d6e) [0x0076] P4.M4.
CRC DMA LR:0x08007acd P:0x40023000 (<=) M:0x20002aac *(a7894d6e) [0x0076] P4.M4.
CRC DMA LR:0x08007b1f P:0x40023000 *(fab893e0) (=>) M:0x20002aac [0x0001] P4.M4.
Видео работы робота с анализом DMA операций:
Функций, относящихся с посчёту CRC оказалось 8 (ВОСЕМЬ!). Ни одна не содержит параметры в явном виде, используются витиеватые вычисления. Часть из этих функций для рассчёта использует рекурсию, что дополнительно усложняет понимание.
Из дампа, сделанного роботом, отлично видно что константа (я назвал её MasterCRC) копируется из Flash в RAM, потом из RAM в RAM. Считается CRC на две половинки флеша: до этой констаны и после этой константы до самого конца, т.е. даже на незанятую прошивкой область. А это значит что если чип перед прошивкой предварительно не очистить — контрольная сумма не сойдётся!
Полный подсчёт CRC выполняется 4 раза. Ужас! Потом считается CRC на CRC. И CRC на CRC на CRC. Ужас! Сильно в манипуляции с CRC я вникать не стал.
DMA приносит первый успех
Кроме подсчёта CRC и странных перемещений из памяти в память в логе оказалось получение уникального ID чипа. С помощью DMA. Это очень подозрительно, т.к. ID чипа задаётся при произодстве, он уникален для каждого кристалла — прекрасный кандидат на роль источника данных для формирования регкода.
Любопытная информация: оказывается 12 байтовый ID чипа содержит внутри себя номер партии, номер пластины (вафли), и даже x-y координаты чипа на этой вафле!Анализ кода после получения ID чипа показал, что дважды вызывается одна и та же функция, сначала над первыми 6 байтами ID, а затем над вторыми. Функция обрабатывает переданный буфер, используя байты как индекс в 256-значном массиве, ксоря и сдвигая результаты.
Подозрение подтвердилось — вызовы вернули мои ID1 и ID2 коды.
Ногодрыжество
Определяя функции из стандартной библиотеки периферии я заметил обработку странной таблицы по адресу 0x800C23C. В ней описывались состояния каждого из 16 пинов всех 7 GPIO портов (вызовы — жуткий копипаст). Стало интересно какие пины для чего используются.
IPU — push supply (умолчание, если не указано иное)
IPD — push ground
AIN — analog in
Out_OD — Out Open-drain
Out_PP — Out Push-pull
частота 50mhz (умолчание, если не указано иное)
Какие-то настройки в порту GPIO_C видимо остались мусором от старых версий/прототипов. Разводка поменялась, порт вообще отключили, а скорость зачем-то меняется.
Обратите внимание на подключение EEPROM Flash. Линии I2C заведены на ноги, где нет аппаратного I2C. Странное решение, не правда ли?
Ну тем лучше. Я никогда не работал с I2C. А тут представилась такая возможность пощупать его на уровне ручного управления сигналами на ножках МК! Скачал доку с сайта TI, нарисовал таблицу состояний, набросал код для робота. Чтобы он по изменениям пинов раскодировал передачу.
И тут меня ждал облом. EEPROM не останавливается отладчиком. И хотя теоретически она могла бы ждать мастера, на практике всё разваливается напрочь.
Ок, зная работу протокола даём имена функциям, поднимаясь уровень за уровнём до грозди функций Flash_ReadData / Flash_WriteData, малоотличающихся друг от друга (копипаст?)
Смотрю на ссылки — чтение и запись вызывается из места ввода кода. Интересно! Оказывается 4 байтовый ответный код после ввода пишется по флеш. А потом читается оттуда. Ожидание этих операций я и принял за проверку. А два разных сообщения на китайском — если прочитали тоже что и записали и если нет (аппаратная ошибка?).
Получается что после ввода код не проверяется. Он проверяется всегда при старте станции. И при ошибке проверки вместо основной RTOS задачи паяльника создаётся другая RTOS задача, которая занимается вводом кода и записью его во флеш. Чтож, логично.
Кроме того в соседнх флеш-функциях происходит чтение-запись солидного куска данных. Размером 0x3AE байт. Похоже на настройки. После их чтения вызывается функция вычисления кода по буферу с данными. До зубовного скрежета напоминающую функцию вычисления ID1 и ID2. И даже таблица с данными ещё одна, точно такая же. Зачем использовать такой код для проверки целостности настроек? Взял бы лучше CRC! Постойте, а что если…? Загоняю в гугл константы из таблицы — точно. Это и есть CRC. Точнее CRC16_CCIT. Две копии одной и той же функции. Две копии таблиц. Чтобы враг не догадался.
Последние шаги
Итак, мы контролируем чтение из флеша. «reset init». Точка останова быстро приводит нас месту где читается свежезаписанный ответ. Ставим watchpoint на прочитанные данные. «resume» Станция как ни в чём ни бывало показывет интерфейс ввода кода.
Опять DMA? Смотрим лог. Сразу после копирования прочитанного кода из флеш происходит два копирования блоков по 32 байта. Смотрим дизассемблер по адресу возврата из DMA операции. В коде видим после копирования 32 байт вызов странной функции с кучей xor внутри. Ставим точку останова.
При вызове функции видим буфер с какими-то данными, в последних 4 байтах которого лежат уже знакомые ID1 и ID2 станции. На выходе из функции видим 16 битное число. Ещё один вызов — буфер с другими данными, в конце так же лежат ID1 и ID2.
Любопытная информация: данные в каждом из 32-байтных буферов это изображения соответствующего иероглифа. Последние 4 байта изображения замененяются в буфере на ID1+ID2. Что это за иероглифы? Может быть имя разработчика? Не знаю, я не силён в китайском.А что если результат функции и есть искомый код-ответ? Запускаем станцию, вводим полученные в отладчике числа, рестарт — и код принят!
Осталось понять что именно вычисляет эта загадочная функция. А делает она вот что:
- кучу XOR между явно заданными константами. Просто взял финальное значение. Назовём его «manyXorValue».
- вычисляет CRC16_CCIT от начала самой себя. Также берём уже посчитанное значение. Назовём его «xorCodeCrc16».
- считает CRC16, полагая в качестве начального значения результат (manyXorValue xor xorCodeCrc16), а вместо уже знакомых двух копий CRC16 таблицы ещё одну таблицу. Очень похожую, но всё-таки другую.
Такое ощущение что оригинальную таблицу нарезали на кусочки по 8 элементов, перемешали, и опять склеили. Например 1-ый кусочек стал 0-ым. 5-ый никуда не делся. А на месте 4-го теперь 31-ый. Пишем короткий код для сопоставления, и вот нужные перестановки для сборки этой странной таблицы: 1, 2, 3, 4, 31, 5, 6, 7, 8, 9, 10, 11, 12, 0, 13, 25, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30.
Переписываем на Python. Проверяем — работает. Для отладки я попросил несколько ребят из интернетов, имеющих такие же станции, дать мне их ID и проверить сгенерированные RG. Проверили ещё на 5 станциях. Результат правильный.
Заключение
- Основой защиты оказался запутанный и сложный код большого объёма (не считал точно, но на вскидку его 10-15%), густо замешанный на работе с железом. Не удивлюсь если многопоточность RTOS тоже играет важную роль. Благо я не собирался понять все тонкости реализации.
- Станция заработала с более новой прошивкой. Наконец-то собрал для неё шикарную алюминиевую ручку с Tao. Спаял этой же станцией.
UPDATE: В комментариях уже дважды спросили про эту ручку. Вот отличный обзор на неё. - Узнал массу новой информации про ARM Cortex M3 и периферию STM32.
- Откровенно разочаровался качеством китайской прошивки. Буду делать открытую, переписанную с нуля.
А если бы защита оказалась более простой? Наверное ввёл бы код, и забыл про неё…
Пишите в комментариях, интересно ли вам узнать продолжение истории: реверс алгоритмов работы паяльной станции и ход разработки моего варианта.
P.S.: Специально для этой статьи переписал код генерации ключей на javascript. Online версия, там же есть ссылка на Python версию. Если объяснения были где-то непонятны — можно почерпнуть детали из кода. Ну и, конечно, оживить вашу собственную станцию, заблокированную обновлением или ремонтом железа.
Комментарии (106)
Germanets
06.03.2018 17:41Любопытная информация: оказывается 12 байтовый ID чипа содержит внутри себя номер партии, номер пластины (вафли), и даже x-y координаты чипа на этой вафле!
— круто сделано, чтобы производитель потом мог не только пытаться разобраться с проблемой в готовом чипе, но и узнать всю историю его производства, а также попробовать поискать другие рядом стоящие чипы, либо чипы с других «вафель», стоящих на тех же местах…
Amareis
06.03.2018 18:04+5Вот уж чего не ожидал китайский товарищ, так это коварных русских хакеров, ковыряющих его самописную защиту)
HeyHappy
06.03.2018 18:12Даже не ожидал, что такое осилю. Чтиво тем интересней, чем больше ты в понимаешь в подобной теме. Интересное начало и ожидание концовки заинтересовали.
MIZANTR0P
07.03.2018 17:37Аналогично. Только отличие в том, что я в данной теме наоборот немного, что понимаю. Но, черт возьми, читал, словно триллер.
glorfindeil
06.03.2018 18:12+4В один день ты взламываешь паяльник. апотом в другой день паяльник будет взламывать тебя. А если серьезно, все очень круто!
SkyTeh
06.03.2018 18:12Не ожидал что будут так заморачиваться с защитой паяльной станции. Любопытно узнать продолжение истории.
vvzvlad
06.03.2018 18:40+2Т.к. владею своим экземпляром я правомерно, то в полном соответствии с ст. 1280 ГК РФ могу «осуществлять действия, необходимые для функционирования программы»
P.S.: Специально для этой статьи переписал код генерации ключей на javascript. Online версия, там же есть ссылка на Python версию.
Как вы «изящно» оправдали свои действия: сначала «ну я купил эти ключи, значит имею полное право заставить станцию заработать», а потом «ну, я тут написал кейген, вы пользуйтесь». Не то, что бы я очень сочувствовал безымянному китайцу, но ведь человек старался, писал.
И почему вас так удивляется RTOS? С ней проще разрабатывать практически любую мелочь, лишь бы ресурсы позволяли.AllexIn
06.03.2018 18:54+1Не понятно что там вообще пытались защитить.
PID на нагревателе? Ситывание показателей с термистора? Вывод инфы на экранчик?vvzvlad
06.03.2018 18:56Там термопара, но не суть.
Защитить пытались прошивку. Вопросы о ее сложности лежит за рамками обсуждения легальности взлома. Была бы программа простейшей, все бы писали свои, а не платили за эту.AllexIn
06.03.2018 18:59Свою писать дороже, чем купить готовую.
Вопрос легальности взлома смысла обсуждать нет — всё легально.
Делиться кейгеном — это уже обсуждаемо. Хотя если кейген не содержит кода из оригинального ПО — то тоже сложно придратьсяюvvzvlad
06.03.2018 19:02+1Свою писать дороже, чем купить готовую.
Ну вот именно это время-силы, потраченное разработчиком и пытались защитить.
Легально, конечно. Я просто отметил, что автор не смог прямо заявить «я взломал, пользуйтесь», а был вынужден сначала оправдаться, хотя бы для себя.Kroligoff
07.03.2018 09:31-7У Автора изначально не было цели «для себя», иначе просто купил за 80р ключ. Подобные личности, пытаются своими действиями, повысить значимость в кругу общения (бложик, форум итд)
TeiSinTai
07.03.2018 07:54+3Я вот думаю, что защиту китайцы ставили от своих. Чтобы соседи по рынку при копировании станции не смогли сэкономить на разработке прошивки.
YetAnotherSlava
08.03.2018 19:05Меня эта прелюдия удивила с другой стороны. Какой там ГК, кому оно интересно?
(включает музыку из кейгенов)
vostrenkov
06.03.2018 18:40+1Потрясающая работа! Я бы скорее сел писать свою прошивку к паяльнику, чем такое осилил
Zolg
06.03.2018 18:54Мне очень повезло, и для работы с периферией автор использовал стандартую библиотеку
в этом случае часто очень продуктивным бывает потратить немного времени на создание FLIRT-сигнатур
x893
06.03.2018 19:16А сразу выйти из функции проверки с положительным ответом?
Zolg
06.03.2018 19:24+2Кейген всегда надежней.
Вот пропатчили вы, например, проверку целостности и серийника при загрузке станции. И все вроде как работает. Но где гарантии, что нет других проверок, сработающих через полчаса (и при провале разогреющих жало до 666C)?
screwer Автор
06.03.2018 19:24+2Я не стал искать эту проверку. Подозреваю в ней припасена ещё порция подлянок. В любом случае, чтобы патч прошёл проверку целостности, придётся скорректировать контрольную сумму. Я её нашёл проделав изрядную часть описанной работы.
Paskin
08.03.2018 17:17Не знаю как в этом конкретном случае — но в мало-мальски серьезных защитах такая функция возвращает не успех/неуспех а какие-нибудь данные — от смещения перехода до ключа раскодировки каких-нибудь таблиц параметров и т.п.
geekmetwice
06.03.2018 20:22-4Поддержу вопрошающих: неужели управление нагревом такое сложное, чтобы ради этого столько «хачить» прошивку?? Жалко время. Ладно если бы был рутер какой или часы, а тут… паяльник… ржач. :) Несомненно одно — вы классный, упорный хакер и молодец. Вам бы ПИСАТЬ такие прошивки, благо рынок мобильных ОС практически закрыт — народу нужен хотя бы один аппарат, где можно гарантировать отсутствие зондов, реклам, обновлений и прочего дерьма. И не на линупсах, конечно.
Zolg
06.03.2018 23:55+2неужели управление нагревом такое сложное, чтобы ради этого столько «хачить» прошивку?? Жалко время.
вы не поверите, есть люди, кейгенящие программы единственной функцией которых является вывод мессаджбокса.
just because it is fun
а здесь к тому же фан весьма необыденный.geekmetwice
08.03.2018 21:41Есть люди, собирающие корабль из зубочисток, но это не оправдывает бесполезности траты времени. Для минусящих клоунов углублю мысль (раз с первого раза не дошло): «НЕТ СМЫСЛА хачить копеечные, примитивнейшие вещи». Особенно с такими затратами времени. Студота, конечно же, не поймёт даже выражения «тратить время» — у них-то его дофига! А как старожил ИТ (который ещё для БК-0010 писал в кодах), скажу: времени всё меньше и меньше, темп всей жизни ускорился — просто расточительно хакать утюги, паяльники и тостеры. Автора я уже похвалил за сам процесс и статью — интересно и поучительно, но уверяю, даже 5 людей не найдётся, которым серьёзно помогли бы эти «исследования прошивки». Пока ты тупо смотришь в экран, пытаясь понять банальнейшую программу, люди СОЗИДАЮТ куда более сложные вещи. И как я написал, создание прошивок с интересным функционалом куда практичнее. Но был не понят прыщавыми «кульхацерами». Что ж, даже не надеялся. :)
ilyaplot
07.03.2018 10:18+1народу нужен хотя бы один аппарат, где можно гарантировать отсутствие зондов, реклам, обновлений и прочего дерьма. И не на линупсах, конечно.
Берите старую нокию 3310. Зондов нет, рекламы нет, обновлений тоже. Не на «линупсах».
aamonster
06.03.2018 20:37+1А опенсорсной прошивки для подобных станций разве нет? Адаптировать опенсорс и править, как понравится — выглядит гораздо интересней, чем отдать несколько часов работы за экономию 80 рублей...
screwer Автор
06.03.2018 20:41+3Я не знаю опенсорсных прошивок. Если найдёте — обязательно поделитесь.
Дело совсем не в 80 рублях, и потратил я во много раз больше времени. Мне это было просто интересно.ELEX
06.03.2018 21:20Не менее интересно было читать! Но в чем «разочарование… прошивкой»? Ее работа или код? В упомянутом обзоре тоже нет нареканий к работе.
screwer Автор
06.03.2018 21:28Прошивка написана грязно. Очень много копипаста. Какие-то куски неиспользуемого кода. Оптимизация для многих (всех?) функций, кроме библиотечных, видимо, была выключена. Код сгенерированный компилятором порой вводит в ступор. Выполняется масса бесполезных, но очень времязатратных действий. Например 4-ех кратное вычисление CRC для 128кб флеша. Или подгрузка почти 1кб данных из EEPROM через дёргание ногами (> секунды). Основной объём этих 1кб это калибровка для 98 всех возможных жал. Причём в 99.9% там будут значения по-умолчанию. Зачем они все сразу? Что мешает загрузить нужные данные калибровки при смене жала? Зачем вообще нужен EEPROM? обычного флеша ещё масса свободного. Можно было бы аккуратно писать в него, экономно расходуя ресурс. И не затрачивая потом времени на чтение.
Zolg
07.03.2018 00:01А не пофиг по большому счету?
Работает? Работает. Температуру держит? Держит. Что изменится от того, что мк будет загружен не на 5, а на 1%?Free_ze
07.03.2018 12:04А не пофиг по большому счету?
При такой культуре разработки в продукте могут оказаться неприятные баги. До потребителя они могут дойти как собственной персоной, так и в виде вклада в себестоимость (фиксы-перефиксы, перфоманс-баги, требующие больших ресурсов).
Работает? Работает.Zolg
07.03.2018 14:18Культура, как культура.
Нет, мой внутренний перфекционизм тоже корчится в эстетических муках, но такой код, увы сейчас не исключение, а правило. И прагматически-экономически оно увы оправдано.
Нет смысла вылизывать state of art код, когда можно взять мк пожирней и вовсе не паритьсяFree_ze
07.03.2018 15:43увы сейчас не исключение, а правило.
Почему вы так считаете? Это же не модный веб, который можно обновлять хоть трижды в день. Нормальные производители встраиваемых систем пишут пусть и не «state of art» код, но стараются делать его качественным и поддерживаемым.
Нет смысла вылизывать state of art код, когда можно взять мк пожирней и вовсе не париться
Это крайности. Качество кода не требует от него быть супер-симпатичным. Снижение затрат на производство — одна из главных целей любого бизнеса. Если будет возможность более дешевые компоненты, то так и поступят. А китаец просто иначе не умеет.Zolg
07.03.2018 17:05Почему вы так считаете?
да так, один мой знакомый рассказывал, повидавший чутка кода производителей может и не нормальных, зато крупных и известных.
alexgubanow
07.03.2018 00:09+1глянь вот эту прошивку github.com/Ralim/ts100
bulaev
07.03.2018 13:34Всё-таки это для другого паяльника. Он крут, удобен, но жал мало и стоят очень дорого. Я пользуюсь несколькими KSGER и одним TS100.
Может и можно позаимствовать часть кода, PID там должен быть схожим. Но основное отличие в выводе на дисплей, меню и т.д.alexgubanow
07.03.2018 20:05Я всего лишь предложил автору глянуть прошивку, имхо очень качественный код, хорошо прокомментирован. Портить это прошу на TS100 нет смысла, главная фишка этого паяльника что все в ручке, в таком исполнении будет работать компенсация холодного конца.
Лично я на данный момент разрабатываю TS100+T12, т.е. берем человеческие жала и хорошую схемотехнику + прошивку, вуаля) Ручку буду печатать на 3д принтере.
dark_snow
09.03.2018 03:52Слушай, а в чем различие этих платок вообще? А то смотрю уже ревизия 2.2 есть — какую брать то в итоге стоит?
screwer Автор
09.03.2018 03:53Насколько я знаю, разработка началась в 2013 и завершилась в 2014 году. Автор уже давно потерял интерес. А все эти «версии» это уловки продавцов, я уже и 3.0 видел, причём под видом 3.0 продавалась плата от 2.0
dark_snow
09.03.2018 04:14Так а брать то какую посоветуешь сам?
screwer Автор
09.03.2018 14:342.1s, это последняя официальная. Чтобы не нарваться на подделку/перемаркировку — магазин KSGER на али. Сам у них брал. Есть уже собранные станции, в алюминиевом корпусе и с хорошим БП.
Но не ведись на просьбы написать обзор. Будут обещать золотые горы, по-факту максимум пару баксов скидки дадут.
vilkin
06.03.2018 23:50screwer, снимаю шляпу… я сдался, не смог пока сам расковырять прошивку до конца.
Вы меня вдохновили на дальнейшие исследования. Буду продолжать!
Я нашел на просторах китайского интернета пару исходников для практически такой же станции. Один на STM32 другой на STC15F2K60S2. Не знаю на сколько это опенсорс, но лежали на файлообменниках совершенно свободно. Если есть интерес пишите поделюсь.dartraiden
07.03.2018 01:57Не знаю на сколько это опенсорс, но лежали на файлообменниках совершенно свободно.
Если не указана лицензия, то код по умолчанию считается несвободным. То есть «можно только смотреть». Причём, даже не факт, что «можно смотреть». Допустим, утёкшие исходники Windows 2000 спокойно лежат на торрент-трекерах, что не делает код открытым.
HueyOne
07.03.2018 07:54-1Скажите, а в банкомате тоже так стеночку можно приподнять? (С)
Не вышел ли с вами на связь китаец?
Squoworode
06.03.2018 20:58-1Не знаю, я не силён в китайском.
Гуглопереводчик давно поддерживает как рукописный ввод, так и распознавание с камеры телефона.ilyaplot
07.03.2018 10:20На алиэкспрессе почти весь китайский текст переведен как раз таким переводчиком. Пользы от этого мало.
Squoworode
07.03.2018 21:19Но ведь есть же. Уж лучше знать, что здесь написано «паяльный свинцовый расплавленный», чем видеть
трёх танцующих осьминоговнепонятные иероглифы.
screwer Автор
09.03.2018 04:11Я только что попробовал. Получилось не очень.
Всего у станции 164 изображения иероглифов. Простое вычисление на базе адресов даёт нам искомые под индексами 1 и 3 (нумерация с нуля, смотрим первый ряд иероглифов на соотв. картинке). Вот их изображения:
Кроме того, в прошивке существует таблица перекодировки двухбайтовых кодов (UTF-8 ?) в индекс глифа. Для наших индексов коды будут 0xCBB2 0xC2CE, но переводчик их не знает, а Unicode изображение слабо похоже на графическое из прошивки (я пробовал и с перестановкой байт в коде).
Пробуйте. Может быть у вас получится лучше.
Nick_Shl
06.03.2018 21:02+1Вообще не понятно почему прошивка не отключила SWO и не включила watchdog...
screwer Автор
06.03.2018 21:11+1Это не особо бы помогло. Connect under reset всё равно позволит подключиться отладчику ещё до старта прошивки. А дальше настройку AFIO и Watchdog можно просто обойти.
LampTester
06.03.2018 21:09+1Гм. Наверное, вот где проходит та граница, которая отличает инженера (схемотехника/разработчика/программиста встроенных систем) от программиста-прикладника. :) Мне бы, например, было проще (и интереснее, очевидно же, что такие проекты делаются не только и не столько из практических соображений, сколько ради интереса) написать свою прошивку, попутно разобравшись с работой и настройкой PID и прочими занимательными вещами, имеющими отношение к физике работы станции. А кому-то интереснее колупать код до просветления. :)
Я не к тому, что кто-то лучше или хуже; я к тому, что как же интересно осознавать, что все мы такие разные. :) Так-то вообще работа проделана фундаментальная и статья получилась интересной, спасибо.dark_snow
09.03.2018 04:03Ну так объединитесь с автором — думаю совпадение ваших векторов саморазвития даст очень успешный результат)
Fullmoon
06.03.2018 22:39Увидел заголовок в RSS, не посмотрел, где опубликовано, решил, что это очередная перепрошивка TS-100 на Гиктаймсе. Всё-таки открыл — а тут такой изумительный детектив.
dec123
06.03.2018 23:04IMHO если убрать все не нужное, то можно прикрутить управление с компа.
screwer Автор
06.03.2018 23:33Можно прикрутить недорогой Bluetooth модуль навроде HC-06 (<200 руб с доставкой на aliexpress) и управлять не только с компа/ноута, но даже со смартфона. Идея подсмотрена на mysku.
dec123
07.03.2018 00:43перед тем как писать прошивку «с нуля» — настоятельно рекомендую этот материал:
www.leoniv.diod.club/projects/power/dxs-90/dxs-90.htmlscrewer Автор
07.03.2018 03:22Спасибо.
Правильно ли я понимаю, что автора подвёл некачественный конструктив самого паяльника?
Для паяльника разность температуры кончика жала и температуры датчика достигает 100°C, в таких условиях нельзя говорить ни о какой точности.
dark_snow
09.03.2018 04:09А юарт у платки только для прошивки или же он как обычный «диагностический» порт может работать? Если брать платку с нуля, только купленную.
screwer Автор
09.03.2018 15:34У контроллера выведены все 4 пина SWD от соотв. ног МК. Юарт не выведен. Аппаратных юартов у чипа 3 штуки. Ноги №2 уже заняты. Остальные не разведены — придётся паяться напрямую к ногам чипа. Это если нужен именно UART.
Выведены пины I2C-1, на эти пины в оригинале вешается оловоотсос.
sbh
07.03.2018 03:55Сколько времени потратили на все?
DekusPokus
07.03.2018 17:53Я генерацию этих ключей сделал еще в 2016 году
mysku.ru/blog/aliexpress/48118.html#comment1829638
Автор почему то решил это не упомянуть, сделав себя единственным кто это сделал.
Заняло у меня это 4 дня.
А RTOS там uCOS II.screwer Автор
07.03.2018 18:08+21. Статья не о кейгене, а о реверсе защиты. Я постарался изложить свои шаги, мысли и идеи доступным для стороннего читателя образом.
2. Я нигде не писал про «единственность». Не надо ревности.
3. Молодец что сделал. Только твой кейген был приватным. Я его не видел и им не пользовался. Делать секретные вещи для себя — личное право каждого.
4. Молодец что за 4 дня. Я не embedded разработчик, очень многие вещи видел впервые. Да и времени свободного не так много, как хотелось бы.
За инфу о RTOS спасибо.
Psychosynthesis
07.03.2018 04:58Блин, ну это очень круто конечно. Хотя лично я бы поленился и тупо купил другую плату с контроллером, ей цена рублей 300 с доставкой — если учесть что всё остальное уже собрано, было бы горааааздо проще. Но, конечно я понимаю что дело больше в спортивном интересе =)
А не расскажете ничего про такие же станции на контроллерах STC? Там, по идее, отличий минимум должно быть, разве что экран у них чаще всего обычный цифровой. Я делал обзор на своём сайте про такой паяльник, если вы знаете историю версий на STC, я б свой обзор дополнил про них. Их, полагаю, тот же человек делал?
P.S. Блок питания для такого же паяла, который тоже «народный» у меня кучу крови выпил пока заработал, я его раза три перепаивал пока оживил после заводского брака =)screwer Автор
07.03.2018 05:19я бы поленился и тупо купил другую плату с контроллером, ей цена рублей 300 с доставкой
Вы не правы. Контроллер на STM32 стоит существенно дороже. На али 2.0 версия стоит >1000, а 2.1s >1300 рублей. На тао несколько дешевле, но один контроллер оттуда везти смысла нет, экономии не будет.
А не расскажете ничего про такие же станции на контроллерах STC? Там, по идее, отличий минимум должно быть, разве что экран у них чаще всего обычный цифровой.
Отличия не просто есть, они кардинальные. Насколько я в курсе — STC построен на базе ядра 8051, это древний, как говно мамонта, 8 битный микропроцессор. STM это современный 32 битный ARM.
На STC станции стоят существенно дешевле, потому что сам и сам процессор дешевле, и спрос ниже. Функционал станций тоже сильно отличается. Насколько я знаю в STC нет калибровки жал. Впрочем я не интересовался ими, поэтому ничего интересного рассказать не смогу.
Их, полагаю, тот же человек делал?
Сомневаюсь. Китай большой.Psychosynthesis
07.03.2018 05:23Отличия не просто есть, они кардинальные. Насколько я в курсе — STC построен на базе ядра 8051, это древний, как говно мамонта, 8 битный микропроцессор. STM это современный 32 битный ARM.
Я про функциональные отличия. Их минимум, если вообще есть.
Насколько я знаю в STC нет калибровки жал.
Зависит от версии. На новых прошивках, насколько я знаю — есть. По крайней мере на моей есть.
Поэтому пока лично я, кроме дисплея, разницы вообще никакой не вижу. Если копеечный контроллер выполняет свои функции, коих в паяльнике, собственно, можно по пальцам одной руки пересчитать, то смысл использовать более навароченный?Nimnul1979
07.03.2018 14:04Скажу Вам так: «Каждый видит то, что может увидеть»… контроллер на STM32 намного лучше STC, раз Вы уже купили… тогда пользуйтесь, зачем сравниваете?
Как можно сравнить клон с оригиналом?Psychosynthesis
07.03.2018 20:29раз Вы уже купили… тогда пользуйтесь, зачем сравниваете?
Я пытаюсь разобраться в ситуации объективно.
Как можно сравнить клон с оригиналом?
Это разные изделия. Кто из них клон — ещё вопрос. Это я к тому, что изделия на STC вообще-то раньше появились, насколько я могу судить.Nimnul1979
08.03.2018 16:43Кто из них клон — ещё вопрос
Плохо Вы осведомлены о контроллерах на STC;)
Это я к тому, что изделия на STC вообще-то раньше появились, насколько я могу судить.
Вот тут опять ошибочка, почитайте китайские форумы ;)
D_EL
07.03.2018 14:04Более навороченный МК можно использовать для облегчения разработки, использования спагетти-кода — HAL.
Shtucer
07.03.2018 17:27Если копеечный контроллер выполняет свои функции, коих в паяльнике, собственно, можно по пальцам одной руки пересчитать, то смысл использовать более навароченный?
Категория "копеечный контроллер" вполне себе подходит к данной STMке. И вопрос тогда звучит так: если оба контроллера копеечные, зачем использовать более навороченный? Типа, зачем мне валенки, если я не курю?
Psychosynthesis
07.03.2018 20:31+1Встречный вопрос — если бы какой-нибудь Core2Duo (ну, просто представим, например), вместе с контроллером памяти, периферии и EEEPROM стоил бы столько же — разумно было бы его использовать в качестве контроллера для паяльника?
Я считаю всему свои задачи.screwer Автор
07.03.2018 21:22Если бы он ещё потреблял так же и имел такие же размеры — почему бы и нет?
STC тоже имеет излишнее количество ресурсов, если всё переписать на тщательно оптимизированном ассемблере, вылизав каждый байт — наверняка хватит даже древнего Z-80. С частотой 3,5мгц и 4-23ткт на команду. Без команд умножения и деления.
Надо выбирать инструмент из практических соображений, а не из % загруженности CPU работой.Psychosynthesis
08.03.2018 04:18Если бы он ещё потреблял так же и имел такие же размеры — почему бы и нет?
Гика видать издалека, это я понимаю =)
Пожалейте старину Оккама.
Shtucer
07.03.2018 23:18Ох, и любите вы выбирать по одному критерию, а выбор делать по другому.
Вопросом выше вы сравниваете "копеечный" контроллер, которых в выборе, кстати, оба. При этом, ваша же цитата: "Я про функциональные отличия. Их минимум, если вообще есть." Но при этом СТМ "более навороченный" и брать его стоит, только если вы делаете навигационный гравикомпас на космический корабль.
Я не спроста про валенки упомянул, потому что ваша логика примерно в том же стиле.
А других критериев и нет. Отвечая на вопрос про Коре2Дуо… ага, его естьсмысл взять… в качестве умного нагревательного элемента.Psychosynthesis
07.03.2018 23:32Я, честно говоря вообще не очень понимаю что вы хотите мне доказать? Вы вообще что обсуждаете? Разработку на контроллере или использование паяльной станции?
Паяльные станции на STM дороже? Дороже. Функциональность у них одинаковая? Одинаковая. Зачем мне STM?
saboteur_kiev
07.03.2018 05:23+2Где-то в соседних темах была статья о психологии китайцев. У них есть отличие — это готовность что-то делать на годы вперед. Поэтому заморочиться с защитой — вполне даже в духе стандартной китайской психологии — продукт хороший, востребованный, надо защититься и до конца жизни обеспеченный человек. Вот и заморочился.
Автору респект. Упоминание про просмотр графики спектрума в столбик — ностальжи.
CryptoPirate
07.03.2018 12:50Благодаря этой статье узнал что breakpoint по русски — точка останова :)
mr_stepik
07.03.2018 12:50Поделитесь, сколько календарного времени заняла эта история? Понятно, что автор не тратил все свое время на эту задачу, но все же?
screwer Автор
07.03.2018 14:02Примерно 2 месяца, за вычетом новогодних праздников, которые я провёл с семьёй вдали от дома и компьютеров. Работал в свободные вечера, пару раз в неделю.
SerSanRR
07.03.2018 12:50Как будто детективный роман прочитал! Агата Кристи отдыхает:) Ждем продолжения!
Dmitri-D
07.03.2018 12:50Паяльник с прошивкой, лампа с прошивкой, да что там, ЧАЙНИК с прошивкой и это уже норма
worldnomad
07.03.2018 14:36Станция заработала с более новой прошивкой. Наконец-то собрал для неё шикарную алюминиевую ручку с Tao. Спаял этой же станцией.
Можно посмотреть ручку?
x893
08.03.2018 20:19Поменял на TS100 С8 на СВ. Тоже примерно такая же проблема была с кодом. Но там ключ зашит во флэш. Немного проще конечно. Но тоже весь день пришлось повозится.
Shtucer
Это что-то из разряда микропроцессор Arduino…
Нет такого "производства". Имелась в виду STMicroelectronics
screwer Автор
Согласен. Исправил.