Security Ripcord


Security Ripcord Friday Wrap-up 9/18/2009

September 18th, 2009 cutaway Posted in Leadership, Programming, Security No Comments » 2,201 views

Slow week, lots of programming.  Gonna rain this weekend.  Looks like we’ll be hanging out at the library and aquarium.

Leadership

During my bike ride on Monday I heard a blast from the past.

“Raise Your Voice”Bad Religion

fa fa fafa fa fa fafa Raise Your Voice!
Don’t be played like someone else’s board game
Don’t be classed out like some desolate redoubt
Don’t be misled you’ve got alot on your head
And nobody’s gonna pay attention when you are dead
So: fa fa fafa fa fa fafa Raise Your Voice!
It’s the primary rule, you gotta wanna be fooled
It’s our daunted restraint that keeps us silent in shame
It’s our nature to be adversarial and free
Our evolution didn’t hinge on passivity
fa fa fafa fa fa fafa Raise Your Voice!

Actually, the song from the album begins with the lead singer stating “I think this is song we could redo in every language of every country we go to.”  True.  I think that every security professional can learn a little from these lyrics as well.

What role do security professionals play?  Auditor, monitors, engineers?  Actually, I think we are just members of the team fulfilling specific roles to keep our organization operating smoothly.  But we cannot do so in silence.  We cannot just push out reports, scan  outputs, and presentations on how people and the organization should operate.  These things are too easy to dismiss.  No, we have to do the thing that some of us dread and many more people don’t want to happen.  We need to “raise our voice.”  We need to talk about the issues.  Have open discussions that challenge the status-quo.  We need to confront common issues with new ideas and methods.

What do we accomplish when we are doing this?  Are we trying to get our way no matter what the cost?  No.  We are trying to open minds and continuously adapt and evolve.  We are verbally raising issues so that the conversations lift from the paper and actively carry on in other discussions.  We are forcing people to actively observe the current situation, address our recommendations, accept or counter these recommendations, and improve themselves and the organization.

One trap that is easy to fall into, however, is thinking that we are always in the right.  That our ideas are the correct direction.  I challenge you to “raise your voice” while also keeping your mind open to new information and other possibilities.  I challenge you to find a way to persuade those that don’t understand while also realizing that you may be one of those who does not have a clear vision of the full picture.  I challenge you to be confident yet humble in your expertise and your efforts to improve your organization and yourself.

I challenge you to “raise your voice,” no matter who is in the room.

Training

No training developed this week.  I did, however, take a few minutes to take last weeks quick tip on HBGary’s Fast Dump Pro and turned it into a training document for the rest of the analysts in my team.  Although the tool is pretty easy to use having an internal document for some of the tools that you don’t use on a regular basis is very helpful.  This allows you to quickly re-familiarize yourself with the tool.  It also helps train new personnel to the methodologies of the team.

How can you contribute to your team?  Isn’t there something that you could quickly write up that would benefit everybody?  If you don’t have that type of system in your team, would creating one help?

“Raise your voice.”

Quick Tip

You will need Mark Hammond’s pywin32 and Tim Golden’s wmi.py for this tip.  Basically, I want to show you an easy way to get exactly the system information that you want.  It will be easy to get all of the system information using Win32_OperatingSystem.  Using Tim’s method you can directly access the specific fields that you want. (inserted periods to help with proper indention due to WordPress stripping whitespace and my need for Python-structure OCD)

import wmi
c = wmi.WMI()
for os in c.Win32_OperatingSystem():
…print os.Caption

But this means that you either have to request each on individually.  This is not so bad and easy if you just want a few specific items.  But what if you want more than a few bits of information?  And what if Microsoft changes the information provided across systems?  You want to be sure that you can access that information without the script failing on you.

To handle this I suggest using a tuple to hold the values of the fields used by Win32_OperatingSystem.  Then run through the tuple using hasattr and getattr to pull the information provided by your call to WMI for the Win32_OperatingSystem information.  Here is an example script .  Of course you don’t have to include everything (as I have done here for clarity).  You can select the fields that are most important to you.  Or, you can include them all and comment out the ones you don’t want.  That way they are easily added in the future when you discover a need.

import wmi

Win32_OperatingSystem_Fields = (
‘BootDevice’,
‘BuildNumber’,
‘BuildType’,
‘Caption’,
‘CodeSet’,
‘CountryCode’,
‘CreationClassName’,
‘CSCreationClassName’,
‘CSDVersion’,
‘CSName’,
‘CurrentTimeZone’,
‘DataExecutionPrevention_Available’,
‘DataExecutionPrevention_32BitApplications’,
‘DataExecutionPrevention_Drivers’,
‘DataExecutionPrevention_SupportPolicy’,
‘Debug’,
‘Description’,
‘Distributed’,
‘EncryptionLevel;’,
‘ForegroundApplicationBoost’,
‘FreePhysicalMemory’,
‘FreeSpaceInPagingFiles’,
‘FreeVirtualMemory’,
‘InstallDate’,
‘LargeSystemCache’,
‘LastBootUpTime’,
‘LocalDateTime’,
‘Locale’,
‘Manufacturer’,
‘MaxNumberOfProcesses’,
‘MaxProcessMemorySize’,
‘MUILanguages’,
‘Name’,
‘NumberOfLicensedUsers’,
‘NumberOfProcesses’,
‘NumberOfUsers’,
‘OperatingSystemSKU’,
‘Organization’,
‘OSArchitecture’,
‘OSLanguage’,
‘OSProductSuite’,
‘OSType’,
‘OtherTypeDescription’,
‘PAEEnabled’,
‘PlusProductID’,
‘PlusVersionNumber’,
‘Primary’,
‘ProductType’,
‘RegisteredUser’,
‘SerialNumber’,
‘ServicePackMajorVersion’,
‘ServicePackMinorVersion’,
‘SizeStoredInPagingFiles’,
‘Status’,
‘SuiteMask’,
‘SystemDevice’,
‘SystemDirectory’,
‘SystemDrive’,
‘TotalSwapSpaceSize’,
‘TotalVirtualMemorySize’,
‘TotalVisibleMemorySize’,
‘Version’,
‘WindowsDirectory’
)

