December 12, 2017, 12:37:21 AM
Welcome, Guest. Please login or register.

Support THS!! Buy a t-shirt at the top-hat-sec store! http://www.top-hat-sec.com/store/p23/T-Shirts.html

Author Topic: Hello World in nasm  (Read 1378 times)

Sam

  • Guest
Hello World in nasm
« on: December 18, 2013, 07:24:12 PM »
Hey!

My new years eve promise to myself is to learn assembly (and shellcode if i find the time) next year. I figured I could cheat and start early. This post might see a bit lame if you already know assembly or just lame in general since I'm really new with this language. At first I will focus on nasm on an intel 32-bit processor architecture on a GNU/Linux system. Might move onto 64 or the Microshit platform on another occasion, who knows.

So, in all its glory, here is my Hello World program :)

Let's try to break this down into something useful/understandable.

The .asm file is divided into 2 different sections as you can see. Here's some beautiful asci to illustrate it :)
|---------------|
|                   
| text section        This section contain the instructions
|                   
|---------------|
|           
| data section       This contain the variables (afaik)
|                   
|---------------|

global _start
^ This will tell the linker where the entry point of the program is. Ie: _start

--------------------------------------------------------------------------------------------------------

Our program need to execute two tasks. Print Hello World! and then exit.
To do this we will do two different system calls to the kernel. The system call we need can be found in the file unistd_32.h. It will probably wary a bit from system to system where you can find it but on the distribution I use it's located here: /usr/include/i386-linux-gnu/asm/unistd_32.h

Looking through the file we can quite easy locate these two system calls:
#define __NR_exit      1
#define __NR_write      4


--------------------------------------------------------------------------------------------------------

The call for the exit function looks like this:
void _exit(int status);

In the man page we can find the following description:       
The  exit() function causes normal process termination and the value of status & 0377 is returned to the parent.

Great, this mean we can pass a return integer that we later on can check with an echo in the terminal. To make sure our program exited as it should.

--------------------------------------------------------------------------------------------------------

Next up is the write function.
ssize_t write(int fd, const void *buf, size_t count);

Man page: write()  writes  up  to  count bytes from the buffer pointed buf to the file referred to by the file descriptor fd.

File descriptors:
0 - stdin
1 - stdout
2 - stderr

This mean that we need to pass stdout (1) to fd (the file descriptor).
const void *buf should contain a pointer to our msg variable which means it will just be msg.
size_t count should contain the length of the variable the pointer is set to. Which means 12 since len("Hello World!") equals 12

This mean the call would look something like this:  write(1, msg, 12);

--------------------------------------------------------------------------------------------------------
This part might be a bit flawed, but it's as far as I've come :)

Name - Explanation
eax  - system call number   
ebx  - 1 argument
ecx  - 2 argument
edx  - 3 argument
esi  - 4 argument
edi  - 5 argument

Worth to note: A functions return value will be placed in eax after execution.
To move data from registry into the memory we will use mov
Also please note that the numbers are entered as hex!

Time to execute the write code:

              mov eax, 0x4                             Assign system call nr 4 to eax
              mov ebx, 0x1                             Assign 1 into argument 1
              mov ecx, msg                             Assign variable msg into argument 2
              mov edx, 0xC                             Assign 12 into argument 3
              int 0x80                                     Call upon the almighty kernel for execution

Time to exit the program:

              mov eax, 0x1                               Assign system call nr 1 to eax
              mov ebx, 2                                  Assign 2 into argument 1
              int 0x80                                      Call upon the almighty kernel for execution



At this point the last piece of the code should be somewhat self explanatory.



Edit:
Almost forgot. This is how to compile it
1) Create object file
nasm -f elf32 -o HelloWorld.o HelloWorld.asm
2) Link it into an executable
ld -o HelloWorld HelloWorld.o

Run as usual



If you made it this far I hope you learnt something :)
Cheers and merry xmas :'(
« Last Edit: December 18, 2013, 07:26:15 PM by Sam »

Offline mazzif

  • Experienced
  • ***
  • Posts: 159
  • Internets: +19/-1
  • Seals say "ARP ARP ARP!!!"
Re: Hello World in nasm
« Reply #1 on: December 18, 2013, 07:44:34 PM »
Cool post and cool to learn a language.  Couple questions.  Why ASM?  What is your compiled exe size. what platforms can you target (Win,Dos,*nix)

In C

Code: [Select]
#include<stdio.h>
main()
{
    printf("Hello World");
}

Compiled for DOS = 11.6 KB (11,912 bytes)

Quote
C:\>heloworld.exe
Hello World
C:\>

No right or wrong answer here, just curious about your perspective.


My hacker box has a Linux system.init

Sam

  • Guest
Re: Hello World in nasm
« Reply #2 on: December 18, 2013, 08:23:38 PM »
So far only 32-bits GNU/Linux platforms but hopefully that will change in the future. I want to learn assembly to gain a deeper understanding how stuff works while also writing some really funky code. Polymorfism is something I'm really curious about for example! :) As well as an encoder.

Anyhow, the compiled code of the program HelloWorld is a stunning 651 bytes
Think that's roughly 18 times smaller or something? Not sure, super late here and I cant really think anymore :D

Offline mazzif

  • Experienced
  • ***
  • Posts: 159
  • Internets: +19/-1
  • Seals say "ARP ARP ARP!!!"
Re: Hello World in nasm
« Reply #3 on: December 18, 2013, 09:17:01 PM »
Yea, I know Steve Gibson at https://www.grc.com codes in ASM and he always praises the super small tight and highly efficient code.  Knowing ASM is good too for Being able to crack programs.  If you can read the memory dumps, it'll share a lot in common with ASM, and youll be able to see what its doing and understand it...and know how to modify it.  I'll stick to the more natural human like languages myself, but I applaud your efforts.


My hacker box has a Linux system.init

Sam

  • Guest
Re: Hello World in nasm
« Reply #4 on: December 19, 2013, 11:09:53 AM »
I just compiled the same code you wrote in Linux and the file ended at 7157 bytes. A lot less than the windows binary but still gigantic compared to the nasm binary.

Offline R4v3N

  • Administrator
  • Super Elite
  • *****
  • Posts: 3693
  • Internets: +160/-1
  • The googles and the metasploits...
    • Top-Hat-Sec
Re: Hello World in nasm
« Reply #5 on: December 19, 2013, 08:33:33 PM »
I just compiled the same code you wrote in Linux and the file ended at 7157 bytes. A lot less than the windows binary but still gigantic compared to the nasm binary.

keep it going sam!