All right, I think we are going to go ahead and get started.
So, practical protocol hacking, it's what we're going to be doing today.
Thank you for joining me.
I know it's late.
I drew the last slot of the day.
I'm standing in front of you guys and a casino party.
So, I won't keep you here too long.
Probably not going to use the full time.
And turn the thing on.
That's the biggest glitch I'm happy.
My name is Luciano Moretti.
This is my third year presenting at CypherCon.
Last year I did a general overview of how I go about reverse engineering protocols.
And this year I decided I am going to go practical with the badge from last year.
I work for Verve by Rockwell Automation.
We're part of Rockwell that helps companies inventory their industrial devices, figure out what they have on their network.
Part of this is we need to figure out how to talk to all those devices to get the information we want.
Like serial numbers, make, model, firmware versions.
Sometimes that's easy in their standard protocols.
A lot of times they're the custom configuration protocols for the devices.
So, what are we going to do today?
We're going to look at how to go from a basic device and getting it to understanding how to talk to it.
In order to do that, we need to understand the device itself, what it does and how it works.
Gain access to its communications.
We need to gather data about the communications and how the device reacts during the communications.
And finally, once we have the data, we need to analyze it and break down the protocol itself.
Now, before we get started, a quick word on safety.
When you're working with any unknown hardware, you always want to be careful of the voltage levels.
Now, the badge last year, we had three AA batteries.
No large capacitors on it.
We're looking probably 4.5 volts about.
And also, while Michael is known as Monster, I'm pretty sure he's not going to let the toy makers make a stun gun badge.
So, how many of you out there have one of the badges, the digital badges from last year?
And we're here.
Okay, I see a lot of people without hands up.
So, we're going to go through what exactly the badge was.
So, the primary goal of the badge was to get points.
And there were several ways you could add to your point total.
The first, you could press a button and it would do a slot machine spin.
And if you landed on green, you'd get earned points.
Now, each badge started with just a few green icons.
The rest were red.
So, you really wanted to add more icons to your badge to improve your chances.
Now, the way that you did that was by interacting with other badges.
You'd find someone who had an icon that you wanted.
You'd hook up a link cable between the two badges, select the icons you wanted to trade, push some buttons, and then the icons would trade.
In order to get more icons available to the entire pool, there was one icon on the badge that was a sticky icon.
And when you traded it, it wouldn't actually trade away from you.
Now, the other thing that happened when you interacted with another badge for the first time is you gained a small amount of points.
So, each unique badge you traded with, you'd get that small amount of points.
And there were six different badge colors for the different levels of badges.
And so, interacting with a higher level badge, say a lifetime badge, would give you more points than just a general attendee badge.
There was also a secret number of points that if you got it on your display and showed it to the toy makers would end up earning you a lifetime badge.
So, when I'm looking at a device, the first thing I do is try and understand what hardware we have.
In the case of the badge, we have a pretty basic display.
We have a six-digit, seven-segment LED display with decimal places.
And we have had a three-column translucent grid with tricolor LEDs underneath them with a slot machine overlay.
The processor behind it last year, unlike this year, was a PIC16F, which is an 8-bit microcontroller.
And for inputs, we had three buttons.
A pick button, a spin button, and a send button.
And finally, we had the link port, which was a 3.5-millimeter TRS or tip ring sleeve, commonly known as a headphone jack.
And the sleeve on these are usually ground.
You might remember these from the eras of Walkmans, Discmans, and iPods.
Once we understand the hardware, the next step is to understand the functions of the devices.
What it does, what its behavior is, and what we expect to see.
So the badge last year had three main modes.
A default flashy screen screensaver, the slot machine mode, and the trade functionality mode.
This is the flashy screen, which is basically our base screensaver.
It looks cool when the badge is not doing anything else.
We get the display of the con name and our point total.
And if we press the buttons, if we press the pick, it goes to trade mode.
Spin does the slot machine spin.
And if we press send, there's no apparent change.
So does anybody have any ideas on what communication we'd expect to see over the link port here?
Any ideas?
More basic, like what would the badge be doing on this screen?
What functionality of the badge itself?
Not necessarily the protocol.
Sending an ID, that could be a thing.
It could be broadcasting its point total.
Not a whole lot that you'd expect at this point.
Oop, I hanged the button the wrong way.
The second major functionality was the slot machine spin mode.
You'd press the spin button in the middle, and then it would do the spin.
Based on where it landed, the point total would change.
Now once again, we need to think about what functionality the badge might want to communicate here.
Are there any ideas of what it might communicate here, or want to communicate?
A success or failure result of the spin, whether you earn points or not.
Any other ideas?
Whether the lights are lined up or not, that could be something you'd want to see.
Oop, I got to advance.
So as far as expected communications, honestly I don't really expect much here, because this is a single badge function.
You don't have the link port usually hooked up when you're doing this.
And if you did have the link port hooked up, usually you didn't see anything happen on the other badge when you did this.
The other major functionality, and this is the main two badge functionality, was the pick and send buttons.
So you connect the two badges together with the TRS cable.
The users would press their pick button to select their green icon.
And then they'd press the send button, and it would trade the two icons between the devices.
Now as I mentioned earlier, there is a sticky icon on the badge, and also we would trade points between the two badges on the first time they interacted with each other.
Now different badge types had different values.
A basic 10D badge was a 10 point, and then all the way up to 100,000 points for a lifetime badge holder.
And I keep forgetting to advance my slides.
So this is a functionality where we see badges interacting with each other and things happening between them.
What kind of things would we expect to see communicated between the badges here?
A badge ID?
Yep.
The icons that we're trading?
Yep, that would be something else that you'd really want to know.
Anyone have any other ideas?
What?
Point values?
Yep, that could be something.
I don't think I have that on here though.
That's a good one.
The type of badge you're trading with?
I think that kind of goes with the badge ID.
Other common things that we'll see in packets often we'll see commands.
Saying what the badge is telling the other device to do.
Checksums, yep.
If you're not familiar with checksums, they're small numbers that are computed using the data in the packet to check to make sure that there are no errors in the transmission.
Subcommands, in a more complicated program, that would be something I would expect to see.
Oftentimes you'll see a header or a start bit of some sort.
Some way to say that your packet is starting.
Other potential common things is a length field to tell the other device how much data they should expect to see.
And I don't necessarily expect to see it in this protocol because it's expected to be a simpler protocol, but protocols that work with devices that do multiple things at the same time often will include a sequence number in it to allow for out-of-sequence processing or messages that get delayed.
Now
, to access the signals and analyze them on the TRS port, we're going to need some tools.
And my favorite tool when dealing with a physical wire is a logic analyzer.
Now, when I did this at CypherCon last year, I used nicely a logic analyzer, which it's a great tool, it's powerful, it has a very nice capture rate, and a really nice software suite to work with, but I was called out on this because its price puts it a little bit out of range for most people who don't need it all the time.
So, we're not going to use it today.
Yeah, they do have a... oh, no, I haven't looked at the discount codes recently.
They do have a good hobbyist and student discount.
Last I knew it was like 50%.
Okay.
What we are going to use is this, which is a Cypress FX2LP based logic analyzer.
Depending on where you get these from, they're much more reasonably priced.
You can pick them up fairly cheap on Amazon, or if you want to wait for the boat from China, even cheaper.
And for the software, we're going to use PulseView.
This is a free graphical front end to the Sigrock package that does the actual capture.
Now, here we're most likely looking at a serial signal, so you could potentially use something like a tie guard or a bus pirate, if you have one of those.
Other tools we're going to use, since it's a physical cable, we're going to use wire strippers to get access to the actual copper, and a multimeter to verify some things.
Mostly continuity, to make sure our wiring is all set up correctly.
We're going to need some jumper wires to hook from the device to the logic analyzer.
And last year when I did this, I used the little clips that came with my Celia, and they worked, but they're finicky and kind of frustrating and have a tendency to slip off.
So, today I'm going to do this using Wego lever nuts.
Now, these are great, as they're way overrated for our usage case here.
All the way up to like 300 volts, 20 amps.
But they're really nice, because they can clamp and unclamp really quickly from a wide variety of wire sizes.
They're rated down to 14 gauge wire, and you can go a little smaller than that, just with a little less holding force.
So, as I said, last year at CypherCon I used the little clips, and I did it by just stripping the sections of the wire very carefully without cutting all the way through, and vampire tapping on with my little clips on the exposed wires.
Well, as I said, it's very finicky.
You have to worry about shorting the wires.
So, we're going to build a wiring harness.
So to do this, we first cut the wire, the TRS cable in half.
It's a good point that using the multimeter, test the continuity on the cable to make sure it's a straight through, not a crossover cable.
I think I had that on the slide in my notes, but I just skipped over it.
So once you strip a TRS cable, you're left with either three wires, or in this case it was two wires and a bare copper.
So you twist the shield copper together and you're left with the three wires.
And when I do this, I usually start with the largest size and work my way down, because you don't want to damage the individual wires on the inside.
Then, once you need to strip the individual wires and clear your copper,
now we're left with the three individual wires and we can use our lever nuts.
And so you use the lever nuts to just simply lift the tab, slide your wire in, and close it all the way, make sure, and then give it a little pull test.
Now these are bus connectors, so you put the same color wire into the same lever nut, and so we'll end up using three lever nuts total for this cable.
Now, once you've got all three of your wires in, we need to add in the jumper wires to connect up to our logic analyzer.
Same basic procedure, I cut the jumper wires in half, strip the copper, and you insert them into the third slot on the lever nuts that I've selected.
Those wires will then end up connecting up to the logic analyzer and allowing us to tap into the signal while still connecting two badges.
And just for safety sake at the end, I stacked them up and taped them to make them easier to handle.
The last thing you want when you're in the middle of doing an acquisition is to bump something and have the wires come out or something else to happen and you lose your signal, so a little electrical tape goes a long way.
You need to test it, and this is where the multimeter comes in really nicely.
There's a continuity center setting on it that I'm using the resistance here because I don't have sound, but you can verify that you don't have any short circuits between the different parts of the cable and that your tip and your ring and your sleeve are still connected straight through.
Finally, we need to use the multimeter to do the same thing between the TRS jack and the individual leads that we're going to connect to our logic analyzer.
This is a little fiddly, but this also tells us which wires are our tip, which are our ring, and which is our sleeve.
In this case, my harness yellow is the tip, red was the ring, and black was the sleeve for my logic analyzer.
And then we have our completed wiring harness.
We can connect it up to our logic analyzer as you can see here and it has the ports available to connect up to two badges.
Then we need to set up our software setup so we can do our data capture.
So, to start off, I connected the badge to it to do a capture and it went into trade mode and just pressed send.
And if you look closely there, you can see we captured a little blip.
Now, this blip isn't very useful in and of itself.
So, the next step is to set up a decoder.
We're going to use a UART decoder.
So, you have to right click on it and choose your channels and assign it and then it will attempt to decode the data.
Now, the data there doesn't look great, it's not right, because our baud rate was wrong.
So, you have to change your baud rate to the correct baud rate.
How do you know the correct baud rate?
Well, last year I just kind of guess and test, trying common ones.
And it turned out that when I put in 9600, it worked really well.
If you really want to know, you can measure the distance, turn your sample rate up, measure the distance between the blips and plug it into the equation and you'll get the exact baud rate.
The other thing that we need to adjust here is our sample rate.
Our default sample rate is too low for those baud rates that we have.
The general rule is you want about 10 times the baud rate, or 10 times the sample rate of your baud rate.
So, for 9600, you're looking at 100 kHz sample rate.
Now, why not just crank our sample rate all the way up?
When you increase your sample rate, it makes the logic analyzer have to capture more data.
And so, you either have less amount of time that you can capture or less channels you can capture depending on the software and the logic analyzer.
So, setting it to the minimum that you would need to capture the signal and data of interest gives you the longest amount and most amount of ability to capture.
Alright, so now we have our decoder set up, but the PulseCU software view isn't real great for working with the data, so we export it.
There are several options, including raw binary stream, but I generally go with a hex dump, usually the canonical hex dump, as it'll have both the hex and the ASCII text translations.
So, after you're done exporting, you're left with a file that looks like this.
You have your byte count on one side, your hex values in the center, and then the ASCII translations of it on the other end.
And looking at our timings a bit in PulseCU as far as where the packet timings were, we can then apply a little text editing magic and break it down into actual packets.
Now that we've got all our stuff set up, it's time to use our logic analyzer and PulseCU to capture the actual communications on the badge while we're doing different tasks.
So, the first one is the flashy screen, the screensaver screen.
So, hook up the badge, hook up your logic analyzer, go on the logic analyzer, let it capture however long it can capture, take a look, and we don't see anything.
Nothing came across.
Which isn't greatly surprising, because this isn't really a multi -badge functionality.
This only really works with one badge, and it's something that happens all the time.
The next major functionality was the slot machine spin.
So, same thing, you hook it up, start your capture, press the button, do the spin, and wait for the spin to stop, stop your capture, and once again we found there was no data.
Also not highly unexpected, because it's a single badge, more or less a single badge functionality.
The one we're really interested though in is the send functionality.
So, one of the first things I did was connect my badge up to the logic analyzer, and then repeatedly just press the send button with one badge connected, and we get data.
The big thing here to notice is what there isn't, and that's change.
All of these packets are exactly the same, and that's very important to know, because that means that we have repeatability in our communications, at least in this packet and at the start.
There's no sequence numbers, there's no times embedded, there's nothing that changes without some data in the protocol itself changing, there's nothing that changes based on the time that it was sent.
So, our send packet is repeatable.
The next step is to hook two badges up, or actually no, the next step we did was still with one badge connected, and I cycled through a send with each of the green icons that I had on my device.
And I did this with some friends with a couple different badges.
And these are just partial captures from the first few from each badge.
And so we can take a look and see what we see here.
For these packets at least the first thing that jumps out at me is all of them seem to start with the constant value, this SNDN exclamation point.
So, SNDN makes me think send.
So, this could be a command.
It's also at the start of the packet, so maybe some sort of delineator.
The next thing we notice is the next two bytes are the same within each badge, but differ between the two badges that we have here.
This is likely our badge number.
The next calendar that's different is this one.
And we notice that it's counting up as we change the icon that we're selecting.
And the one... this is not going to work well.
I'll try it.
This one here is the left shamrock from badge one.
And badge two didn't have left lemon, so I had to start with left shamrock.
And so we see that between the two badges, both when we send left shamrock it sends the same number.
When we increment it and send left diamond, we both get two.
And working through the entire process and a full badge, and about three badges, we find this is consistent, and we can overlay it over our badge, and we have our icon numbers.
The last piece that changes, and is interesting, is this last column, which we see is counting down, but is different between the two badges.
Does anybody have any ideas on what this could be?
Checksum, yep.
That's the most likely option here, especially with its position at the end and the mismatch.
So I'd most likely expect this to be a checksum of some kind.
Now that we've got a basic idea of what we're looking at, we can do a full trade between two badges and capture the data.
Now there's something very interesting that could be easily missed in this slide.
We've got two lines here.
We've got our D0, which is their tip, and we have our D1, which is our ring line.
There's no data on D1.
All of the data is on our D0 line, which is interesting.
Usually in a standard TTL UART, you hook the TX of one up to the RX of the other, and the RX of one up to the TX of another.
So this is using a one-wire serial protocol.
Now this kind of makes sense, as we pointed out earlier, the gentleman over here, when we beeped out our cable and did the continuity check, it was a straight-through cable.
There wasn't a crossover.
So the badges either have to be using one wire or no, some other way of negotiating which line to use.
In this case, they're using a mode-on-the-pick UART to do one-wire communication.
There were a couple groups last year who were working on this protocol, and one of them got stuck trying to figure out the second line.
Now, here in PulseView, there's no data.
They didn't have a really good logic analyzer.
I think they were trying...
Shoot, what's the little hacking device?
Flipper, yeah.
I think they were trying to use the UART on the flipper to figure it out.
And they were seeing some data on their second line.
And it's really interesting, because when I used my SLEA to look at this, which has an analog function, I also noticed some changes on that line.
But they matched up a little bit, they matched up with the pulses on the other line, and were a lot shorter and smaller.
When they designed this badge, they didn't ground the second line.
And so what we're seeing is a capacitive induction on that second line, and it can confuse some logic analyzers and some devices.
But, to the more interesting part, the data that we actually captured from the transfer.
So this is two exchanges of trading gear and cherry between first from badge 1 to badge 2, and then trading it back from badge 2 to badge 1.
And when I did this, I kind of staggered my button press times on the send button a little bit, to try and force one badge to start the transaction.
So right away, the first thing that chomps out to me is all of our packets are starting with this SNDN exclamation point.
On our previous, when we were looking we said this might be a command, send command, made sense at the time.
But, it's common across all of our packets, so this is pretty much most likely a header to the packet for processing.
We look over again at our column with our icons, and the icons match up to the icon numbers that we're expecting to see in this trade.
We'll also notice that in the second and third packets there's another column that has the icons and the numbers in them as well.
Looking at our badge numbers, this column that we thought was badge numbers, we can see it alternating, starting with one badge number a second badge number replying, and then the first badge number again.
Now, the PIC16 is an 8-bit processor, but after looking at several badges, the number is 2-byte value.
And we also see the numbers mirrored there.
So we know that from attendance stuff that they generally make 700 to 1,000 digital badges a year, somewhere in that range, which is much larger than 256 that would fit in a single byte.
So it makes sense that our badge numbers are 2-bytes long.
But they're also not in the tens of thousands.
So this is most likely a little-endian number.
And so when we decode them as little-endian numbers, we end up with badge number 0169 in hex, or 361, and badge 028C in hex, or badge 652.
Now this column we didn't look at before, and now we can see that it changes.
This is most likely our command bytes that tell the badges what packet they're doing and what they need to do.
And taking some guessing here, I came up with these names for the packets.
We have a goodbye, a start of a trade, a trade response, and a confirmation.
So putting that all together, we have IM badge 028C.
I'm going to be sending the left gear icon.
IM badge 0169.
I got the left gear icon, and I'm sending center cherry back to 028C.
IM 028C.
I'm going to confirm that I got your center cherry from badge 0169.
And I sent the left gear.
IM 028C.
Goodbye.
So now we need to go back and look at that last byte that we thought was a checksum.
Now when I'm dealing with checksums and trying to decode checksums, there's two websites that I generally use.
CRCCalc.com and SCADA Core's online checksum calculator.
These are both webpages that you go in.
You can plug in your data that you want to checksum, hit go, and it spits out checksums using dozens of algorithms.
And then you can take the number that you expect and go down the column.
And usually you'll find it match.
In this case, when I did that, I found it was a checksum 8 2's complement.
Which is basically 100 hex minus the sum of all the bytes truncated to 8 bits.
Now when I'm working with other protocols, there's a few interesting things I've found with people who have done with checksums and CRCs.
Sometimes they'll CRC or checksum just part of a packet and not the whole packet.
They'll leave off the header or some other piece of data that they don't really care about.
I've had one where we've had the CRC was in the middle of the packet.
So one of the big differences between checksums and CRCs.
Checksums generally just sum everything up and runs a little bit of math on it.
But they're not position dependent.
If you have two bytes transposed, it won't catch that.
A CRC is a little more complicated algorithm and takes the position within the byte stream into account.
And so that'll catch if the length is different or if two of the bytes are transposed.
So I've seen somewhere they put the CRC in the middle of the data segment and you have to perform the CRC with the CRC field set to zeros and then populate the CRC into the packet.
So this is where I was last year Thursday night at a CypherCon and all excited end of the night, went to show wire.
And he goes, you're missing a packet.
Programmers start counting at zero.
I'm like, what?
Programmers start counting at zero.
Our commands start at one.
So then I couldn't sleep.
Got back to my hotel room.
I'm like, I need to go to sleep.
I'm presenting tomorrow.
I need to get some rest.
Can't sleep.
So get up.
Break my badges out.
Break the logic analyzer out.
Recapture a trade.
I'm like, no, there's nothing else there.
Okay, well, I'll deal with it tomorrow.
Nope, can't sleep.
Laying in bed.
Get up again.
And sitting there, I just start running my logic analyzer in captures, which is the nice thing about the Celia is it's a streaming analyzer, whereas the PulseView is a fixed number of captures.
So I'm sitting there streaming on the Celia captures and just start playing around with the badge.
Just trying different things.
Doing spins.
Again, maybe I missed something during the spin.
You know, doing other things.
And then I hit the send button on the flashy screen and there's a blip.
So I connect up the two badges, lay them on the flashy screen, screen saver, and press the send button.
And there's a blip and a blip back.
And I end up with this communication.
I am 028C.
The new command is 0, which I dubbed hello.
I am 0169 and are goodbye.
So what does this do?
What's the point of this?
At first, my first thought it was a test mode for the TRS port.
Verify that the serial communications work.
There was another test mode on the badges that if you held the send and the pick and the send button down when you powered it on, it would do a cycle through all the LEDs so they could verify the solder joints on all the LEDs.
I thought that this was probably some way to do that.
But after I went back the next morning, showed wire, he said, yep, you got it.
And he's like, so he asked me, what does it do?
And I'm like, well, I think it's this.
And he's like, you know, actually, it's a way to trade points without trading icons.
So if you went up to someone else's badge, normally you'd hook the cable up, you'd pick, you'd do your send, and it would send the icons, and it would also trade points the first time.
This time, you could hook the cable up, just press your send button on your screen and you'd get the point values transferred.
Not sure anybody actually realized that functionality during the con.
So now we're left with our five commands.
So now what?
Now that we understand how to talk to the badge, what can we do with it?
Well, one of the ideas is we can start looking for exploits.
We could write a fuzzer, make mistakes in the protocol, see what happens.
Can we get it to buffer overflow or buffer underflow?
What happens if we send
a packet with an icon that doesn't exist?
Or what if we start trying commands that don't exist?
What does the badge do?
What does it react with?
Well, one of the obvious things we can do, other things we can obviously do, is now we know how to trade arbitrary icons.
And if you get really creative, you can write a script with a starting score and a target score and get that, your score on your badge as close as possible.
Now, there's a few other things and catches with this.
First, we need to know the ID ranges for the badges and their associated point values.
And then we have the issue that you only trade points the first time you talk to a badge.
So if you've talked to any of the ID numbers you try and use to set up your point total that you've already talked to previously, it might not work.
So does anybody have any other ideas of what we could do with this?
Okay, I didn't think about it either.
So we've got a little demo.
So this is my setup.
And often at work, when we finish dissecting a protocol, we have to write a simulator to verify, one, that we understand it, and two, it helps to have a simulated device to test against instead of the real device.
So I went ahead and made a simulated badge.
And so this setup is an ESP32 that I flashed with MicroPython.
And this same board, if you guys recognize it, is available over in the Hardware Hacking Village right now.
So if you haven't gotten one yet, I highly recommend you go over there and get a free ESP32 badge, which can do cool stuff like this.
I've actually got this badge powered off of the 3.3 volt lines off of this dev board, the ESP32 board.
I've got the tip connected up to the microprocessor's UART2.
And I've got the pick and send buttons that I traced out to the microcontroller hooked up to GPIO pins.
So...
we're going to turn all the icons on this badge green.
Yes, it would have.
And it wouldn't really be fun if we couldn't do it multiple times.
So let's turn them all red again.
Thank you.
That's my talk today.
Any questions we've got?
Oh, I went a little longer than I expected.
Yeah.
Sort of.
They had the firmware readout bit on the PIC set last year.
So the readout protection.
And I've looked into it.
I've tried to figure out how to read out the firmware of the PIC.
And there's some companies, if you can send your board over to Russia or Asia somewhere, there's companies that'll do it for you.
The only method that I've found that's published for bypassing that is decapping the chip and exposing the quote one-time programmable bit that does the write protect, or the readout protect, or it's not a one-time programmable, because when you erase the badge,
it clears it.
When you erase the PIC, it clears the write protect.
That's the only way to clear it.
Only official way to clear it.
But if you mask off just that one area of the chip and expose it to UV, you can erase it.
But you have to decap the chip.
Yeah.
The question was, is there a, in the code, did I find any way for it to factory reset the badge?
I haven't found it.
I know that there is a jumper on the back of the badge that you can solder.
I don't remember if you solder it or desolder it at the end of the con.
To put it into post-con mode, they usually put that on the badges.
It's a resistor you pull.
I don't remember the details.
I never do that with my badges, because I like to play with them.
Oh, we got another one.
Yeah, usually a UART, the one device will pull the line high and drive the line up and down.
The PIC microcontrollers have an open drain mode in them, where the UART lines are open drain.
And so they'll
have a pull-up resistor, but when they drive the line when the one is talking, it can pull that down, and usually it's in listen mode unless it's transmitting.
Now, to get around that on the ESP32, because the ESP32 doesn't have that mode, but my demo here, I was still using a single line to drive that UART.
And the ESP32 is I'll back up a little bit so I'm not feedbacking.
The ESP32 is really nice in that it has, its GPIOs are pretty much fully matrixed, and so I was able to actually dynamically remap the pin at runtime between TX and RX.
Now, that can cause some funny behavior on the badge side if I wasn't careful because I was backdriving power into the badge sometimes.
So it would be a little funny sometimes funny behavior when you turn it off.
It wouldn't actually fully turn off.
But it worked for the purposes of talking to it as long as you didn't turn the badge off.
I did look at it a lot.
I took it down to part last night.
There's no active comms on this badge in between badges.
And the firmware is fully available if you can hook up to the USB port.
Purposefully, I talked with Whisker and he said he purposely wrote it obtusely to make it hard to understand.
So my first reaction when I looked at it was like, this looks like code written by an electrical engineer who's never written Python before.
Looks like embedded C.
But, yeah, so I
I have, I did try and dump it into Copilot and my instance of Copilot didn't I pointed it at a link to the file and it said, oh, I'll process that and code review it and get back to you.
And it never got back to me.
So AI, I'm not fully worried about AI taking our jobs yet.
I did hear that somewhat Josh dumped it into a different one and he had some pretty good success with it.
So, alright, I think it's time to go party, so I'm going to call it, unless if you guys have any other questions I'm happy to answer them after, but have a good night, enjoy the rest of CypherCon.
Thank you.