Everybody and welcome to the next video.
So in this video we're going to be going over saving state now.
We're also going to be going over how to build functions in assembly.
Now the reason these two kind of go into play is we've briefly talked about this in another videos but
when you create a function in any language such as Python or an assembly what happens is is the stack
you get your owns section of the stack as well as all of the variables and registers and everything
is different when it when the function runs because the function can do ten thousand things.
But when the function returns it needs to provide the stack needs to be put back in the registers need
to be put back into their correct alignment that they were before the function was called.
So what do we got here.
We've got our basic setup right.
So what we're going to do first is we're going to do we're just going to define a string define a bite
we'll just call this
red team
to nation and 0 0 8 for our new line and then we'll get the length.
So what we need to do first is before we make a function call we need to push onto the stack the registers
all the contents of the registers and the CPA flags which will come important later.
Now there's you can do this manually and go through and push every single register onto the stack in
a specific order and then pop them back off.
However what we're going to do is we are going to use Maxim's function or command to do this.
Now all that's going to do is replace it with all the same single parameter or single instruction so
moving so it's to put it into a different term so to push on something onto a stack you use push and
then the register so or push whatever text you want or whatever hex you want and then to pop it off
the stack you do pop and then the register that you want it to go to set and then it takes the next
X bytes and puts it onto them and puts it into the register.
Now we're gonna we're gonna see examples of that in this particular video.
So the first thing we want to do is before we make a function call we want to push the registers.
Now to do that with Nazism we would do push 80.
Now what that's gonna do is that's going to push all of the registers onto the stack for us.
Then what we're gonna want to do after that is push RFD for the flags.
Now that's going to push the flags over to the registers or to the stack.
Now we've got our registers pushed onto the stack and then we've got our flags sitting on top of that.
Now the order of this is important because remember a stack is first in first out so with this we'd
have to if we wanted to reverse it.
So we'd give ourselves a little bit of space so when we complete the function call we want to reverse
this.
So we want to do a pop RFD so we pop the flags off and read and reset the flags to what was on the stack.
And then we do a pop or 80 pop 80s will pop everything in the next sets of information off the stack
and put it into the registers themselves.
So this is how we save the state.
So at this point we've saved the state everything in between these two.
These four calls are going to be done.
We can do whatever we want to the stack whatever we want to.
The registers and as long as we follow some key important behaviors which we'll go over in a second.
We'll always be able to return to normal functionality.
So how you call a function in assembly is call and then you give it a name.
So this could be a memory address or this could be in our case we'll use something called a label which
is just a text version of it so we can reference it quickly in source code.
So we'll do a print text.
Right.
So case sensitivity is still important what we'll do is we'll go above this and we're going to do print
text.
That's it.
So it's very very similar to start because start is in itself a function.
That's all it's doing.
It's just an initial entry point but as far as the assembly code is concerned it's still treated as
a function.
So if we change this global underscore start to global print text it would run print text instead of
underscore start.
So now we've got our code block right so the first thing we need to do is when you call a function in
assembly you need to do an epilogue.
Now what this is is it keeps track of EDP which is the base pointer and then it also keeps track of
ESB.
So what you first want to do is you want to push the contents of BP or the base pointer onto the stack.
So we do push BP.
Now this is because we want to be able to recover from this later.
Now BP could would have whatever we've used in the previous application.
So in Start if we had set something to BP.
This is just so it can be restored later because we're using BP to hold the ESB which is the instruct
which is the stack pointer so ESB is the is the stack pointer.
So that points that is the memory address of the top of the stack.
And that is a very important registry.
That registry gets messed up in any way you're going to end up popping things off the stack and setting
registers to weird values that it wasn't meant to happen.
And then one VIP starts executing the code it's not going to do anything it's just going to it's just
going to break depending on what data is in there it's going to break in different ways.
So we've got our EVP and then we're going to move
DSP into EVP.
So now our HBP register is holding our stack pointer of our current spot right here.
So now the flags and the registers data the tip the flags data which is the last bit that we added in
has a certain memory address associated with it.
That's what it is in ESPN so we're saving that to EBV.
Then we go ahead and do whatever code we want.
That is our epilogue.
So this right here that's an epilogue and you'll find that pretty commonly if you start doing our reversal
or debugging of applications in assembly you're going to see a function of the logs similar to this.
Now in our case we're in do something simple we're just going to move 0 4 in x.
We're just gonna basically print something to the screen.
So move X we'll do string and then move ADX string with the length and then we'll do interrupt 0 8.
Right.
So we've done it we've done our print statement.
However we've done our epilogue so we need to do our prologue.
Now there's two ways to go about this.
You could do move ESB EVP and then pop EVP off the stack which will then reset the value to what we
did up here.
Now you can do that.
That's completely fine.
However what we're gonna do is we're going to let Nasim take care of that.
Nazism has a command called leaf that will just interpret run those commands specifically.
So leave will just run the opposite of what we did for our epilogue.
And this is a prologue then in assembly we want to return to the next to the previous application so
right now if we did this we would go through we'd push these onto the stack the registers and the flags
we'd call the print statement it would come back down and then push the registers and flags again and
then keep printing so would just keep printing however we want to be able to return.
So this is just a read all that's going to make sure we come back to here now with our EVP or PSP now
reset to the corrective pointer or the correct memory address we can then pop off the flags which will
then reset the flags with the correct values and then we pop off the registers and now we're back exactly
where we were when we started then we can run our our exit which we can do normally.
So let's go ahead and compile this perfect and we'll go ahead and link it.
Perfect.
Go and run it.
There we go.
So now we've got functions working we understand the prologue and epilogue and how we're how we're going
to be staving registers and flat the CPO flags onto the stack and popping them back off now again with
assembly it's very important that you keep track of registers and flags at any point in time because
if something gets messed up there's no error handling to fix this you're going to have to fix it yourself
or fix the code that caused it to mess up.
Now this is going to take a little bit to sink in.
So let's go over the code download the source code that I have above the video it's got a lot a lot
more comments and descriptions on certain things.
Go ahead and reread it if you don't understand anything.
Reach out to the Facebook group.
Everybody is more than happy to help you but play around with this.
Make another function.
Maybe have one down here that does something else maybe it reads from something reads a file.
We're gonna go over how to read and write the files but take a look at it see if you can figure it out
right now on your own with what you've already what you understand now.
So go out and play with it understand this.
It's important when looking at assembly to be able to see when stacks and and registers and flags are
being saved.