Security Ripcord


The Price of Disassembly

May 11th, 2008 cutaway Posted in Disassembly, Hacking, atlas | No Comments »

I was checking prices for a few books that atlas mentioned in his interview on Learn Security Online. I was not expecting to pay this much for any of the books. I think I’ll wait. Those of you who are done with your versions might think about becoming a reseller. Or, you can contact me if you are willing to make a donation.

Hacker Disassembling Uncovered

Hacker Disassembling Uncovered Prices

Go forth and do good things,

Don C. Weber


Help support my training and travel to security conferences. Get your SANS Training and GIAC Certifications through the Security Ripcord.


Keep Your Heads Up In The Stack

May 8th, 2008 cutaway Posted in Leadership, Management, Professionalism, Security, USMC | 1 Comment »

I’ve been doing a little running lately getting ready for the Corpus Christi Beach to Bay Relay. Today, instead of our usual four mile run, we decided to work on some sprints. We ran a mile and then started a series of 100 yard sprints with a 100 yard walk in between. Needless to say that the walking reset was filled full of huffing and puffing. At one point I noticed that I was hanging my head like most people do when they are tired. When I realized this I did what I always do, what I taught myself in the Marines after long runs and forced marches, I raised my head and started looking around. I use to do this because whenever you are the most tired is when you are the most vulnerable. You are not paying attention, you are breathing heavy, and you are doing everything you can just to take a break for a minute or two. Fortunately, the repercussions of me doing this now are not the same as they were back then.

All of this got me thinking about how we react to situations as a whole. I started thinking about how through training and effort we can begin to overcome hardships. I started thinking about how diligent practice can instill good habits and create muscle memory in any individual. Muscle memory is a condition where a body reacts without, or more precisely with only a little, thinking. You can see this by reviewing Rich Mogull’s posts on how he handled several car accidents after being out of the paramedics for a while. Rich did what came natural to him. He just reacted and, I’m sure, did a great job and a service.

“Yes, yes,” you are thinking to yourself right now. We have heard this all before. Practice makes perfect. Practice your incident response. Practice your backup procedures. Practice your disaster recovery. Practice makes perfect. Practice, Practice, Practice. Blah, blah, blah. Yes, I am tell you that. But what I want to emphasize is that you can train yourselves all day long and still make mistakes.

Running with my head down took me back to the days of running through the hills of Camp Pendleton and training myself to keep my head up and aware of my surroundings no matter how tired I was at the time. But what it really got me thinking about was being in the stack. Not the stack you are use to hearing about, the stack of Marines that are just about to enter a building or room that may contain hostiles. It didn’t matter where we were, once people started lining up and getting ready to move to action, their heads dropped. Not because they were tired or lazy, but because they were focused and waiting. Like a spring ready to uncoil all of its power. This occurred so often that it was not surprising to hear, “Keep your heads up in the stack!” whispered over the radio. Or have someone give you a quick rap on the helmet as a reminder. Everybody did it, everybody got sucked into it, and everybody was aware of it and watched out for their buddy, because that person was watching out for them.

So, how does this apply to us? Well, security professionals have a lot to accomplish on any given day. Logs to review, servers to patch, incidents to respond to, training to develop and give (and that is just the short list). Let’s face it. We are swamped with responsibility and duties. Everybody groans when we walk into a room but everybody notices when our duties start falling behind because it directly affects their business. With all of this activity, with all of this responsibility, it is very easy to get set into a common routine or mode. It is very easy for our heads to drop into our computers, logs, management consoles, spreadsheets, etc. We are doing our jobs and we are getting it done, but are we aware of our surroundings. Are we aware of the common sights and sounds of the office environment and server room. Are we listening to people talk when they need our guidance, input, or for us to listen for listening’s sake?

If you are, then good on you. Now look around and see who is not. Please, tap them on the head and tell them, “Keep your head up in the stack!”

Go forth and do good things,

Don C. Weber


Help support my training and travel to security conferences. Get your SANS Training and GIAC Certifications through the Security Ripcord.


Assembly Debugging with VTrace

May 4th, 2008 cutaway Posted in Programming, Security | No Comments »

Although my last foray into assembly via a Hello World program was helpful, it only scratched the surface. I was thinking about moving onto some user input programs next when I realized that it might be more helpful if I learned how to do some quick arithmetic using assembly. To do this I located some additional resources to help my understanding of assembly.

Together with my old version of Hello World I created an assembly program that would print out a “Number is 0″ and then “Number is 1″. My intention was to set a register to 0 and then to increment the register so that it equaled 1. The following is the program.

DISCLAIMER UPDATE:  The following assembly code does not work.  That is the point.  The walk through after the code, however, does help.

// Assembly Arithmetics

.data
NUMS:
.string “Number is ”
NUMSLEN:
.short $-NUMS
EOL:
.string “\n”
EOLLEN:
.short $-EOL

.text
.globl _start

_start:
//Print NUMSTRING
movl $4,%eax
movl $1,%ebx
movl $NUMS,%ecx
movl $NUMSLEN,%edx
int $0×80

//Make a register equal to zero and print
xor %ecx,%ecx
xor %edx,%edx
inc %edx
int $0×80

//Print EOL
movl $EOL,%ecx
movl $EOLLEN,%edx
int $0×80

//Print NUMSTRING
movl $NUMS,%ecx
movl $NUMSLEN,%edx
int $0×80

//Increment register from zero to one
xor %ecx,%ecx
xor %edx,%edx
inc %ecx
inc %edx
int $0×80

//Print EOL
movl $EOL,%ecx
movl $EOLLEN,%edx
int $0×80

//Exit
ret

To help me compile this I also created a quick Makefile.

arth.as: arth.as.o
ld arth.as.o -o arth.as.exe
arth.as.o: arth.as.s
as arth.as.s -o arth.as.o

This Makefile allowed me to just type “make” every time that I needed to make a change to the assembly program. This happened several times before I came to the assembly program above. Once I had the executable, I thought I was good to go. Unfortunately.

bt as # ls
Makefile arth.as.s
bt as # make
as arth.as.s -o arth.as.o
ld arth.as.o -o arth.as.exe
bt as # ls
Makefile arth.as.exe* arth.as.o arth.as.s
bt as # ./arth.as.exe
Number is

Segmentation fault
bt as #

Dang ol’ Seg fault. What do I do now? Well, I was going to start moving things around and checking against other simple programs available via Google when I remembered that I could step through the executable using VTrace. After a little trial and error I taught myself to attach to the executable, step through each instruction, pull all of the registry values, pull selected registry values, and run the program all of the way through. The following output shows each of these steps. You will notice that I decided to start using several arrays to help me consistently output the values of the registers.

