RFID эмулятор

Эмулятор карт EM Marine

nx7y1axfe7tmjncpeuqzbkdykew.jpeg

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

Технология RFID


t7isjiwudci0aomuaurjqk0hccy.jpeg


Внешний вид RFID-меток

RFID (англ. Radio Frequency IDentification, радиочастотная идентификация) — имеет достаточно широкий частотный диапазон и достаточно большое количество различных стандартов, которые так или иначе применимы к данной технологии. Для справки используются частоты: 135кГц, 400 кГц, 6.78МГц, 13.56МГц (карты метро и банковские карты), 27.125МГц, 40.68 МГц, 433.29 МГц, 869 МГц, 915 МГц, 2.45 ГГц, 5.8 ГГц и 24.125ГГц. Как видно частотный диапазон очень широкий.
Мы же будем говорить о самых распространённых и наименее защищённых картах частотного диапазона 125 кГц. Я разберу стандарт EM Marine 4102, так как именно с ним наиболее хорошо знаком. Однако код эмулятора позволяет работать и с другими стандартами, работающих на частоте 125 кГц.
Чтобы мы могли дальше углубиться в теорию, следует рассказать пару слов о принципе работы RFID. Отсюда и далее всё что относится к стандарту 125 кГц EM Marine, но так или иначе применяется и в других RFID решениях.

4ddpmmff69fr4-qrsbiyttybhhu.png

Считыватель, кроме того что просто читает содержимое метки, так ещё и передаёт питание в приёмник. Метка из себя представляет ПЗУ, которое питается от электромагнитного поля, и после подачи питания просто отдаёт записанную информацию.

nqyym8udkky4n4grn71lavj3s_c.png

Из этой схемы хорошо видно, как устроен передатчик и приёмник. Оба их колебательных контура настроены в резонанс и используется для передачи данных и передачи энергии, для питания пассивной метки, в роли которой выступает наша карта.
Более детально о принципе работы можно прочитать в [1]

cqx6f-9dzwk3xu-rihcqjomsh1e.jpeg


Внутренности разобранной карты

Если разобрать карту, то можно увидеть антенну в виде катушки и чип залитый компаундом, в котором находится ПЗУ и конденсатор ёмкостью 75 пФ.

Описание протокола EM4102


Прежде, чем мы пойдём дальше, давайте разберёмся со стандартом EM4102, который мы будем эмулировать. EM4102 совместимая RFID-метка содержит 64 бита памяти только для чтения. По сути — это и есть ПЗУ, то есть информация может быть считана из неё, но не может быть изменена либо записана, проще говоря этот чип единожды прошивается на заводе. Структуру памяти метки можно посмотреть на рисунке ниже.

hbk2nsubzbyknvfoe-uwztvdx0q.png

Когда метка попадает в электромагнитное поле, излучаемое считывателем RFID, она получает энергию от поля (питание) и начинает передачу данных как точно как показано на картинке выше. Первые 9 битов — это логическая единица. Эти биты используются как последовательность маркеров для обозначения начала передачи. Поскольку во всех остальных данных используется чётность, эта девятибитная последовательность единиц больше не будет встречаться ни в каком другом месте. Далее идут 10 групп по 4 бита данных и 1 бит чётности на каждую группу. Наконец, есть 4 бита контрольной суммы и последний стоповый бит, который равен нулю.
После окончания передачи, метка продолжает передавать в цикле эти данные пока на неё приходит питание. Поэтому мы на ридере наблюдаем постоянное считывание метки.
Приведу пример строки бит данных, которые передаёт метка с номером: 0×06 — номер версии, и 0×001259E3 — данные.

ifsbgzhw38cxhdjkmcwxkm9sfwq.png

Кстати, номер, напечатанный на карте можно перевести в hex-номер, который получит считыватель. Например, на карте записан номер: 116,23152

  • 116 в десятичной системе счисления — это 0×74 в шестадцатиричной;
  • 23152 в десятичной — это 0×5A70 в шестнадцатиричной;


