Example #1
0
        private async void HandleWiteTag(INFCMiFareTag nMifareTag)
        {
            byte[] data = await Read4Pages(nMifareTag, 0);

            // write
            if (data != null)
            {
                byte[] FirstTag = MainTabViewModel.Current?.DataBag.GetData();
                byte[] mem      = new byte[80];
                data.CopyTo(mem, 0);
                byte[] dstData = MainTabViewModel.MergeTagData(FirstTag, mem);

                bool result = true;
                for (byte i = 4; result && (i < 16); i++)
                {
                    result = await WritePage(nMifareTag, i, dstData.Skip(4 * i).Take(4).ToArray());
                }

                if (result)
                {
                    MainTabViewModel.Current?.DataBag.SetData(dstData);
                }
            }

            MainTabViewModel.Current.cbNFCRead  = false;
            MainTabViewModel.Current.cbNFCWrite = false;
        }
Example #2
0
        private async void HandleReadTag(INFCMiFareTag nMifareTag)
        {
            byte[] FirstTag = MainTabViewModel.Current?.DataBag.GetData();
            byte[] data     = await Read4Pages(nMifareTag, 4);

            if (data != null)
            {
                data.CopyTo(FirstTag, 16);
                data = await Read4Pages(nMifareTag, 8);

                if (data != null)
                {
                    data.CopyTo(FirstTag, 32);
                    data = await Read4Pages(nMifareTag, 12);

                    if (data != null)
                    {
                        data.CopyTo(FirstTag, 48);
                        MainThread.BeginInvokeOnMainThread(() => MainTabViewModel.Current?.SetControlsVisibility(FirstTag[41]));
                        MainTabViewModel.Current?.DataBag.SetData(FirstTag);
                    }
                }
            }

            MainTabViewModel.Current.cbNFCRead  = false;
            MainTabViewModel.Current.cbNFCWrite = false;
        }
Example #3
0
        public static async Task <byte[]> DoFastRead(
            this INFCMiFareTag tag,
            byte from,
            byte to,
            byte batchSize)
        {
            var results = new List <MifareCommandResult>();

            while (from < to)
            {
                var thisTo = (byte)Math.Min(from + batchSize, to);
                var data   = await tag.SendMifareCommand(0x3a, from, thisTo);

                results.Add(data);

                from = (byte)(from + (byte)(batchSize + 0x1));
            }

            if (results.Any(x => x.Error != null))
            {
                throw new Exception($"Failed to fast read; first error: {results.First(x => x.Error != null).Error}");
            }

            var all = MifareCommandResult.Combine(results);

            return(all.Data);
        }
Example #4
0
        public Task <bool> WritePage(INFCMiFareTag tag, byte page, byte [] data)
        {
            var tcs = new TaskCompletionSource <bool>();

            tag.SendMiFareCommand(NSData.FromArray(new byte[] { 0xA2, page, data[0], data[1], data[2], data[3] }),
                                  (tagdata, error) => tcs.SetResult((tagdata != null) && (error == null) && (tagdata.Count() == 1)));
            return(tcs.Task);
        }
Example #5
0
        public static Task <MifareCommandResult> SendMifareCommand(
            this INFCMiFareTag tag, params byte[] command)
        {
            var tcs = new TaskCompletionSource <MifareCommandResult>();

            tag.SendMiFareCommand(
                NSData.FromArray(command),
                (data, err) => tcs.SetResult(MifareCommandResult.From(data, err)));

            return(tcs.Task);
        }
Example #6
0
        public static async Task <byte[]> WritePage(
            this INFCMiFareTag tag,
            byte page,
            byte[] data)
        {
            var cmd = new byte[] { 0xa2, (byte)(page) }.Concat(data).ToArray();
            var result = await tag.SendMifareCommand(cmd);

            if (result.Error != null)
            {
                Debug.WriteLine(result.Error);
            }

            return(result.Data);
        }
Example #7
0
        public Task <byte[]> Read4Pages(INFCMiFareTag tag, byte page)
        {
            var tcs = new TaskCompletionSource <byte[]>();

            tag.SendMiFareCommand(NSData.FromArray(new byte[] { 0x30, page }), (data, error) =>
            {
                if ((data != null) && (error == null) && (data.Count() == 16))
                {
                    tcs.SetResult(data.ToArray());
                }
                else
                {
                    tcs.SetResult(null);
                }
            });
            return(tcs.Task);
        }
Example #8
0
        public async Task WriteAmiibo(NFCTagReaderSession session, INFCMiFareTag tag, DetectedAmiibo amiibo)
        {
            var dynamicLockBytes = new byte[] { 0x01, 0x00, 0x0F, 0xBD };
            var staticLockBytes  = new byte[] { 0x0F, 0xE0, 0x0F, 0xE0 };

            var dump = amiibo.TagData;

            // this is ille🚨al so i took it out, but the flow is:
            // 1. make a copy of the tag dump
            // 2. decrypt the encrypted part of the tag dump using the original tag uid and secret nintendo key material
            // 3. reencrypt the now decrypted parts of the tag dump using the uid of the target tag and secret nintendo key material
            // 4. write the tag dump (not the lock bits) to the tag
            // 5. write the dynamic lock bits to 0x82
            // 6. write the static lock bits to 0x2
            // 7. draw the amiibo on the card for good luck

            // check https://www.3dbrew.org/wiki/Amiibo for amiibo data structure
            // check https://github.com/AcK77/AmiiBomb-uino for a good cloning reference

            await Task.Yield();

            session.AlertMessage = "Various implementation details removed and left to the reader (check the source).";
        }