class sysWMI():
…def __init__(self):
……self.wmiObj = wmi.WMI()

…def getSysInfo(self):
……info = {}
……for obj in range(len(Win32_OperatingSystem_Fields)):
………if hasattr(inf, Win32_OperatingSystem_Fields[obj]):
…………print Win32_OperatingSystem_Fields[obj] + “: ” + str(getattr(inf, Win32_OperatingSystem_Fields[obj]))

sysInfo = sysWMI()
sysInfo.getSysInfo()

Personal Input

Happy Birthday #4, Collier!!!   I love you, son.  You are a great son and I am proud to be your father. Although sometimes I raise my voice TO you, I raise my voice FOR you everyday.

Go forth and do good things,

Don C. Weber


Friday Wrap-up 8/21/2009

August 21st, 2009 cutaway Posted in Leadership, Programming, Security No Comments » 2,506 views

Okay, I have been out of the blogging game a little too long.  It is time for me to start generating some more content.  So we will begin by doing a weekly wrap-up.  Basically I am going to go over a few of the things that occurred during my week.  I might even just set up a draft and populate as I go the hit submit on Friday afternoon.  As everybody will have started drinking by then my post should be well received.

I’m going to start out a little formless.  Hopefully this will start taking a  little better shape as we move forward.

Leadership

Lead from the front.  Some people might not like it, but the only reason they have time to bitch about it is because they are not doing it themselves.  You only learn from your mistakes.  If you aren’t leading you aren’t making enough mistakes to challenge yourself and provide yourself with enough opportunities to improve.

Training

I finally got around to using Wink the other day.  I developed some training using the same old Power Point slides everybody seems to generate.  You know the type, all words and no joy….er…pictures.  Even when you have a screen shot in PPTs it is just more words.  So, at the request of one of my team, I branched out with some flash video.  Of course Irongeek has been doing this for years and provides a walk through of what and how he does it: How I make Hacking Illustrated Videos.  Luckily I didn’t have to refer to Irongeek’s site as Wink was very easy to use.  I generated a quick training on doing a network capture using tcpdump.  Unfortunately I did it on my work system so I cannot provide it here.  But the point I wanted to make was that it was very easy.  Secondly, after pulling the video off my Linux system and onto my Windows system for emailing to the team, I noticed that I could import the Wink project back into the Windows version and add audio.  Now, I haven’t tried this completely, but it seemed straight forward.  So, hopefully, we will be seeing some of this later.  Next time I’ll generate the video on my own box and I’ll be able to provide it here.  Besides, everybody already knows how to do network capture with tcpdump, right?

Quick Tip

For the training I was just talking about I had to create a 10MB file.  It didn’t require any real data, I just needed some random bits but in a large file for demonstrating the file splitting functionality of tcpdump.  So I tried using “dd” to fill up the 10MB file using the following command.

# dd if=/dev/random 0f=./test_10MB.dat

I was doing this on a Ubuntu Linux box.  Although this seems like it would work, and there are plenty of search results that say to do it using this technique, this does not work on Ubuntu Linux.  All this does is create a 4KB file.  I tried all kinds of different concatenation techniques.  But I couldn’t get a 10MB file.

It turns out that Linux systems do not produce enough entropy to fill a 10MB file quickly.  If the Wikipedia /dev/random entry is to be trusted we see that “When the entropy pool is empty, reads from /dev/random will block until additional environmental noise is gathered. (Source: Linux Programmer’s Manual, section 4)”.

So, left out to dry I queried a friend of mine (Thank you, Schism) and he pointed out that the best way to do this is to use the following command.

# dd if=/dev/urandom 0f=./test_10MB.dat

Which, of course, works like a charm.  He was also quick to point out that this does not provide the “randomness” as is produced by /dev/random, but for my purposes it worked well enough.

Development

I have been working with Python programming a bit over the last few months.  It has been interesting watching the program I have been working transform into something useful.  I wish that I could provide a little more information about it, but it is still an ongoing project, so I’ll refrain.

One thing I can talk about is building function calls in Python.  I am not sure if I am using the right terminology for it, but basically what I mean is creating a list of functions and then calling them based on the results from some other function.  For instance if you can define a table or list of functions like this:

func_table = ( one, two, three )

Then create a function of those names (necessary indent removed by WordPress, so just pretend)

def one():

print “one”

def two():

print “two”

def three():

print “three”

Finally you can call each function by referencing them via the list.

for i in range (3):

func_table[i]()

When run this will produce

one

two

three

Special note: if you are returning information from these functions then you will need to store them in a variable before using or returning.  At least that is my experience.

Not very exciting until you start thinking about using tests instead of iterating through the loop.  This can be used to clean up complex code very nicely.  My understanding is that this will also help with optimizing the execution of the code as well.  What the magic balance between this method and several “if” statements is, I do not know.

Can anybody describe to me a good method of testing this optimization?  I don’t know enough about programming to come up with a complex enough task to challenge the CPU and memory of my system and produce viable results.  If you have a recommendation leave a comment and I will test and post results.  Or, you can run it yourself and post your results in the comments.  Either way it will be beneficial to us all.

BTW, thank you, Invisigoth.  I learned this from reviewing your code.

Personal Input

Not much today as I need to get down stairs with the boys.

Go forth and do good things,

Don C. Weber


Assembly Debugging with VTrace

May 4th, 2008 cutaway Posted in Programming, Security No Comments » 2,705 views

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


Hello World Assembly Compiling