Комбинируя их, мы получаем серийный номер карты, который нам даст считыватель: 0×00745A70.

Модуляция сигнала


Передача данных от метки до считывателя осуществляется с помощью модуляции несущего сигнала считывателя (в нашем случае несущей частоты 125 кГц). Обратите внимание, что от этой несущей частоты идёт и питание и ей же осуществляется модуляция сигнала. Для начала рассмотрим упрощённую схему взаимодействия считывателя и метки. Запомните эту картинку, мы ещё будем к ней обращаться.

4utwhjd6hjl0jqsa2c3b-upvqnu.png

Как видно у метки есть колебательный контур LC, диод, служащий для выпрямления переменного тока, конденсатор для сглаживания пульсаций (это часть питания метки), и транзистор, управляя которым мы можем модулировать сигнал. На считывателе это будет отражаться в изменении тока протекающего в катушке. Проще говоря, при попадании в поле считывателя, метка потребляет электрический ток (примерно постоянно), при передаче информации она транзистором изменяет значение потребляемого тока и таким образом считыватель может получить сигнал, измеряя потребляемую мощность.
Считыватель генерирует магнитное поле, с помощью модулятора и катушки и снимает промодулированный сигнал, затем декодирует его.

vk6eotf9d8td3ywv5ywegsdmrgk.png


Пример модуляции несущего сигнала

Если я вас окончательно не запутал, то едем дальше. Для того чтобы передать данные, нам необходимо модулировать сигнал. То есть на несущую частоту наложит биты передаваемой информации.
По стандарту RFID есть три популярных схемы модуляции:

  • Манчестер код
  • Двухфазный манчестер код
  • Кодирование фазовым сдвигом


Поскольку в стандарте EM4102 используется схема Манчестерского кодирования, то её и рассмотрим. При модуляции для EM4102 протокола длинна бита может быть 64, 32 или 16 периодов несущей частоты (125 кГц).

d26ut_yh1lnr2cr2leklav2ilqi.png

Таким образом, при данном кодировании метка будет изменять уровень передачи сигнала в середине битового периода. Переход от низкого к высокому уровню представляет состояние логической »1», а переход от высокого уровня к низкому, представляет состояние логического »0».

vrnj8sxrcrh0qhgtzaiuu0-infy.jpeg


Реальный промодулированный сигнал, снятый на катушке считывателя.

Делаем RFID-эмулятор


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

xkblbhwic2ox0oznfygvnyrtsgs.jpeg


Вот такой миниатюрный таракан, вполне может эмулировать метку

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

qzlozduwvqarmgj7-eratkdh0rq.png


Катушка индуктивности около 1 мкГн и микроконтроллер ATtiny85

