My apologies to Craig for the delay in publishing this paper as I was a little busy attending BH/DefCon and the neverending work on ChicagoCon. But this one is definitely worth the wait as many of you expressed interest in the topic of this article. Well done, Mr. Heffner.

Last time we went over the C programming language in an introductory article specifically focusing on getting the security professional on the road to coding (or at least the road to understanding). This time around we extend the series of coding articles for non-programmers with an area of high interest in the infosec community, reverse engineering.

This paper is intended as an introduction to reverse engineering for someone who has no experience whatsoever on the subject. You should have some basic knowledge of C programming, and access to a Windows or Linux box (preferably both) using the x86 architecture (i.e., your average computer). No knowledge of assembly code, registers, or the like is assumed, although it helps. This introduction section of the paper is intended for the newcomer who has little or no understanding of what reverse engineering is, and may be skipped by those looking for more technical details.

As always, feedback is encouraged as well as future topic ideas for Craig.

Don

Last edited by don on Thu Aug 09, 2007 11:58 am, edited 1 time in total.

Thanks Craig for explaining this topic in a simple and clear visual manner. I think this is the first time I really understood the basic of Assembly and RCE. I know that this is just an introduction but it really helps to grasp the fundamentals for other advance related topics. Looking forward the second part of this article.

Keep up the good work!!

Last edited by blackazarro on Thu Aug 09, 2007 11:58 am, edited 1 time in total.

Thanks for your awesome paper. I have been interested in learning more on RCE and have been held up by the fact that no one writes to the true entry level person. Your overview of registers was very well wrote.

I ran through the Hello World examples and had slight differences. I understand each disassembler will spit something different, I am wondering if you can tell me what is going on though. I m using gdb 6.6-debian.

These instructions serve to save the stack pointer on the stack. Notice that at main+42, this value is loaded back into ESP in order to restore the stack pointer before returning.

Code:

and $0xfffffff0,%esp

This instruction zeros out the last byte in the ESP register. This is done to ensure that the stack pointer is aligned on a 16-byte boundary (the default stack boundary is 16) in order to increase CPU execution time. There's a short semi-discussion on it at the Kernel Trap forums: http://kerneltrap.org/node/8236 .

As far as puts() goes, it's not much different from printf() when just printing out a string. You should see the memory address where the string is located pushed onto the stack just before the call to puts(). It will place a positive number in the EAX register if successful (probably 1), and a -1 in EAX if it fails.

The jnz (jump if not zero) instruction jumps if the zero flag is clear.

Code:

jnz Jump if the zero flag is set to 0

For example, if an operation such as CMP turns out to be true, the result will be zero which means that the zero flag will be set to 1. If the next instruction is a jnz, the jump will not be taken. However, if the CMP operation is not true, the result will be a non-zero value meaning that the zero flag is clear or 0. Since the zero flag is clear the next jump (jnz) will be taken.

I've been doing some research on reversing and assembly lately for a crack me challenge and spotted this error when I went back on reading this article.