chevron_left chevron_right
Login Register invert_colors photo_library


Stay updated and chat with others! - Join the Discord!
Thread Rating:
  • 1 Vote(s) - 5 Average


Tutorial Reverse Engineering 101 - Part 3 filter_list
Author
Message
Reverse Engineering 101 - Part 3 #1
In the last part, we saw how to do some basic branch and subroutine tracing with the flow of control. In this edition, we are going to have a close look at variables and data manipulation.

I want to run this one a little differently. So, I will give you the original code up front, but I'm going to put it into a spoiler. For those of you who want or need to see the code before we start, you may look. Keep in mind that in the real world, getting the code is our goal, so we obviously don't have it up front. Try and avoid looking at it as long as you can, hopefully this will force you to think through the logic.
The code is in this spoiler.
Spoiler:
[Image: pLWsYHe.png]



Ok, since I'm assuming you havent looked at the code, we're not going to start off with a disassembly dump. Instead, we're going to first look at the symbols so that we can roadmap the functions we want to disassemble before we get started.
[Image: yJAaetW.png]

We are only interested in things in the text section (for now), and only ones with code in our file. That leaves
  • _start
  • add
  • main
  • mul
We know _start is a libc function, so we don't have to reverse it (we can easily get that from other sources).

Let's go ahead and run this binary so we can see what it does as well
[Image: kDAOZVf.png]
Ok, so we can see it's going to use both add  and mul to create its useful output, so we're going to go ahead and reverse those now.

[Image: n9kYMXh.png]
Ok, our first function. We can see a generic call frame. What does that say to us? (answer in spoiler below).
Spoiler:
A generic call frame allocation (simple stack pivot) says to us that this function has NO local variables. At this point we assume the function has also been marked const
Let's have a look at the end of the function to see what type it is.
[Image: 4U92OFj.png]
because this is a simple return, we know that this function returns a primitive value. We know that because no manipulation is done on eax (primitive type), but eax is not popped off the stack (returns a value).

Let's trim away all the fat now and look at the meat
[Image: SmSNqbn.png]
Here we see something unique to 64 bit. Since the 64 bit ABI specifies stack passage, the first 2 lines are assignments of what look like local variables.
They are not
The first 2 lines are assignments of temporary variables. These are not temp variables like you use in your code, these are variables that are only needed for 1 or 2 machine instructions. They exist for only a few clock cycles. Just from looking at this, those variables only exist for about 8 clock cycles. On this machine that means that they exist for 2.0X10^-9 seconds.
They copy in 2 unmanipulated items, meaning we know that this function takes 2 arguments. Also, since they don't sign extend anything we can assume they are integers.
Code:
int add(int a, int b)

Now, let's take a look at some meat
[Image: E7PBrha.png]
I don't want you to see that third line, but I need it to make my point. The first two lines in this image copy the temporary variables into more temp variables?
The answer is no. They are copying the temporary variables into registers. On most systems, ALL arithmatic MUST be performed on registers. So, seeing these two clues us into an imminent math operation, which we see in the third line.
the third line (in pseudo code) becomes
Code:
eax = eax + edx

Since that's the last line of our function, let's go ahead and write our code:
Code:
int add(int a, int b)
{
   return (a + b);
}

Onwards now to mul:
[Image: NQvpUVE.png]
The first thing that should jump out to you is that this one does NOT have a general call frame allocation. That means to us that we do have local variables. Let's look closer at the frame and figure out how many we have (and assume a type)

[Image: XsH7Uk3.png]
From here we see 24 bytes of allocation. This clues us in that there's a few integer variables, but also possibly structures and local temp variables.
To make sure, let's have a look at our assignments:

[Image: o4gaKqv.png]
Now, some of you are going to ask how I knew to stop there. Well, it's simple. Variables are always first defined, then initialized, then dealt with. Meaning that given a good idea of the functions output, and the size of the allocations we can stop at the first non-assignment.
Here, we see the first two lines are copying arguments (because they aren't normally used GPR's and they are first in the frame). So, we know now that our function takes at least 2 arguments. The third line uses a much lower offset (closer in the frame), which clues us in that there are no more arguments.
Code:
int mul(int a, int b)
Ok, so what about the other variables?
One is a static assignment, the other is from the call frame. Specifically from argument 2 (0x18 offset). So, we can infer the following:
Code:
int mul(int a, int b)
{
   int c;
   int d;
   c = 0;
   d = b;
}