Вот это дамы и господа настоящее Хакерство, когда познания устройства оборудования и кода такие, что позволяют делать вот такие решения, которые не предусмотрены стандартом и документацией! И они работают, проверенно на собственном опыте. Вот истинное значение слова хакер, а не взломщик или вор.
Забегая вперёд скажу, что данной катушки для нормальной работы недостаточно, и всё же пришлось делать нормальную антенну, повесить конденсаторы по питанию, резонансный конденсатор. Но вот для демонстрации принципов работы вполне подойдёт.
Как же это работает, хаки:

  • Катушка фактически питает микроконтроллер AVR через контакты ввода/вывода. Каждый такой контроллер имеет диоды на портах ввода/вывода, которые предотвращает повышение напряжения на этом выводе выше напряжения питания микросхемы или опускание уровня сигнала ниже уровня земли. Они используются так же для предотвращения статического пробоя, который приводит к выходу из строя микросхемы. При поднесении катушки к считывателю, в ней наводится ЭДС равная нескольким вольтам. Когда напряжение на катушке превышает напряжение питания контроллера, то часть этой энергии через эти ограничивающие диоды передаются к шине питания микросхемы. В результате получается, что микроконтроллер получает питание. А верх и низ синусоидальной волны усекается, и сигнал становится более похож на прямоугольный меандр.
  • Фильтрация питания с использованием ёмкости кристалла AVR. Обычно, когда ставят микросхему, то ставят конденсаторы по питанию, для фильтрации помех (обычно 0,1 мкФ керамику и электролит параллельно). В данном решении фильтрация осуществляется только внутренней ёмкостью шин питания в кремниевом кристалле микроконтроллера AVR. Она небольшая, но даже её достаточно для стабильного питания и работы, при питании от импульсов с частотой 125кГц!
  • Работа осуществляется при очень низком напряжении. Микроконтроллер ATtiny85 предназначен для работы при напряжении всего 2,5 В. Существует версия с расширенным диапазоном напряжений до 1,8 В. При этих напряжениях обычные тактовые генераторы AVR не работают, но этого можно избежать применив следующий хак…
  • Катушка индуктивности применяется не только для питания микросхемы, но ещё и для тактирования микроконтроллера! Выше мы говорили, что получаем прямоугольную волну, которая остаётся после того как ограничивающие диоды забрали немного энергии. Эта форма волны является входом Clock нашего микроконтроллера! И весь код работает на частоте 125 кГц, синхронно с несущей частотой считывателя RFID. Это гениально, ребята!
  • Прошивка? На таких низких скоростях микропрограммное обеспечение микросхемы больше похоже на последовательность операций ввода-вывода, выполняемых синхронно с каждым тактовым циклом несущей. Не остается много лишних циклов. В протоколе EM4102 вы потенциально можете выполнить некоторую полезную работу с 32 тактовыми циклами между каждым битом. Однако с протоколом HID вам необходимо выводить фронт FSK каждые 4 тактовых цикла. В результате прошивка на RFID-метке крайне тупая. «Исходный код» на самом деле представляет собой просто набор причудливых макросов ассемблера, которые преобразуют код метки RFID в длинную последовательность инструкций ввода-вывода.


Прежде чем мы пойдём разбирать код данного эмулятора давайте сделаем ему нормальную антенну. Мои эксперименты с текущей схемотехникой выявили её крайнюю нестабильность работы. Она работает только прям у считывателя и то не всегда. Поэтому сначала я припаял конденсатор 0,1 мкФ на ножки питания контроллера, а потом решил сделать настоящий большой колебательный контур, как в настоящей метке.

ga0ozvfi-lvukq9ffafi5lc6gko.jpeg


Первая модификация — конденсатор 0,1 мкФ по питанию

Создание антенны


Никаких хитростей в создании катушечной антенны нет, но всё же требует чтения документации и понимания физики процесса. Это не сложно, и справится даже школьник, требуется только немного терпения и усидчивости.
Собрать и настроить антенну очень просто, прямо как в картинке из [1].

wbvgnjr0ucfijuvyswm1n92qbyg.png

Для расчёта антенны надо вспомнить немного теории. Нам необходимо сделать колебательный контур, который будет настроен на частоту 125 кГц. Откроем курс Теоретических Основ Электротехники и прочитаем, что же такое колебательный контур:

Колебательный контур, электрическая цепь, содержащая катушку индуктивности и конденсатор, в которой могут возбуждаться электрические колебания.
s63rt4afkc0ibtfvswi0abchyka.jpeg


Параллельный колебательный контур

Если оставить всю математику и перейти к сути, у колебательного контура есть такой параметр, как резонансная частота, которая определяется по формуле.

$f=\frac{1}{2\pi \sqrt{LC}}$

