Jun 16, 2013

Detecting NFC Tag removal hacking

By
Using NFC to launch actions or perform certain tasks when you tap your device on a tag is a pretty cool thing. In fact, it’s hardly something new, as we’ve even covered a few tools that let you do so easily. These past uses, however, rely on tapping a tag to perform an action. Wouldn’t it be useful for other use-cases if you could activate a task when removing a tag from your device? Just think; this could allow you to do things such as setting up an NFC-based alarm or both activating and removing settings changes when a tag is touched.

Similarly to the previously linked article, this functionality is accomplished using AnyTAG NFC.  However, it is actually a modified version of AnyTAG that is used in this guide, and a few modifications are made to your device’s NFC.apk to add in the android.nfc.action.TAG_LOST intent and enable tag removal detection functionality.

What this mod can do?
after did this mod, with AnyTag(mod) + tasker + secure settings plugin + secure settings helper, you can:
1. put your phone on the "Bedside tag", your phone turn to silence mod, take the phone off the tag, your phone auto turn off silence mod
2. put your phone on the "CarDock tag", your phone auto unlock, turn to CarHome mode, run some special apps, take the phone off the tag, your phone auto kill some special apps, exit carhome mode, lock screen ...
3. Other things you can image....

How to use tasker to auto unlock your phone and run some apps?
tasker + secure settings plugin + secure settings helper
Create task, add actions:
1. Secure Settings, Screen & Keyboard Lights On 5 seconds
2. Wait 60ms
3. Secure Settins, Keyguard Enabled
4. Wait 100ms
5. Secure Settings, Keyguard Disabled/BG
6. run apps ....
7. do things you want ...
8. Secure Settings, Screen & Keyboard Light On 10 Seconds
...
..

How to do that
1. Download the mod AnyTag.apk from attachments. Install it.
2. Download the mod Nfc.apk (device dependence) from attachments, copy it to /system/app/Nfc.apk, reboot

download modified anytag.apk: AnyTAG1.2.6-mod.apk

download modified Nfc.apk:
AOKP ROMs
Galaxy Nexus 4.1.2 AOKP: Nfc.apk
Galaxy Nexus 4.2.1 AOKP: Nfc4.2.1-mod-originSign.apk
Galaxy Nexus 4.2.2 AOKP: Nfc4.2.2-mod.apk

InsertCoin
HOX InsertCoinV17 4.1.1(not test): Nfc-HOX-InsertCoinV17-4.1.1.apk

Stock ROMs
Galaxy Nexus 4.2.1 (thanks for LoveNFC): Nfc-mod-combine-GN4.2.1.apk
Galaxy Nexus 4.2.1 Tag lost with no sound: Nfc-mod-combine-GN4.2.1 -TagLostMute.apk 
Galaxy Nexus 4.2.2 : Nfc-GN-stock422-combine-mod.apk
Google Nexus4 4.2.2 (thanks for LoveNFC): NfcNci-mod-combine-N4-4.2.2.apk
Google Nexus4 4.2.2 Tag lost with no sound: NfcNci-mod-combine-N4-4.2.2 - TagLostMute.apk
Galaxy Note2 N719 4.1.1 : Nfc-Note2-4.1.1(N719).apk
Galaxy Note2 N7100 4.1.2 : NfcNote2-7100 4.1.2 - mod.apk
Galaxy Note2 Sprint 4.1.2 : Nfc-Sprint-note2-4.1.2-mod.apk
Galaxy Note2 LTE(N7105 XXDMB2) 4.1.2 : Nfc-Note2LTE-N7105XXDMB2-4.1.2-mod.apk
Galaxy S3 i747 4.1.1 (thanks for klau1): Nfc-mod-combine.apk
Galaxy S3 4.1.2 (tested by fruitloopy) : Nfc-GS3-4.1.2-mod.apk

Others
4.1.2-N7100UBDMB1-CRISKELO-v14--->same as----
---->AmnoSferum_9.0.1_Mescaline_XXDMD2: Nfc-N7100UBDMB1-CRISKELO-v14-mod.apk

3. Download tasker, Secure settings plugin for tasker, Secure Settings Helper

Video demo

"Bedside Tag": http://youtu.be/_c9Lo-jwErg
galaxy note2(china telecom N719): http://youtu.be/UlbxGoGjysI
TouchStone& "Carmode Tag": http://youtu.be/zeJZ_Cy7_mM
ES Ftp Tag with PC react: http://www.youtube.com/watch?v=_1oN2vmHwtY 

Mod Details:

1. mod nfc.apk(mod android source code and rebuild), when tag lost, broadcast intent with action "android.nfc.action.TAG_LOST"



2. mod AnyTag NFC Launcher apk, play a trick with TagId, when intent action is "TAG_LOST", Tagid=Tagid + "_TAG_LOST", otherwise, Tagid = Tagid + "_TAG_DISCOVERED"


