TikTok's (log data) encryption is accomplished by a native library. The Android Java code just serves as proxy function to the native function
Okay, doing my first baby steps with r2frida (which combines the power of @radareorg and @fridadotre).
Gonna share my progress in this thread (live, so keep calm).
The goal: Runtime inspection of data sent out by TikTok !!before!! it gets encrypted
1/many
TikTok's (log data) encryption is accomplished by a native library. The Android Java code just serves as proxy function to the native function

https://t.co/T63vo3N4fw
1) Unlike raw C-functions, JNI functions like the one showcased above, receive pointers to complex Java objects .
F.e. a function receiving a String on the Java layer...
In order to retrieve a C-String, to go on working with it in the native code, some translation functionality is required. This functionality is provided by the ...
If you look at the example screenshot again, you see exactly this. Functions provided by the 'env' pointer are used to parse the Java function arguments (f.e. jByteArrays) ...

2) There are two ways to expose JNI methods from a native library:
a) export them with proper naming convention, so that JNI could recognize same on library load
b) use the JNI functionality 'registerNatives'...
The second method of registering methods is wel suited for obfuscated code, as the methods neither have to follow naming convention, nor do they have to be exported.


Internally, this data is forwarded to the native JNI method 'ttEncrypt'.
We already saw this signature in a previous screenshot

1) the call address of the native function implementation (0x7d70d1d5 in example)
2) The function name (ttEncrypt)
...
'(' start of parameters
'[B' byte[]
'I' int
')' end of parameters
'[B' byte[] (return value)
- the app is inspected on a physical device, running Android 9
- the device uses a !!32bit!! ARM application core
Now to get started, I already have the latest @fridadotre server running on my USB connected android device and 'frida-ls-device' shows it being ready-for-action

Instead of 'launch', two other options could be used:
- 'spawn' (like 'launch', but the process would not be resumed automatically after attaching)
Important: commands targeting the r2frida plugin have to be prefixed with '\'

The signature of the static method 'EncryptorUtil.a' should look familiar to us (if you read the first tweets). It represents the Java layer of the encryption method and is called 'a' in this version

So lets search the whole address space for our native method name 'ttEncrypt'
Note: If you'd use r2's ascii search nothing would happen, you have to use the '\' prefix to search with r2frida

Reason: The memory region was not populated when r2 was started (encryption library was loaded after process launch)

1) Quit r2
2) Open r2 with r2frida, again, but this time **attach** to the already running process
et voila ... the memory offset is mapped and dumpable with 'px' (without backslash prefix)

So chances are high, that this data is part of the structure which gets handed in to 'registerNatives'

- method name (C-string)
- method signature (C-string)
- method pointer (native pointer)

The result is promising: Only one hit, for a search across the whole address space:

- 0x8448b74c (expected, method name pointer)
- 0x8448b756 (ptr to signature string, yay)
- 0x8448b1d5 (likely pointer to JNI method implementation)

Arm 32 supports two instruction sets "ARM mode" (32bit) and "Thumb mode" (16bit) which could be used interchangebly
For ARM the LSB is 0 (even address)
For THUMB the LSB is 1 (odd address)
This means the function address 0x8448b1d5 homes code in THUMB mode (16bit), while the first instruction resides at 0x8448b1d4
(sorry if it gets a bit complicated, will be clear in a second)
No seriously, as explained, on arm32 we have to disassemble at [THUMB mode address - 1] = 0x8448b1d4

Now to get a feeling on how often this function is called, lets use 'r2frida' power to trace it.
Important: The thumb address has to be used here!!!

Some actions in the TikTok app ... trace logs for ttEncrypt-calls arrive

Trying to runtime-parse the function parameters, which represent Java object instances would be insane (maybe impossible)

It would be way easier to runtime-inspect these

Hitting [alt+1] moves us straight to the marked branch offset:

Hitting 'u' returns us to the parent function, followed by [alt+2] which brings us into the 2nd branch


