Hey, I’m Rob, one of the software developers at Pelicargo. I handle our backend software, deployment, and weird projects.
One of the features that we’ve been working on is called Track and Trace which offers fast cargo delivery by letting you track and trace your cargo as it flies around the world. This feature is especially beneficial for businesses looking for e-commerce shipping solutions, ensuring that their products reach customers promptly and reliably. Furthermore, for those dealing with heavy equipment transport, our system provides the peace of mind that comes with knowing exactly where your valuable cargo is at all times. We already have a basic system for this that existing customers have benefited from, where it would take a screenshot of the airline’s tracking page and forward it to you, letting you get a daily update on your shipment without leaving your email.
These issues have been relatively minor in the grand scheme of things. We’ve been busy building an excellent platform for both you and us to use, but we’re stabilizing and want to revamp this to be consistently useful no matter the airline you book with.
"Hard to read, not exactly helpful, and, god forbid, not a consistent design..."
Most Some of you reading will likely have been a freight forwarder or someone who has dealt with shipping things around for longer than I’ve been in the software industry (not too long). Feel free to skip this section, it’s probably nothing new.
Air Waybills (AWBs) are simply receipts for an airline agreeing to ship some cargo on an aircraft. They contain information on the carrier, shipper, weight, etc. For us though, the most important bit of information they carry is the AWB Number. This is a unique 11 digit number, and it’s the only bit of information that we have in our system that ties an otherwise-ethereal Pelicargo shipment to something that actually is real.
AWB numbers follow a specific format:
"Anatomy of a AWB number..."
The first three digits are the airline prefix (no idea who assigns these, all the things that I can find are on the 2 character codes), followed by seven digits that are completely up to the airline to define, and followed by a “check” number. The check is the remainder of the previous 7 numbers divided by 7, just in case someone mistyped a number.
However the kicker with AWB numbers is that past what I’ve explained, there’s no coordination or central way for these to be tracked. Each airline is at the liberty to just have their own proprietary tracking web page or app, which they definitely take. So armed with nothing but a bunch of AWB numbers and stubborn determination, that's where I come in.
Without spilling our secrets too much (we gotta run a business and all), Track And Trace is an orchestrator of many airline-specific entities that can determine which one to feed AWB numbers and get structured data back. I’ll be getting technical but will attempt to recognize my own jargon and link to explanations where necessary.
Some airlines don’t mind some automation, to which I’m very thankful, but some really don’t like any form of automation. Thankfully, nothing has fully stopped me yet, and usually the best backup is going the more involved route: decompiling the Android app.
Let me take you on the adventure of “Unspecified Middle Eastern Airlines”, hereafter referred to as ME. ME is one of those automation-hating airlines. The website itself seems straightforward - just send it some data and you get the information - but it has a whole bunch of cookie shenanigans that were impenetrable without more effort than what was necessary. So we turn to their Android app.
I grabbed the app on my development phone via Aurora Store which lets us both have an installation of the app and also the APK file to pull apart on my computer. I transferred it over and pulled up JADX, which turns the impenetrable blob of data into code that’s pretty close to what was originally written. After poking around though, I saw a very bad sign:
"Minified Javascript. As intelligible for you as it is for me..."
This is minified JavaScript. Almost all Android apps are written in Java which as the name doesn’t imply, is almost entirely unrelated to JavaScript. JADX doesn’t know what to do with it, and it’s been run through a process that makes it very unreadable. After poking around a bit more, it’s revealed that the Android app is pretty much a wrapper around a React Native application. We’ll have to take a different approach.
The first step of this approach is to launch the app. Easy, right?
"Oh no...."
Well then. If what we’ve done previously is like a MRI scan, then it’s time to get invasive. (Rooting your phone is simply giving you complete access to your phone - apps like to block it to be annoying for “security reasons”)
Going all the way back to JADX, it thankfully revealed the culprit: Jail Monkey. It’s built in to ME’s app, and we can see the exact point that’s causing our issue:
Even if you have no clue what exactly you’re looking at, you should be able to pick up on the fact that it checks for
isJailBroken
(technically just exposes it but it’s all the same in this case). Now, how do we fix it? It may seem that we can just edit the code, smash it back together, then send it to the phone, but it isn’t that easy. Decompiling programs isn’t perfect and you won’t be able to re-compile them unless you’re really lucky. So we gotta go one step lower and disassemble (not decompile!) the app.
The disassembler I used is APKTool. Feed the APK file through APKTool, and you’re left with a bunch of Smali files. Java programs, and by extension Android apps, are not directly run on a computer unlike most programs, but instead use a thing called the Java Virtual Machine. This topic can get very in-depth but the simple rundown is that it’s a computer simulated in your computer. Implement the simpler simulator and then your program will run anywhere [citation needed]. “Smali” is simply a representation of JVM instructions that can actually be read by human eyes and doesn’t look like complete nonsense.
"As you can tell, it still doesn’t look great..."
The goal here is not to stop the checks from occurring, but instead to prevent the results from actually escaping. To do this, it’s actually a pretty simple change (although the prerequisite knowledge required a crash course). Just change all instances of move-result v0
to const/4 v3, 0x0
. This prevents the check from being moved to the result, as well as ensures that the result is fixed to a “false” value for each individual check.
The next step is to toss it all back together and send it to the phone. To add more tools to the mix, I used APKLab, a plugin for VSCode. Install it, open the main directory containing the APKTool output, right click apktool.yml
and (with the phone plugged in) click Rebuild and Install the APK
. Badda bing, badda boom, we have a modified app installed.
Booting up ME’s app confirms the changes work - I toss in a few AWB numbers from our system and it prints out their status as it should. A long detour for a minor victory, but a victory nonetheless.
Thankfully, the hardest part is behind us, because from here on out, we only need one more tool: Requestly. You ever hear those ads for VPNs talking about how you’d get hacked by daring to log into Starbucks wifi? We’re going to do that to ourselves with Requestly. (Oh and don’t worry, you have to go through extra steps to get it set up - connect to that wifi freely.)
I grabbed it and followed the instructions for Android in the “Connect Apps” popup. The gist of that is to set your phone to route its traffic through your computer, install a security certificate (make sure to uninstall it when you’re done), and you should be good to go. Once that’s accomplished, you can hit the “Intercept Traffic” button. Now, every web request that the phone makes is displayed in full from the Requestly dashboard.
Now, the only step is to open up the app, toss in a valid AWB number and…
…Voilà! A full request, with everything needed to send it, as well as the output format! From here on out, it’s just adding this into the Track And Trace software. As said earlier, that part (unfortunately) can’t be elaborated upon for business reasons. A bit of a sudden end, but the data has been acquired!
Yes and no. Some airlines cooperate nicely, some are even more complicated than this one. But the real difficulty is sheer volume. There’s a bunch of airlines and each one handles things differently. At launch, this feature is assured to have support for our 15 most common carriers, but over Pelicargo’s existence, we have handled about 75 different airlines, or at least entities with different AWB prefixes. That’s going to take some serious effort for both initial support and maintenance, but we’re happy to commit.
Discover what it's like to be a part of the Pelicargo team.
770 Massachusetts Ave, 390054, Cambridge, MA 02139
Pelicargo 2023 All Rights Reserved