We also have what looks like another variable assignment, though its an interesting one, because it comes from a register that we haven't initialized yet. eax was chosen for a reason here (you will see why later), so we are going to assume this is zero fill, and ignore it for now since its essentially uninitialized.

[Image: rtgzC4o.png]
Oh no...this looks like the start of a loop..let's break out the pseudocode..
Code:
7a5:
         goto 7bd

[Image: TDUpV1D.png]
I captured much more than we need, but let's just pseudo it all while we have it. Leave out the frame exit and return, they are there for reference
Code:
7a5:
         goto 7bd
7bd:
         if (d > 0)
                   goto 7a7
         if (b >= 0)
                   goto 7cc
         c = -c
7cc:
         return c

Ok, that makes sense. I'll give you a little time to figure out what this means, take a look at the spoiler to confirm your answer.
Spoiler:
The first conditional is a jump back upwards in our code. This is our while condition, and we are using a while loop (basically everything is a while loop).

The second conditional makes us assume we haven't sign extended our parameters, meaning they are all positive. This seems to make sure our answer is negative if b was negative.

Now, let's go have a look at 7a7.
[Image: r47Cuon.png]
the next instruction after this is 7bd, so this makes up the rest of the function.
Since there are no jumps here, this means that there are no loops or conditionals in this block.

We do see a call though, to add, which we have already dumped and know takes 2 integer arguments. So, instead of tracing through it, let's just identify and relate those.
[Image: aKIh3it.png]
Remember our original offsets.
0x14 = a (parameter)
0x4 = c (will be return value)
[Image: XSFqQSi.png]
So, we can interpret the code from both of those images as
Code:
add(a, c)

Now, we know add returns a value as well (being a + c in this case), so lets look at how the return is treated (return will be in %eax per C ABI)
[Image: uYYoq41.png]
Ok, so its moving our result into offset 0x4. Which above we said was variable c.
Code:
c = add(a, c)
making our function so far:
Code:
int mul(int a, int b)
{
   int c;
   int d;
   c = 0;
   d = b;
   while (d > 0)
   {
       c = add(a, c);
       //more missing
   }
   if (b < 0)
       c = -c;
   return c;

Now, let's see what happens next:
[Image: 8hSsgut.png]
So, we are going to decrement the value at offset 0x8.
Looking back, 0x8 was variable d.
This is also the last line in our loop, so this makes our code now complete and as
Code:
int mul(int a, int b)
{
   int c;
   int d;
   c = 0;
   d = b;
   while (d > 0)
   {
       c = add(a, c);
       --d;
   }
   if (b < 0)
       c = -c;
   return c;

Sweet! Now we have both functions complete. Let's take a quick look at main.
[Image: KE743Ad.png]
Ok, non-general call frame allocation. 16 bytes, so we have some variables to figure out.

[Image: 3Uof0AK.png]
It's going to require a trained eye to see this, but we only have 2 static assignments before we start doing maniplulation. This means that we only have 2 variables assigned right now, but we have 4 total.
Code:
int main(void)
{
   int a;
   int b;
   int c;
   int d;
   a = 2;
   b = 2;
}

Ok, now let's go ahead and trim away all the garbage
[Image: Oct9eRi.png]
So, we've got a call to add, a call to mul, and 2 calls to printf.

At this point I'm going to do something different. I am not going to reverse the rest of main, YOU ARE
I will, however give you a strings dump (since we have printf)
[Image: fhgmX8f.png]

What I want you to do, is IN A SPOILER reply with an annotated reverse engineering of the remaining part of main. If you finish it, then also post your full program source. I will reverse the rest of this function as part of the next edition so you can check if you did it properly.



THIS IS IMPORTANT!
I need feedback from you guys. Things are about to get extremely difficult and I need to know if you are grasping at straws or if I'm being too easy.

@Slacker here's your mention
(This post was last modified: 10-16-2016, 01:04 AM by phyrrus9.)

[+] 3 users Like phyrrus9's post
Reply

RE: Reverse Engineering 101 - Part 3 #2
Has been looking to learn about RE for a while. Thanks, OP!

Reply

RE: Reverse Engineering 101 - Part 3 #3
sorry im new what can we do with re

Reply

RE: Reverse Engineering 101 - Part 3 #4
This is just fantastic thanks for posting the next part!

Reply

RE: Reverse Engineering 101 - Part 3 #5
Been a long time since I read any of this. While I was reading it in the past it was fairly simple to follow considering I personally have no experience what's so ever in the reverse engineering fields.

On a updated note, I plan on attempting to reverse engineer a program that I've paid for, ran into technical errors and received nothing but ignorant, non supportive and utterly insulting responses. So keep an eye out as I attempt to make this happen and post periodic updates along the way. (And be ready for some questions I'm sure.)
@Skullmeat @phyrrus9 @Bish0pQ @mr.kurd and @ender are my best friends on SL

Reply

RE: Reverse Engineering 101 - Part 3 #6
(08-31-2017, 03:02 PM)Slacker Wrote: Been a long time since I read any of this. While I was reading it in the past it was fairly simple to follow considering I personally have no experience what's so ever in the reverse engineering fields.

On a updated note, I plan on attempting to reverse engineer a program that I've paid for, ran into technical errors and received nothing but ignorant, non supportive and utterly insulting responses. So keep an eye out as I attempt to make this happen and post periodic updates along the way. (And be ready for some questions I'm sure.)