More from Machine learning
Starting a new project using #Angular? Here is a list of all the stuff i use to launch my projects the fastest i can.
A THREAD 👇
Have you heard about Monorepo? I created one with all my Angular (and Nest) projects using https://t.co/aY5llDtXg8.
I can share A LOT of code with it. Ex: Everytime i start a new project, i just need to import an Auth lib, that i created, and all Auth related stuff is set up.
Everyone in the Angular community knows about https://t.co/kDnunQZnxE. It's not the most beautiful component library out there, but it's good and easy to work with.
There's a bunch of state management solutions for Angular, but https://t.co/RJwpn74Qev is by far my favorite.
There's a lot of boilerplate, but you can solve this with the built-in schematics and/or with your own schematics
Are you not using custom schematics yet? Take a look at this:
https://t.co/iLrIaHVafm
https://t.co/3382Tn2k7C
You can automate all the boilerplate with hundreds of files associates with creating a new feature.
A THREAD 👇
Have you heard about Monorepo? I created one with all my Angular (and Nest) projects using https://t.co/aY5llDtXg8.
I can share A LOT of code with it. Ex: Everytime i start a new project, i just need to import an Auth lib, that i created, and all Auth related stuff is set up.
Everyone in the Angular community knows about https://t.co/kDnunQZnxE. It's not the most beautiful component library out there, but it's good and easy to work with.
There's a bunch of state management solutions for Angular, but https://t.co/RJwpn74Qev is by far my favorite.
There's a lot of boilerplate, but you can solve this with the built-in schematics and/or with your own schematics
Are you not using custom schematics yet? Take a look at this:
https://t.co/iLrIaHVafm
https://t.co/3382Tn2k7C
You can automate all the boilerplate with hundreds of files associates with creating a new feature.
Thanks for this incredibly helpful analysis @dgurdasani1
Two questions. 1/ Does this summarise the AZ published data :
The plan is to extend the time interval for all age groups despite it being largely untested on the over 55yrs, although the full data is not yet published
Do we have the actual numbers of over 55yr olds given a 2nd dose at c12 weeks and the accompanying efficacy data?
Not to mention the efficacy data of the full first dose over that same period?
I’d quite like to know whether I am to be a guinea pig & the ongoing risks to manage
You attached photos of excerpts from a paper. Could you attach the link?
Re Pfizer. As I understand it the most efficacious interval for dosing was investigated at the start of the trial.
Here’s the link to the
I’ve got to say that this way of making and announcing decisions is not inspiring confidence in me and I am very pro vaccination as a matter of principle, not least because my brother caught polio before vaccinations available.
Two questions. 1/ Does this summarise the AZ published data :
The plan is to extend the time interval for all age groups despite it being largely untested on the over 55yrs, although the full data is not yet published
SUMMARY: the Oxford/Astra trial examined dosing with gaps between 4-12 wks- although longer gaps appear to be limited mostly to younger participants. There was no difference reported in published data between these & efficacy from the 1st dose seems high for severe disease.
— Deepti Gurdasani (@dgurdasani1) December 31, 2020
Do we have the actual numbers of over 55yr olds given a 2nd dose at c12 weeks and the accompanying efficacy data?
Not to mention the efficacy data of the full first dose over that same period?
I’d quite like to know whether I am to be a guinea pig & the ongoing risks to manage
You attached photos of excerpts from a paper. Could you attach the link?
Re Pfizer. As I understand it the most efficacious interval for dosing was investigated at the start of the trial.
Discussions of 1 vs 2 doses suggest many are not aware of Pfizer's trials which evaluated 1 vs 2 dose immunogenicity, assessed multiple formulations (BNT162b1 BNT162b2 etc) & conducted dose-ranging in both young & old adults at the start. Saw "clear benefit of booster at day 21" pic.twitter.com/mpyxu9xFSF
— Dr Nicole E Basta (@IDEpiPhD) December 31, 2020
Here’s the link to the
I’ve got to say that this way of making and announcing decisions is not inspiring confidence in me and I am very pro vaccination as a matter of principle, not least because my brother caught polio before vaccinations available.