Пример #1
0
        private async Task HandleCard(SmartCard card)
        {
            try
            {
                connection = await card.ConnectAsync();
                IccDetection cardIdentification = new IccDetection(card, connection);
                await cardIdentification.DetectCardTypeAync();
                LogMessage("Connected to card\r\nPC/SC device class: " + cardIdentification.PcscDeviceClass.ToString());
                LogMessage("Card name: " + cardIdentification.PcscCardName.ToString());
                LogMessage("ATR: " + BitConverter.ToString(cardIdentification.Atr));

                if ((cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass) &&
                    (cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightC
                    || cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralight
                    || cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightEV1))
                {
                    MifareUltralight.AccessHandler mifareULAccess = new MifareUltralight.AccessHandler(connection);
                    
                    byte[] responseUid = await mifareULAccess.GetUidAsync();
                    LogMessage("UID:  " + BitConverter.ToString(responseUid));
                    if (!BinaryDump && !ByteArrayEqual(responseUid, AmiiboUID)) //I used this because for some reasons responseUid == AmiiboUID was always false
                    {
                        MessageDialog dialog = new MessageDialog("The dump UID and the amiibo UID don't match");
                        LogMessage("Amiibo UID: " + BitConverter.ToString(responseUid) + " != Dump UID: " + BitConverter.ToString(AmiiboUID));
                        await dialog.ShowAsync();
                        return;
                    }
                    LogMessage("Using key: " + BitConverter.ToString(AmiiboPass));
                    byte[] Authresponse = await mifareULAccess.TransparentExchangeAsync(new byte[] { 0x1B, AmiiboPass[0], AmiiboPass[1], AmiiboPass[2], AmiiboPass[3] }); //PWD_AUTH
                    LogMessage("Auth sent !");
                    LogMessage("Auth Response length: " + Authresponse.Length.ToString());
                    if (Authresponse.Length == 0)
                    {
                        LogMessage("No response from Amiibo, can't restore dump !");
                        MessageDialog dlg = new MessageDialog("No response from Amiibo, wrong password ?");
                        await dlg.ShowAsync();
                        return;
                    }
                    LogMessage("Auth response: " + BitConverter.ToString(Authresponse));
                    //Using page layout from: https://www.3dbrew.org/wiki/Amiibo#Page_layout
                    #region WritePages
                    mifareULAccess.WriteAsync(0x4, getNBytes(AmiiboDump,0x10));
                    LogMessage("Page 0x4 wrote !");
                    mifareULAccess.WriteAsync(0x5, getNBytes(AmiiboDump, 0x14));
                    LogMessage("Page 0x5 wrote !");
                    mifareULAccess.WriteAsync(0x6, getNBytes(AmiiboDump, 0x18));
                    LogMessage("Page 0x6 wrote !");
                    mifareULAccess.WriteAsync(0x7, getNBytes(AmiiboDump, 0x1C));
                    LogMessage("Page 0x7 wrote !");
                    mifareULAccess.WriteAsync(0x8, getNBytes(AmiiboDump, 0x20));
                    LogMessage("Page 0x8 wrote !");
                    mifareULAccess.WriteAsync(0x9, getNBytes(AmiiboDump, 0x24));
                    LogMessage("Page 0x9 wrote !");
                    mifareULAccess.WriteAsync(0xA, getNBytes(AmiiboDump, 0x28));
                    LogMessage("Page 0xA wrote !");
                    mifareULAccess.WriteAsync(0xB, getNBytes(AmiiboDump, 0x2C));
                    LogMessage("Page 0xB wrote !");
                    mifareULAccess.WriteAsync(0xC, getNBytes(AmiiboDump, 0x30));
                    LogMessage("Page 0xC wrote !");
                    mifareULAccess.WriteAsync(0x20, getNBytes(AmiiboDump, 0x80));
                    LogMessage("Page 0x20 wrote !");
                    mifareULAccess.WriteAsync(0x21, getNBytes(AmiiboDump, 0x84));
                    LogMessage("Page 0x21 wrote !");
                    mifareULAccess.WriteAsync(0x22, getNBytes(AmiiboDump, 0x88));
                    LogMessage("Page 0x22 wrote !");
                    mifareULAccess.WriteAsync(0x23, getNBytes(AmiiboDump, 0x8C));
                    LogMessage("Page 0x23 wrote !");
                    mifareULAccess.WriteAsync(0x24, getNBytes(AmiiboDump, 0x90));
                    LogMessage("Page 0x24 wrote !");
                    mifareULAccess.WriteAsync(0x25, getNBytes(AmiiboDump, 0x94));
                    LogMessage("Page 0x25 wrote !");
                    mifareULAccess.WriteAsync(0x26, getNBytes(AmiiboDump, 0x98));
                    LogMessage("Page 0x26 wrote !");
                    mifareULAccess.WriteAsync(0x27, getNBytes(AmiiboDump, 0x9c));
                    LogMessage("Page 0x27 wrote !");//Until here i manually wrote the write addreses to test if the writing works, but i'm too lazy to replace those arleady working functions with a cycle
                    for (int i = 0; i < 0x5A; i++) mifareULAccess.WriteAsync((byte)(0x28/*Page*/ + i), getNBytes(AmiiboDump, 0xA0 /*ADDR of page 0x28*/ + (i*4)));
                    LogMessage("Page 0x28 to 0x81 wrote !");
                    #endregion
                    LogMessage("Dump restored :) !");
                    MessageDialog msg = new MessageDialog("Dump restored !");
                    await msg.ShowAsync();
                }
                else
                {
                    LogMessage("This tag is not an Amiibo !");
                    MessageDialog msg = new MessageDialog("This tag is not an Amiibo !");
                    await msg.ShowAsync();
                    var apduRes = await connection.TransceiveAsync(new Pcsc.GetUid());
                    if (!apduRes.Succeeded)
                    {
                        LogMessage("Failure getting UID of card, " + apduRes.ToString());
                    }
                    else
                    {
                        LogMessage("UID:  " + BitConverter.ToString(apduRes.ResponseData));
                    }
                }
                connection.Dispose();
            }
            catch (Exception ex)
            {
                connection.Dispose();
                LogMessage("Exception handling card: " + ex.ToString());
                MessageDialog msg = new MessageDialog("Exception handling card: " + ex.ToString());
                await msg.ShowAsync();
            }
        }