Any time man! You should document the process you go through to do it if you're able to. Not everybody does reverse engineering the same way, and I think it's critical that people get multiple approaches. Sometimes what I posted here just doesn't work (like if you're trying to reverse engineer IDA, which is a reverse engineering tool), and you have to take a different approach, or do some completely hacky shit (like you have to do with IDA)

Reply

RE: Reverse Engineering 101 - Part 3 #7
I am going to attempt to reverse engineer a program called Karma a program made by Karasoft. The lack of respect and support by the creator of said program was ignorant and insulting. There is a "cracked" version that was released by said creator with a rat and xmr miner on it. Sooo figured I would take a whirl at it.
@Skullmeat @phyrrus9 @Bish0pQ @mr.kurd and @ender are my best friends on SL

Reply

RE: Reverse Engineering 101 - Part 3 #8
Also considering doing something I haven't seen much conversation about since I joined here and attempting to mess with his website a little bit. Lol been a long time since I was being walked through that shit so I might brush the dust off the old tutorials I was given Smile
@Skullmeat @phyrrus9 @Bish0pQ @mr.kurd and @ender are my best friends on SL

Reply

RE: Reverse Engineering 101 - Part 3 #9
(08-31-2017, 03:26 PM)Slacker Wrote: Also considering doing something I haven't seen much conversation about since I joined here and attempting to mess with his website a little bit. Lol been a long time since I was being walked through that shit so I might brush the dust off the old tutorials I was given Smile

Oh god, it's been ages since I've seen a properly executed defacement! Do you have any interesting vectors?

Reply

RE: Reverse Engineering 101 - Part 3 #10
(08-31-2017, 03:28 PM)phyrrus9 Wrote:
(08-31-2017, 03:26 PM)Slacker Wrote: Also considering doing something I haven't seen much conversation about since I joined here and attempting to mess with his website a little bit. Lol been a long time since I was being walked through that shit so I might brush the dust off the old tutorials I was given Smile

Oh god, it's been ages since I've seen a properly executed defacement! Do you have any interesting vectors?
Haven't even began looking into any of it yet. I know my target and that's about it lol I'm going to be doing it all via tutorial threads here on site since all my old friends are no longer around to tea h me and others want money to teach me...
Not wanting to use programs to do it either I want to manually do as much as possible lol
@Skullmeat @phyrrus9 @Bish0pQ @mr.kurd and @ender are my best friends on SL

Reply






Users browsing this thread: 1 Guest(s)