Ok.
So i have been messing around with Assembly, and i was wondering: just HOW does a linkes ELF64 File look like, and can i directly write a linked file in plain-text? (like create a file e.G "main", write the hex-values of the system-calls, and then run it without linking or assembling.)
I have tried objdump -x main but i don't think, this is the entire ELF-File, because there is too less information, as i think.
Here the output:
main: Dateiformat elf64-x86-64
Inhalt von Abschnitt .text:
4000b0 b8040000 00bb0100 0000b9d0 006000ba .............`..
4000c0 0c000000 cd80b801 000000cd 80 .............
Inhalt von Abschnitt .data:
6000d0 48454c4c 4f2c2057 4f524c44 HELLO, WORLD
my Assembler Code:
section .data
msg: db "HELLO, WORLD"
len: equ $-msg
section .text
;write
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, len
int 80h;
;quit
mov eax, 1
int 80h;
EDIT: My Compiler is finished now, I just stuck with assembler and let NASM/ld do the job
If you want to see the entire structure of your executable try:
objdump -D some_exe
and if you want to see your file in hex format do:
xxd some_exe
or
hexdump some_exe
can i directly write a linked file in plain-text?
Well... Theoretically you can if you know exactly the instructions of the executable and you write them in binary to a plaintext file.
For example, for any given executable exe_file you can do this:
touch temp_file plaintext_file
xxd -p exe_file > temp_file
xxd -p -r temp_file > plaintext_file
chmod u+x plaintext_file
The plaintext_file will be an executable exactly the same as your exe_file. If between steps 2 and 3 you modify the temp_file you are directly modifying the executable by hand, although it is not very likely to change something "specific", unless you have very deep understanding of elf64 format (which I don't and I'm not sure what can be achieved with this).
Note: I know step 1 is redundant, I used it for demonstrating that you are starting with 2 simple plaintext files.
Related
I wrote a simple "Hello world" in assembly under debian linux:
; Define variables in the data section
SECTION .data
hello: db 'Hello world!',10
helloLen: equ $-hello
; Code goes in the text section
SECTION .text
GLOBAL _start
_start:
mov eax,4 ; 'write' system call = 4
mov ebx,1 ; file descriptor 1 = STDOUT
mov ecx,hello ; string to write
mov edx,helloLen ; length of string to write
int 80h ; call the kernel
; Terminate program
mov eax,1 ; 'exit' system call
mov ebx,0 ; exit with error code 0
int 80h ; call the kernel
After assembling
nasm -f elf64 hello.asm -o hello.o
ld -o hello hello.o.
I got a 9048 byte binary.
Then I changed two lines in the code: from .data to .DATA and .text to .TEXT:
SECTION .DATA
SECTION .TEXT
and got a 4856 byte binary.
Changing them to
SECTION .dAtA
SECTION .TeXt
produced a 4856 byte binary too.
NASM is declared to be a case-insensitive compiler. What is the difference then?
You're free to use whatever names you like for ELF sections, but if you don't use standard names, it becomes your responsibility to specify the section flags. (If you use standard names, you get to take advantage of default flag settings for those names.) Section names are case-sensitive, and .data and .text are known to NASM. .DATA, .dAta, etc. are not, and there is nothing which distinguishes these sections from each other, allowing ld to combine them into a single segment.
That automatically makes your executable smaller. With the standard flags for .text and .data, one of those is read-only and the other is read-write, which means that they cannot be placed into the same memory page. In your example program, both sections are quite small, so they could fit in a single memory page. Thus, using non-standard names makes your executable one page smaller, but one of the sections will have incorrect writability.
I'm trying to disassembly app written in assembly. I'm on Linux, x64:
$ objdump -d my_app
my_app: file format elf64-x86-64
That's it. What's wrong with it? It's not a simple hello world of a few lines, it's around 200 lines of code.
The same with gbd:
$ gdb -q my_app
Reading symbols from my_app...(no debugging symbols found)...done.
(gdb)
And
$ radare2 my_app
Warning: Cannot initialize section headers
Warning: Cannot initialize strings table
Warning: Cannot initialize dynamic strings
Warning: Cannot initialize dynamic section
-- Calculate checksums for the current block with the commands starting with '#' (#md5, #crc32, #all, ..)
update:
$ objdump -D my_app
my_app: file format elf64-x86-64
compiling:
$ fasm my_app.asm
# => my_app
update2:
; simplified
format ELF64 executable 3
include "import64.inc"
interpreter "/lib64/ld-linux-x86-64.so.2"
needed "libc.so.6"
import printf, close
segment readable
A equ 123
B equ 222
C equ 333
segment readable writeable
struc s1 a, b, c {
.a1 dw a
.b1 dw b
.c dd c
}
msg:
.m1 db "aaa", 0
.m2 db "bbb", 0
.m3 db "ccc", 0
segment readable executable
entry $
mov rax, 2
mov rdi, "something.txt"
mov rsi, 0
syscall
; .............
; omitted
Asking fasm to directly produce an ELF binary without the use of a linker will only create segments but no sections in the output. This confuses some tools. In particular objdump -d is specifically documented to operate on sections. Note that gdb can still debug and disassemble it, if you give it some addresses, e.g. the entry point.
I'm learning NASM and DEBUG using Windows XP (32-bit) for academic purposes. I'm struggling to get my first simple HelloWorld program to work. It's called prog1.asm.
Here is the code for my prog1.asm file:
bits 16
org 0x100 ; Start program at offset 100h
jmp main ; Jump to main program
message: db 'Hello world',0ah, 0dh,'$'
main: mov dx,message ; Start address of message
mov ah,09 ; Prepare for screen display
int 21h ; DOS interrupt 21h
int 20h ; Terminate program
This code above is just written out from the book that I've been using to study, as you're probably aware I'm like brand new to this. I have nasm.exe in the directory that I'm working with here.
When I'm in my directory, I run nasm -f prog1.asm -o progm1.com -l prog1.lst in an attempt to use the prog1.asm file to create the executable file prog1.com that is created by NASM and an output listing file prog1.lst also produced by NASM.
Running this command gives me the following error:
nasm: fatal: unrecognized output format 'prog1.asm' - use -hf for a list
type 'nasm -h'for help
If anyone is familiar with this problem and can help, it'd be much appreciated, let me know if more details are required.
-f option selects output format. Try this:
nasm prog1.asm -f bin -o progm1.com -l prog1.lst
i'm new to assembly language, I finished writing a simple program so i ran the follow commends
nasm -o learn.bin learn.asm
to assemble the code then
chmod +x learn.bin
and then finally to run it
./learn.bin
but the last returned an error
bash: ./learn.bin: cannot execute binary file
im running ubuntu with an atom intel CPU
any help would be awesome,
Thanks in advance
The error message sounds like you don't have a proper ELF executable header on it. It IS possible to assemble a file using Nasm's -f bin output format (the default, if you don't specify an output format). But it needs an ELF header stuffed into it.
The usual way would be nasm -f elf32 learn.asm (or perhaps -f elf64 if you've got 64-bit code). This "should" produce "learn.o", if all goes well. Then you've got to link this "linkable object" file using ld -o learn learn.o (add -melf-i386 if you're using 64-bit ld... which you probably are). Or, depending on the code, gcc -o learn learn.o (add -m32 for 64-bit gcc). I see that Jester has just told you that (in fewer words).
Here's an example of a file that "should" work the way you're trying to do it:
[map all hkhw.map] ; optional
;==========================
bits 32
ORIGIN equ 8048000h
org ORIGIN
section .text
code_offset equ 0
code_addr:
;--------------------------- ELF header----------------------
dd $464c457f,$00010101,0,0,$00030002,1,main,$34,0,0,$00200034,2,0
dd 1,code_offset,code_addr,code_addr,code_filez,code_memsz,5,4096
dd 1,data_offset,data_addr,data_addr,data_filez,data_memsz,6,4096
main:
;--------- your code goes here -------------------------------
push byte 4
pop eax
xor ebx, ebx
mov ecx, msg
push byte msg_len
pop edx
int 80h
push byte 1
pop eax
int 80h
;------------ constant data -----------------------
; (note that we're in .text, not .rdata)
align 4
;-------------------------------------------------------------
align 4
code_memsz equ $ - $$
code_filez equ code_memsz
data_addr equ (ORIGIN+code_memsz+4095)/4096*4096 + (code_filez % 4096)
data_offset equ code_filez
section .data vstart=data_addr
;------------ initialized data -------------
msg db "Hello from Nasm, all by itself!", 10
msg_len equ $ - msg
;---------------------------------------------------------------------------
idat_memsz equ $ - $$
bss_addr equ data_addr + ($ - $$)
section .bss vstart=bss_addr
;------------- uninitialized data ----------------------
;-------------------------------------------------
udat_memsz equ $ - $$
data_memsz equ idat_memsz + udat_memsz
data_filez equ idat_memsz
;========================
Well... that didn't format well. Probably unreadable. Try Nasm Forum. We can help you more if you post the code
You can't (normally) run plain binary files under linux. You'll have to create an ELF executable by first asking nasm to produce an object file and then using a linker. Note that your code should also of course be written for linux. There are plenty of examples on the internet, see this tutorial for example.
I'm running on Ubuntu 12.10 64bit.
I am trying to debug a simple assembly program in GDB. However GDB's gui mode (-tui) seems unable to find the source code of my assembly file. I've rebuilt the project in the currently directory and searched google to no avail, please help me out here.
My commands:
nasm -f elf64 -g -F dwarf hello.asm
gcc -g hello.o -o hello
gdb -tui hello
Debug information seems to be loaded, I can set a breakpoint at main() but the top half the screen still says '[ No Source Available ]'.
Here is hello.asm if you're interested:
; hello.asm a first program for nasm for Linux, Intel, gcc
;
; assemble: nasm -f elf -l hello.lst hello.asm
; link: gcc -o hello hello.o
; run: hello
; output is: Hello World
SECTION .data ; data section
msg: db "Hello World",10 ; the string to print, 10=cr
len: equ $-msg ; "$" means "here"
; len is a value, not an address
SECTION .text ; code section
global main ; make label available to linker
main: ; standard gcc entry point
mov edx,len ; arg3, length of string to print
mov ecx,msg ; arg2, pointer to string
mov ebx,1 ; arg1, where to write, screen
mov eax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
mov ebx,0 ; exit code, 0=normal
mov eax,1 ; exit command to kernel
int 0x80 ; interrupt 80 hex, call kernel
This statement is false.
The assembler does produce line number information (note the -g -F dwarf) bits.
On the other hand he assembles what is obviously 32-bit code as 64 bits, which may or may not work.
Now if there are bugs in NASM's debugging output we need to know that.
A couple of quick experiments shows that addr2line (but not gdb!) does decode NASM-generated line number information correctly using stabs but not using dwarf, so there is probably something wrong in the way NASM generates DWARF... but also something odd with gdb.
GNU addr2line version 2.22.52.0.1-10.fc17 20120131, GNU gdb (GDB) Fedora (7.4.50.20120120-52.fc17)).
The problem in this case is that the assembler isn't producing line-number information for the debugger. So although the source is there (if you do "list" in gdb, it shows a listing of the source file - at least when I follow your steps, it does), but the debugger needs line-number information from the file to know what line corresponds to what address. It can't do that with the information given.
As far as I can find, there isn't a way to get NASM to issue the .loc directive that is used by as when using gcc for example. But as isn't able to take your source file without generating a gazillion errors [even with -msyntax=intel -mmnemonic=intel -- you would think that should work].
So unless someone more clever can come up with a way to generate the .loc entries which gives the debugger line number information, I'm not entirely sure how we can answer your question in a way that you'll be happy with.