Time
9 hours 10 minutes
Difficulty
Advanced
CEU/CPE
9

Video Description

Welcome to the Basic Static Analysis - Part 3, where we would be covering Calling Conventions. We'll begin with understanding of the calling conventions. In cdecl (C declaration) function, the caller is responsible for cleaning up the stack. While for stdcall (standard call), an API developed by Microsoft, the callee is responsible for cleaning up the stack. The hands-on demonstration will engage as part of the module and would include the following:

  • The key differences between a cdecl call and stdcall.
  • Different ways assembly code is generated.
  • Several assembly instructions such as PUSH instructions and how they work.
  • How compilers, debuggers, and disassemblers work with assembly.

Video Transcription

00:04
Hi. Welcome. This I bury my name is Sean Pierce and on the subject matter expert for instruction to malware analysis. Today we're gonna be covering calling conventions and exiting six assembly.
00:14
So what exactly are calling conventions? Well, in simple terms, when a function call is made with parameters, the assembly code will do a series of pushes to push those primaries onto the stack in reverse order.
00:29
And then we'll execute the call instruction and the call instruction as its operandi. It's
00:36
second part of the instruction eyes, the location of the function call.
00:41
And in most code,
00:43
the caller is responsible for cleaning up the stack.
00:47
So
00:48
the instruction right after that call instruction
00:52
is usually a sub
00:54
e S P instruction
00:56
where the stack is being cleaned up
01:00
because
01:00
the caller had just pushed a bunch of values onto the stack. If it pushed three values on the stack and pop three values, that would work just as well.
01:11
But, uh, I'm sorry. It's not sub e S p. It's ah like Addie sp.
01:18
The other major calling convention is standard coal. It's actually something made up by Microsoft and its how it it's a P I works, and it works pretty much the same way where it pushes the parameters in reverse order and the Kali. The only difference is the Kali is responsible for cleaning up the stack
01:38
so
01:38
you'll see in a standard Cole. There's push, push, push, and then
01:42
a coal.
01:44
And then right under the coal is
01:48
no other,
01:49
uh, parameters.
01:51
And there are no other like stack instructions like Addie SP
01:57
or add something TSP or,
02:00
you know, pop, pop, pop or whatever else. And inside that function Cole,
02:08
that function cleans up the stack. It does pop pop pop at the end, or it'll do
02:15
a ah
02:16
Rhett for or whatever. Where is it? It is explicitly saying
02:22
I am going to fix the stack
02:25
and you might think, OK,
02:28
that doesn't matter very much. And you're right, it doesn't. The compiler just needs to choose one be consistent or or not. For instance, it can. It can do some pretty cool optimization Sze like with recursive function calls and
02:43
we're not gonna look ATT.
02:45
Some of the more advanced cases of how compilers cannon optimize code really well,
02:50
but you should know it is rather expensive toe push
02:53
time wise to push something onto the stack
02:58
or to pop it off. So we're gonna look at an instance where a compiler
03:01
might choose to do it a different way.
03:05
But for now,
03:06
we're gonna look at the difference between a standard coal and a C declaration call.
03:12
And we can actually do both in the same program,
03:15
you know, with
03:16
no instructions right next to each other.
03:20
And then I'm going to show you the different ways that data can be put onto the stack as just kind of a preference thing by different compilers. We kind of saw some differences between D. C. C and visual studio last time, and I will show those really quickly getting this time. So here we have our hello world function again. But
03:38
this time
03:40
we're going to have two variables that are going to be
03:45
passed in
03:46
to the print F function,
03:49
along with a another parameter the format string.
03:53
So if you're gonna print hello world
03:55
and right under that is a P I function, call hold message box A, which just pops up. Ah, message box.
04:06
So
04:08
we're going to just debug this,
04:11
build it,
04:26
Okay,
04:27
I'm going to go and generate the disassembly.
04:30
We can look at it side by side if we want to.
04:35
So
04:36
up here we see push EVP
04:42
move ESPN tvp
04:44
and in sub d s. P.
04:46
So
04:47
these are the beginnings of most functions most or what we would call procedures or,
04:55
uh,
04:57
subroutines is what the old terminology is for it. Um,
05:01
the push EVP
05:02
takes the current base pointer
05:05
and then pushes it onto the stack. So it's kind of saving that value,
05:11
and then it takes the current
05:13
E S P at the bottom of the stack or excuse me, that the top of the stack and puts it to E v. P. So what you're essentially saying is
05:24
I am going to
05:26
save
05:27
where my current E V p is,
05:30
and then
05:30
wherever my e S P s,
05:32
that's my new
05:34
base of the frame. So that's where I'm going to start
05:39
counting my values now.
05:42
So as soon as this move happens, E d P and E S P E are the same value there. Pointing to the same location of memory move doesn't mean
05:50
like move is and
05:53
what you might think of it, uh,
05:55
in terms of like, copy paste, but move is more like a copy.
06:00
It doesn't zero out anything.
06:02
So
06:03
when you
06:04
have these two values that equal the same thing, you have a stack frame
06:10
of
06:11
no size
06:13
and then we're subtracting
06:15
08 d.
06:16
I'm sorry. Zero D eight
06:18
hex
06:20
bites from E. S. P. So we're extending our stack. So now we have
06:27
d eight hex bytes available
06:30
on the stack that we can use for storage of variables, mostly local variables. Um,
06:38
that's pretty much the only local variables should be stored on the stack.
06:44
So what does it do that?
06:46
Well, there's a push,
06:48
push, push.
06:50
So it's saving Maur registers onto the stack. And this is another type of convention it's not. Call your collar convention. It's
07:00
the compiler deciding that the Kali
07:03
should save the registers
07:05
so
07:08
it can't rely on the fact that the code cannot rely on the fact that if it makes a call instruction,
07:15
that
07:17
bill, it's registers will still be the same values
07:21
these air general purpose registers like we were talking about last time. And that means they could be used by the code for anything.
07:30
And you really shouldn't think
07:32
that
07:34
if you call something or jump somewhere or do something, that the
07:40
registers will still be the same value afterwards. So a lot of compilers
07:46
uses convention
07:46
where it seems the registers it's gonna mess with
07:50
on the stack, and then right before going to exit,
07:55
it'll pop them back off. So if you go down to the bottom, we can see that it's popping those
08:00
original three values
08:03
back into there
08:03
registers. It doesn't know what what's in those registers. That may not matter. It may not care. It's just kind of safety thing. It's just, you know, just in case. The code calling this one main was relying on the fact that it could still use those registers,
08:20
which it shouldn't,
08:20
um,
08:22
it's saving that. So it's just being good.
08:24
Code up Compilers may optimize this out, but, ah, this convention
08:31
in the X 86 official
08:35
um,
08:35
manual by Intel,
08:37
they say, Do not expect that these registers will be saved,
08:41
but compilers try to save them anyway.
08:46
So what's it doing next?
08:48
It does L E. A.
08:50
Which is loaded, effective address,
08:52
and it's
08:54
this. This is really a shortcut, used a lot of times to generate to do some quick math
09:01
because you can combine multiple additions, attraction multiplication operations together and it's pretty fast. But in this context,
09:09
it's same
09:11
what is E. V. P. Minus my stack size?
09:16
And then it grabs that location
09:18
and then puts it,
09:20
or it grabs the value at that location and puts it into E. T. I.
09:24
What's that using for? I don't really know just yet.
09:31
So the next instruction is It puts the value of 36 hacks into a E C X, and it's moving
09:39
the this value and to eat a X. And, uh,
09:45
I know what this is now because since I built this program
09:50
using debug right up here,
09:52
it's adding some extra half safety net type code.
09:58
So
09:58
if
10:01
this code
10:01
is executed
10:03
by accident, like if we have a buffer overrun,
10:07
Ah, or we something goes wrong and the e I P
10:13
starts executing
10:13
the stack code.
10:16
Uh, it'll break here. CC
10:20
is the instruction
10:24
and three,
10:26
which is interrupt
10:28
three, which is software interrupt, which means a little signal, a debunker
10:33
that something has gone wrong.
10:37
This is a repeat string instruction,
10:41
so
10:41
that has to do with E D. I
10:45
Yeah,
10:46
we'll see.
10:46
That has to do with, um,
10:48
the destination register and the source register.
10:52
And
10:54
we can see here
10:56
that
10:58
it's gonna use
10:58
the value at this address.
11:01
And then whatever E s I
11:05
Yeah, whatever E. S. I is pointing to eyes generally
11:11
what the string operation will use or generally the value and e s I and Edie I with this, the string
11:18
instructions do, and these repeat instructions can act as a loop.
11:22
Not a whole lot of compilers will produce these instructions.
11:26
Um, because they like to have more control.
11:30
Oh, are they would like to manipulate the logic in there,
11:33
loops of it more. But ah, the string operations were made by Intel because they noticed, ah, lot of the processing power their chips were doing were string operations.
11:45
But, uh,
11:46
they weren't that much faster than the other ways Compilers figured out how to do them.
11:52
So not that common. But you still see him every once in a while
11:56
so we can see
11:58
hello being stored in too far one.
12:03
And that's what this instruction down here,
12:05
where it's basically
12:07
storing, borrow.
12:07
There's a reference here. This is a memory reference to ever This string is stored in memory
12:15
and storing that address
12:18
into location of variable one.
12:22
And we're doing the same for
12:24
credible to.
12:26
And here is really what I want to show you.
12:28
Print F
12:31
is taking three parameters.
12:35
The 1st 1
12:37
It's gonna be a bar, too.
12:39
So it's going to do this maneuver
12:41
where it's gonna move
12:43
the location into E. X and then push e X. So
12:48
this is a string
12:50
and a string.
12:52
It's pretty much character array. At least one if we're keeping it simple.
12:58
It's a character array
13:00
of
13:01
Ask e one bite, one bite asking values.
13:05
So
13:07
when we
13:07
push
13:09
from right to left
13:11
and we're pushing it in the opposite order,
13:16
we're gonna go from Bar one
13:18
of order.
13:18
I'm sorry far to borrow one,
13:22
and we could have used a X again,
13:24
But the compiler decided to
13:26
store bar one E. C. X,
13:31
and then it pushes E. C X,
13:33
and then it pushes this last value. This memory value must contain a reference to this format string.
13:41
And then this call is performed
13:45
where a print off is then executed, then right after it,
13:48
We see an ad E s P
13:52
on zero c.
13:54
So zero c
13:56
was
13:56
the damage done to the stack by this push this push And in this push,
14:03
so that was
14:05
12 bytes. Their push for here. Eight here, 12 here and 12 and hex is C
14:13
zero x zero x zero c is
14:18
the standard way of writing it. But if you also if you put an H at the end of it, we know it's hex.
14:26
So that
14:26
was See, Dackell?
14:30
So this is pretty common. This is, you know, the standard See libraries that it's using. And that's the calling convention
14:37
standard Cole made by Microsoft and pretty much on Lee used by Microsoft. So not really standard at all.
14:45
It's called, It
14:46
does the opposite.
14:48
So for this line of code,
14:52
we're gonna do something similar we're going to
14:54
Ah,
14:58
yes.
15:01
I don't know why that instruction was produced.
15:03
Uh, so it's gonna do a push.
15:05
So that was this. No bite or zero. That's gonna do another push for the reference to this string.
15:11
Another push
15:13
for the reference to this string.
15:18
The reference to this string,
15:20
and I'm gonna do another push
15:22
as a reference to this zero
15:26
then is going to do a call.
15:30
Now this call looks a little weird
15:33
and that's because it's stored
15:37
the location of this function
15:41
at this location.
15:43
This D S is data segment
15:46
and D word means 32 bits
15:50
and PTR means pointer.
15:52
So
15:52
it's a 32 bit pointer in the data segment.
15:56
So
15:58
this is part of our I A t e r,
16:00
um,
16:03
are
16:04
import address table
16:07
and
16:08
you don't know what that is. That's okay. It's part of the p E file structure.
16:12
It is important. So you should get to know it down the line.
16:15
But for now, just know that location
16:18
of this function is stored here,
16:22
and we can see it a bit more elegantly and here in a minute.
16:26
So afterwards,
16:29
there is no, uh, ad E S P.
16:33
So
16:33
this function, this message box a function
16:37
cleaned up the stack
16:40
it at some point
16:41
did ah, minus 16
16:45
bites or it added 16 bites to E. S. P
16:52
to clean it up.
16:53
So you might be curious to see what
16:56
while other code is here. This is
17:00
you know, compilers will insert code for you.
17:03
And ah, lot of that has to do with performance or security checks to make sure stack isn't corrupted or something
17:11
or to set exception handlers,
17:14
Ah, ch handlers
17:17
and,
17:18
uh, especially in debugging code because I built it in debug mode.
17:22
It'll produce
17:25
extra kind of security checks and rapper functions and stuff to just double check things. And then this last instruction this instruction is very, very common. You should really get to know the X or, uh, excellent e a taxi exit. It will make e x zero and
17:41
the return value
17:44
is
17:45
kept any axe. So return zero means
17:49
turned yea x to zero and then used the rep function,
17:55
which is down here.
17:57
And here's ah,
18:00
you know, the pop pop pop that we saw earlier and
18:03
another
18:06
double check
18:07
to see. Make sure that ah, the E S p is correct.
18:11
And so, while we're in debugging mode,
18:15
we're trying to figure out why something isn't working like a particular
18:19
function in 1/3 party libraries and working, you can work out.
18:23
Maybe Why? And as I was saying was I mentioned this the CC
18:30
uh, bites
18:32
before These are
18:34
the instructions a CC disassembled. So if you looked at this in a hex editor, be just B c, c, c, c, c, c, c, c, c, c, c, c, c and et cetera. And this is also in case you are code kept executing the on this return value. Or maybe jump was off and jumped down here or something like that. It happens
18:53
from time to time.
18:56
So if we want to look at this
18:59
Ah,
19:00
in a disassemble er
19:03
without an I d
19:04
we can with Ida.
19:07
If we didn't have the source code
19:11
like
19:11
we often don't for malware,
19:15
we would find this very useful somebody. Hello?
19:18
The project we made last time I'm going to go to
19:22
do you both because that's what we were just looking at.
19:26
Disassemble it
19:29
a saying that it noticed that there is some debugging information in there.
19:33
Uh, does it want to try? Does it want to retrieve the file to say no? Because we usually don't have that file.
19:41
I say, No, I don't really like the proximity of you,
19:44
and this might seem pretty innocent, and you might click through it and try to find
19:49
where
19:51
your
19:52
you know a few lines of code were,
19:55
but, uh, remember when I was saying there's a lot of added
20:00
a lot of added code, a lot of, uh,
20:03
protections built in for the stack
20:07
for performance to help de buggers.
20:11
Well, this is it. So
20:14
last time we went and
20:17
jude the strings
20:18
and found the strings that we knew were reference. But I'm going to show you another technique that's very popular with reverse engineers. And probably the most common technique is that we go view the imports. These are all the functions that our program
20:33
has requested. The call, and you might look at the sneer, just like, Hey, I didn't call that function quarry performance performance counter or get current threat I d or any of that. And I know that's more than debugging code and just
20:47
other boilerplate code that Microsoft will insert in there when it's inserting its see libraries or
20:56
whatever else.
20:57
So
20:59
we call the function
21:00
message box, eh?
21:02
So
21:03
I'm gonna go there.
21:04
I'm going to see this at that location.
21:07
If I hit X,
21:10
I can see where else this memory address is reference and memory.
21:14
And over on the right,
21:18
right here,
21:18
you'll be able to see that it's reference in two places. But if I want to get a list of all of them, I can hit X
21:26
and I can see that,
21:30
Uh, it's cold
21:32
right here.
21:33
So these two values are the same address.
21:37
And if you look over at type one is a pointer and the other one is it's being read is what the R stands for in the P stands for and below it, there's a jump. So something is jumping
21:52
there.
21:53
So we're just gonna go with where we know this thing is being called.
21:59
And
22:00
if you remember, this function was a thing built into
22:06
this program by the compiler, and it was like, you know, check. Yes, I are,
22:11
Yes, p
22:12
whatever was checking it was checking something about the stack.
22:15
Um,
22:18
but we pretty much get the same instructions that we saw, you know, with the same CC values. The same,
22:25
you know, push, push, push, push, push, push. And
22:30
so
22:30
Ida doesn't actually know
22:33
what the stack was used for.
22:36
These weren't assembly instructions that's figured out that based on
22:40
how the assembly was referencing
22:42
the various values in the stack. It said, OK, there's probably three local variables in here. They got that right sometimes gets it wrong,
22:51
especially with, ah arrays.
22:53
But it also figured out that this function was Message Box, eh?
23:00
And so it's said Okay, Message box A, according to Microsoft, has thes parameters and it knows, is calling them or it's going to push them onto the stack from right to left in reverse order.
23:12
So it's said Okay, what were the last four pushes?
23:17
And it's like, Okay, so that was the primer to that. It was You type the parameter to this is caption the parameter to this is text and the president of this is window handle.
23:27
So
23:29
it's very kindly provided, um,
23:34
hints as to,
23:37
uh, what the primers to this meshes box is. But be warned that sometimes the analysis gets a little messed up, and it might
23:48
be a little off, so these air helpful, but you should not just completely rely on them.
23:53
It's also very helpful that it put a little comment here and said, Hey, this is referencing
23:59
Ah, Pointer!
24:00
And that pointer is pointing to an ask e string. So it's gonna guess that This is a string,
24:08
and it names the A for asking and then whatever the string is,
24:12
so that's very helpful.
24:15
We could also rename things in Ida.
24:18
So if I click this and hit end,
24:21
I can rename this variable, too,
24:25
for one.
24:27
Rename this variable too far, too.
24:33
And then I just named this
24:37
format string.
24:42
Mmm.
24:45
So
24:47
I know this is print F.
24:49
That's what it said in
24:52
my D bugger. And that's what's said in my source code.
24:56
But this is showing up his sub short for subroutine and then
25:00
a number, which is the memory address that is going to
25:03
so I can click on it and then scroll down and get a peek of what's there. And it looks like there's just a jump there
25:11
so I can follow his jump by double clicking
25:15
on
25:15
the label, and
25:18
I confined all this other stuff. I like to highlight the calls on jumps, and I can see that it's calling into several other things. And I'm just thinking,
25:27
you know, is this print off? Is this something else? While, as it turns out, Microsoft
25:33
doesn't actually include
25:37
the sea
25:37
libraries that are standard. It made its Microsoft implemented its own See runtime libraries.
25:45
Uh,
25:47
usually they're bundled with See visual See runtime libraries or V C
25:51
um, run time.
25:53
Whatever there's there's a lot of programming at libraries out there for programmers to use,
26:00
but they're pretty standard.
26:00
But these are not
26:03
This is not it. Uh, this is Maur,
26:07
uh, debugging code. And it's also more code to check certain things.
26:14
Like the proud owners that you gave
26:17
print f were safe because there have been vulnerabilities. But they can't change the functionality
26:22
of
26:23
standard library calls because,
26:26
uh, maybe that might break old software if you tried to re compile it.
26:32
So we know somewhere down this line there's gonna be a print F or equivalent thereof.
26:40
So I happen to know
26:41
what exactly this programming dysfunction call is.
26:47
So I'm gonna go over and look in the imports tab.
26:51
It's gonna be underscore. Underscore something
26:55
because,
26:56
uh,
26:56
that's generally with a
26:59
name it. I can search by hitting control F, and it's typing in print.
27:03
I can see it right here towards the bottom, but I'm gonna type in print anyway.
27:10
So there's two function calls
27:11
underscoring the score. STD io
27:15
underscore common the F print us
27:18
and then above it is s print off. I'm score s
27:22
So the compiler is doing its best to protect us from being dumb programmers,
27:29
and that's very nice.
27:30
Um,
27:32
and we can see if we hit escape, we can go back and our analysis, and we can get to our original stuff
27:37
and you'll notice that this function wasn't named Maine.
27:41
And you can see
27:42
with the X, you can say what
27:45
is what has a reference to this location.
27:48
You can see there's a jump.
27:51
What? Has a reference to this location?
27:52
Jump further back has a reference to this location,
27:56
you know? And then you can't keep going like that.
28:02
Uh, click that hit X on that and see what calls that function.
28:06
Um, we can see there's more checking code for RV Park Si,
28:12
and for preparation code for us,
28:15
we can jump. See what calls this?
28:18
We can see that. Ah,
28:23
that were
28:26
another function this
28:29
And
28:30
so
28:30
if I was curious to see what function calls this
28:34
function
28:36
made,
28:37
I can say, uh, I could go under,
28:41
uh,
28:41
view
28:42
and then graphs, or it can right click
28:45
and
28:47
say
28:48
uh, extra s graphs
28:52
from
28:52
I could see that this function
28:55
call
28:56
this function
28:57
and then this function
28:59
and then this function,
29:02
so that could be useful. If you're trying to get an idea of what a function does because
29:08
you can use this graphing recursive lee, and you can say, OK, I know
29:14
you know, this function has a bunch of functions that calls,
29:18
uh, what are they? How many of them are libraries? Because, ah,
29:23
if you the pink
29:25
labeled function calls or function names are those libraries or functions that Ida has referenced or Ida has recognized.
29:36
So if we want to see this,
29:37
uh, actually executing
29:41
and we didn't have the original source code, we can always crack open all the V bugger
29:55
start. Hello, don t x c.
30:02
And here Ali is looking in libraries and analyzing them.
30:07
So we might not always No,
30:10
uh exactly
30:11
where are code is just similarly to, um
30:17
us not knowing where this code was in, Ida,
30:19
we might not know
30:22
where the code we want is in
30:25
on ladybug,
30:26
so we can do the same sort of thing
30:29
where we can right click
30:30
and then find, uh,
30:33
sorry, it search for
30:34
all in her module, Coles
30:37
and we can look for And that basically looks for call instructions.
30:44
We can find the call instructions. Like to message box, eh?
30:49
So we could go there,
30:52
uh, and see the same sort of
30:55
push, push, push Cole
30:57
on. Dhe said a break point. We can do that with, like, two,
31:02
and this will set a soft breakpoint. So behind the scenes it's actually putting. And
31:07
three construction there
31:11
or a C C bite
31:14
and then when
31:15
this
31:17
code gets executed will stop there,
31:19
And then the D bugger will take over and then replace that bite with the original bite that was there and then begin to execute
31:27
as if nothing had ever happened.
31:30
So
31:32
I'm gonna put a great point here
31:34
where the entrance to this
31:37
main function is which all he was kind enough to recognise removed this break point
31:42
playing.
31:44
It ran. It has now stopped at my break point.
31:48
And now I can do the same sort of step over
31:52
that I could with visual studio's de bugger.
31:55
Now this is important.
31:59
Here, let me start over.
32:02
I'm sure. Yes.
32:07
My break point is still there. someone hit Playing is gonna go break point
32:09
And
32:10
the first instruction was pushed EVP.
32:14
The next one was yes. Movie ESPN tpp. And as I was saying earlier, This is important because
32:22
here the stack is going to be manipulated.
32:24
So this first
32:27
thing that's at the top of the stack a k a. The lower memory address is the return function from the previous
32:34
core.
32:35
So the previous function that called this one
32:37
said Okay, call
32:40
101780
32:44
So it pushed
32:45
E i p onto the stack.
32:47
So e i p was going to execute this instruction next, but said the call
32:52
force it to come to this address. So now I'm going to make my own stack here.
33:00
So how do I do that safely? Well, the first step is
33:04
push EVP so I save the current base pointer.
33:08
I'm gonna move e s p e e v p. We can see e b p was just overwritten here.
33:15
It's now the same values E s P.
33:19
Now I'm gonna make room on the stack.
33:23
So
33:24
sapo over
33:25
and sub
33:28
And it took
33:30
a d eight bites
33:31
and
33:34
so we can see here
33:36
on the stack is now allocated all of this for us
33:40
for to use and, uh, local variables and see how they're all filled with C. C's.
33:45
That was the depot.
33:49
That was the debugging code that was added in
33:52
because we didn't say this was released ready so that, you know, this thing probably has bugs, and we're gonna wanna fix them. So, uh, just in case any of this could gets executed, the D bugger will kick in and say, Oh, something wrong happened.
34:05
So now we have a local stack frame.
34:08
So now we're going to We're about to execute another function we're gonna or in our saving the registers
34:15
push, push, push.
34:17
It doesn't know within them, doesn't care. It's just trying to
34:21
make sure that
34:23
those values air now saved.
34:29
So now we're going to.
34:34
So this is important
34:37
where
34:37
the string hello
34:39
is being stored in a local variable on the stack
34:45
so it can do step over.
34:49
And now we can see a reference to the helo String is right here.
34:55
Step over again. And now Hello. Now, world is, uh,
35:02
again being used. Now if
35:06
we used if we're debating
35:07
the release version,
35:09
these CC bites would not be here.
35:17
Step over is gonna push yaks.
35:21
It's gonna push
35:22
world, and then it's gonna push the format String
35:27
and Ali D book
35:28
was nice enough to say, Oh, print Fok. You at least have to have one parameter. And that's a format string because it doesn't know how many primaries are gonna get pushed in tow.
35:37
Uh,
35:37
print off
35:38
function
35:40
call or pushed his parameters. So
35:45
now I'm gonna make this call. I'm just gonna step over. I could step in and watch it actually do exactly what it says it's going to do.
35:53
I can even flip over to the tab and Seo to print out. So
36:00
we noticed that Ah,
36:01
the values are still on the stack here.
36:06
And now, as I step over
36:07
the next instruction, did this ad E S p zero c?
36:12
So now the stack
36:14
frame has decreased.
36:16
The data is still there on the stack,
36:20
but the stack pointer
36:22
the extent is Doc Pointer E S P is now pointed here.
36:27
It's not pointing lower. So as far as the pilot is concerned, as sorry as all these instructions are concerned, this is now the top of the stack. These other values don't matter. They don't care about him. They're gonna override him.
36:39
They do anything else
36:40
there, they no longer exist.
36:44
So
36:45
step over again
36:46
is gonna push zero. Um,
36:49
push. Hello, World push alert. Push zero.
36:53
And then Cole
36:55
Ah,
36:58
Message box, eh? So watch carefully, because
37:00
while the S p is up here, as soon as we're gonna call it, the Kali function is gonna clean up the stack.
37:10
New modules are being loaded, and all these analyzing them is disassembling all their code.
37:15
Those are some pretty big deal Els.
37:19
So
37:20
just a minute.
37:22
So now there's a pop up that's happened. And that's what dysfunction does
37:25
hit. Okay, now, that function finished,
37:29
you can notice the stack has cleaned up,
37:31
and so
37:34
it didn't need to do that. Ah,
37:36
the ad e s p
37:37
So
37:39
that's pretty much the major difference between those calling conventions. And you should be aware of thumb.
37:47
And I don't really care what happens to the rest of this function. So I'm just gonna terminate the process
37:53
and take a quick look
37:55
that
37:58
the release version.
38:05
So it's stopped in what looks to be the same place. I'm slightly different. Boilerplate code.
38:09
Um, there's the ch
38:13
the, um
38:15
exception handling,
38:15
uh, code.
38:19
So we're gonna find the
38:24
inner module. Cole.
38:28
Find references to
38:37
search for inner module calls.
38:40
Go to message box, eh?
38:45
See the world?
38:52
This
38:52
looks like it's calling print up from there.
39:00
It's about right.
39:02
So here's another function. Call up or here's some more coat up here and separating. The code is in three,
39:09
just in case something
39:10
overran where it's supposed to go.
39:15
Say, step over,
39:17
it's over and we can see it doing this stack manipulation.
39:22
It didn't subtract nearly as much
39:30
there. It's doing some checking
39:36
there. Here's where it's pushing
39:38
the, uh,
39:40
parameters to print F,
39:43
and
39:44
it's that special
39:45
print F function that Microsoft made. That's a little safer.
39:51
It does some
39:52
more parameter pushing for another little function call. It's going to make,
40:00
which is the V F print off,
40:09
and that finished, Which is means that printed to the screen.
40:15
And now it's fixing up the stack
40:23
on this stuff
40:32
so
40:36
you'll notice.
40:37
It says add E s P. Zero See here
40:45
is cleaning up the stack and now about to start pushing
40:47
for the next function call, which is Message box, eh?
40:52
Push, Push!
40:54
Cole,
40:57
I'm gonna switch over to wherever I need to call. There it is.
41:01
And then it's ready to in this function, which is returned zero, which is
41:07
easy quickly to do. It's excellent. Yea x e x,
41:12
as I said before,
41:13
and I'm
41:14
much done with us. Exit out
41:20
so quickly and cig win.
41:24
We noticed that the compiler changed in visual studio from
41:30
ah,
41:31
what functions it was calling based on the release. And what
41:36
how
41:37
what wrapper functions that had
41:39
And cig one is another has uses the G C C compiler, the gene you see compilers what it stands for
41:45
and
41:49
it will produce a different code as well.
41:52
Every compiler has its own little
41:53
huh?
41:55
Programmers, that made it so it's kind of important. So here we demonstrated that, uh, I've compiled this program just like I did in visual studio.
42:07
So now I'm going to
42:10
go find that program.
42:14
Si sigue win
42:15
home, Sean.
42:19
Hey, that you see?
42:22
And I'm gonna crack it open and ida and see what kind of code it produced.
42:36
So cig win
42:37
with G C c. Insert a lot of extra code.
42:43
This looks to be some parameter checking,
42:45
but I'm gonna go and find the code that I'm most interested in.
42:51
And I see message box A right there.
42:55
I'm gonna go X.
42:59
I'm going to say OK, it's only reference in two places. One is a call instruction and the others and move instruction, the call instructions, what I'm interested in
43:08
and this is something that I really want to show you in that, uh, Like I said, push instructions are very expensive, time wise. And so some compilers have moved away from them
43:20
and
43:21
the G c C compiler in this case
43:23
Ah,
43:24
when
43:25
instead of pushing into the stack, it simply does a move. So it moves
43:32
the variable
43:34
onto the stack. Because you can do that. You could move,
43:37
um,
43:38
your register
43:40
or the pointer to the string. Um,
43:44
the pointer restored and Farsi.
43:45
You could just move that
43:47
into the stack.
43:50
And
43:51
this way he doesn't have to push,
43:53
but it does have to make sure that stack is the right size by time. It calls print F.
44:00
So
44:00
the compiler
44:01
is being
44:04
a bit
44:05
more advanced
44:06
and how it's trying to do something
44:09
Similarly,
44:12
when it calls message box, eh?
44:15
It stores,
44:17
Uh, it does another little trick.
44:22
Which malware will do frequently,
44:24
in which
44:25
we'll have a function pointer
44:29
and store that function pointer in a register and then call that register?
44:32
This makes it very hard for disassembly hours to figure out
44:36
what functions are being called from where,
44:39
unless it's more intelligently guided pro. But even then, I'd approve will frequently not catch
44:46
this little trick.
44:51
So
44:52
afterwards you'll see sub d S p.
44:55
It's not cleaning up
44:58
after
44:59
this function. Call because message box A will clean up after itself.
45:04
It's cleaning up for
45:06
all the instructions before it. So these to function calls.
45:09
So,
45:10
uh, G. C. C. Is trying to be a bit faster than the maximum visual studio's compiler.
45:17
That's it for this demo. I thank you for watching we covered Standard Cola versus See Tackle. We looked at different ways. Code has generated, and he steps through a lot of assembly there, and we talked about
45:29
how compilers will choose to do certain things
45:34
how in one instance, ah, lot of push instructions were used to get data onto the stack and then in another instance, with GCC, it'll just move
45:44
the data onto the stack and instead of pushing and then
45:50
we'll clean up the stack
45:51
when it's done with it
45:53
and the next video, we're going to do some stack analysis on some actual malware,
45:59
so
46:00
hope to see you there.

Up Next

Intro to Malware Analysis and Reverse Engineering

In this malware analysis course you will learn how to perform dynamic and static analysis on all major files types, how to carve malicious executables from documents and how to recognize common malware tactics and debug and disassemble malicious binaries.

Instructed By

Instructor Profile Image
Sean Pierce
Instructor