ZINC :zinc: Android NFC cyborg multitool development

Just fixed that. It indeed works this way, I was stupidly discarding the extra block I was receiving.

Well it’s an out of range because I’m trying to put > 127 into a signed byte by turning my decimal iterator into a byte. So I guess the tag reads the byte as unsigned with a max of 255 rather than 127 which makes a lot more sense.

Edit: Did a whole lot of conversion bug fixing and I’m now getting 136 blocks which sounds correct…

1 Like

Still a bit empty but definitely coming together


You need to make the settings button brighter and the borders of the buttons in the menu darker. Otherwise, it’s a great interface!

1 Like

I did that and you’re right it looks better :pray:

So today I’m kinda tired of NFC so let’s explore magnets a bit.
I added a feature called the Haptic Lab where the magnet measurmet and stimulation tools will live.
I started off with a simple teslameter allowing you to compare your magnets’ strength. Eventually, when the profile and personal data will be setup I will have a way to log these measurements :grin:
Next step is to add a powerful signal generator tool to this section which I conveniently have already coded for my previous attempt at a biomagnet app :ok_hand:
It will allow you to use your phone + a little usb accessory to stimulate your implant at various frequencies and signal. You’ll be able to explore the full spectrum of sensitivity with the convenience of an app !
Anyway here is the feature’s landing page

The slider defines a rolling average filter size for the sensor raw data. May or may not remove it…


The signal generator to tingle your titans is in. I’m happy with how simple the UI is despite having a lot of options. Of course it will probably change, this is a draft


Did that today. I feel like they totally could have coded the actual memory size in there instead of that power of two mess avoiding the need for a lookup table though :expressionless:
But hey, as much as I hate hardcoding things, this is actually helpful. Now to try the fast read


So what exactly is in the mysterious black hole at the end of sector 0 of the XSIID’s memory?

Tag reader just skips blocks between 231 to 256 (E7-100).
By brute forcing with my app I fail after bloc 239 (EF).

The doc says EA-EB as well as EE-FF are invalid and return NAK which is inconsistent the previous statements.

I assume I fail after EF because EE and EF were read with a command involving EC as an address which is fine and the next would be F0 which is not fine anymore.
And EE and EF are filled with 0’s because that’s the NAK…
EA and EB probably pass under the radar for the same reason.

Sorry for the rambling, I kinda figured it out as I was writing. I guess now my question is how do I explore sector 1 of the 2k I2C? How do I specify the sector I’m reading? The read address only takes a single byte for the address.

Edit: Also is the best way to approach this to hard code the memory layout for every single chip and go straight through the accessible parts with a fast read or is it possible to do something more flexible where I explore the entire memory? Checking if it’s readable or not iteratively ? I can’t imagine the first option being the reasonable one

Edit: ok I found SECTOR_SELECT… Still confused as to how I can tell if a block is blocked and just spits filler 0s or if it actually empty

Can I just say, I really love this project.
Thanks for your time and effort giving back to the community and bringing us along for the ride.

I started making one ages ago, but i didn’t know what I was doing, pretty shitty and rudimentary, but here if you want to have a look

@hoker also shared his code on Github for Biocom App.

Not sure if theres anything in there that may help you or save time

but heres the link


Thank you !!!

Me neither :joy: for the nfc part I learn as I go

Cool! His app was an inspiration to start this


I did figure it out but it involves checking each block one by one, not taking advantage of the fact that read returns 4 blocks.
I can think of a couple optimizations but overall it’s very inefficient.

Nevertheless I’m relieved to see something that corresponds to the docs!

Problem: So when you do a read command it will return the block you asked for + the three following ones. If the specified address is not readable you get the proper error. BUT if one of the three following blocks is an invalid address you get filler 00’s. And there is no way to differentiate between an unreadable block filled in with 00’s and an actual empty one with actual 00’s.

