RfidResearchGroup / ChameleonUltra

The new generation chameleon based on NRF52840 makes the performance of card emulation more stable. And gave the chameleon the ability to read, write, and decrypt cards.
https://chameleonultra.com
GNU General Public License v3.0
922 stars 153 forks source link

unstable EM4100 emulation #25

Closed doegox closed 1 year ago

doegox commented 1 year ago

I'm doing some tests with a Proxmark

Some IDs cannot be seen by the Proxmark while some can. OK: lf em sim --id 0501020304 FAIL: lf em sim --id 0102030405

When digging, it appears the problem comes from the moment emulation stops and LF field is checked before starting again. Maybe this takes too long and next broadcast is desync.

I found that it works fine by removing the following lines, I hope it is safe to do so...

             // 如果广播次数超过上限次数,则重新比较场状态,根据新的场状态选择是否继续模拟标签
             if (m_send_id_count >= LF_125KHZ_BORADCAST_MAX) {
                 m_send_id_count = 0;                                        // 广播次数达到上限,重新识别场状态并且重新统计广播次数
-                ANT_NO_MOD();                                               // 确保天线不短路而导致无法获得RSSI状态
-                nrfx_timer_disable(&m_timer_send_id);                       // 关闭广播场的定时器
-
-                // 我们不需要任何的事件,仅仅需要检测一下场的状态
-                NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk | LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk;
                 if (lf_is_field_exists()) {
                     nrf_drv_lpcomp_disable();
-                    nrfx_timer_enable(&m_timer_send_id);                    // 打开广播场的定时器,继续模拟
-                    m_is_send_reboardcast_last_edge = true;                 // 如果继续的话需要发送0的后一个沿
                 } else {
+                    nrfx_timer_disable(&m_timer_send_id);                       // 关闭广播场的定时器
                     // 开启事件中断,让下次场事件可以正常出入
                     g_is_tag_emulating = false;                             // 重设模拟中的标志位
                     m_is_lf_emulating = false;

And all code related to m_is_send_reboardcast_last_edge can then be removed also.

xianglin1998 commented 1 year ago

m_is_send_reboardcast_last_edge flag is another solution added by another enthusiast to solve the problem of PM3 being unable to search for ID cards, interesting...

xianglin1998 commented 1 year ago

The code you deleted is used to detect whether the chameleon has left the RF field. If it has already left, quickly turn off the simulation and switch the field lights. The significance of this code is to solve the problem where LPCOMP can only trigger on the rising edge.

doegox commented 1 year ago

Ok I see, I did some more tests and we can still disable the timer and configure LPCOMP. What's really the cause of the issue is the ANT_NO_MOD(). I will create a PR to remove the m_is_send_reboardcast_last_edge hack and the ANT_NO_MOD. I tested many different IDs and it seems robust.

xianglin1998 commented 1 year ago

Good!!! When I have time, I will help you test the simulation of the EM card.

ShigemoriHakura commented 1 year ago

The note of ANT_NO_MOD writes "make sure antenna is shorted so we can get correct rssi status" so I think it's not right to remove that line ... and two no mod can make sure the last bit is 0. and as the em data is stored in u64 which is not hardcoded, i think we should not assume the last bit is what you said "so detection will always be done when ant mod is off, "

doegox commented 1 year ago

yes this is what I discussed in https://github.com/RfidResearchGroup/ChameleonUltra/pull/27 I did a new PR to change the strategy : https://github.com/RfidResearchGroup/ChameleonUltra/pull/28

It doesn't inject a ANT_NO_MOD (that breaks the emulation) but it samples the field during the half bit when mod is off. I tested it even with #define LF_125KHZ_BORADCAST_MAX 1 to force sampling after every single ID and it's very stable.

xianglin1998 commented 1 year ago

Nice😍

doegox commented 1 year ago

ok let's close this one