===================mod nfc.apk======================
--------------DeviceHost.java
find: public interface DeviceHostListener {
add: public void onTagLost(TagEndpoint tag);

find: public interface TagEndpoint {
add: public void SetTagLostCallBack(DeviceHost host);

find: String dump();
add: public void notifyTagLost(TagEndpoint tag);

--------------NfcService.java:
find: static final int MSG_SE_MIFARE_ACCESS = 12;
add: static final int MSG_TAG_LOST = 13;

find: Context mContext;
add: private DeviceHost mDeviceHost;

find: public void onSeMifareAccess(byte[] block) { ... }
add: 
public void onTagLost(TagEndpoint tag) {
sendMessage(NfcService.MSG_TAG_LOST, tag);
}

find: TagEndpoint tag = (TagEndpoint) msg.obj;
add: tag.SetTagLostCallBack(mDeviceHost);

find: case MSG_NDEF_TAG: ... break;
add: case MSG_TAG_LOST:
if (DBG) Log.d(TAG, "Tag lost message");
TagEndpoint tagLost = (TagEndpoint) msg.obj;
dispatchTagEndpointLost(tagLost);

break;

find: private void dispatchTagEndpoint(TagEndpoint tagEndpoint) { ... }
add: private void dispatchTagEndpointLost(TagEndpoint tagEndpoint) {
Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(),
tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), mNfcTagService);

mNfcDispatcher.dispatchTagLost(tag);
playSound(SOUND_END);
}

--------------NativeNfcTag.java
find: import com.android.nfc.DeviceHost.TagEndpoint;
add: import com.android.nfc.DeviceHost;

find: static final int STATUS_CODE_TARGET_LOST = 146;
add: private DeviceHost mHost;

find: private PresenceCheckWatchdog mWatchdog;
add: private synchronized void doTagLost() {
mHost.notifyTagLost(this); 
}


public synchronized void SetTagLostCallBack(DeviceHost host) {
mHost = host;
}

find: // Restart the polling loop
add: doTagLost();

--------------NativeNfcManager.java
find: private void notifySeMifareAccess(byte[] block) { ... }
add: 
public void notifyTagLost(TagEndpoint tag) {
mListener.onTagLost(tag);
}


----------NfcDispatcher.java
find: public Intent setTagIntent() { ... }
add: public Intent setTagLostIntent() {
intent.setData(null);
intent.setType(null);
intent.setAction("android.nfc.action.TAG_LOST");
return intent;
}

find: public boolean dispatchTag(Tag tag) { ... }
add: public boolean dispatchTagLost(Tag tag) {
DispatchInfo dispatch = new DispatchInfo(mContext, tag, null);

resumeAppSwitches();

dispatch.setTagLostIntent();
if (dispatch.tryStartActivity()) {
if (DBG) Log.i(TAG, "matched TAG");
return true;
}

if (DBG) Log.i(TAG, "no match");
return false;
}

===================mod anytag.apk======================
1. apktool.bat d anytag.apk anytag
2. mod Androidmanifest.xml, MainActivity.smali, TagReceiver.smali
3. apktool.bat b anytag
4. java -jar signapk.jar testkey.x509.pem testkey.pk8 anytag.apk com.anytag.android-1.apk
5. copy com.anytag.android-1.apk to phone: /data/app, change permission to rw-r--r--
6. reboot phone

-------------Androidmanifest.xml
find:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
add:
<intent-filter>
<action android:name="android.nfc.action.TAG_LOST" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_LOST" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

