In this video, we will have a look into hooking a see function, for example, the string compare within
the C library.
And this means we are not having access from our Java site.
So we cannot simply hook those parameters or this return value in this function over here.
And this sounds to be a very rough task, but to be honest, it isn't figuring out where this function
is in this library.
Of course, this will be very rough and therefore I would like to split this video into two parts.
The first part will be about reverse engineering, a native library.
This will be a little bit complicated, so we will face arm assembly but on a very high level.
So we will skip out all the rest and we only focus on the most important parts, this type of reverse
engineering, its whole cost on itself.
Nevertheless, I would like to give you at least a preview on how you could do this, because then you
know what you're looking for and then you can navigate around on your own in this code.
I mean, on a high level, yes, of course, we cannot learn arm assembly in just a few minutes, but
I guess this will helps you a lot in understanding the code, or at least the important part of the
code, and also to find the function of what you are looking for to solve really our challenges or tasks
already.
Okay.
The second part will be about hooking this spring compare function.
And this is this will be a lot of fun because we do not have to learn many new things.
Most of them are already known.
And the only thing we need to do is we need to bring them together.
So we need to complete our puzzle with everything we know about hooking and natal function.
All righty.
Okay.
After finishing this lecture, we will have our final challenge.
And this will be a real world application and real world capture the flick.
And if we can solve this, we will obtain our last pet the red bed.
And this is freaking amazing because it shows how many things we have learned in this chapter over here.
But for now, let's do the step by step.
So we start with a little challenge I have prepared for you and this one.
This is performing and check within plain see function.
This is something we have to figure out and also to identify that this one is happening and then we
will be able to hook it so we can observe the the parameters of the C function and also the return value.
Therefore, I would suggest let's start with this one.
Let's switch back to Ubuntu VM and have a look into this application.
Let's go.
Okay.
So here we are back at Ubuntu VM and now let's have a look into this little exercise I have prepared
for you.
So within the attachment of the section, you can find this application named and C func freedom and
let's put this into a new directory, C Funk of freedom and now let's have a look into this one.
So we're getting our smartphone screen and this one and now we are opening a new terminal in this directory
and we are using ADB install on this application and there we have it.
So we've got an and very well-placed amazing looking icon over here and you can see those colours.
These are now the signature apps for this course over here.
Let's open this and wow, even more amazing, this layout and all this.
Yeah, this background and all the other colours, right?
Absolutely.
You are absolutely right on this one.
Okay.
We also got this motivating text.
Give this application a try and this is definitely something you should do.
Here we are having our flag.
So let's see, what's the functionality of this app?
If you are if you're inserting a text, let's see.
Then we can see the flag is wrong.
So test seems not to be our flag.
And to be honest, this is the whole functionality of this application.
There isn't much more in there.
We're having a function that's checking if our flag is being correct or not.
Therefore, let's have a look into this one.
So let's reverse engineer this with Jade Scooby and let's see what's inside.
Okay.
So we go into the the Android manifest example and here we can see we are only having one activity,
the main activity, no permissions, nothing fancy in there.
So we double click on this one.
And here we can see we've got public native.
So this is our native method.
Hide and seek.
We can see we are also loading this library native lip.
If you take a look into the slip directory, here we have them.
This one, this is 6432 x 86, which is 32 bit and this one is x 86, 64 bit.
All right.
This means by having these directories, this application also works in our virtual machine.
We have those dos dependencies over here.
Nevertheless, I would like to use it on a real smartphone over here.
So that's a way faster for me.
But you can also try this on the virtual machine.
It should definitely work.
Alrighty.
Now, let's see.
We've got this method.
Hide and seek.
This one is being called over here and we can see.
Okay, this one has an object which is being fetched from the added text field.
This is this one over here.
In this one.
This is our edited text.
So the text we are putting into this one will be it will be forwarded to this function.
We're having a string as a parameter and string as return value.
And now we already might realize something.
Here we can see the text view will be set to the return value over here.
And if we are having a look the return value is now flag is wrong.
So this is the return value and this means we have no influence regarding to the check itself.
Let me put this on the right maybe.
And now let's get out the graphic tablet and let's talk about this one.
Okay.
So let's get these pieces together.
We've got an function which is named hide and seek.
Hide and seek.
This one has a spring as a parameter.
This is an object.
This one is also returning back in string and it's being a native function.
Okay.
Now, let's.
Let's figure this out.
This one over here.
This is our parameter.
This is the object that's being provided to this function over here.
The function is returning back in string, which is this one over here.
So this is the string.
And the string will be displayed over here.
All right.
And this means we have no influence regarding to the check because the check is being performed within
this function itself.
Let me clean this here.
So if this one here is the function.
Then what we can look for now is the following.
We can hook the parameter, of course, and we can hook the return value over here.
But none of them is related to the check itself.
The check might be performed within this function.
Within another function, for example, this string compare function which takes our object or parameter
and compares it against.
I'm running out of color, so I'm checking blue once again against this value, which is our flag.
And now the only thing we can influence is this one.
But this is also something we could simply type in here.
Then we are getting back and return string, which claims is the flag is wrong or if the flag might
be correct.
Do you think we need to do is we need to figure out where this function is or what this function over
here is, and then we need to apply our hook in there.
So we need to hook into this one and observe those parameters and also the return value of this one.
And this is something we can, of course, also do with freedom.
If you're having the address of this one, then everything is easy because it's exactly the same approach.
But how do we get this address over here?
And therefore, we have to do a little bit of research because we do not know what this function over
here is.
It might be in string compare, but it might be something different.
We have to reverse engineer this native library to figure out what this one over here is.
And if you notice, then we can hook this.
All right.
I mean, if you would like to cheat on yourself, what you can also do is you can simply modify the
return value over here.
So you can claim that if flag has been correct.
But this is not the approach we would like to take over here, because modifying and string within the
output is not modifying the check itself.
This one over here.
So we would simply just cheat on ourselves.
And let's assume we've got the following case.
So let's assume this one over here.
This is some cryptographic functionality that takes our input and compares this input against instead
the key.
If we are able to figure out what the static key is, then we are able to decrypt all these configuration
files that contains password sensitive information, access tokens and things like this.
If you are simply just modifying the output that you decryption has been successful.
We are not getting anything right now and so the things we need to do are the following.
We need to get this this native library lib, native dash lib as old and we need to disassemble it.
Then we need to identify where this function is being used, our native function, and then we have
to identify whether this check is being performed.
And to be honest, this has been a really rough task a few years ago, but till 2009, we are having
an amazing tool out there that helps us a lot.
And this amazing tool, it's Chitra.
Chitra has also a compiler for several different architectures, including the ARM architecture, which
means besides having the assembly code, we are also getting out sort of C C++ code.
OC This is not that accurate like the Java code because this task is it's freaking hard to even be performed.
But the output, it's ridiculous how good we can read this and by tweaking it a little bit, yeah,
we can absolutely use it for our reverse engineering approach.
And this is where this first part is about reverse engineering, this library, and identifying this
check functionality which can be then in the second part easily be hooked.
Alrighty.
Okay.
So therefore let's start, let's start installing Chitra and let's figure out how this is being done
and let's go.
Okay.
So the first thing we need to do is we need to extract the native library out of this application.
But this is absolutely not a big deal.
We can simply go into this APK and we can right click extract here.
So this is in zip archive and we can simply extract this content in there and let's do this.
So here we have this now and but then Libia now having those libraries.
All right, if you are already familiar with assembler, then you have the free choice to go for.
What's the most comfortable architecture for you right now?
Here we are having 64.
I'm 32 x 86 and also 64 bit version for me right now.
I like to stick to 32 bit version and this is the architecture where I feel safe right now.
So this one over here, okay, to analyze this application, we first need to get our tool of choice
and my tool of choice.
It's Chitra.
Chitra is freaking amazing and yeah, therefore let's install it.
We go into our world famous internet.
Here we have it and that's the official page and chitra desh is our dot org.
And here we can also download it directly from GitHub.
So if we click on this one, here we have the version 1001, we click on this one and now we're downloading
it.
Okay, so the download has been finished and we also have this SHA 256 some to verify if our downloaded
file is exactly the same over here and therefore let's verify this.
So within downloads we are now providing an SHA 256 some or we're generating a new one over this zip
archive.
And this might take a while because it's a little bit large, but here we can see this is what we've
got and this is what it should be.
In this match just perfectly.
All right.
So please only download sheet graph from the official page over here.
Okay, so now we have downloaded it.
No notes, and here we have it.
I double click on this one and then we hit extract and we extract this into.
Into our tools.
There we have it.
All right.
Meanwhile, I do some a little bit of cleanup.
Okay.
So the extraction has been finished.
We click on show files and here we have it.
I rename this real quick to Chitra.
And this one over here.
This is the that's the starting script.
So we can take one quick look into this.
But by verifying this Shazam, we can be pretty sure that this that's the intended file over here.
So, yeah, this is just matched with that largest cheat wrap that we would have to take, look into
this one and go down the rabbit hole for me right now.
I trust it, but feel free to do your own investigation on this one.
All righty.
So, oh, one too much, maybe.
Let's go into this one once again.
Let's start Chitra.
So we are simply starting the script and this will launch this application launcher here.
Okay.
Here we have now the project overview.
And for now we are not having any Chitra project.
So we are creating a new one new project.
Here we have the option between non share project and share project.
And this one is for multiple people working on the same file.
This is here, not the case.
So we are the only person who are working on this project right now.
So we click non share and here we have to define and project name.
This is the z function Frida.
Okay.
And then we simply can click finish.
And that's all for now.
So here we have created our new project.
By the way, Chitra has now this amazing debug feature.
So this was long required and finally in version ten, it's there.
But we do not want to debug it.
We want to disassemble this application.
And this is what is tracking is for the tracking decode process.
So we hit this.
And then let's see.
All right, so here we have it.
Maybe I have already started.
Or instead she tried before on this on this machine over here.
Normally, there should be some pop up regarding to an user agreement and things like this.
So please read carefully through this.
And if you accept them, then you can simply hit the reset button.
Then it should be now synchronized once again.
So this is now the code browser and what we need to do is we need to load our library into this one.
In my case, I'm choosing the arm 32 bit version, so I go into file and then import file this one over
here and then I go into EPS and see if I'm free to and this one, the library.
And then here we have it lib native dash lib as all the arm 32 bit version I click select file to import
and here we can now see yeah that's the pop up of Chitra.
And so Chitra has already identified the architecture.
We can see this one is an arm little Indian 32 bit B eight version and this fits perfectly so we can
simply use this or keep the default value over here.
Then all we need to do is we simply need to click.
Okay.
Now the application is being loaded and there are some quick check up until this pop up appears.
The lip native dash liposome has not been analyzed.
Would you like to analyze it now?
And this is definitely something we want to have.
Otherwise Chitra is not.
Yeah, it's not creating those nice tables regarding to functions and point does variable strings and
stuff like this.
So we definitely want to analyze this native library over here.
I click yes.
And now we've gotten very important pop up.
These are the default values.
And the only thing I would like to add other following tool, I would like to use the arm aggressive
instruction finder because ARM has two modes.
One of them is the arm mode and the other one is the thumb mode.
The AR mode means every instruction is four bytes long within the stump mode, every instruction is
two bytes long.
And Frida has this amazing feature trying to detect if in code section is our mode or thumb mode.
And the other option is the the compile parameter ID this one and this one helps us to reverse engineer
this application.
We get some additional information within the parameter IDs.
And so therefore I also activate this one.
All right.
And yeah, so that's all the default values plus and the compiler parameter ID and also the aggressive
instruction finder.
Alrighty.
Okay.
Now we can click the analyze button.
So here we're getting an overview about this binary.
For example, the name IDs, bytes and stuff like this.
We can simply ignore this right now on the bottom.
Right, we can see the progress and also over here so we can watch Chitra reverse engineering this application.
Now we've got a huge section here and yeah, it has been also finished right now.
Perfect.
So Chitra has now finished analyzing this native library here.
All right, let's have a quick look around this OC in the middle over here we have gotten code listing
and this is the assembly code.
On the left we've got our symbol tree, which is very important for us right now.
We've got imports and exports.
So freedom is also making a difference between them, which is also super amazing because then we can
easily see yet which module we need to use within our freedom script.
All right, beside then we also have this function over here and this might be a little bit duplicated
because these functions are also listed in imports or exports, but we can use them to search through
this.
And for example, let's see which function we want to identify if we go back into this one.
So let's see.
Within the main activity.
The function we are looking for is hide and seek.
So let's see.
We're going into this folder and we're typing in hide and seek.
And then we go, here we have them.
And this one is an export function.
And here we have the whole function name.
If we click on this, we get directly redirected.
Let's put this on the side to this function in the disassemble view.
And now that's the amazing part about Chitra.
We also get the compiled output on the right.
So over here we have now compiled output regarding to this assembler overview.
In case if you're not really familiar with the assembly, we can only stick to this one on the right
and we can already see our parameters.
For example is Chennai Environment, which is parameter one.
Then we've got an undefined.
So Chitra does note that this one here is this this object and we'll be having our trace string and
this is our argument that's being passed into this function.
So if we go back into trade X, there we have it.
This is our object because the first argument in a chain i.e. function, that's the environment pointer.
The second one is the this object.
And the third one, this is our parameter.
In this case, our string.
We are passing into this.
Alrighty.
Okay, let's close this.
So let's make this maybe a little bit larger.
By looking at this, I already realize something.
You may also have seen this so far.
This one over here.
So here we've gotten string compare.
We've got this one.
We will take a look into this in a moment.
But this one here seems to be in string that's being compared.
Might this be our flag?
I mean, this wasn't the intention during the creation of this challenge.
So Chitra has to compile this application and figured out there isn't static string which is been used
only once here.
So therefore we are simply just putting this string hardcoded into the into this string compare function
with indeed compiler output.
So this is not the intended way to solve this challenge.
But nevertheless, if this works, then it's an easy way.
And if you find something like this, go for the easy way.
So there's no reason to flex about this one and make it more complex than it is.
And let's try this out if this one is really flag.
So let's get out our smartphone once again.
Okay.
Here, we're having the flag.
Let's see.
We can also use the keyboard, by the way.
Insane.
Frida Hooks.
Och.
And let's see.
So I'm hitting check in.
Three, two, one.
Okay, nice.
This one is really deflect and yeah, as already mentioned, this is not the intended way, but it is
an easy way.
So if you find something like this, go for it.
Okay, but now let's assume it's not that easy.
So this one over here, this won't be an hardcoded string.
So maybe that's a variable that's being complicated, concatenated out of many other strings until we
reach over here.
So the thing we want to do is the following.
Maybe let's get out the graphic tablet and discuss this over here.
Alrighty.
Just give me a second.
Okay.
So here we are back on the graphic tablet.
And regarding to this one, we have already identified our comparison function and this one over here,
this string compare.
We notice right now because this one here seems to be obviously our flag, this parameter in there.
This means this might be our parameter that's being provided to this function over here via the hide
and seek method.
And this is something we can figure out right now.
So maybe let's clean this over here real quick.
Here, be having PC bar one and if we do a middle mouse button, click on this one.
We get all these occurrence of this variable and this one is being assigned over here at this line and
this one is using and chain I environment function and get string UTF chars and this one over here parameter
one we notice right now this is our environment pointer regarding to the NDDC functions and this one
over here, this is our parameter that's being provided to this function, to this hide and seek function.
This is our object.
So let's write this down.
This one, and this is our object and this one is being used over here.
And this one over here.
That's our environment point.
And this one over here.
So parameter to this one is the this object.
Okay.
And this means this here is ARX zero and this one is our x one.
And this one over here, this is ARX Tool.
If you're going back into the indicate function on the Java side, we can see hide and seek only one
parameter, which means this is our object, our ax two because environment pointer and this object
are not listed over here, but they exist in the index side.
All right.
So nice.
We have already identified our parameter that's being used over here.
We can now also assign a name to this one.
If we click on this, then we hit the L button and then we can rename this one, for example, to the
user input.
If we click, okay, then all these occurrences also change.
So now we're having our user input in there and this one we can also rename this one.
This is our environment pointer.
E and the pointer.
Nice.
So now it's a little bit more here.
It's a little bit easier to read.
Let's see.
Here we have an get string UTF chars.
We can now look this up what this function does.
But we can also assume that this one over here is simply just returning in char pointer, which is an
array.
So we're getting back in string and this one is now our string that's being used or referenced over
here.
So this is some kind of typecasting from our user input in this choice string to this native char point
over here.
And this means in PC one and this one over here, this is now our user input, once again, user input.
All right.
But now we've got to duplicate them because we have already used it.
Then we simply we can simply cha cha array.
Okay.
And now we hit the middle button on this one and then we have all these occurrences of this one.
We can see it's being used within this string compare.
So we are now comparing in this function our user input with this one over here.
And this means the function we are interested in is this one over here, this string compare function.
The first parameter over here.
This is our user input and the second one, and this is finally our flag.
If you hooking this function, we can also observe these parameters.
I mean, our user input, that's not relevant.
But this one over here, this would be super nice to fetch so we can fetch the values that's being used
within a string compare function.
And if this one here, this one, if this one won't be that easy to recognize, let's say this one over
here is also in variable and it's being complained about.
Sorry, it's been complexly generated.
So we do not know what this one is.
We do not care because at this point we need to have the plaintext over here, this one already.
Okay.
And regarding to the rest, we do not care about this one, so we can simply ignore the rest.
So the things we are interested in is our user input.
We need to get this this point where we identify what is our user input.
And I mean regarding to an index function, it's not really hard.
We always get this nice structure environment pointer, this object.
This object and then afterwards our user input, and then we can also track this user input down.
So for example, it will be used over here and this one will be assigned to a new variable and this
one is then being used over here.
All righty.
This is all we need to know regarding to reverse engineering an application with Cheetah right now.
All righty.
So this is all for part one.
Right now, we have seen how we can reverse engineer a native library.
So this is now C++ code, and she was also performing an amazing job in reconstructing the source code.
I mean, it's not that nice as in Java, but it's absolutely helpful.
We get also some assistance over here.
Chain I environment point that has been recognized.
This one not but it can be replaced by us right now.
Let's do this really quick.
This object.
Okay.
And this is our user input.
And then all we need to do is we need to track down the user input.
Then we have to identify what this method over here is doing.
But it's simply just returning an array, which means this is now our new converted user input and this
one is being used over here.
So this is the function we want to hook.
Alrighty.
Okay.
In the next video, we will learn how to hook this function over here.
We've got several possibilities and we will discuss all of them in the next video in case if you have
any questions regarding to this topic or regarding to Chitra, feel free to write me a message.
Otherwise, I'm looking forward to see you in the next video when we're finally hooking this method
over here.
Alrighty.
See you there.