Here a simple example of exporting C function to Nasm.
;
; @author [JaPh]
; @date 17 August, 2009
; @file 1.asm
; @site http://xjaphx.blogspot.com/
;
; @command
; assemble nasm -f elf -l 1.lst 1.asm
; link gcc -o 1 1.o
; run ./1
;
extern printf
SECTION .data
message: db "[JaPh]Hello World",0
SECTION .text
global main ; entry point
main:
push ebp
mov ebp, esp
push dword message ; address of 'message'
call printf ; printf()
add esp, 4 ; 1 push = 4 bytes
mov esp, ebp
pop ebp
mov eax, 0
ret
The equivalent program written in C
#include <stdio.h>
int
main( int argc, char *argv[] )
{
printf("[JaPh]Hello World");
return 0
}
Have fun!@
-:== Crackme Info ==:-
Difficulty: 1 - Very easy, for newbies
Platform: Unix/linux etc.
Language: Assembler
Link: Click to refer
Solution:
This is a pretty simple crackme under Linux. The tools you need is GNU Debugger (GDB) and OBJDUMP, supported w/ every Linux distribution.
Download then extract file.
If you run the executables blah, it shows nothing.
Let's have a quick view of this binary in assembly
$ objdump -D blah
This is result
blah: file format elf32-i386
Disassembly of section .text:
08048094 <.text>:
8048094: 31 c0 xor %eax,%eax
8048096: b8 2f 00 00 00 mov $0x2f,%eax
804809b: cd 80 int $0x80
804809d: 3d ad de 00 00 cmp $0xdead,%eax
80480a2: 75 16 jne 0x80480ba
80480a4: b8 04 00 00 00 mov $0x4,%eax
80480a9: bb 01 00 00 00 mov $0x1,%ebx
80480ae: b9 c4 90 04 08 mov $0x80490c4,%ecx
80480b3: ba 06 00 00 00 mov $0x6,%edx
80480b8: cd 80 int $0x80
80480ba: 31 c0 xor %eax,%eax
80480bc: 40 inc %eax
80480bd: 31 db xor %ebx,%ebx
80480bf: cd 80 int $0x80
Disassembly of section .data:
080490c4 <.data>:
80490c4: 4f dec %edi
80490c5: 6b 65 6a 21 imul $0x21,0x6a(%ebp),%esp
80490c9: 0a .byte 0xa
Quick view, as you know about Linux programming, you surely know the the system call (interrupt) 80h.
The first syscall:
8048094: 31 c0 xor %eax,%eax
8048096: b8 2f 00 00 00 mov $0x2f,%eax
804809b: cd 80 int $0x80
This syscall is to retrieve the group id (0x2f), getgid().
Reference Linux system call table
And then, program will try to compare the result from getgid() and 0xDEAD.
If not equal, it will jump below
80480ba: 31 c0 xor %eax,%eax
80480bc: 40 inc %eax
80480bd: 31 db xor %ebx,%ebx
80480bf: cd 80 int $0x80
This is the exit() syscall (0x01).
If it equals, then the program will try to print the message by syscall write().
The message is stored in data section (0x080490C4).
OK!
So, here we can find our solutions.
+ Either, create a new group and set id is 0xDEAD (57005)
+ Or, patch the conditional jump.
The first solution is to set group id to 57005 ( using setgid() ), then add user to the group by groupadd().
I'm going to talk about patching the jump next.
Load gdb
$ gdb blah
We set breakpoint at 0x804809d
(gdb) break *0x804809d
(gdb) run
Breakpoint 1, 0x0804809d in ?? ()
(gdb) info registers
eax 0x1f4 500
ecx 0x0 0
edx 0x0 0
ebx 0x0 0
esp 0xbf9c04d0 0xbf9c04d0
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x804809d 0x804809d
eflags 0x200246 [ PF ZF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x0 0
As you see, my group id is 500 (stored in EAX); hence, program will exit immediately.
Let's do the patch 2-NOP bytes at 0x80480a2
(gdb) x/x 0x80480a2
0x80480a2: 0x04b81675
We need to patch 2 bytes: 75 16
therefore,
(gdb) set {int} 0x80480a2 = 0x04b89090
(gdb) quit
Now re-run the patched crackme.
$ ./blah
Okej!
well done! you patched the crackme.
Hope this tutorial be a little guide for whom to start cracking in Linux like me.
Have fun!@
Quote from: http://www.nasm.us/doc/nasmdoc9.html
9.1.2 Function Definitions and Function Calls
The C calling convention in 32-bit programs is as follows. In the following description, the words caller and callee are used to denote the function doing the calling and the function which gets called.
- The caller pushes the function's parameters on the stack, one after another, in reverse order (right to left, so that the first argument specified to the function is pushed last).
- The caller then executes a near
instruction to pass control to the callee.CALL - The callee receives control, and typically (although this is not actually necessary, in functions which do not need to access their parameters) starts by saving the value of
inESP so as to be able to useEBP as a base pointer to find its parameters on the stack. However, the caller was probably doing this too, so part of the calling convention states thatEBP must be preserved by any C function. Hence the callee, if it is going to set upEBP as a frame pointer, must push the previous value first.EBP - The callee may then access its parameters relative to
. The doubleword atEBP holds the previous value of[EBP] as it was pushed; the next doubleword, atEBP , holds the return address, pushed implicitly by[EBP+4] . The parameters start after that, atCALL . The leftmost parameter of the function, since it was pushed last, is accessible at this offset from[EBP+8] ; the others follow, at successively greater offsets. Thus, in a function such asEBP which takes a variable number of parameters, the pushing of the parameters in reverse order means that the function knows where to find its first parameter, which tells it the number and type of the remaining ones.printf - The callee may also wish to decrease
further, so as to allocate space on the stack for local variables, which will then be accessible at negative offsets fromESP .EBP - The callee, if it wishes to return a value to the caller, should leave the value in
,AL orAX depending on the size of the value. Floating-point results are typically returned inEAX .ST0 - Once the callee has finished processing, it restores
fromESP if it had allocated local stack space, then pops the previous value ofEBP , and returns viaEBP (equivalently,RET ).RETN - When the caller regains control from the callee, the function parameters are still on the stack, so it typically adds an immediate constant to
to remove them (instead of executing a number of slowESP instructions). Thus, if a function is accidentally called with the wrong number of parameters due to a prototype mismatch, the stack will still be returned to a sensible state since the caller, which knows how many parameters it pushed, does the removing.POP
There is an alternative calling convention used by Win32 programs for Windows API calls, and also for functions called by the Windows API such as window procedures: they follow what Microsoft calls the convention. This is slightly closer to the Pascal convention, in that the callee clears the stack by passing a parameter to the instruction. However, the parameters are still pushed in right-to-left order.
Here some helpful documentations and papers for Linux/NASM
Linux Assembly Tutorial: Step-by-Step
Write a useful program with NASM
NASM Documentation
Introduction to UNIX Assembly Programming
Linux Assembler Tutorial
* Linux System Call Table
They also includes many references and other document links inside, just visit and check it out!
Have fun!@
I'm kinda new to assembly language; also, it's very much difficult than C.
Well, as you search throughout Internet, it's very hard to find a long and complete tutorial on assembly programming under Linux. You may find it in several books about assembly like Professional Assembly Programming, Art of Assembly, Assembly Step-by-step Guide... but it merely talks about assembly under Linux environment. It's quite uncommon while programming under Linux...I just don't know why !!! If you know, tell me please!
As I read a simple tutorial about programming assembly under Linux, the language used is Netwide Assembler (NASM: http://www.nasm.us/).
Well then, let's take a look at what they guide about it.
@ The assembly program divides into three parts
1. The .data section: is used to declare initialized data and constants
- Instructions use: DB, DW, DD, DQ and DT
Samples:
section .data
message db 'Hello World!',10 ;declare a message with initialized bytes 'Hello World!", plus LF character
2. The .bss section: is used to declare uninitilized data, or called variables; memory space is reserved for variables.
- Instruction use: RESB, RESD, RESQ and REST
Samples:
section .bss
filename resb 255 ;reserve 255 bytes for filename variable
3. The .text section: the actual assembly program is written here. It begins with GLOBAL indicator to mark the entry of program, just like main() function in C/C++.
Sample:
section .text
global _main
_main:
... ;assembly code instructions here
@ Linux system calls
1. Assembly uses interrupt to create a system call. Often, int 80h
2. The order of parameters for system calls: EBX, ECX, EDX, ESI, EDI and EBP. So, you can use up to 6 parameters for a system call; well, it's enough since you cannot find any Linux system call use more than 6 parameters.
3. The register EAX always stores return value of the call.
4. The order of system call interrupt in NASM is straightforward: system call numbers then parameters from left to right.
That's some notes I take after reading a long journal on NASM.
Let's do a simple code:
I = A program uses exit() system call.
section .text
global _main
_main:
mov eax,1 ;system call number of exit() is 1
mov ebx,0 ;next is the first parameter, which will be stored in ebx; well here, we set exit code is 0
int 80h ;activate the exit() call by interrupting, postfix h indicates the value of hex, or you can write 0x80, show the same meaning
II - Compile and Link program
1. Compilation: use terminal to do the job
~ ] $ nasm -f elf exit.asm
It will produce the object file *.o
2. Linking: to connect object file and product the executable binary
~ ] $ ld -s -o exit exit.o
The binary hello will be created.
3. Run program:
~ ] $ ./exit
If it's correct, it will run smoothly w/o error or warning.
That's all I can say about NASM 'til this time.
If you wanna know more about it, why not go ahead and try. then write a tutorial for it.
People really appreciate if you like to share the rare and hard things
Have fun!@