-------------MainActivity.smali
find:
.method resolveIntent(Landroid/content/IntentV
....
....

.line 160
.local v0, action:Ljava/lang/String;
const-string v4, "android.nfc.action.TAG_DISCOVERED"

invoke-virtual {v4, v0}, Ljava/lang/String;->equals(Ljava/lang/ObjectZ

move-result v4
add:
# qlg added 2013-01-31------------------------------------------------
# if ("android.nfc.action.TAG_DISCOVERED".equals(paramI ntent.getAction()) or 
# "android.nfc.action.TAG_LOST".equals(paramIntent.g etAction()))

if-nez v4, :cond_2

const-string v4, "android.nfc.action.TAG_LOST"

invoke-virtual {v4, v0}, Ljava/lang/String;->equals(Ljava/lang/ObjectZ

move-result v4
# -------------------------------------------------------qlg added end

find:
if-eqz v4, :cond_1
add:
:cond_2

find:
.line 161
add:
#qlg added begin -------------------------------------------------------------
#
#if intent.action = "android.nfc.action.TAG_LOST" then 
# v0 = tagid + "_TAG_LOST"
#else
# v0 = tagid + "_TAG_DISCOVER"
#
const-string v1, "android.nfc.extra.ID"

invoke-virtual {p1, v1}, Landroid/content/Intent;->getByteArrayExtra(Ljava/lang/String[B

move-result-object v2

invoke-static {v2}, Lcom/anytag/android/TagReceiver;->ByteArrayToHexString([B)Ljava/lang/String;

move-result-object v1

const-string v4, "android.nfc.action.TAG_LOST"

invoke-virtual {v4, v0}, Ljava/lang/String;->equals(Ljava/lang/ObjectZ

move-result v4

if-nez v4, :ActionTagLost

const-string v0, "_TAG_DISCOVERED"

goto :TagIdTrick

:ActionTagLost

const-string v0, "_TAG_LOST"

:TagIdTrick
new-instance v2, Ljava/lang/StringBuilder;

invoke-static {v1}, Ljava/lang/String;->valueOf(Ljava/lang/ObjectLjava/lang/String;

move-result-object v3

invoke-direct {v2, v3}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/StringV

invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/StringLjava/lang/StringBuilder;

move-result-object v2

invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v0

#--------------------------------------------------------------------qlg add end

comment:
#const-string v4, "android.nfc.extra.ID"

#invoke-virtual {p1, v4}, Landroid/content/Intent;->getByteArrayExtra(Ljava/lang/String[B

#move-result-object v3

#.line 163
#.local v3, tagId:[B

find:
.line 164
.local v1, db:Lcom/anytag/android/database/DatabaseHandler;
comment:
#invoke-static {v3}, Lcom/anytag/android/TagReceiver;->ByteArrayToHexString([B)Ljava/lang/String;
#move-result-object v4
#invoke-virtual {v1, v4}, Lcom/anytag/android/database/DatabaseHandler;->getTag(Ljava/lang/StringLcom/anytag/android/object/Tag;
add:
invoke-virtual {v1, v0}, Lcom/anytag/android/database/DatabaseHandler;->getTag(Ljava/lang/StringLcom/anytag/android/object/Tag;

find:
.line 167
new-instance v4, Lcom/anytag/android/object/Tag;
comment:
#invoke-static {v3}, Lcom/anytag/android/TagReceiver;->ByteArrayToHexString([B)Ljava/lang/String;
#move-result-object v5

find:
const-string v6, "no name"
comment:
#invoke-direct {v4, v5, v6}, Lcom/anytag/android/object/Tag;-><init>(Ljava/lang/String;Ljava/lang/StringV
add:
invoke-direct {v4, v0, v6}, Lcom/anytag/android/object/Tag;-><init>(Ljava/lang/String;Ljava/lang/StringV


---------------TagReceiver.smali
find:
.method resolveIntent(Landroid/content/IntentV
...
...
.line 39

add:
#qlg added 2013-01-31---------------------------------------------------------------
#
#if intent.action = "android.nfc.action.TAG_LOST" then 
# v0 = tagid + "_TAG_LOST"
#else
# v0 = tagid + "_TAG_DISCOVERED"
#
invoke-virtual {p1}, Landroid/content/Intent;->getAction()Ljava/lang/String;

move-result-object v0

const-string v1, "android.nfc.extra.ID"

invoke-virtual {p1, v1}, Landroid/content/Intent;->getByteArrayExtra(Ljava/lang/String[B

move-result-object v2

invoke-static {v2}, Lcom/anytag/android/TagReceiver;->ByteArrayToHexString([B)Ljava/lang/String;

move-result-object v1

const-string v4, "android.nfc.action.TAG_LOST"

invoke-virtual {v4, v0}, Ljava/lang/String;->equals(Ljava/lang/ObjectZ

move-result v4

if-nez v4, :ActionTagLost

const-string v0, "_TAG_DISCOVERED"

goto :TagIdTrick

:ActionTagLost

const-string v0, "_TAG_LOST"

:TagIdTrick
new-instance v2, Ljava/lang/StringBuilder;

invoke-static {v1}, Ljava/lang/String;->valueOf(Ljava/lang/ObjectLjava/lang/String;

move-result-object v3

invoke-direct {v2, v3}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/StringV

invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/StringLjava/lang/StringBuilder;

move-result-object v2

invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v0

#--------------------------------------------------------------------qlg add end


find:
.line 46
comment:
#const-string v9, "android.nfc.extra.ID"
#invoke-virtual {p1, v9}, Landroid/content/Intent;->getByteArrayExtra(Ljava/lang/String
#move-result-object v8

#.local v8, tagId:[B

find:
.line 48
.local v1, db:Lcom/anytag/android/database/DatabaseHandler;
comment:
#invoke-static {v8}, Lcom/anytag/android/TagReceiver;->ByteArrayToHexString([B)Ljava/lang/String;
#move-result-object v9
#invoke-virtual {v1, v9}, Lcom/anytag/android/database/DatabaseHandler;->getTag(Ljava/lang/StringLcom/anytag/android/object/Tag;
add:
invoke-virtual {v1, v0}, Lcom/anytag/android/database/DatabaseHandler;->getTag(Ljava/lang/StringLcom/anytag/android/object/Tag;

find:
.line 51
new-instance v9, Lcom/anytag/android/object/Tag;
comment:
#invoke-static {v8}, Lcom/anytag/android/TagReceiver;->ByteArrayToHexString([B)Ljava/lang/String;
#move-result-object v10

#invoke-direct {v9, v10, v11}, Lcom/anytag/android/object/Tag;-><init>(Ljava/lang/String;Ljava/lang/String
add:
invoke-direct {v9, v0, v11}, Lcom/anytag/android/object/Tag;-><init>(Ljava/lang/String;Ljava/lang/String

(via xda)

0 comments:

Post a Comment

Back to Top