Solution? My approach is to have a solid memory dumping algorithm that can handle any tag before I even think about optimizing specifically for each specific chip.
So I did a few optimizations to just reading every single block and discarding the “extra” blocks (which would be horribly inefficient) using some recursive stuff and got down from ~2s to ~1.7s for 1000B. I’m still looking for better ways though. This way is the fastest the more blocks are non-zero but if they’re all zero it’s just as bad…

for the code addicts

Anyway, I will probably hard code optimized read-patterns for the most common chips in the end but having a generic memory dump was necessary. If you can think of something better let me know!

1 Like

You have to do the work that so many previous app developers just never have… You have to derive it. You have to read the data sheets and understand them, you have to read the configuration bytes (e.g. get AUTH0 byte value) if you have access to them, you have to read the lock bytes and figure out which blocks are set to read only, and then finally for what you can’t read or derive you can probe with direct reads and make assumptions… but these will mostly be outliers. Most things can be figured out by reading the current state of lock bytes and configuration bytes and knowing what the values mean.

1 Like

I’m reading sectors 0 and 1 of the xSIID just fine! :partying_face:

Sectors 2 and 3 which are being selected successfuly but when reading them I get the contents of sector 0 (according to the doc I should be getting mostly NAKs).

Anyway the next step is to check out those config bytes.

After that I’m going to switch to a more harcoded method of fully supporting specific chips.
The idea of being able to entirely analyze a chip with no prior knowledge of it’s tech in a single read is… not for the near future (mainly because is not made for that):laughing: Instead I want to implement fully the relevant chips and start gamifying things! Further chip support will be added over time.


Hmm I don’t think there are sectors 2 or 3 on the ntag i2c 2k chip in the xSIID?

It says so in the docs. 2 is fully inaccessible and 3 is mostly inaccessible with a couple lines of “mirrored session registers”.
Unless the xSIID is not i2c “plus” 2k?

I think it is because I get a passive ACK for sector select 0,1,2 and 3 but not 4

(I know it’s pointless to access them but I just wanna :grimacing:)

Hmm interesting. I don’t know the full details and can’t review the docs in full right now, but I do know that some of the interactions with the chip only work through I2C channel and not NFC… odd as that sounds.

So if you select sector 3 you can’t read page F8?

Nah any address I read, I get back the content of sector 0 including F8 :man_shrugging:
It’s not a big deal but you know, it tickles my curiosity.

UNLESS, as soon as you do a failed read it automatically reverts to sector 0?
I think that’s it! I checked the very fist of my reads on sector 2 and 3 and it is “blocked” instead of the sector 0 value.
Kinda sucks though because it means I cant iterate over other sectors without it reseting every time I hit an invalid address :angry:
I will end up coding a “map of readable space” for the most common chips because keeping it generic seems impossible. Unless analyzing the register bytes helps but I suspect they follow the same design principles

Sure but GET_VERSION is how you should ID your memory map and only read valid addresses :slight_smile:

Of course other chip types that don’t support such a command will require other more complex methods… but toy should be able to use historical bytes and ats/atr to do some basic chip ID first… then probe from there.

1 Like

Yup, that’s already setup, I can detect the type of tag and do preset operations based on that. I will be following this idea now.

I was just trying to see how far I can go with something completely generic and abstract. That could take any tag and run a long in depth scan to get every possible info no mater the type of tag. Which would also help handle outliers. But I realize tags are just not designed to be used in this way.

Funny enough I was watching this yesterday

It kinda touches on this idea of exploring what things can do, not just what they’re supposed to.

1 Like


Just wanted to jump in and say that, as much as BioCom was fun to make and all, it’s not a very well written project. I’ve learned a lot over the years and have tried to pour it and all my love :two_hearts: into Apex Manager (As well as a secret VK project that’s nearly finished?!?!).

Anyways, I mention that to say that if you’re wanting to make any NFC android applications, definitely don’t do it the way I did in BioCom and instead use the newer Reader mode API for NFC handling. There’s a bunch of documentation online for it. The one foreground dispatch system just really isn’t very easy to use these days.


As a user, I like it.
Simple, quick, clean, fast and reliable

1 Like