Где f — частота колебаний, L — индуктивность катушки, C — ёмкость конденсатора.
В данном случае у нас есть фиксированный параметр — частота, а ёмкостью и индуктивностью мы можем играться. Для того чтобы рассчитать катушку, воспользуемся документом [2]. Все кто хоть как-то собираются делать антенны для RFID меток (любых частот), обязаны с ним ознакомиться!
Многие умельцы, для ридеров, так и для эмуляторов (суть не важна) делают круглые катушки. Их проще считать и изготавливать, но они имеют существенный недостаток — их линейные размеры больше карточки. Я хочу изготовить катушку индуктивности в форме прямоугольника, с линейными размерами меньше размеров стандартной карты и, чтобы результирующее устройство было размером со стандартную карту RFID. В результате выбираю размер будущей катушки индуктивности практически такой же, как стоит в настоящей метке, то есть примерно 70×40 мм. Если конденсатор выбрать 10 нФ, то индуктивность катушки (из формулы выше), должна составлять у нас 162 мкГн. Теперь смотрим в документации по расчёту прямоугольной катушки. Для намотки катушки выбрал провод сечением 0,2 мм. В результате открываем соответствующий раздел документации, и нашему взору представляется следующая славная формула.

2sxlidzz79jn7f90qf2kwfego6k.png

Как видим параметры толщины и ширины катушки у нас неизвестные и изменяемые (упираются в толщину провода 0,2 мм), но общие прикидки мне дали цифру в 42 витка. Можно было бы сделать несколько итераций, и сделать прям точный-точный расчёт, но в нашем штучном случае, и так сойдёт.
После чего, необходимо изготовить каркас 70×40 мм для намотки катушки. Его я изготовил из текстолита и на него намотал катушку.

xi9plnqlsrg1ijjxunyxucbautg.jpeg


Каркас из текстолита

x0dpiueub0rf-h0h3gunti_rigm.jpeg
zpirxbrhy4bjbhoee0bxer4puvc.jpeg


Намотка и готовая катушка

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

h2izmye-etkqsc6oa5trbqg9xk8.jpeg


Начнём подбор резонансного конденсатора

Сначала я проверил конденсатор емкостью 10 нФ, который должен быть резонансным. Но амплитуда сигнала сразу просела, по сравнению с пустой катушкой. Тогда я взял конденсатор меньшего номинала. И так перебирал конденсаторы, пока не поймал резонанс. Таким образом резонансная ёмкость конденсатора составила 3,2 нФ.

x5fkn2po9g7zw29wjs4casc3f24.jpeg


Сигнал без конденсатора, пустая катушка

qigzul1npawgpiawtc6gdd1g_4e.jpeg


Сигнал 10 нФ

udxqe9opjkjpjsjo10puubmxcbq.png


1 нФ, 2 нФ

r0msywo7s7p_saykajl0ngp4shy.png


3 нФ, 4 нФ, 2,2 нФ

z7kjo0l6rfahoeyxi2z-oupaxvi.jpeg


3,2 нФ

Видно, что пробовал разные варианты, и было ясно что максимум лежит где-то между 3 и 4 нФ и результатом стал конденсатор 3,2 нФ (состоящий из двух конденсаторов в параллели). Всё, наша катушка готова к дальнейшим опытам.
Вообще, хочу заметить, что катушку можно сделать вообще в виде дорожек на печатной плате, и при небольшой серии изделий так и стоит делать. Вот, пример такой платы, именно на 125 кГц от Alexander Guthmann. К сожалению, сайт практически умер, а автор давно не выходит на связь, так что довольствуемся только моими фото. Если кто поможет его найти, буду признателен! Не знаю что с ним случилось.

vscejq-mpuiz17timrxjqhnn6c0.jpeg

Таким образом, делать эмулятор сразу в виде печатной платы — нет никаких проблем. Думаю имея руководство [2], сможете рассчитать такое самостоятельно, раз это смог сделать четырнадцатилетний немецкий школьник.

Пробежимся по коду


Давайте кратенько пробежимся по коду, который можно посмотреть вот тут. Там пример эмуляции двух типов карт, я разберу только EM4102.

