Reverse-Engineering Training Part 2
The main function. I wonder what those function calls do?

Reverse-Engineering Training Part 2

Hello! Welcome back to part 2 of my reverse-engineering challenge walkthrough.

Before we dive further into the program’s Assembly dump, I will run one last Linux tool on the program called “strings.” The “strings” tool looks for strings inside of the program. Strings are segments of data in memory that are meant to be readable by human beings. If there’s anything in this program that can be easily interpreted by humans, the “strings” program will find it. Let’s take a look!

No alt text provided for this image

Ok, there’s some nonsense in here, but some good stuff too.

  • 8675309 - Looks like one of my senior analysts has a sense of humor. I can hear the song in my head now.
  • Usage: a.out <email> <key> - Hey, there’s our error message from earlier!
  •  ** %d - Hey, there are those 2 asterisks from our output, followed by “%d”. That percent value is a variable that will eventually represent a numeric value, much like our “** -1” from earlier.
  • @ise.io - There’s my company’s domain! I bet there’s something in this program that checks to see that the user’s email input contains this.

Alright, let’s dive further into the Assembly.

The numbers you see on the left of the following output, to the left of the colons (‘:’) are the location in memory (a memory address) where that instruction lies. Don’t worry about the mnemonics like “pushq” and “jmpq” in the middle of the output just yet. Just understand that we are looking at instructions that, if the program navigates to those memory addresses, will be performed by the processor.

Going further into the “objdump” output of this challenge, we see the start of the Procedural Linkage Table”. This table exists in the program because, before it is compiled, the program isn’t sure where these functions are going to wind up in memory. The program can instead reference this table for the function it needs (but doesn’t know where it will be yet in memory) and later a separate entity will write the correct memory address into this table.

No alt text provided for this image

In the table, we see calls to several functions that give hints as to what this program does. Functions like “strcpy” (string copy) will copy characters meant to be human-readable to another location in memory. We should pay special attention to this function when it is called because, not only is it notorious for causing memory corruption issues, it is likely handling user input. One of the goals of reverse engineering is to trace user input.

We also see calls to things like “printf” and “puts”. These functions will display output to the screen, such as our error message from earlier.

We also see “strstr” (string string) and “strcmp” (string compare). These functions will compare a region of memory that represents human-readable characters against another region of memory that represents human-readable characters. These functions are commonly used to check user input against a baseline.

Consider a process meant to check a user’s password. That process might use the function “strcmp” to check a user’s input of “password123” against the program’s stored value of “passw0rd124” and find that the user’s input is incorrect. These functions should be investigated once we see which regions of memory are being referenced to be compared in these functions.

We proceed further into the challenge's Assembly dump and see the start of the main function. Once the program’s preamble finishes setting up memory, this function will execute the program’s main purpose. Let’s take a look and see if we find anything interesting.

No alt text provided for this image

Hoo, boy. Lots of goodies. First we have a function call to “check_argcount”. If the name of this function is anything to go by, that’s probably the function responsible for checking that we have the correct number of command line arguments. This function is probably why, earlier when we gave the program dummy arguments for an email and a key, the error message disappeared!

Next, we have a call to “check_argv”. This could do a lot of different things, but we can be make a reasonable guess it’s somehow checking the email and key arguments we enter on the command line for something. Maybe it’s responsible for seeing if our key is correct?

Finally, we have “check_key”. If the name is anything to go by, this function will make sure we have entered the proper key. But if that’s the case, then what does “check_argv” do? Surely these aren’t redundant checks.

Ok, we’ve investigated the Assembly dump. In the next article, we will dive into the program mid-operation with the tool GNU Debugger (GDB)!

Great lesson! Keep up the great work!!

To view or add a comment, sign in

More articles by Christopher Campbell

  • Reverse-Engineering Training Part 3

    Hello! Welcome back to part 3 of my reverse-engineering challenge walkthrough. Today we will begin investigating the…

  • Reverse Engineering Training

    Hello. My company conducted some internal training recently on reverse-engineering.

    4 Comments

Others also viewed

Explore content categories