IDLE 1.1.3
>>> import vtrace
>>> tr = vtrace.getTrace()
>>> tr.execute(’/root/Development/test_programs/c/misc/as/c_stuff.as.exe’)
>>> tr.getPid()
11683
>>> arrRegs = ['eax','ebx','ecx','edx']
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 0
ebx : 0
ecx : 0
edx : 0
>>> arrAllRegs = tr.getRegisters()
>>> for key in arrAllRegs:
print “%s : %s” % (key,arrAllRegs[key])

debug1 : 0
debug0 : 0
debug3 : 0
debug2 : 0
debug5 : 0
debug4 : 0
debug7 : 0
debug6 : 0
edi : 0
eax : 0
cs : 115
fs : 0
ebp : 0
__fs : 0
__cs : 0
gs : 0
edx : 0
ebx : 0
ds : 123
__es : 0
ecx : 0
eip : 134512756
esp : 3213311088
ss : 123
__ds : 0
__ss : 0
__gs : 0
eflags : 2097798
es : 123
orig_eax : 11
esi : 0
>>> tr.run()
>>> arrAllRegs = tr.getRegisters()
>>> for key in arrAllRegs:
print “%s : %s” % (key,arrAllRegs[key])

debug1 : 0
debug0 : 0
debug3 : 0
debug2 : 0
debug5 : 0
debug4 : 0
debug7 : 0
debug6 : 0
edi : 0
eax : 4294967258
cs : 115
fs : 0
ebp : 0
__fs : 0
__cs : 0
gs : 0
edx : 134516943
ebx : 1
ds : 123
__es : 0
ecx : 134516941
eip : 1
esp : 3213311092
ss : 123
__ds : 0
__ss : 0
__gs : 0
eflags : 2163202
es : 123
orig_eax : 4294967295
esi : 0
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258 <- NOTE: Remember these values for later
ebx : 1
ecx : 134516941
edx : 134516943
>>> tr.detach()
>>> tr.getPid()
0
>>>

Okay, that didn’t help. I guess I need to step through using “tr.stepi()” and output the registry value after each step. Let’s see if it helps. I have inserted the assembly code as NOTE: throughout the output.

IDLE 1.1.3
>>> import vtrace
>>> tr=vtrace.getTrace()
>>> tr.getPid()
0
>>> tr.execute(’/root/Development/test_programs/c/misc/as/arth.as.exe’)
>>> tr.getPid()
14727
>>> arrAllRegs = tr.getRegisters()
>>> for key in arrAllRegs:
print “%s : %s” % (key,arrAllRegs[key])

debug1 : 0
debug0 : 0
debug3 : 0
debug2 : 0
debug5 : 0
debug4 : 0
debug7 : 0
debug6 : 0
edi : 0
eax : 0
cs : 115
fs : 0
ebp : 0
__fs : 0
__cs : 0
gs : 0
edx : 0
ebx : 0
ds : 123
__es : 0
ecx : 0
eip : 134512756
esp : 3220532048
ss : 123
__ds : 0
__ss : 0
__gs : 0
eflags : 2097798
es : 123
orig_eax : 11
esi : 0
>>> arrRegs = ['eax','ebx','ecx','edx']
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 0 <- NOTE: All registers appear to start clean
ebx : 0
ecx : 0
edx : 0
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4 <- NOTE: movl $4,%eax
ebx : 0
ecx : 0
edx : 0
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4
ebx : 1 <- NOTE: movl $1,%ebx
ecx : 0
edx : 0
>>> tr.stepi()
>>>
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4
ebx : 1
ecx : 134516928 <- NOTE: movl $NUMS,%ecx
edx : 0
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4
ebx : 1
ecx : 134516928
edx : 134516939 <- NOTE: movl $NUMSLEN,%edx
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 2048 <- NOTE: int $0×80 I’m not sure why this register changed UPDATE: Confirmed, this register is changed with the result of “int $0×80″, which means the next “int $0×80″ will do the system call assigned to 2048 or $0×800
ebx : 1
ecx : 134516928
edx : 134516939
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 2048
ebx : 1
ecx : 0 <- NOTE: xor %ecx,%ecx
edx : 134516939
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 2048
ebx : 1
ecx : 0
edx : 0 <- NOTE: xor %edx,%edx
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 2048
ebx : 1
ecx : 0
edx : 1 <- NOTE: inc %edx
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258 <- NOTE: int $0×80 Okay, this is probably the segfault, but VTrace doesn’t stop stepping here
ebx : 1
ecx : 134516941 <- NOTE: movl $EOL,%ecx I’m also not sure why it seems like it stepped twice and executed the next instruction
edx : 1
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258
ebx : 1
ecx : 134516941
edx : 134516943 <- NOTE: movl $EOLLEN,%edx
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258
ebx : 1
ecx : 134516928 <- NOTE: movl $NUMS,%ecx
edx : 134516943
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258
ebx : 1
ecx : 134516928
edx : 134516939 <- NOTE: movl $EOLLEN,%edx
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258
ebx : 1
ecx : 0 <- NOTE: xor %ecx,%ecx
edx : 134516939
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258
ebx : 1
ecx : 0
edx : 0 <- NOTE: xor %edx,%edx
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258
ebx : 1
ecx : 1 <- NOTE: inc %ecx
edx : 0
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258
ebx : 1
ecx : 1
edx : 1 <- NOTE: inc %edx
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258
ebx : 1
ecx : 134516941 <- NOTE: movl $EOL,%ecx
edx : 1
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258 <- NOTE: Complete run through stopped here
ebx : 1
ecx : 134516941
edx : 134516943 <- NOTE: movl $EOLLEN,%edx
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258
ebx : 1
ecx : 134516941
edx : 134516943
>>> tr.stepi()
>>> for i in arrRegs:
print “%s : %s” % (i,tr.getRegisterByName(i))

eax : 4294967258 <- NOTE: Step through stops here as well
ebx : 1
ecx : 134516941
edx : 134516943
>>> tr.detach()
>>> tr.getPid()
0
>>>

Not much help there. Basically, VTrace will step right through a segmentation fault. Although, now that I run through the program step by step I think I can see where the program failed. I guess the “int $0×80″ changes the register $eax. I believe this means that I have to reset this value before writing.

What still bothers me though is the fact that VTrace did not stop on the segmentation fault. I thought debuggers did this. That is when I realized that VTrace is not necessarily a debugger. Actually VDB is a debugger and I should have used that instead of troubleshooting with VTrace. I guess I could just reset the register before telling it to print, I think I’ll try VDB to see if it will help me identify the exact step where the executable stops.