Перво-наперво, как гласит код, нам при прошивке микроконтроллера надо прошить fuse-биты в значение lfuse to 0xC0: таким образом, чтобы контроллер тактировался от внешнего генератора. Обращаю внимание, что любая перепрошивка контроллера будет сопряжена с тем, что его надо будет тактировать от внешнего источника!
Весь код основан на макросах. Напомню, что такое макросы — это программа, которая подготавливает код к компиляции. Наша программа состоит всего из нескольких ассемблеровских инструкций: rjmp, call (2 такта), nop, ldi, out и ret (все по 1 такту)! Всё, весь остальной код формируется макросами в зависимости от макроса серийного номера (дефайна). Особенность работы в том, что у нас достаточно мало тактов для нормальной работы. Попробуй успей за 32 такта сделать что-то, учитывая что инструкции перехода в контроллере AVR занимают 2 такта. Поэтому весь код генерируют макросы в зависимости от ID-карты.

#define FORMAT_IS_EM4102
#define EM4102_MFR_ID 0x12
#define EM4102_UNIQUE_ID 0x3456789A

Дефайнами задаём какой тип карты мы эмулируем и задаём ID-карты. Это главный макрос, на основании которого и формируется остальной код. И, тадам, его величество макросы.

.macro delay cycles
.if \cycles > 1
rjmp .+0
delay (\cycles - 2)
.elseif \cycles > 0
nop
delay (\cycles - 1)
.endif
.endm

Макрос задержки, принимает на вход количество тактов задержки. Достаточно очевидный рекурсивный макрос, осуществляет задержку с помощью команды nop (нет операции, 1 такт) и команды rjmp .+0 (перейти на следующую строку, 2 такта). Комбинируя эти команды между собой, можно сделать задержку нужной длинны в тактах. По сути код ничего не делает, только тратит машинное время.
Если вы ещё соображаете, то дальше я вам совсем изнасилую мозг, но код так гениален что вам придётся потерпеть.
Рекурсивный макрос кодирования манчестер-кодом.

.macro manchester bit, count=1
.if \count
manchester (\bit >> 1), (\count - 1)
.if \bit & 1
baseband_1
baseband_0
.else
baseband_0
baseband_1
.endif
.endif
.endm

.macro stop_bit
baseband_0
baseband_1_last
.endm

Собственно тут и осуществляется вся логика. Принимает на вход битовую маску и счётчик битов. Если счётчик не нуль, то вызываем ещё раз сами себя, декрементируя счётчик (рекурсивный макрос, ага). Далее в самом теле идут вызовы макросов baseband_0, baseband_1 и baseband_1_last. В зависимости от того, какой бит у нас »1» или »0», мы модулируем сигнал манчестер кода с нуля на единицу или с единицы на нуль.
Помните выше я приводил таблицу в статье, как идёт кодирование содержимого карты, где идут биты чётности, и стоп биты в конце. Так вот, наша задача теперь ID-метки закодировать этим методом, для этого у нас существуют два макроса.

#define ROW_PARITY(n) ( (((n) & 0xF) << 1) | \
(((n) ^ ((n) >> 1) ^ ((n) >> 2) ^ ((n) >> 3)) & 1) )

#define COLUMN_PARITY ((EM4102_MFR_ID >> 4) ^ \
(EM4102_MFR_ID) ^ \
(EM4102_UNIQUE_ID >> 28) ^ \
(EM4102_UNIQUE_ID >> 24) ^ \
(EM4102_UNIQUE_ID >> 20) ^ \
(EM4102_UNIQUE_ID >> 16) ^ \
(EM4102_UNIQUE_ID >> 12) ^ \
(EM4102_UNIQUE_ID >> 8) ^ \
(EM4102_UNIQUE_ID >> 4) ^ \
(EM4102_UNIQUE_ID))

ROW_PARITY — расчёт бита чётности в строке из четырёх бит, COLUMN_PARITY — расчёт контрольной суммы всей посылки.

Вся логика работы у нас описывается в макросе в .main