April 27th, 2008 cutaway Posted in atlas, Hacking, Programming 1 Comment » 5,231 views

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: 0x080490a4 offset: 176 ent/size: 0/ 0 align: 1
Elf Section: [ .data] VMA: 0x080490a4 offset: 164 ent/size: 0/ 12 align: 4
Elf Section: [ .bss] VMA: 0x080490b0 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: 0x080490a4 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 $0x80490a4, %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: 0x080490a8 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 $0x80490a5, %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: 0x080482a0
==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 (0x1f 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: 0x080481c0 offset: 448 ent/size: 0/ 89 align: 1
Elf Section: [ .gnu.version] VMA: 0x0804821a 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: 0x0804824c 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: 0x080482a0 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: 0x0804849c offset: 1180 ent/size: 0/ 8 align: 4
Elf Section: [ .eh_frame] VMA: 0x080484a4 offset: 1188 ent/size: 0/ 4 align: 4
Elf Section: [ .ctors] VMA: 0x080494a8 offset: 1192 ent/size: 0/ 8 align: 4
Elf Section: [ .dtors] VMA: 0x080494b0 offset: 1200 ent/size: 0/ 8 align: 4
Elf Section: [ .jcr] VMA: 0x080494b8 offset: 1208 ent/size: 0/ 4 align: 4
Elf Section: [ .dynamic] VMA: 0x080494bc 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: 0x080495b4 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: 0x080494a8 offset: 1192 memsize: 272 align: 4096 (filesz: 268) flags: 6
[ Dynamic linking information] VMA: 0x080494bc 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
0x8048260L Address of init function
0x8048480L Address of termination function
0x8048148L Address of symbol hash table
0x80481C0L Address of string table
0x8048170L Address of symbol table
0x59L Size of string table
0x10L Size of one symbol table entry
0x0L For debugging; unspecified
0x8049588L Processor defined value
0x8L Size in bytes of PLT relocs
0x11L Type of reloc in PLT
0x804824CL Address of PLT relocs
0x8048244L Address of Rel relocs
0x8L Total size of Rel relocs
0x8L Size of one Rel reloc
0x8048224L Unknown: 0x6FFFFFFEL
0x1L Unknown: 0x6FFFFFFFL
0x804821AL Unknown: 0x6FFFFFF0L
0x0L 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 0x80482d0 ; 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 0x804958c ; ‘\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: 0x080482a0 Length: 0x01e0
====== File Offset: 0x02a0 Size in File: 0x01e0
====== 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 $0x80483a0 ; 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 0x80482f2 ; call (local) :+1b:
80482dc: \x81\xc3\xac\x12\x00\x00 add $0x12ac, %ebx
80482e2: \x8b\x83\xfc\xff\xff\xff mov 0xfffffffc(%ebx), %eax
80482e8: \x85\xc0 test %eax, %eax
80482ea: \x74\x02 jz 0x80482ee ; 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, 0x80495b4 ; .bss, (), completed.1(), __bss_start(), _edata(), , completed.1, __bss_start, _edata
804830d: \x74\x1b jz 0x804832a ; jz (local) :+1d:
804830f: \xeb\x2b jmp 0x804833c ; 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, 0x80495a0
8048328: \xff\xd2 call *%edx

Referenced by: (local) at 804830d
804832a: \xa1\xa0\x95\x04\x08 mov 0x80495a0, %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, 0x80495b4 ; .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 0x80494b8, %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 $0x80494b8 ; .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 $0x80495a4, %ecx ; hello(), hello
8048383: \xba\xb1\x95\x04\x08 mov $0x80495b1, %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 $0xc, %esp
80483ab: \xe8\x42\xff\xff\xff call 0x80482f2 ; call call_gmon_start(), call_gmon_start (80482d0) (+0×22) :-b9:
80483b0: \x81\xc3\xd8\x11\x00\x00 add $0x11d8, %ebx
80483b6: \xe8\xa5\xfe\xff\xff call 0×8048260 ; call .init, (), _init(), , _init (8048260) :-156:
80483bb: \x8d\x83\x20\xff\xff\xff lea 0xffffff20(%ebx), %eax
80483c1: \x8d\x93\x20\xff\xff\xff lea 0xffffff20(%ebx), %edx
80483c7: \x89\x45\xf0 mov %eax, 0xfffffff0(%ebp)
80483ca: \x29\xd0 sub %edx, %eax
80483cc: \xc1\xf8\x02 sar $0×2, %eax
80483cf: \x39\xc6 cmp %eax, %esi
80483d1: \x73\x1f jnc 0x80483f2 ; jnc (local) :+21:
80483d3: \x89\xd7 mov %edx, %edi
80483d5: \x8d\x74\x26\x00 lea 0×0(%esi), %esi
80483d9: \x8d\xbc\x27\x00\x00\x00\x00 lea 0×0(%edi), %edi

Referenced by: (local) at 80483f0
80483e0: \xff\x14\xb2 calll *(%edx, %esi, 4)
80483e3: \x8b\x4d\xf0 mov 0xfffffff0(%ebp), %ecx
80483e6: \x46 inc %esi
80483e7: \x89\xfa mov %edi, %edx
80483e9: \x29\xf9 sub %edi, %ecx
80483eb: \xc1\xf9\x02 sar $0×2, %ecx
80483ee: \x39\xce cmp %ecx, %esi
80483f0: \x72\xee jc 0x80483e0 ; jc (local) :-10:

Referenced by: (local) at 80483d1
80483f2: \x83\xc4\x0c add $0xc, %esp
80483f5: \x5b pop %ebx
80483f6: \x5e pop %esi
80483f7: \x5f pop %edi
80483f8: \x5d pop %ebp
80483f9: \xc3 ret
80483fa: \x8d\xb6\x00\x00\x00\x00 lea 0×0(%esi), %esi
End Subroutine: __libc_csu_init(), __libc_csu_init (80483a0) 35 lines 0×60 bytes

Subroutine: __libc_csu_fini(), __libc_csu_fini (8048400) 30 lines 0×50 bytes
Variables:
fffffffc ( 4) _____________________________________________________
fffffff8 ( 4) _____________________________________________________
fffffff4 ( 4) _____________________________________________________
Starting address: 8048400 Ending address: 804844f

; __libc_csu_fini(), __libc_csu_fini
Referenced by: ELF Start, .text, (), _start(), , _start (80482a0) at 80482ab
8048400: \x55 push %ebp
8048401: \x89\xe5 mov %esp, %ebp
8048403: \x83\xec\x18 sub $0×18, %esp
8048406: \x89\x5d\xf4 mov %ebx, 0xfffffff4(%ebp)
8048409: \xe8\xe4\xfe\xff\xff call 0x80482f2 ; call call_gmon_start(), call_gmon_start (80482d0) (+0×22) :-117:
804840e: \x81\xc3\x7a\x11\x00\x00 add $0x117a, %ebx
8048414: \x89\x7d\xfc mov %edi, 0xfffffffc(%ebp)
8048417: \x8d\x83\x20\xff\xff\xff lea 0xffffff20(%ebx), %eax
804841d: \x8d\xbb\x20\xff\xff\xff lea 0xffffff20(%ebx), %edi
8048423: \x89\x75\xf8 mov %esi, 0xfffffff8(%ebp)
8048426: \x29\xf8 sub %edi, %eax
8048428: \xc1\xf8\x02 sar $0×2, %eax
804842b: \x8d\x70\xff lea 0xffffffff(%eax), %esi
804842e: \xeb\x04 jmp 0×8048434 ; jmp (local) :+6:

Referenced by: (local) at 8048437
8048430: \xff\x14\xb7 calll *(%edi, %esi, 4)
8048433: \x4e dec %esi

JMPed from: (local) at 804842e
8048434: \x83\xfe\xff cmp $0xffffffff, %esi
8048437: \x75\xf7 jnz 0×8048430 ; jnz (local) :-7:
8048439: \xe8\x42\x00\x00\x00 call 0×8048480 ; .fini, (), _fini(), , _fini
804843e: \x8b\x5d\xf4 mov 0xfffffff4(%ebp), %ebx
8048441: \x8b\x75\xf8 mov 0xfffffff8(%ebp), %esi
8048444: \x8b\x7d\xfc mov 0xfffffffc(%ebp), %edi
8048447: \x89\xec mov %ebp, %esp
8048449: \x5d pop %ebp
804844a: \xc3 ret
804844b: \x90 nop
804844c: \x90 nop
804844d: \x90 nop
804844e: \x90 nop
804844f: \x90 nop
End Subroutine: __libc_csu_fini(), __libc_csu_fini (8048400) 30 lines 0×50 bytes

Subroutine: __do_global_ctors_aux(), __do_global_ctors_aux (8048450) 30 lines 0×30 bytes
Starting address: 8048450 Ending address: 804847f

; __do_global_ctors_aux(), __do_global_ctors_aux
8048450: \x55 push %ebp
8048451: \x89\xe5 mov %esp, %ebp
8048453: \x53 push %ebx
8048454: \x52 push %edx
8048455: \xbb\xa8\x94\x04\x08 mov $0x80494a8, %ebx ; .ctors, ‘\xff\xff\xff\xff’ (.ctors) , (), __CTOR_LIST__(), __fini_array_end(), __fini_array_start(), __init_array_end(), __init_array_start(), , __CTOR_LIST__, __fini_array_end, __fini_array_start, __init_array_end, __init_array_start
804845a: \xa1\xa8\x94\x04\x08 mov 0x80494a8, %eax
804845f: \xeb\x16 jmp 0×8048477 ; jmp (local) :+18:
8048461: \xeb\x0d jmp 0×8048470 ; jmp (local) :+f:
8048463: \x90 nop
8048464: \x90 nop
8048465: \x90 nop
8048466: \x90 nop
8048467: \x90 nop
8048468: \x90 nop
8048469: \x90 nop
804846a: \x90 nop
804846b: \x90 nop
804846c: \x90 nop
804846d: \x90 nop
804846e: \x90 nop
804846f: \x90 nop

Referenced by: (local) at 804847a
JMPed from: (local) at 8048461
8048470: \x83\xeb\x04 sub $0×4, %ebx
8048473: \xff\xd0 call *%eax
8048475: \x8b\x03 mov (%ebx), %eax

JMPed from: (local) at 804845f
8048477: \x83\xf8\xff cmp $0xffffffff, %eax
804847a: \x75\xf4 jnz 0×8048470 ; jnz (local) :-a:
804847c: \x58 pop %eax
804847d: \x5b pop %ebx
804847e: \x5d pop %ebp
804847f: \xc3 ret
End Subroutine: __do_global_ctors_aux(), __do_global_ctors_aux (8048450) 30 lines 0×30 bytes

====== Section Header: .fini ======
====== Starting Address: 0×08048480 Length: 0x001b
====== File Offset: 0×0480 Size in File: 0x001b
====== Size in Memory: 0×0000
==================

Subroutine: .fini, (), _fini(), , _fini (8048480) 11 lines 0x1b bytes
Starting address: 8048480 Ending address: 804849a

; .fini, (), _fini(), , _fini
8048480: \x55 push %ebp
8048481: \x89\xe5 mov %esp, %ebp
8048483: \x53 push %ebx
8048484: \x83\xec\x04 sub $0×4, %esp
8048487: \xe8\x66\xfe\xff\xff call 0x80482f2 ; call call_gmon_start(), call_gmon_start (80482d0) (+0×22) :-195:
804848c: \x81\xc3\xfc\x10\x00\x00 add $0x10fc, %ebx
8048492: \xe8\x69\xfe\xff\xff call 0×8048300 ; call __do_global_dtors_aux(), __do_global_dtors_aux (8048300) :-192:
8048497: \x5a pop %edx
8048498: \x5b pop %ebx
8048499: \x5d pop %ebp
804849a: \xc3 ret
End Subroutine: .fini, (), _fini(), , _fini (8048480) 11 lines 0x1b bytes
0: (), (), (), (), (), (), (), (), (), (), (), (), ./../include/libc-symbols.h(), ./../include/libc-symbols.h(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/config.h(), ./../include/libc-symbols.h(), (), (), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/csu//(), abi-note.S(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/abi-tag.h(), abi-note.S(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/config.h(), abi-note.S(), (), ./../include/libc-symbols.h(), ./../include/libc-symbols.h(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/config.h(), ./../include/libc-symbols.h(), (), (), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/csu//(), abi-note.S(), init.c(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/crti.S(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/defs.h(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/defs.h(), initfini.c(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/crti.S(), (), ./../include/libc-symbols.h(), ./../include/libc-symbols.h(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/config.h(), ./../include/libc-symbols.h(), (), (), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/crti.S(), crtstuff.c(), crtstuff.c(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/crtn.S(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/defs.h(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/defs.h(), initfini.c(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/crtn.S(), (), ./../include/libc-symbols.h(), ./../include/libc-symbols.h(), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/config.h(), ./../include/libc-symbols.h(), (), (), /glibc-tmp-91a3c13f482c0e54fcb31801829d957b/glibc-2.3.6/build-glibc-2.3.6/csu/crtn.S(), __libc_start_main@@GLIBC_2.0(), _Jv_RegisterClasses(), __gmon_start__(), (), __libc_start_main(), _Jv_RegisterClasses(), __gmon_start__()
8048114: .interp, ‘/lib/ld-linux.so.2′ (.interp) , (),
8048128: .note.ABI-tag, ‘\x04′ (.note.ABI-tag) , (),
804812c: ‘\x10′ (.note.ABI-tag)
8048130: ‘\x01′ (.note.ABI-tag)
8048134: ‘GNU’ (.note.ABI-tag)
804813c: ‘\x02′ (.note.ABI-tag)
8048140: ‘\x04′ (.note.ABI-tag)
8048144: ‘\x01′ (.note.ABI-tag)
8048148: .hash, ‘\x03′ (.hash) , (),
804814c: ‘\x05′ (.hash)
8048150: ‘\x04′ (.hash)
8048154: ‘\x01′ (.hash)
8048158: ‘\x02′ (.hash)
804816c: ‘\x03′ (.hash)
8048170: .dynsym, (),
8048180: ‘=’ (.dynsym)
8048188: ‘\xde’ (.dynsym)
804818c: ‘\x12′ (.dynsym)
8048190: ‘.’ (.dynsym)
8048194: ‘\xa0\x84\x04\x08\x04′ (.dynsym)
804819c: ‘\x11′ (.dynsym)
804819e: ‘\x0e’ (.dynsym)
80481a0: ‘\x01′ (.dynsym)
80481ac: ‘ ‘ (.dynsym)
80481b0: ‘\x15′ (.dynsym)
80481bc: ‘ ‘ (.dynsym)
80481c0: .dynstr, (),
80481c1: ‘_Jv_RegisterClasses’ (.dynstr)
80481d5: ‘__gmon_start__’ (.dynstr)
80481e4: ‘libc.so.6′ (.dynstr)
80481ee: ‘_IO_stdin_used’ (.dynstr)
80481fd: ‘__libc_start_main’ (.dynstr)
804820f: ‘GLIBC_2.0′ (.dynstr)
804821a: .gnu.version, (),
804821c: ‘\x02′ (.gnu.version)
804821e: ‘\x01′ (.gnu.version)
8048224: .gnu.version_r, ‘\x01′ (.gnu.version_r) , (),
8048226: ‘\x01′ (.gnu.version_r)
8048228: ‘$’ (.gnu.version_r)
804822c: ‘\x10′ (.gnu.version_r)
‘ (.gnu.version_r)
804823a: ‘\x02′ (.gnu.version_r)
804823c: ‘O’ (.gnu.version_r)
8048244: .rel.dyn, ‘\x84\x95\x04\x08\x06\x04′ (.rel.dyn) , (),
804824c: .rel.plt, ‘\x94\x95\x04\x08\x07\x01′ (.rel.plt) , (),
8048260: .init, (), _init(), , _init
8048278: .plt, (),
8048288: __libc_start_main() (PLT)
80482a0: ELF Start, .text, (), _start(), , _start
80482d0: call_gmon_start(), call_gmon_start
80482f2: __i686.get_pc_thunk.bx(), __i686.get_pc_thunk.bx
8048300: __do_global_dtors_aux(), __do_global_dtors_aux
8048340: frame_dummy(), frame_dummy
8048374: main(), main
80483a0: __libc_csu_init(), __libc_csu_init
8048400: __libc_csu_fini(), __libc_csu_fini
8048450: __do_global_ctors_aux(), __do_global_ctors_aux
8048480: .fini, (), _fini(), , _fini
804849c: .rodata, ‘\x03′ (.rodata) , (), _fp_hw(), , _fp_hw
80484a0: ‘\x01′ (.rodata) , _IO_stdin_used(), _IO_stdin_used(), _IO_stdin_used
80484a2: ‘\x02′ (.rodata)
80484a4: .eh_frame, (), __FRAME_END__(), , __FRAME_END__
80494a8: .ctors, ‘\xff\xff\xff\xff’ (.ctors) , (), __CTOR_LIST__(), __fini_array_end(), __fini_array_start(), __init_array_end(), __init_array_start(), , __CTOR_LIST__, __fini_array_end, __fini_array_start, __init_array_end, __init_array_start
80494ac: __CTOR_END__(), __CTOR_END__
80494b0: .dtors, ‘\xff\xff\xff\xff’ (.dtors) , (), __DTOR_LIST__(), , __DTOR_LIST__
80494b4: __DTOR_END__(), __DTOR_END__
80494b8: .jcr, (), __JCR_LIST__(), __JCR_END__(), , __JCR_LIST__, __JCR_END__
80494bc: .dynamic, ‘\x01′ (.dynamic) , (), _DYNAMIC(), , _DYNAMIC
80494c0: ‘$’ (.dynamic)
80494c4: ‘\x0c’ (.dynamic)
80494c8: ‘\x60\x82\x04\x08\x0d’ (.dynamic)
80494d0: ‘\x80\x84\x04\x08\x04′ (.dynamic)
80494d8: ‘\x48\x81\x04\x08\x05′ (.dynamic)
80494e0: ‘\xc0\x81\x04\x08\x06′ (.dynamic)
80494e8: ‘\x70\x81\x04\x08\x0a’ (.dynamic)
80494f0: ‘Y’ (.dynamic)
80494f4: ‘\x0b’ (.dynamic)
80494f8: ‘\x10′ (.dynamic)
80494fc: ‘\x15′ (.dynamic)
8049504: ‘\x03′ (.dynamic)
8049508: ‘\x88\x95\x04\x08\x02′ (.dynamic)
8049510: ‘\x08′ (.dynamic)
8049514: ‘\x14′ (.dynamic)
8049518: ‘\x11′ (.dynamic)
804951c: ‘\x17′ (.dynamic)
8049520: ‘\x4c\x82\x04\x08\x11′ (.dynamic)
8049528: ‘\x44\x82\x04\x08\x12′ (.dynamic)
8049530: ‘\x08′ (.dynamic)
8049534: ‘\x13′ (.dynamic)
8049538: ‘\x08′ (.dynamic)
804953c: ‘\xfe\xff\xff\x6f\x24\x82\x04\x08\xff\xff\xff\x6f\x01′ (.dynamic)
804954c: ‘\xf0\xff\xff\x6f\x1a\x82\x04\x08′ (.dynamic)
8049584: .got, __gmon_start__(), (),
8049588: .got.plt, (), _GLOBAL_OFFSET_TABLE_(), , _GLOBAL_OFFSET_TABLE_
804958c: ‘\x00\x00\x00\x00\x00′… (.got.plt+0×4)
8049590: ‘\x00\x00\x00\x00\x8e\x82\x04\x08′… (.got.plt+0×8)
8049594: __libc_start_main()
8049598: .data, (), data_start(), __data_start(), , data_start, __data_start
804959c: __dso_handle(), __dso_handle
80495a0: ‘Hello World
‘ (.data) , p.0(), p.0
80495a4: hello(), hello
80495b1: ‘\x0c’ (.data) , hlen(), hlen
80495b4: .bss, (), completed.1(), __bss_start(), _edata(), , completed.1, __bss_start, _edata
80495b5: ‘GCC’ (.bss)
80495b8: _end(), _end

bt hello #

Dang, the GCC output is so big and convoluted, I couldn’t keep up with it.

Now that we have seen the output of these files, you are probably asking yourself, “Why are disassemblers important?” Well, they analyze the executable for us so that we do not have to open the file in a hex editor and then begin decrypting the system calls and opcodes. It also provides us with the locations of various interesting instructions and data within the virtual memory. I am certain that atlas has programmed in more features that I have not implemented here and I’m willing to place a bet that he has something very interesting in the works for future versions of Disass-3. For now we are just going to have to wait.

Of course I know that none of this is very exciting. Just so you know, I did try to think of something that would liven it up a little bit. Alas, it did not happen. But at least I did learn a thing or two about Assembly. Hopefully you did as well.

Go forth and do good things,

Don C. Weber

Technorati Tags , , , , , , ,

Hello Sleep – C I H4K U

April 25th, 2008 cutaway Posted in Hacking, Programming, Security No Comments » 3,904 views

Here is the latest exercise I worked on. This time I have taken the Hello World c-program I demonstrated in the Hello World – C to Assembly post and added a sleep to it. The sleep command paused the program long enough so that I was able to locate the memory allocated to the program and change the value of the output. Of course I would have liked to have figured out a way to detect the code involved with the program instead of the actual string to be output because this might not be known. But, I guess I am going to have to deal with this for now.

This first section will demonstrate the modifications that were made to the c-program to turn it into hello_sleep.c. I diffed the assembly file with the version from yesterday so that you and I could see the difference.

bt hello_sleep # cat hello_sleep.c
#include <stdio.h>
#include <unistd.h> //Required for sleep cmd

main(){

//Declare local variables
unsigned int sec = 300; // 5 Minutes

sleep(sec);
printf(“Hello World\n”);
return(0);
}
bt hello_sleep # ls
Makefile hello_sleep.c
bt hello_sleep # make hello_sleep.s
cc -S hello_sleep.c
bt hello_sleep # ls
Makefile hello_sleep.c hello_sleep.s
bt hello_sleep # cat hello_sleep.s
.file “hello_sleep.c”
.section .rodata
.LC0:
.string “Hello World\n”
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
movl $300, -4(%ebp)
subl $12, %esp
pushl -4(%ebp)
call sleep
addl $16, %esp
subl $12, %esp
pushl $.LC0
call printf
addl $16, %esp
movl $0, %eax
leave
ret
.size main, .-main
.section .note.GNU-stack,”",@progbits
.ident “GCC: (GNU) 3.4.6″
bt hello_sleep # diff hello_sleep.s ../hello/hello.s
1c1
< .file “hello_sleep.c”

> .file “hello.c”
19,23d18
< movl $300, -4(%ebp)
< subl $12, %esp
< pushl -4(%ebp)
< call sleep
< addl $16, %esp
bt hello_sleep # make
cc -c hello_sleep.c
cc hello_sleep.o -o hello_sleep.exe
bt hello_sleep # ls
Makefile hello_sleep.c hello_sleep.exe* hello_sleep.o hello_sleep.s
bt hello_sleep # ./hello_sleep.exe
Hello World
bt hello_sleep # ./hello_sleep.exe

While this was running I opened another terminal and went to work. Of course I had already set up my tools – VTrace which is now a part of VDB. I also installed the latest version of libdisassemble and disass-3 which @ just released today. I’ll leave the installation process to you this time. I have highlighted some key information and if you see a “<- NOTE: ” it is an added comment.

bt dev # python <- NOTE: Time to learn Python
Python 2.4.3 (#1, Apr 3 2006, 14:02:53)
[GCC 3.4.6] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import vtrace <- NOTE: Pull in the VTrace functions and objects
>>> tr = vtrace.getTrace() <- NOTE: Create an object that will do the work
>>> tr.ps() <- NOTE: Output the process list. This could be scripted for future dynamic results.
[(1, 'init [3] ‘), (1008, ‘/sbin/udevd –daemon ‘), (2178, ‘/usr/sbin/syslogd ‘), (2181, ‘/usr/sbin/klogd -c 3 -x ‘), (2198, ‘/sbin/dhcpcd -d -t 10 eth0 ‘), (2227, ‘/usr/sbin/cupsd ‘), (2238, ‘/usr/sbin/crond -l10 ‘), (2274, ‘/usr/sbin/gpm -m /dev/mouse -t ps2 ‘), (2543, ‘/bin/bash /usr/bin/fstab-update –daemon ‘), (2841, ‘-bash ‘), (2842, ‘/sbin/agetty 38400 tty2 linux ‘), (2843, ‘/sbin/agetty 38400 tty3 linux ‘), (2844, ‘/sbin/agetty 38400 tty4 linux ‘), (2845, ‘/sbin/agetty 38400 tty5 linux ‘), (2846, ‘/sbin/agetty 38400 tty6 linux ‘), (2884, ‘/bin/sh /usr/X11R6/bin/startx ‘), (2902, ‘/usr/X11R6/bin/xinit /usr/X11R6/lib/X11/xinit/xinitrc — -auth /root/.serverauth.2884 ‘), (2903, ‘X :0 -auth /root/.serverauth.2884 ‘), (2919, ‘/bin/sh /usr/X11R6/lib/X11/xinit/xinitrc ‘), (2923, ‘/bin/sh /opt/kde/bin/startkde ‘), (2957, ‘kdeinit Running… ‘), (2962, ‘dcopserver [kdeinit] –nosid ‘), (2964, ‘klauncher [kdeinit] –new-startup ‘), (2966, ‘kded [kdeinit] –new-startup ‘), (2975, ‘kwrapper ksmserver ‘), (2977, ‘ksmserver [kdeinit] ‘), (2978, ‘kwin [kdeinit] -session 10736c6178000117232847800000030170000_1208991555_703768′), (2980, ‘kdesktop [kdeinit] ‘), (2984, ‘kicker [kdeinit] ‘), (2987, ‘kio_file [kdeinit] file /tmp/ksocket-root/klauncherPvcYNb.slave-socket /tmp/ksocket-root/kdesktopnUuTnb.slave-socket’), (2991, ‘kxkb [kdeinit] ‘), (2995, ‘artsd -F 10 -S 4096 -a alsa -m artsmessage -c drkonqi -l 3 -f ‘), (2999, ‘kaccess [kdeinit] ‘), (3002, ‘krandrtray -session 10736c6178000117232848400000030170007_1208991555_690824 ‘), (3006, ‘kmix [kdeinit] -session 10736c6178000117232848400000030170008_1208991555_687965′), (3007, ‘konsole [kdeinit] -session 10627400000120899154700000029640010_1208991555_692031 –ls’), (3011, ‘knotify [kdeinit] ‘), (3012, ‘konsole [kdeinit] –ls ‘), (3016, ‘konsole [kdeinit] –ls ‘), (3017, ‘-bash ‘), (3027, ‘-bash ‘), (3044, ‘-bash ‘), (3125, ‘/bin/sh /usr/bin/firefox ‘), (3137, ‘/bin/sh /opt/firefox/run-mozilla.sh /opt/firefox/firefox-bin ‘), (3142, ‘/opt/firefox/firefox-bin ‘), (3159, ‘/usr/local/libexec/gconfd-2 14 ‘), (21770, ‘/usr/bin/python /usr/bin/pydoc vtrace ‘), (21776, ‘less ‘), (22462, ‘./hello_sleep.exe ‘), (22936, ‘python ‘), (23047, ‘sleep 1 ‘)]
>>> tr.attach(22462) <- NOTE: Attach to the running process. It is sleeping so be very quite.
>>> tr.searchMemory(‘Hello’) <- NOTE: Search the memory for, well, Hello
[134513956L, 134518052L] <- NOTE: Those are the memory addresses in decimal form. The “L” means that it is a long integer.
>>> tr.readMemory(134513956L,14) <- NOTE: Read the memory location
‘Hello World\n\x00\x00′
>>> tr.readMemory(134518052L,14)
‘Hello World\n\x00\x00′
>>> tr.writeMemory(134513956L,’h4k3d’) <- NOTE: Change the memory location
>>> tr.writeMemory(134518052L,’h4k3d’)
>>> tr.readMemory(134513956L,14) <- NOTE: Check your work
‘h4k3d World\n\x00\x00′
>>> tr.readMemory(134518052L,14)
‘h4k3d World\n\x00\x00′
>>> tr.detach() <- NOTE: Step away very quitely

>>>
bt dev #

Did you wake it? No??…Good. Now just sit back and wait for it. It will wake up on its own. You actually have to wait the full amount of time. The method I used above blocks the process from running once VTrace attaches to the process. I believe that it can be done without blocking but that is for another time. Ohhhhh, here is the return value. I’ll include a few of previous lines that I have already shown so you can remember where we were at.

bt hello_sleep # make
cc -c hello_sleep.c
cc hello_sleep.o -o hello_sleep.exe
bt hello_sleep # ls
Makefile hello_sleep.c hello_sleep.exe* hello_sleep.o hello_sleep.s
bt hello_sleep # ./hello_sleep.exe
Hello World
bt hello_sleep # ./hello_sleep.exe
h4k3d World
bt hello_sleep #

Sweet!!!

Go forth and do good things,

Don C. Weber

Technorati Tags , , , , , , , , ,

Hello World – C To Assembly

April 24th, 2008 cutaway Posted in Programming, Security 1 Comment » 3,011 views

Just a little work I have been doing.

Hello World – C

The following shows a Hello World file written in C along with a quick Makefile that helps compile.

bt hello # ls
Makefile hello.c
bt hello # cat Makefile
hello: hello.o
cc hello.o -o hello.exe
hello.o: hello.c
cc -c hello.c
hello.s: hello.c
cc -S hello.c
bt hello # cat hello.c
#include <stdio.h>

main(){
printf(“Hello World\n”);
return(0);
}
bt hello # make
cc -c hello.c
cc hello.o -o hello.exe
bt hello # ls
Makefile hello.c hello.exe* hello.o
bt hello # ./hello.exe
Hello World
bt hello #

Disassemble Hello World – C

This next set of commands shows how I disassembled the Hello World – C program. It also shows how to halt the compilation of the program so that a file with the assembly code is produced. I did this to compare with the output of the disassembler and verify that I was looking at the correct information. The disassembler I used is the Python disassembler called libdisassembly which can be found in IMMUNITY’s Free Software repository.

I’ve bolded some key information. The first is the File Offset and Size information where the assembly code is located in the object file.  The second is an error message that keeps showing up at the end of the disassembly.  I bolded it because I am not sure what it is or means.  Please update the comments if you have any idea.

bt test_programs # wget http://www.immunityinc.com/downloads/libdisassemble2.0.tar.gz
–22:10:35– http://www.immunityinc.com/downloads/libdisassemble2.0.tar.gz
=> `libdisassemble2.0.tar.gz’
Resolving www.immunityinc.com… 66.175.114.214
Connecting to www.immunityinc.com|66.175.114.214|:80… connected.
HTTP request sent, awaiting response… 200 OK
Length: 44,801 (44K) [application/x-gzip]

100%[===================================================================>] 44,801 182.57K/s

22:10:35 (182.48 KB/s) – `libdisassemble2.0.tar.gz’ saved [44801/44801]

bt test_programs # ls
assembly/ c/ c++/ libdisassemble2.0.tar.gz perl/ python/ ruby/
bt test_programs # tar zxvf libdisassemble2.0.tar.gz
libdisassemble/
libdisassemble/disassemble.py
libdisassemble/opcode86.py
libdisassemble/README
libdisassemble/LICENSE
libdisassemble/opcode86.pyc
bt test_programs # ls
assembly/ c/ c++/ libdisassemble/ perl/ python/ ruby/
bt test_programs # ls libdisassemble/
LICENSE README disassemble.py* opcode86.py opcode86.pyc
bt test_programs # cd c/hello/
bt hello # ls
Makefile hello.c hello.exe* hello.o
bt hello # objdump -x hello.o

hello.o: file format elf32-i386
hello.o
architecture: i386, flags 0×00000011:
HAS_RELOC, HAS_SYMS
start address 0×00000000

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000033 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 00000068 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000068 2**2
ALLOC
3 .rodata 0000000d 00000000 00000000 00000068 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .note.GNU-stack 00000000 00000000 00000000 00000075 2**0
CONTENTS, READONLY
5 .comment 00000012 00000000 00000000 00000075 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 hello.c
00000000 l d .text 00000000
00000000 l d .data 00000000
00000000 l d .bss 00000000
00000000 l d .rodata 00000000
00000000 l d .note.GNU-stack 00000000
00000000 l d .comment 00000000
00000000 g F .text 00000033 main
00000000 *UND* 00000000 printf

RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000020 R_386_32 .rodata
00000025 R_386_PC32 printf

bt hello # ../../libdisassemble/disassemble.py hello.o 0034 0033

Disassembling file hello.o at offset: 0×34
00000034: push %ebp
00000035: mov %esp, %ebp
00000037: sub $0×8, %esp
0000003A: and $0xf0, %esp
0000003D: mov $0×0, %eax
00000042: add $0xf, %eax
00000045: add $0xf, %eax
00000048: shr $0×4, %eax
0000004B: shl $0×4, %eax
0000004E: sub %eax, %esp
00000050: sub $0xc, %esp
00000053: push $0×0
00000058: call 0×1
0000005D: add $0×10, %esp
00000060: mov $0×0, %eax
00000065: leave
00000066: ret
Error Parsing Opcode – Data: Offset: 0×0
Traceback (most recent call last):
File “../../libdisassemble/disassemble.py”, line 265, in parse
ndx = ord(self.data[off])
IndexError: string index out of range

bt hello # make hello.s
cc -S hello.c
bt hello # cat hello.s
.file “hello.c”
.section .rodata
.LC0:
.string “Hello World\n”
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
subl $12, %esp
pushl $.LC0
call printf
addl $16, %esp
movl $0, %eax
leave
ret
.size main, .-main
.section .note.GNU-stack,”",@progbits
.ident “GCC: (GNU) 3.4.6″
bt hello #

Go forth and do good things,

Don C. Weber

Technorati Tags , , , , , , ,