More assembly soon!!

UPDATE: As I mentioned inline, the call “int $0×80″ writes it’s return value to %eax. This means that I will l have to update %eax with a decimal 4 every time I want to write out. Also, I have come to realize that whether I use VTrace, VDB, or GDB no debugger is going to help me overcome bad code. I guess I need a book because online resources don’t seem to be cutting it for me. I did find one resource that mentioned that the values in the registers are not necessarily ASCII and that they will need to be converted before being output. But then the same resource went straight into memory modification to write the number with the original string instead of outputting them one at a time like I have here. I’m going to try and get a grasp on this before I start delving into memory modification.

Go forth and do good things,

Don C. Weber


Help support my training and travel to security conferences. Get your SANS Training and GIAC Certifications through the Security Ripcord.


Organized Security

May 4th, 2008 cutaway Posted in Leadership, Management, Security | 1 Comment »

Work has been quite an experience over the last couple of months. I have spent my time in the usual security professional mode - Firefighter. It is especially aggravating when much of that firefighting is documentation for certification and accreditation of a system (that could be quickly improved with the same level of effort) or collecting information through what could be considered broken processes. Security Blog readers hear about both of those concerns all of the time as they peruse the Security Blogscape. Security professionals wishing that they could make a difference within their organization. Wishing that the managers of the system and network administrators would just listen and implement. Hoping that the executive management will empower the security professionals within their organization by conveying to the rest of the company the importance of secure operations. Let’s face though, when we start talking about security within our different organizations the majority of what we want is for our organizations to follow good business practices. Companies who have a firm grasp on how their technology operates and have a process for change through open communications are much more secure that the companies that buy security products to act as stop gaps and try to prove or give the illusion of compliance.

The next generation of security professionals need to recognize this fact. Certainly we train them to know that their companies should be following industry standards like ISO 27001:2005 as I have already pointed out. But have we really started providing them with the abilities to integrate this into ITIL or CMMI. No, that is because for a business to achieve these standard they need to have business professionals to guide them through the process. Unfortunately, these business professionals have not been trained on how the security frameworks will fit into the organization and their compliance efforts. So, there is a gap. And when there is a gap that people don’t understand they tend to do one of two things:

  • Ignore it.
  • Throw money at it until they wish they had gone with the other method.

We’ll let me let all of you in on a little secret. It is something that you can take back to your organization and begin to implement immediately and it will not affect anybody outside of the security group, at first. Are you ready???? You might just hate this answer, so stop reading if you cannot handle it. Okay, I want you to “Document Your Processes!” *Gasps are heard around the world* Yes, documentation will get you over the hump. I’m not talking long, drawn out documentation that makes you stop everything that you are doing. No, I am talking about quickly documenting the steps you take to address any issue you devote time to repeatedly. I am also talking about creating process flow diagrams that show where and how tasks touch other departments within your organization. Don’t spend a lot of time on it at first. Just get it written down and saved into a location that all of your team members can access it. Then print them out and put them in a binder that will become your Standard Operating Procedures (dang, how did SOP slip in there?). As this binder starts to fill up, make copies and deliver a a copy to your boss and the other managers of the departments you deal with on a regular basis.

Now the ITIL and CMMI experts are ready to jump in here and tell us, “This is not enough to be compliant.” They would be correct. But each of them will have to admit that it is one way to start down the path. It is a necessary step that they will be looking for as they go down their checklists. See, a few of the things that they want to see from you and your department are:

  • Does your department have documented processes and procedures?
  • Does your department control their efforts through some type of program or project management method?
  • Does your department have methods to analyze and improve the processes and procedures?
  • Does your department make these process and procedures available to other departments within the organization?

By documenting how you approach each one of your department’s responsibilities you will start down a path that can be successfully integrated into the organization’s business processes. Managers will be able to start looking at your productivity and perform metrics on your duties which will help them determine many things, such as your value to the whole organization or whether your department is short handed. And what does it do for your department as a whole? You become more effective and efficient because you start doing things the same way every time (until it does not make sense to). You have opened communications to the rest of the organization and provided them with a method to take your example and some of your ideas and turn them into their own ideas (oh, the power of suggestion). All of this documentation you will help you and other members of your department quickly determine where your processes need improvement. Process documentation is an excellent tool when it comes time to point out issues to the members of your department. It drives straight to the heart of the problem in a manner that is easy for them to understand and provides them with the opportunity to make visible and fulfilling improvements.

Is all of this enough to “fill the gap” that I spoke of earlier? Of course not. It is just a start. One of the things that I am starting to consider are classes and certifications in program/process management. For this I have been pointed to the Program Management Institute by several security professionals and bloggers. I really don’t think it is going to hurt any security professional if they add PgMP, PMP, or CAPM to their alphabet soup. In fact, as individuals begin to progress through their careers these or similar education may become necessary. Many of our technical Brethern (who are still reading) are shifting uncomfortably in their seats because dreams of management duties are starting to fill their heads. Those, at least, that don’t come from a structured software or hardware development background. And they shouldn’t. Because these are the skill sets that are also necessary for technical engineers to improve how they do their business as much as it is a means for the managers to improve the department or organization.

Open communications is one of the things that we promote within our organizations. If your organization is “open communications challenged” then you must first start looking at yourself before you start pointing fingers or stomping feet. You must set the example. Live the lifestyle you preach. Hopefully it will make a difference. If it does not, well, then at least you have improved yourself and your department. The people around you will be more prepared for the next thing that comes along.

Go forth and do good things,

Don C. Weber


Help support my training and travel to security conferences. Get your SANS Training and GIAC Certifications through the Security Ripcord.


Hello World Assembly Compiling

April 27th, 2008 cutaway Posted in Hacking, Programming, atlas | 1 Comment »

I have moved on from C code to Assembly. Certainly I broke down the C into Assembly earlier, but this time I wanted to write and compile from an Assembly file. This proved more difficult than I expected. This is not because doing so is hard, it is because of the differences between the INTEL and AT&T syntaxs. I didn’t realize that this was going to be a problem until I tried to use NASM to compile the hello.s file. NASM expects INTEL syntax while GCC output a file in AT&T syntax. The following is an example of the error messages I received.