header
manchester ROW_PARITY(EM4102_MFR_ID >> 4), 5
manchester ROW_PARITY(EM4102_MFR_ID >> 0), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 28), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 24), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 20), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 16), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 12), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 8), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 4), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 0), 5
manchester COLUMN_PARITY, 4
stop_bit

Ну то есть, так же точно передаём заголовочные 9 бит, потом манчестер кодинг, высчитывая бит чётности для каждых 4-х бит, в конце контрольная сумма и стоп бит.
Осталось разобраться, что же такое baseband. Для этого у нас служат ещё одни макросы обёртки (да сколько можно-то, а?).

.macro baseband_0
rcall baseband30_0
rjmp .+0
.endm

.macro baseband_1
rcall baseband30_1
rjmp .+0
.endm

.macro baseband_1_last
rcall baseband30_1
rjmp main
.endm

.macro header
manchester 0×1FF, 9
.endm

Максросы baseband* — выполняют ассемблеровский код: вызывают соответствующие функции, и потом делают переход на другую команду. Макрос baseband_1_last — аналогична макросу baseband_1, кроме того что делает безусловный переход не на команду ниже, а в начало функции main. Макрос header — служит для вывода заголовка из девяти однотипных бит равных единице, и вызывает макрос манчестера с передачей числа и количества передаваемых бит.
Последнее, что осталось разобрать — это функции baseband30_0 и baseband30_1. Они описываются следующим кодом.

baseband30_0:
ldi r16, OUT_PINS // 1
rjmp baseband30 // 2

/*
* Emit a 1 at the baseband layer.
* Takes a total of 30 clock cycles, including call overhead.
*/
baseband30_1:
ldi r16, 0 // 1
rjmp baseband30 // 2

/*
* Internal routine for baseband32_0 and _1. Must use
* a total of 24 clock cycles. (32 — 1 ldi — 2 rjmp — 3 rcall)
*/
baseband30:
out _SFR_IO_ADDR (DDRB), r16 // 1
delay 19 // 19
ret // 4

В зависимости от того, какая функция вызывается baseband30_0 или baseband30_1 в регистр r16 записывается значение того что должно быть на пине ввода/вывода: 1 или 0. После этого идёт безусловный переход на baseband30 осуществляется вывод и задержка на 19 тактов, после чего идёт возврат.
Самая большая магия этого кода, что он просчитан точно до каждого такта, каждый такт передачи манчестерского кода занимает ровно столько периодов, сколько допустимо стандартом, а именно 32 такта процессора! Это фантастически гениально, надо помнить сколько тактов занимает каждая команда.
Давайте его скорее скомпилируем и посмотрим как он выглядит, как развернутся все эти макросы. Компилируем командой make (предварительно установив avr-gcc) и дизассемблируем получившийся elf-файл

00000000 __vectors:
0: 0e c0 rjmp .+28 ; 0x1e __ctors_end
2: 15 c0 rjmp .+42 ; 0x2e __bad_interrupt
...

Вначале у нас вектора прерываний, но нас интересует только первый jump. Так как остальные вектора никуда не ведут.


0000001e __ctors_end:
1e: 11 24 eor r1, r1
20: 1f be out 0x3f, r1 ; 63
22: cf e5 ldi r28, 0x5F ; 95
24: d2 e0 ldi r29, 0x02 ; 2
26: de bf out 0x3e, r29 ; 62
28: cd bf out 0x3d, r28 ; 61
2a: 02 d0 rcall .+4 ; 0x30 main
2c: 11 c1 rjmp .+546 ; 0x250 _exit

Здесь мы настраиваем порты ввода/вывода, и вызываем функцию main. A main состоит из безумного количества вызовов функций baseband30* и jump (так развернулся наша адский цирк макросов).

