But a comeback in this section.
We will take a look at the break up codes.
So this one is super interesting and maybe we are able to understand our first program after this section,
our first complete program after the section.
Let's have a look.
In the last section, we have taken a look onto the following program.
So we have done our typical analysis.
We have identified parameters and return values.
In this case, zero parameters, return value integer.
We have also learned more about the P zero object and why we do have a local register, even if we do
not have a local variable over there.
All right.
What we did not learn is more about the I get instruction.
And the question, of course, is, what is this?
I get instruction and what does this I get instruction and how do I know that this one is taking the
p zero value storing it into V zero?
Well, I also got some help on this one and the help I've got is the dalvik up code instruction set.
And this is a kind of list full of instructions and the corresponding description to what this instruction
does.
I couldn't find an official documentation, which is, in my case, super ridiculous that there isn't
one out there.
But I have found a super amazing site and this site has most, maybe barely all instructions and the
corresponding descriptions to them.
And this side I really want to show you right now.
So I switch to my ubuntu VM, then I go into my browser of choice and I search for dalvik up codes within
Google and this one over here.
I do not want to pronounce this name because it will be definitely wrong, but really thanks to this
one who has put this website online.
So this is an Yeah.
Nice list of all these instructions over here and you definitely want to bookmark the site right now
because it will use this a lot.
I also look them permanently up in this list over here and here.
Let's have a look into the I get object instruction.
Sorry, in the I get instruction and here we can see we've got I get v x, we y field ID and the c description
to this reads an instance field into v x instance field is our this dot power.
And by reading an instance field into v x, we are reading this this power into our v zero and it doesn't
have to be v zero.
Of course, therefore is this x parameter over there and can be also v one to be three and so on.
And we can also see the instances referenced by V zero.
So this description is amazing because it directly or immediately tells you what this instruction does.
And the author didn't stop by doing this description.
The author also puts in an example on the right.
Without this website, I wouldn't have learned smartly, and therefore I'm really grateful to this author.
Okay, let's do this once again.
So what does I get?
Does we take the right path and read it into the left part?
So the left part is holding this value afterwards.
That's all nice.
Let's get back into our example.
This one over here.
Let's take this list and see how far we can get in understanding this function over here at power,
because we haven't looked up those instructions yet.
And what we do is we take a look at the smiley code, we figure out our parameters, return values,
and then we will try to complete the puzzle by looking up the missing instructions.
Okay, let's see how good this goes.
So I'm going to build this application once again in case I did modify it in any way so that we are
using this code.
All right.
Already done.
I delete this directory over here and we do this one second APK tool D.
Okay.
This has been also finished.
Then we go into the back Smiley Comm app hacking smiley one and I open the new terminal over here.
We can close this one, and I'm opening the playable smiley player, that smiley file.
All righty.
Let's zoom out a little bit.
Enable Java.
Yeah.
And also just focus on this one over here.
Alrighty.
Here.
I've got my graphic tablet and now we analyze the smiley code.
We will slowly do this step by step and we will reconstruct the whole Java code.
Afterwards, I show you a different approach, the way I like to reverse engineer this code.
But for now, let's keep it to restoring the Java source code.
All right, let's do a little bit of a recap.
What do we already know?
So let's go.
So we've got our method, this method, public add power.
This is our method name.
So we write this down next to this add power.
This method has now two parameters.
Those two both are from the type Capital II, which means we've got two integer values.
We can also find those labels over here.
If you take a look into those two, these are our parameters.
Yeah.
The first one is in a.
And the second one is in to be.
Okay.
Next, we've got this one over here, the return type, and it's also returning an integer value.
Therefore, we can write this down over here.
And now we've got our fashion prototype.
Pretty nice, right?
Next, we've got this local one.
Local one.
Sorry.
This way.
And this means we've got a local register.
We doesn't know if this register is just a placeholder for a return value of another function or for
example, for an instance field.
Or if this local register is used for storing and variable.
If we go down a little bit, we can find this one over here.
And this means our local register B0 is a local variable with the name sum and this sum is also from
type integer.
So let's write this down.
We've got an inch some over here.
We do not know if the sum now gets initialized with a value or if it's holding in value.
We just know these information at this moment.
Then we've got our two year labels parameters.
And what I like to do is I like to keep track of this.
So we know A is P one and we know it's B is P two.
And we also do this for the label sum.
So this label over here, this local variable sum is referenced by the Register V zero right at this
moment.
This might change later on if this register gets reused because this label is or this variable is not
going to be used further.
Then this might change.
But for now we know we zero is referencing the label or this variable sum.
Okay, let's move on.
Okay.
So we did understand this part, also this part.
This and this part.
Now we've got this one over here.
Let's focus only on this one right here.
This is a new instruction, new opcode.
So let's look this up or let's first have a look into this.
We've got an const slash four, then we've got V zero, comma zero, zero.
Now let's look this up here.
We had our break up code site, so we are looking for const slash four and here we've got the description
con slash for b x comma lit for this lit four.
Looks super strange, but if you read the description, we know what lit four means.
Puts the four bit constant into v x.
So we've gotten value over here.
For example, the value two or the value four, and this value gets moved into this register weeks.
We've also got an example on the right side, so let's have a look into this one.
We have 2 seconds slash 4v1, then we've got this hash tag and then this integer value two.
So we can represent numbers and smiley with the hash tag.
Then we can write the date symbol value or we can write zero x the hex representation of this value.
Okay.
And what's this?
And this is the bytecode.
So this is the hex code.
And if you represent this hex code in binary values, these are the ones and zeros that execute this
instruction.
Const for v1, comma hashtag int to.
So this is moving the value to enter the register we want.
All right.
Not that hard for this instruction.
Okay, let's get back.
So let's do this once again, this instruction.
We've got const slash four, we zero, comma zero, x zero.
So we are now looking only at this instruction and we do in the further explanation on this, we are
moving zero into V zero.
And if we get back to the reference dalvik reference, our V0 is the reference with v x and this one
is referenced with lit form.
So therefore we also know how to read this.
Okay, regarding to paper for let's take a look onto this.
So we are moving four bits into the register.
We zero four bits.
We can represent them in this way.
One, two, three, four.
Those four zeros gets moved into we zero.
Why do we move four zeros and not eight, for example, in whole byte?
This depends on the compiler.
So the compiler tries to save as much as space or memory as possible.
And in this case, we can see the register is being initialized with zero and four bits.
Representing this value is enough, so the compiler optimized this code and used only four bits to initialize
this value.
Zero.
Okay, let's have a look into this instruction once again and more in detail.
I mean, you might think, wait, there is more, but let's figure this out.
All right.
If you take a look back into the description, these two are referenced with V, X and this one is referenced
with Lit four.
But what about this lit for those four bits?
This is a little bit annoying or confusing.
Let's have a look into a real example.
Let's try to start the number ten into this register.
We zero the number ten, this one over here, 0x8.
The hash sign is a common in smiley and it's being automatically generated by the APK tool.
So this one is only for better readability.
This does not affect the code itself.
The value zero XA is being translated into ten and that it does not disturb the code itself.
A comment is being appended by the APK tool.
So we can we can completely ignore everything after and comment, but it helps us to to read this code
a little bit easier to get the view onto the bits we need the binary representation of this value.
Ten We can do this by splitting this up.
So we've got to square zero to square one, to square two to square three.
And to square for this one is one, two, four, eight, 16.
So if you want to represent the number ten, we have to add eight plus two.
And therefore those two bits are set and the rest isn't.
This is the binary representation of the number ten.
And if you take a look into this, we can see, yes, this number fits into four bit.
So we can also start in number ten with this instruction over here into the register, we zero.
And now let's try to store the value 20 with constant slash for we zero.
And then we've got 20 which is zero x 14.
This is 16 square zero, which is one times four and 16 square one times one plus plus.
It's 20.
Yes.
Okay.
Let's do the binary representation of this value.
20.
We do the same approach to square zero.
To square one.
To square two to square three to square four.
We've got one, two, four, eight, 16, and here we've got 16 plus four.
Four.
We've got this bit set.
This not this is it.
Not not.
All right.
Here we can see we have a problem.
If you try to store four bits and devalue 20, this does not work.
If we stick to all four bits, we will store the value four in our case into V zero.
So afterwards we zero would be four.
But it might be important that the value of zero at the register v zero is holding the value 20 and
four is not equal to 20.
Right.
Sigma.
Therefore, the compiler throws an arrow and we get message that we cannot use or we cannot store this
value into a four bit register.
We have to extend this register and I guess the next one is 16.
So in our case it would be cost 16.
16 has now a lot of additional bits over here.
And 1616.
This works out.
We can store the value 20 into our visitor register with this one.
So if you write code, we do not care about this because this is something that the compiler does automatically.
But if you want to patch this application and we want to increase this value over here, then we have
to take care about this and then we can figure out what's the next possible instruction for this.
For example, slash 16.
Or we can simply use const because const as default is set to 32 bit.
So if you encounter an icon slash four or slash 16 instruction, then think about this value.
And yet if you need to increase this, furthermore, replace also this instruction not only the value.
So by switching out those values over here, replacing this, for example, with zero x 14, this will
not work because const for four bits cannot hold this value.
Therefore, simply remove this one over here and we are good to go.
So I guess this instruction is now clear, isn't it?
There we go.
Let's clean up this a little bit.
Okay.
So we talked about this instruction.
What does this do?
Well, just kidding.
Let's have a look.
We've got our end.
Some in some is referenced by V zero.
In this case, we are moving the value zero into V zero, which means we are moving the value zero into
our sum variable over here.
And I like to keep track on those register.
So I would also write down the equals zero.
Okay.
So we initialize our sum with the value zero.
This is what this instruction over here does.
Right.
So we also understand this one.
Then we already talked about this one.
Here we go.
We have a new instruction.
This one over here.
If we look up the Dalvik code, let's have a look into this.
So let's write this down.
We've got an ad in.
With zero comma p one.
Comma p two.
Okay.
So we have three register at this instruction and this one.
Yeah, I'm pretty comfortable to say what this one does, but let's figure this out.
Okay.
Back at the opcode, let's see.
We are searching for it int and we can see it int we x we y we set calculate v y plus we set and puts
the result into weeks.
Alrighty calculates we y plus we set.
So these two gets added together.
And the result is thought into weeks.
Okay.
I guess that's also not that hard.
Let's have a look at the example over there.
It's three, three, two, three, two and puts the result into zero.
It's exactly the same.
Okay, so let's have a look back onto our code.
So we split this up once again.
And then we say, okay.
P one gets added together with P two.
And the result of this gets thought into We zero.
Let's replace those registers with the original labels.
So let's write this down in the mathematical operation.
So we've got V zero as equals, p one plus p two.
This is what this instruction does.
Okay.
Now let's replace those registers with our labels.
We know our V0 is sum and therefore sum equals P one is our a a plus, p two is our b OC.
This is what this instruction does.
Let's clean this up and write it down.
Yeah, more clean.
Well, this one over here.
Is sum equals A plus B.
Okay.
So we also got this one.
And finally, there's our return.
We zero.
We also know what this one does.
It's returning our be zero, which was referenced or assigned with some E label.
Some.
And yeah, there we go.
We have restart the Java source code out of the smiley code.
Isn't this ridiculous?
Nice, in my opinion.
It definitely is.
So it's super nice to write this down.
In this way we can reconstruct the whole Java code and this will help you learning smiley more and more.
In my case, I'm not a real fan of writing this down in the original Java code because we can simply
take this function and yeah, decompile or recompile this into Java and then we can see, okay, this
is the Java code corresponding to this smiley function.
In my case, I'd like to write this down in a little bit different way because we are not interested
in those Java functions, or at least in those Java names we are more interested in which register is
holding much value because we want to patch some values to improve our power level, improve our gold
items and things like this.
And this needs to be done on a register level.
So we cannot simply tell some.
It's now equals 40.
So it's not working in this way.
Therefore, we have to go into the smiley code onto the left, and then we have to patch the register,
which is exactly doing this step within the initialization or something else.
So now I'm going to show you my approach.
It's pretty the same, but I label this a little bit different.
So let me clean this up and then we have a look into this.
Okay.
So don't get me wrong, this travel source code is amazing.
And if you like to stick to this one, of course, do this.
I'm now going to show you my approach.
And this is just my personal reference.
If you like to do this in the same way, then feel free to go also into this labelling.
But if you like to stick to the Java approach, absolutely no problem.
You just need to know or just need to be able to reconstruct the code out of the smiley function.
So let's see how I would normally write this down.
I start with the same approach.
Method public edge power.
So here's our method add power.
Then we've got those two parameters and I would not name them A and B, I would name them P one and
P two.
I like to stick to the registers, so in my case I would name have boobs.
So in my case I would have named this int p one and int p two and then yes, return value also integer.
We are good to go.
Just a small difference regarding to the approach we have done before.
Okay.
Then I ought to move on with the next line.
But in this case, I do not care about this local one because I'm doing this for one instruction after
each other and I'm not going to into this one and look this up downwards because I do not care about
this label.
Let's see if you do not care about this one, how the approach looks like this.
We can now go from top to the button, each instruction after each instruction.
Then we have those parameters and here we already got those two.
And of course, we can also use those labels over here so we can say this one is a and this one is B,
not a big deal.
But normally I do not care about those labels.
Okay.
Next, we've got this one over here and we can write this down exactly as it is.
This value gets taught into V zero.
And normally I do not like those hex values.
So I would write down with zero as equals zero.
Okay, next we've got this label over here and here we can see how OC this B0 register has now disabled
some and is from type integer.
So I would write this down as a comment over here, but I would like to keep track onto v zero and not
label some.
So I would write down int some.
This way.
And we can move on with the next one here.
We can see OC P1 gets added to the P2 and this restore result is stored into V zero.
And we write this down exactly as it is.
We zero is equals P1 plus P2.
And last but not least, we are returning this register v zero.
And this is the way I like to do this, because by looking into this code we do not have to substitute
those, register with the labels or things like this.
We can directly see, okay, we've got our P one for example over here, we've got the P two over here.
These two gets added.
This means we've got a new value here in this register and this will afterwards be returned.
And here we initialize this register.
So by doing this in this way, it's more clean for me.
But this is my personal preference.
If you like to re substitute those values and stick to the Java code, feel free to do so.
OC Regarding to which approach you are using, this should be always the same.
So take a look into the smiley code and go through this line by line and instructions that are unknown
to you.
Please look them up.
This type of code table is super amazing and I'm doing this most of the time.
I also encounter a lot of new instructions and I look them up in the description.
Maybe I write some little programs to understand some complex instructions, but afterwards, yeah,
I know what they do.
And then I write it down in the following way, as you can see here in this pencil drawing, this one
over here.
And by doing this in this way, even a complex smiley code gets split into single pieces and we can
understand and write this down afterwards.
It's pretty amazing if you take a look on to the left and now realize, well, you understand every
single instruction already in this smiley code, and before you started this course, you might have
even not known smiley.
So this is a huge step already.
And we will get further and further within this chapter.
All right.
Okay.
In the next section, we will extend this program a little bit.
We will add new variables, maybe new functions, things like this.
And by doing this, we will also repeat the steps over and over again.
This might be a little bit boring, but by repeating this, you will get more and more familiar with
Smiley.
And after some point when it makes click, you stare at some smiley code and you realize, Whoa, I'm
able to read this smiley code in the freaking amazing.
Believe me, you will have this moment.
All right.
So I'm looking forward to see you in the next section.