bt hello # nasm -f elf hello.s
hello.s:1: error: attempt to define a local label before any non-local labels
hello.s:1: error: parser: instruction expected
hello.s:2: error: attempt to define a local label before any non-local labels
hello.s:2: error: parser: instruction expected
hello.s:3: error: attempt to define a local label before any non-local labels
hello.s:4: error: attempt to define a local label before any non-local labels
hello.s:4: error: parser: instruction expected
hello.s:5: error: attempt to define a local label before any non-local labels
hello.s:6: error: attempt to define a local label before any non-local labels
hello.s:6: error: parser: instruction expected
hello.s:7: error: attempt to define a local label before any non-local labels
hello.s:7: error: parser: instruction expected
hello.s:9: error: parser: instruction expected
hello.s:10: error: parser: instruction expected
hello.s:11: error: parser: instruction expected
hello.s:12: error: parser: instruction expected
hello.s:13: error: symbol `movl’ redefined
hello.s:13: error: parser: instruction expected
hello.s:14: error: parser: instruction expected
hello.s:15: error: symbol `addl’ redefined
hello.s:15: error: parser: instruction expected
hello.s:16: error: parser: instruction expected
hello.s:17: error: parser: instruction expected
hello.s:18: error: symbol `subl’ redefined
hello.s:18: error: parser: instruction expected
hello.s:19: error: symbol `subl’ redefined
hello.s:19: error: parser: instruction expected
hello.s:20: error: symbol `pushl’ redefined
hello.s:20: error: parser: instruction expected
hello.s:22: error: symbol `addl’ redefined
hello.s:22: error: parser: instruction expected
hello.s:23: error: symbol `movl’ redefined
hello.s:23: error: parser: instruction expected
hello.s:26: error: parser: instruction expected
hello.s:27: error: parser: instruction expected
hello.s:28: error: parser: instruction expected
bt hello #

It wasn’t after a lot of reading that I realized that the two syntaxes are completely different. This explained why my attempts at correcting these errors did not work at all. Of course, hunting for the problem lead me to some very useful resources.

From these resources I determined there were three ways to compile and run the Hello World assembly code program. For the AT&T syntax a developer could use the GCC command or a combination of the AS and LD commands (yes, as I am working on Linux, case sensitivity does matter, but I am using caps for emphasis). The INTEL syntax requires the use of NASM and LD. The following output shows the compilation performed in each case. Note the size of the executable generated by the GCC command (ouch!!).

NASM Command

bt nasm # nasm -f elf hello.asm
bt nasm # ld -s -o hello_nasm.exe hello.o
bt nasm # ./hello_nasm.exe
Hello World
bt nasm # ls -al
total 20
drwxr-xr-x 2 root root 4096 Apr 26 23:46 ./
drwxr-xr-x 3 root root 4096 Apr 26 23:39 ../
-rw-r–r– 1 root root 685 Apr 26 23:46 hello.asm
-rw-r–r– 1 root root 720 Apr 26 23:46 hello.o
-rwxr-xr-x 1 root root 536 Apr 26 23:46 hello_nasm.exe*
bt nasm #

AS Command

bt as # as -o hello_as.o hello_as.s
bt as # ld -s -o hello_hello_as.o
bt as # ./hello_as.exe
Hello World

bt as # ls -al
total 20
drwxr-xr-x 2 root root 4096 Apr 27 00:00 ./
drwxr-xr-x 4 root root 4096 Apr 26 23:55 ../
-rwxr-xr-x 1 root root 444 Apr 27 00:00 hello_as.exe* <-NOTE: Size Winner Is AS
-rw-r–r– 1 root root 620 Apr 27 00:00 hello_as.o
-rw-r–r– 1 root root 770 Apr 27 00:00 hello_as.s
bt as #

GCC Command

bt hello # gcc -o hello.exe hello.s
bt hello # gcc -s -o hello_stripped.exe hello.s
bt hello # ls -al
total 32
drwxr-xr-x 4 root root 4096 Apr 27 00:48 ./
drwxr-xr-x 12 root root 4096 Apr 23 20:19 ../
drwxr-xr-x 2 root root 4096 Apr 27 00:00 as/
-rwxr-xr-x 1 root root 7932 Apr 27 00:48 hello.exe*
-rw-r–r– 1 root root 766 Apr 26 22:59 hello.s
-rwxr-xr-x 1 root root 2808 Apr 27 00:48 hello_stripped.exe* <-NOTE: Even stripped GCC is bigger
drwxr-xr-x 2 root root 4096 Apr 26 23:54 nasm/
bt hello # ./hello.exe
Hello World

bt hello # ./hello_stripped.exe
Hello World

bt hello #

It is very easy to see that how you compile the assembly code leads directly to the size of the executable and, perhaps, the speed and stability as well. Of course I cannot prove either of these theories, but I will take this guess because of the additional systems calls that go into the GCC version.

What I can do, in the meantime, is show you how these programs appear after they have been run through a disassembler. The versions compiled via AS and NASM are amazingly similar. The version compiled through GCC, however, is not even close. It’s output really shows how the additional libraries play a roll in the overall size of this executable. To disassemble these programs I will use the latest version of atlas’ Disass-3.0. I’ll leave the download and installation of this tool up to you.

NASM

bt nasm # disass-cli hello_nasm.exe
VirtualMemory:init:section: .text
BEGIN Processing Sub: ELF Start, .text (8048080) …..END Processing Sub: ELF Start, .text (8048080)
disass v3.00 Enhanced Disassembler
ELF HEADER OBJECT:hello_nasm.exe
= Intimate Details:
==Magic: ELF
==Type: Executable file
==Machine Arch: Intel 80386
==Version: 1
==Entry: 0×08048080
==Program Headers(offset): 52 (0×34) bytes
==Section Headers(offset): 256 (0×100) bytes
==Flags: 0L
==Elf Header Size: 52 (0×34 bytes)
==Program Header Size: 32 (0×20 bytes)
==Program Header Count: 2 (0×2)
==Section Header Size: 40 (0×28 bytes)
==Section Header Count: 7 (0×7)
==Section Header String Index 6 (0×6 bytes)

= Sections:
Elf Section: [ ] VMA: 0×00000000 offset: 0 ent/size: 0/ 0 align: 0
Elf Section: [ .text] VMA: 0×08048080 offset: 128 ent/size: 0/ 35 align: 16
Elf Section: [ .got.plt] VMA: 0×080490a4 offset: 176 ent/size: 0/ 0 align: 1
Elf Section: [ .data] VMA: 0×080490a4 offset: 164 ent/size: 0/ 12 align: 4
Elf Section: [ .bss] VMA: 0×080490b0 offset: 176 ent/size: 0/ 0 align: 1
Elf Section: [ .comment] VMA: 0×00000000 offset: 176 ent/size: 0/ 31 align: 1
Elf Section: [ .shstrtab] VMA: 0×00000000 offset: 207 ent/size: 0/ 46 align: 1

= Program Headers:
[ Loadable program segment] VMA: 0×08048000 offset: 0 memsize: 163 align: 4096 (filesz: 163) flags: 5
[ Loadable program segment] VMA: 0×080490a4 offset: 164 memsize: 12 align: 4096 (filesz: 12) flags: 6
Dynamics:

Virtual Memory: hello_nasm.exe, start: 8048080, flags: 0

====== Section Header: .text ======
====== Starting Address: 0×08048080 Length: 0×0023
====== File Offset: 0×0080 Size in File: 0×0023
====== Size in Memory: 0×0000
==================

Subroutine: ELF Start, .text (8048080) 9 lines 0×23 bytes
Starting address: 8048080 Ending address: 80480a2

; ELF Start, .text
8048080: \xb8\x04\x00\x00\x00 mov $0×4, %eax
8048085: \xbb\x01\x00\x00\x00 mov $0×1, %ebx
804808a: \xb9\xa4\x90\x04\x08 mov $0×80490a4, %ecx ; .got.plt, .data, ‘Hello World
‘ (.data)
804808f: \xba\x0c\x00\x00\x00 mov $0xc, %edx
8048094: \xcd\x80 int $0×80
8048096: \xb8\x01\x00\x00\x00 mov $0×1, %eax
804809b: \xbb\x00\x00\x00\x00 mov $0×0, %ebx
80480a0: \xcd\x80 int $0×80
80480a2: \xc3 ret

End Subroutine: ELF Start, .text (8048080) 9 lines 0×23 bytes
8048080: ELF Start, .text
80490a4: .got.plt, .data, ‘Hello World
‘ (.data)
80490b0: .bss

bt nasm #

AS

bt as # disass-cli hello_as.exe
VirtualMemory:init:section: .text
BEGIN Processing Sub: ELF Start, .text (8048074) …..END Processing Sub: ELF Start, .text (8048074)
disass v3.00 Enhanced Disassembler
ELF HEADER OBJECT:hello_as.exe
= Intimate Details:
==Magic: ELF
==Type: Executable file
==Machine Arch: Intel 80386
==Version: 1
==Entry: 0×08048074
==Program Headers(offset): 52 (0×34) bytes
==Section Headers(offset): 204 (0xcc) bytes
==Flags: 0L
==Elf Header Size: 52 (0×34 bytes)
==Program Header Size: 32 (0×20 bytes)
==Program Header Count: 2 (0×2)
==Section Header Size: 40 (0×28 bytes)
==Section Header Count: 6 (0×6)
==Section Header String Index 5 (0×5 bytes)

= Sections:
Elf Section: [ ] VMA: 0×00000000 offset: 0 ent/size: 0/ 0 align: 0
Elf Section: [ .text] VMA: 0×08048074 offset: 116 ent/size: 0/ 35 align: 4
Elf Section: [ .got.plt] VMA: 0×08049098 offset: 167 ent/size: 0/ 0 align: 1
Elf Section: [ .data] VMA: 0×08049098 offset: 152 ent/size: 0/ 15 align: 4
Elf Section: [ .bss] VMA: 0×080490a8 offset: 167 ent/size: 0/ 0 align: 4
Elf Section: [ .shstrtab] VMA: 0×00000000 offset: 167 ent/size: 0/ 37 align: 1

= Program Headers:
[ Loadable program segment] VMA: 0×08048000 offset: 0 memsize: 151 align: 4096 (filesz: 151) flags: 5
[ Loadable program segment] VMA: 0×08049098 offset: 152 memsize: 16 align: 4096 (filesz: 15) flags: 6
Dynamics:

Virtual Memory: hello_as.exe, start: 8048074, flags: 0

====== Section Header: .text ======
====== Starting Address: 0×08048074 Length: 0×0023
====== File Offset: 0×0074 Size in File: 0×0023
====== Size in Memory: 0×0000
==================

Subroutine: ELF Start, .text (8048074) 9 lines 0×23 bytes
Starting address: 8048074 Ending address: 8048096

; ELF Start, .text
8048074: \xb8\x04\x00\x00\x00 mov $0×4, %eax
8048079: \xbb\x01\x00\x00\x00 mov $0×1, %ebx
804807e: \xb9\x98\x90\x04\x08 mov $0×8049098, %ecx ; .got.plt, .data, ‘Hello World
‘ (.data)
8048083: \xba\xa5\x90\x04\x08 mov $0×80490a5, %edx ; ‘\x0c’ (.data)
8048088: \xcd\x80 int $0×80
804808a: \xb8\x01\x00\x00\x00 mov $0×1, %eax
804808f: \xbb\x00\x00\x00\x00 mov $0×0, %ebx
8048094: \xcd\x80 int $0×80
8048096: \xc3 ret

End Subroutine: ELF Start, .text (8048074) 9 lines 0×23 bytes
8048074: ELF Start, .text
8049098: .got.plt, .data, ‘Hello World
‘ (.data)
80490a5: ‘\x0c’ (.data)
80490a8: .bss

bt as #

GCC

bt hello # disass-cli hello.exe
VirtualMemory:init:section: .init
BEGIN Processing Sub: .init, (), _init(), , _init (8048260) …..END Processing Sub: .init, (), _init(), , _init (8048260)
VirtualMemory:init:section: .plt
BEGIN Processing Sub: .plt, (), (8048278) …..END Processing Sub: .plt, (), (8048278)
BEGIN Processing Sub: __libc_start_main() (PLT) (8048288) …..END Processing Sub: __libc_start_main() (PLT) (8048288)
VirtualMemory:init:section: .text
BEGIN Processing Sub: ELF Start, .text, (), _start(), , _start (80482a0) …..END Processing Sub: ELF Start, .text, (), _start(), , _start (80482a0)
BEGIN Processing Sub: __libc_csu_fini(), __libc_csu_fini (8048400) …..END Processing Sub: __libc_csu_fini(), __libc_csu_fini (8048400)
BEGIN Processing Sub: __libc_csu_init(), __libc_csu_init (80483a0) …..END Processing Sub: __libc_csu_init(), __libc_csu_init (80483a0)
BEGIN Processing Sub: __do_global_ctors_aux(), __do_global_ctors_aux (8048450) …..END Processing Sub: __do_global_ctors_aux(), __do_global_ctors_aux (8048450)
BEGIN Processing Sub: frame_dummy(), frame_dummy (8048340) …..END Processing Sub: frame_dummy(), frame_dummy (8048340)
BEGIN Processing Sub: call_gmon_start(), call_gmon_start (80482d0) …..END Processing Sub: call_gmon_start(), call_gmon_start (80482d0)
BEGIN Processing Sub: __do_global_dtors_aux(), __do_global_dtors_aux (8048300) …..END Processing Sub: __do_global_dtors_aux(), __do_global_dtors_aux (8048300)
VirtualMemory:init:section: .fini
BEGIN Processing Sub: .fini, (), _fini(), , _fini (8048480) …..END Processing Sub: .fini, (), _fini(), , _fini (8048480)
disass v3.00 Enhanced Disassembler
ELF HEADER OBJECT:hello.exe
= Intimate Details:
==Magic: ELF
==Type: Executable file
==Machine Arch: Intel 80386
==Version: 1
==Entry: 0×080482a0
==Program Headers(offset): 52 (0×34) bytes
==Section Headers(offset): 3484 (0xd9c) bytes
==Flags: 0L
==Elf Header Size: 52 (0×34 bytes)
==Program Header Size: 32 (0×20 bytes)
==Program Header Count: 7 (0×7)
==Section Header Size: 40 (0×28 bytes)
==Section Header Count: 34 (0×22)
==Section Header String Index 31 (0×1f bytes)

= Sections:
Elf Section: [ ] VMA: 0×00000000 offset: 0 ent/size: 0/ 0 align: 0
Elf Section: [ .interp] VMA: 0×08048114 offset: 276 ent/size: 0/ 19 align: 1
Elf Section: [ .note.ABI-tag] VMA: 0×08048128 offset: 296 ent/size: 0/ 32 align: 4
Elf Section: [ .hash] VMA: 0×08048148 offset: 328 ent/size: 4/ 40 align: 4
Elf Section: [ .dynsym] VMA: 0×08048170 offset: 368 ent/size: 16/ 80 align: 4
Elf Section: [ .dynstr] VMA: 0×080481c0 offset: 448 ent/size: 0/ 89 align: 1
Elf Section: [ .gnu.version] VMA: 0×0804821a offset: 538 ent/size: 2/ 10 align: 2
Elf Section: [ .gnu.version_r] VMA: 0×08048224 offset: 548 ent/size: 0/ 32 align: 4
Elf Section: [ .rel.dyn] VMA: 0×08048244 offset: 580 ent/size: 8/ 8 align: 4
Elf Section: [ .rel.plt] VMA: 0×0804824c offset: 588 ent/size: 8/ 8 align: 4
Elf Section: [ .init] VMA: 0×08048260 offset: 608 ent/size: 0/ 23 align: 16
Elf Section: [ .plt] VMA: 0×08048278 offset: 632 ent/size: 4/ 32 align: 4
Elf Section: [ .text] VMA: 0×080482a0 offset: 672 ent/size: 0/ 480 align: 16
Elf Section: [ .fini] VMA: 0×08048480 offset: 1152 ent/size: 0/ 27 align: 16
Elf Section: [ .rodata] VMA: 0×0804849c offset: 1180 ent/size: 0/ 8 align: 4
Elf Section: [ .eh_frame] VMA: 0×080484a4 offset: 1188 ent/size: 0/ 4 align: 4
Elf Section: [ .ctors] VMA: 0×080494a8 offset: 1192 ent/size: 0/ 8 align: 4
Elf Section: [ .dtors] VMA: 0×080494b0 offset: 1200 ent/size: 0/ 8 align: 4
Elf Section: [ .jcr] VMA: 0×080494b8 offset: 1208 ent/size: 0/ 4 align: 4
Elf Section: [ .dynamic] VMA: 0×080494bc offset: 1212 ent/size: 8/ 200 align: 4
Elf Section: [ .got] VMA: 0×08049584 offset: 1412 ent/size: 4/ 4 align: 4
Elf Section: [ .got.plt] VMA: 0×08049588 offset: 1416 ent/size: 4/ 16 align: 4
Elf Section: [ .data] VMA: 0×08049598 offset: 1432 ent/size: 0/ 28 align: 4
Elf Section: [ .bss] VMA: 0×080495b4 offset: 1460 ent/size: 0/ 4 align: 4
Elf Section: [ .comment] VMA: 0×00000000 offset: 1460 ent/size: 0/ 108 align: 1
Elf Section: [ .debug_aranges] VMA: 0×00000000 offset: 1568 ent/size: 0/ 136 align: 8
Elf Section: [ .debug_pubnames] VMA: 0×00000000 offset: 1704 ent/size: 0/ 37 align: 1
Elf Section: [ .debug_info] VMA: 0×00000000 offset: 1741 ent/size: 0/ 642 align: 1
Elf Section: [ .debug_abbrev] VMA: 0×00000000 offset: 2383 ent/size: 0/ 118 align: 1
Elf Section: [ .debug_line] VMA: 0×00000000 offset: 2501 ent/size: 0/ 511 align: 1
Elf Section: [ .debug_str] VMA: 0×00000000 offset: 3012 ent/size: 1/ 174 align: 1
Elf Section: [ .shstrtab] VMA: 0×00000000 offset: 3186 ent/size: 0/ 295 align: 1
Elf Section: [ .symtab] VMA: 0×00000000 offset: 4844 ent/size: 16/ 1984 align: 4
Elf Section: [ .strtab] VMA: 0×00000000 offset: 6828 ent/size: 0/ 1104 align: 1

= Program Headers:
[ Entry for header table itself] VMA: 0×08048034 offset: 52 memsize: 224 align: 4 (filesz: 224) flags: 5
[ Program interpreter] VMA: 0×08048114 offset: 276 memsize: 19 align: 1 (filesz: 19) flags: 4
[ Loadable program segment] VMA: 0×08048000 offset: 0 memsize: 1192 align: 4096 (filesz: 1192) flags: 5
[ Loadable program segment] VMA: 0×080494a8 offset: 1192 memsize: 272 align: 4096 (filesz: 268) flags: 6
[ Dynamic linking information] VMA: 0×080494bc offset: 1212 memsize: 200 align: 4 (filesz: 200) flags: 6
[ Auxiliary information] VMA: 0×08048128 offset: 296 memsize: 32 align: 4 (filesz: 32) flags: 4
[ Indicates stack executability] VMA: 0×00000000 offset: 0 memsize: 0 align: 4 (filesz: 0) flags: 7
Dynamics:
libc.so.6 Name of needed library
0×8048260L Address of init function
0×8048480L Address of termination function
0×8048148L Address of symbol hash table
0×80481C0L Address of string table
0×8048170L Address of symbol table
0×59L Size of string table
0×10L Size of one symbol table entry
0×0L For debugging; unspecified
0×8049588L Processor defined value
0×8L Size in bytes of PLT relocs
0×11L Type of reloc in PLT
0×804824CL Address of PLT relocs
0×8048244L Address of Rel relocs
0×8L Total size of Rel relocs
0×8L Size of one Rel reloc
0×8048224L Unknown: 0×6FFFFFFEL
0×1L Unknown: 0×6FFFFFFFL
0×804821AL Unknown: 0×6FFFFFF0L
0×0L Marks end of dynamic section

Virtual Memory: hello.exe, start: 80482a0, flags: 0

====== Section Header: .init ======
====== Starting Address: 0×08048260 Length: 0×0017
====== File Offset: 0×0260 Size in File: 0×0017
====== Size in Memory: 0×0000
==================

Subroutine: .init, (), _init(), , _init (8048260) 8 lines 0×17 bytes
Starting address: 8048260 Ending address: 8048276

; .init, (), _init(), , _init
Called from: __libc_csu_init(), __libc_csu_init (80483a0) at 80483b6
8048260: \x55 push %ebp
8048261: \x89\xe5 mov %esp, %ebp
8048263: \x83\xec\x08 sub $0×8, %esp
8048266: \xe8\x65\x00\x00\x00 call 0×80482d0 ; call_gmon_start(), call_gmon_start
804826b: \xe8\xd0\x00\x00\x00 call 0×8048340 ; frame_dummy(), frame_dummy
8048270: \xe8\xdb\x01\x00\x00 call 0×8048450 ; __do_global_ctors_aux(), __do_global_ctors_aux
8048275: \xc9 leave
8048276: \xc3 ret
End Subroutine: .init, (), _init(), , _init (8048260) 8 lines 0×17 bytes

====== Section Header: .plt ======
====== Starting Address: 0×08048278 Length: 0×0020
====== File Offset: 0×0278 Size in File: 0×0020
====== Size in Memory: 0×0004
==================

Subroutine: .plt, (), (8048278) 4 lines 0×10 bytes

; .plt, (),
JMPed from: __libc_start_main() (PLT) (8048288) at 8048293
8048278: \xff\x35\x8c\x95\x04\x08 pushl 0×804958c ; ‘\x00\x00\x00\x00\x00′… (.got.plt+0×4)
804827e: \xff\x25\x90\x95\x04\x08 jmpl *0×8049590 ; ‘\x00\x00\x00\x00\x8e\x82\x04\x08′… (.got.plt+0×8)
8048284: \x00\x00 add %al, (%eax)
8048286: \x00\x00 add %al, (%eax)
End Subroutine: .plt, (), (8048278) 4 lines 0×10 bytes

Subroutine: __libc_start_main() (PLT) (8048288) 3 lines 0×10 bytes

; __libc_start_main() (PLT)
Called from: ELF Start, .text, (), _start(), , _start (80482a0) at 80482bc
8048288: \xff\x25\x94\x95\x04\x08 jmpl *0×8049594 ; __libc_start_main()
804828e: \x68\x00\x00\x00\x00 push $0×0
8048293: \xe9\xe0\xff\xff\xff jmp 0×8048278 ; jmp .plt, (), (8048278) :-1b:
End Subroutine: __libc_start_main() (PLT) (8048288) 3 lines 0×10 bytes

====== Section Header: .text ======
====== Starting Address: 0×080482a0 Length: 0×01e0
====== File Offset: 0×02a0 Size in File: 0×01e0
====== Size in Memory: 0×0000
==================

Subroutine: ELF Start, .text, (), _start(), , _start (80482a0) 28 lines 0×30 bytes
Starting address: 80482a0 Ending address: 80482cf

; ELF Start, .text, (), _start(), , _start
80482a0: \x31\xed xor %ebp, %ebp
80482a2: \x5e pop %esi
80482a3: \x89\xe1 mov %esp, %ecx
80482a5: \x83\xe4\xf0 and $0xf0, %esp
80482a8: \x50 push %eax
80482a9: \x54 push %esp
80482aa: \x52 push %edx
80482ab: \x68\x00\x84\x04\x08 push $0×8048400 ; push __libc_csu_fini(), __libc_csu_fini (8048400) :+155:
80482b0: \x68\xa0\x83\x04\x08 push $0×80483a0 ; push __libc_csu_init(), __libc_csu_init (80483a0) :+f0:
80482b5: \x51 push %ecx
80482b6: \x56 push %esi
80482b7: \x68\x74\x83\x04\x08 push $0×8048374 ; push frame_dummy(), frame_dummy (8048340) (+0×34) :+bd:
80482bc: \xe8\xc7\xff\xff\xff call 0×8048288 ; call __libc_start_main() (PLT) (8048288) :-34:
80482c1: \xf4 hlt

80482c2: \x90 nop
80482c3: \x90 nop
80482c4: \x90 nop
80482c5: \x90 nop
80482c6: \x90 nop
80482c7: \x90 nop
80482c8: \x90 nop
80482c9: \x90 nop
80482ca: \x90 nop
80482cb: \x90 nop
80482cc: \x90 nop
80482cd: \x90 nop
80482ce: \x90 nop
80482cf: \x90 nop
End Subroutine: ELF Start, .text, (), _start(), , _start (80482a0) 28 lines 0×30 bytes

Subroutine: call_gmon_start(), call_gmon_start (80482d0) 26 lines 0×30 bytes
Starting address: 80482d0 Ending address: 80482ff

; call_gmon_start(), call_gmon_start
80482d0: \x55 push %ebp
80482d1: \x89\xe5 mov %esp, %ebp
80482d3: \x53 push %ebx
80482d4: \x83\xec\x04 sub $0×4, %esp
80482d7: \xe8\x16\x00\x00\x00 call 0×80482f2 ; call (local) :+1b:
80482dc: \x81\xc3\xac\x12\x00\x00 add $0×12ac, %ebx
80482e2: \x8b\x83\xfc\xff\xff\xff mov 0xfffffffc(%ebx), %eax
80482e8: \x85\xc0 test %eax, %eax
80482ea: \x74\x02 jz 0×80482ee ; jz (local) :+4:
80482ec: \xff\xd0 call *%eax

Referenced by: (local) at 80482ea
80482ee: \x58 pop %eax
80482ef: \x5b pop %ebx
80482f0: \x5d pop %ebp
80482f1: \xc3 ret

; __i686.get_pc_thunk.bx(), __i686.get_pc_thunk.bx
Called from: __libc_csu_fini(), __libc_csu_fini (8048400) at 8048409
Called from: __libc_csu_init(), __libc_csu_init (80483a0) at 80483ab
Called from: (local) at 80482d7
Called from: .fini, (), _fini(), , _fini (8048480) at 8048487
80482f2: \x8b\x1c\x24 mov (%esp), %ebx
80482f5: \xc3 ret
80482f6: \x90 nop
80482f7: \x90 nop
80482f8: \x90 nop
80482f9: \x90 nop
80482fa: \x90 nop
80482fb: \x90 nop
80482fc: \x90 nop
80482fd: \x90 nop
80482fe: \x90 nop
80482ff: \x90 nop
End Subroutine: call_gmon_start(), call_gmon_start (80482d0) 26 lines 0×30 bytes

Subroutine: __do_global_dtors_aux(), __do_global_dtors_aux (8048300) 31 lines 0×40 bytes
Starting address: 8048300 Ending address: 804833f

; __do_global_dtors_aux(), __do_global_dtors_aux
Called from: .fini, (), _fini(), , _fini (8048480) at 8048492
8048300: \x55 push %ebp
8048301: \x89\xe5 mov %esp, %ebp
8048303: \x83\xec\x08 sub $0×8, %esp
8048306: \x80\x3d\xb4\x95\x04\x08\x00 cmpb $0×0, 0×80495b4 ; .bss, (), completed.1(), __bss_start(), _edata(), , completed.1, __bss_start, _edata
804830d: \x74\x1b jz 0×804832a ; jz (local) :+1d:
804830f: \xeb\x2b jmp 0×804833c ; jmp (local) :+2d:
8048311: \xeb\x0d jmp 0×8048320 ; jmp (local) :+f:
8048313: \x90 nop
8048314: \x90 nop
8048315: \x90 nop
8048316: \x90 nop
8048317: \x90 nop
8048318: \x90 nop
8048319: \x90 nop
804831a: \x90 nop
804831b: \x90 nop
804831c: \x90 nop
804831d: \x90 nop
804831e: \x90 nop
804831f: \x90 nop

Referenced by: (local) at 8048333
JMPed from: (local) at 8048311
8048320: \x83\xc0\x04 add $0×4, %eax
8048323: \xa3\xa0\x95\x04\x08 mov %eax, 0×80495a0
8048328: \xff\xd2 call *%edx

Referenced by: (local) at 804830d
804832a: \xa1\xa0\x95\x04\x08 mov 0×80495a0, %eax
804832f: \x8b\x10 mov (%eax), %edx
8048331: \x85\xd2 test %edx, %edx
8048333: \x75\xeb jnz 0×8048320 ; jnz (local) :-13:
8048335: \xc6\x05\xb4\x95\x04\x08\x01 movb $0×1, 0×80495b4 ; .bss, (), completed.1(), __bss_start(), _edata(), , completed.1, __bss_start, _edata

JMPed from: (local) at 804830f
804833c: \xc9 leave
804833d: \xc3 ret
804833e: \x89\xf6 mov %esi, %esi
End Subroutine: __do_global_dtors_aux(), __do_global_dtors_aux (8048300) 31 lines 0×40 bytes

Subroutine: frame_dummy(), frame_dummy (8048340) 37 lines 0×60 bytes
Starting address: 8048340 Ending address: 804839f

; frame_dummy(), frame_dummy
8048340: \x55 push %ebp
8048341: \x89\xe5 mov %esp, %ebp
8048343: \x83\xec\x08 sub $0×8, %esp
8048346: \xa1\xb8\x94\x04\x08 mov 0×80494b8, %eax
804834b: \x85\xc0 test %eax, %eax
804834d: \x74\x21 jz 0×8048370 ; jz (local) :+23:
804834f: \xb8\x00\x00\x00\x00 mov $0×0, %eax
8048354: \x85\xc0 test %eax, %eax
8048356: \x74\x18 jz 0×8048370 ; jz (local) :+1a:
8048358: \x83\xec\x0c sub $0xc, %esp
804835b: \x68\xb8\x94\x04\x08 push $0×80494b8 ; .jcr, (), __JCR_LIST__(), __JCR_END__(), , __JCR_LIST__, __JCR_END__
8048360: \xe8\x9b\x7c\xfb\xf7 call 0×0
8048365: \x83\xc4\x10 add $0×10, %esp
8048368: \x90 nop
8048369: \x8d\xb4\x26\x00\x00\x00\x00 lea 0×0(%esi), %esi

Referenced by: (local) at 804834d
Referenced by: (local) at 8048356
8048370: \xc9 leave
8048371: \xc3 ret
8048372: \x90 nop
8048373: \x90 nop

; main(), main
Referenced by: ELF Start, .text, (), _start(), , _start (80482a0) at 80482b7
8048374: \xb8\x04\x00\x00\x00 mov $0×4, %eax
8048379: \xbb\x01\x00\x00\x00 mov $0×1, %ebx
804837e: \xb9\xa4\x95\x04\x08 mov $0×80495a4, %ecx ; hello(), hello
8048383: \xba\xb1\x95\x04\x08 mov $0×80495b1, %edx ; ‘\x0c’ (.data) , hlen(), hlen
8048388: \xcd\x80 int $0×80
804838a: \xb8\x01\x00\x00\x00 mov $0×1, %eax
804838f: \xbb\x00\x00\x00\x00 mov $0×0, %ebx
8048394: \xcd\x80 int $0×80
8048396: \xc3 ret
8048397: \x90 nop
8048398: \x90 nop
8048399: \x90 nop
804839a: \x90 nop
804839b: \x90 nop
804839c: \x90 nop
804839d: \x90 nop
804839e: \x90 nop
804839f: \x90 nop
End Subroutine: frame_dummy(), frame_dummy (8048340) 37 lines 0×60 bytes

Subroutine: __libc_csu_init(), __libc_csu_init (80483a0) 35 lines 0×60 bytes
Variables:
fffffff0 ( 10) _____________________________________________________
Starting address: 80483a0 Ending address: 80483ff

; __libc_csu_init(), __libc_csu_init
Referenced by: ELF Start, .text, (), _start(), , _start (80482a0) at 80482b0
80483a0: \x55 push %ebp
80483a1: \x89\xe5 mov %esp, %ebp
80483a3: \x57 push %edi
80483a4: \x56 push %esi
80483a5: \x31\xf6 xor %esi, %esi
80483a7: \x53 push %ebx
80483a8: \x83\xec\x0c sub