00000030 main:
30: 01 d1 rcall .+514 ; 0x234 baseband30_1
32: 00 c0 rjmp .+0 ; 0x34 main+0x4
34: fd d0 rcall .+506 ; 0x230 baseband30_0
36: 00 c0 rjmp .+0 ; 0x38 main+0x8
38: fd d0 rcall .+506 ; 0x234 baseband30_1
3a: 00 c0 rjmp .+0 ; 0x3c main+0xc
3c: f9 d0 rcall .+498 ; 0x230 baseband30_0
3e: 00 c0 rjmp .+0 ; 0x40 main+0x10
40: f9 d0 rcall .+498 ; 0x234 baseband30_1
42: 00 c0 rjmp .+0 ; 0x44 main+0x14
44: f5 d0 rcall .+490 ; 0x230 baseband30_0
46: 00 c0 rjmp .+0 ; 0x48 main+0x18
48: f5 d0 rcall .+490 ; 0x234 baseband30_1
4a: 00 c0 rjmp .+0 ; 0x4c main+0x1c
4c: f1 d0 rcall .+482 ; 0x230 baseband30_0
...
22e: 00 cf rjmp .-512 ; 0x30 main

И так далее… пока не джампнемся снова на main

Ну и глянем как же выглядит наш baseband модуль.

00000230 baseband30_0:
230: 08 e1 ldi r16, 0x18 ; 24
232: 02 c0 rjmp .+4 ; 0x238 baseband30

00000234 baseband30_1:
234: 00 e0 ldi r16, 0×00; 0
236: 00 c0 rjmp .+0; 0×238 baseband30

00000238 baseband30:
238: 07 bb out 0×17, r16; 23
23a: 00 c0 rjmp .+0; 0×23c baseband30+0×4
23c: 00 c0 rjmp .+0; 0×23e baseband30+0×6
23e: 00 c0 rjmp .+0; 0×240 baseband30+0×8
240: 00 c0 rjmp .+0; 0×242 baseband30+0xa
242: 00 c0 rjmp .+0; 0×244 baseband30+0xc
244: 00 c0 rjmp .+0; 0×246 baseband30+0xe
246: 00 c0 rjmp .+0; 0×248 baseband30+0×10
248: 00 c0 rjmp .+0; 0×24a baseband30+0×12
24a: 00 c0 rjmp .+0; 0×24c baseband30+0×14
24c: 00 00 nop
24e: 08 95 ret

В конце видно как delay развернулся в список jump и nop для задержки. Вот такая красивая магия.
Ну что же, с кодом разобрались. Соберите вытекший мозг с ушей, переходим к испытаниям.

Испытания


Применим все полученные знания и проведём испытания. Компилируем прошивку, прошиваем контроллер, не забывая правильно выставить Fuse-биты.

zsaq2qcpblojaz3ykgnhddl3uuo.jpeg


Платка для прошивки

Подключаем наш колебательный контур и тестируем на настоящем промышленном считывателе, никаких полумер, честные боевые условия.

1gp8fypt7hfk0-1cohn2xcn03vu.jpeg


Испытательный стенд

И, о чудо! Оно работает, корректно считывается и в цикле даёт корректный ID! Без внешнего питания, с работой только от поля. Осталось всё это привести в порядок и сделать настоящую RFID-метку.

fogej2u1nbcbhf0xucrbedd1xlw.jpeg


Окончательный «заламинированный» вариант метки

Итого


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

Домашнее задание


Раз вы всё-таки прочитали эту крутую статью, я её писал, старался, делал, теперь пора и вам что-то попробовать сделать. В коде эмулятора есть раздел, который эмулирует карты стандарта HID Proximity, с кодированием фазовым сдвигом. Вам в качестве развлечения и лучшего усвоения материала следует разобраться со стандартом HID и этим кодированием. Решение присылайте в комментарии. Удачи.

Список литературы


  1. AppNote 411 RFID Made Easy
  2. AN710 Antenna Circuit Design for RFID Applications
  3. При подготовке статьи использованы материалы сайта priority1design.com


oug5kh6sjydt9llengsiebnp40w.png

© Habrahabr.ru