NASM label or instruction expected at start of line - nasm

I had trying assembly a file.
But it has some error.
How can I fix it? Why it failed?
I had assembly the following code using nasm ipl.asm -o ipl.bin -l ipl.asm.lst:
; Omitted because it is not important.
error: mov si, failmsg
call putstr
bl: hlt
jmp bl
; Omitted because it is not important, too.
(above ipl.asm)
but it failed with:
ipl.asm:80: error: label or instruction expected at start of line
How can I fix it? Why it fail?

(Copied from the comment of #ecm. Thank her.)
bl is a register name, so we can't name a label using bl.

Related

ld can not find symbol _start error after assemble and link .asm file to 64 bit executables

I have a shellcode file.
Then use ndisasm to build the assembly code.
ndisasm -b 64 shellcode > shellcode.asm
cat shellcode.asm | cut -c29->key.asm
I add 2 lines to the key.asm file
global_start:
_start:
$vi key.asm
global_start:
_start:
xor eax,eax
push rax
push qword 0x79237771
push qword 0x76772427
push qword 0x25747320
. . .
. . .
. . .
push qword 0x20757577
push rsp
pop rsi
mov edi,esi
mov edx,edi
cld
mov ecx,0x80
mov ebx,0x41
xor eax,eax
push rax
lodsb
xor eax,ebx
An then I assemble and link it to 64 bit executables
$nasm -f elf64 -g -F stabs key.asm
$ld -o key key.o
It gives me a warning
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080
I tested it out with gcc
gcc -o key key.o
I still get an error almost the same as the first one
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In
function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
And when I run ./key with gdb after I use $ld NOT $gcc
$gdb -q ./key
$run
I get a seg fault
Starting program: /mnt/c/Users/owner/Documents/U
M/Computer_Security/ExtraCredit/key
Program received signal SIGSEGV, Segmentation fault.
0x000000000040013a in global_start ()
If I debug after run with gcc then the file will not be found because of exit status
Can you explain why does it happen? And how can I fix this problem? Thanks
It gives me a warning
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080
This isn't actually a problem, as long as you're fine with the entry point being the start of the text segment (i.e. the first instruction in your shellcode).
You got the error because you left out the space between the global keyword and the _start symbol name. i.e. use global _start, or don't bother. What you did defined a label called global_start, as you can see from your later error message.
You segfault on lodsb because you truncated a stack address with mov edi,esi instead of mov rdi, rsi. And if you fix that then you fall off the end of your code into garbage instructions because you don't make an exit system call. You're already running this inside gdb, use it!
I tested it out with gcc: gcc -o key key.o
I still get an error almost the same as the first one
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:
In function `_start':
(.text+0x20): undefined reference to `main'
No, that's a totally different error. If you had exported _start correctly, you would have gotten an error for conflicting definitions of _start (between your code and the CRT start files).
This error is that the _start definition in crt1.o (provided by gcc) has a reference to main, but your code doesn't provide a main. This is what happens when you try to compile a C or C++ program that doesn't define main.
To link with gcc, use -nostdlib to omit the CRT start files and all other libraries. (i.e. link pretty much exactly like you were doing manually with ld.)
gcc -nostdlib -static key.o -o key # static executable: just your code
Or dynamically linked without the CRT start files, using your _start.
gcc -nostdinc -no-pie key.o -o key
You can call libc functions from code linked that way, but only on Linux or other platforms where dynamic linking takes care of running libc initialization functions.
If you statically link libc, you can only call functions like printf if you first call all the libc init functions that the normal CRT startup code does. (Not going into detail here because this code doesn't use libc)
Your code is wrong. Between global and _start must have a space. That is one of your problems.
section .text
global _start
_start:
xor eax,eax
push rax
...
In addition, to get why the segmentation fault is happening, you have to debug it. You could look the assembly instruction that does the segfault.
x/5i $eip

my little asm program has a segment fault

I am a newbie to assembly language, and here is my little program.
section .data
section .text
global _start
_start:
nop ; make gdb happy
; put your experiments here
mov eax,4
; put your expeirments here
nop ; make gdb happy
section .bss
This code is compiled with these commands:
nasm -f elf64 -g -F stabs 001.asm -o 001.o
ld -o test 001.o
But when I run, it generates a core dump file with segment fault.
1.Why this little program has a segment fault?
2.How to gdb this with core dump file?
enter image description here
Your program doesn't contain code that ends it. After executing the final nop in your code, the CPU continues to execute whatever the memory after that contains until it crashes. To fix this problem, tell the operating system to terminate your process. On amd64 Linux, you can use the following code:
mov eax,60 ; system call 60: exit
xor edi,edi ; set exit status to zero
syscall ; call the operating system

NASM Error, Unrecognized output format

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

Assembly execve failure -14

Program writes executable placed in it's second segment on disk, decrypts it(into /tmp/decbd), and executes(as it was planned)
file decbd appears on disk, and can be executed via shell, last execve call return eax=-14, and after end of the program, execution flows on data and gets segfault.
http://pastebin.com/KywXTB0X
In second segment after compilation using hexdump and dd I manually placed echo binary encrypted via openssl, and when I stopped execution right before last int 0x80 command, I've already been able to run my "echo" in decbd, using another terminal.
You should have narrowed it down to a minimal example. See MCVE.
You should comment your code if you want other people to help.
You should learn to use the debugger and/or other tools.
For point #1, you could have gone down to:
section .text
global _start ;must be declared for linker (ld)
_start:
mov eax,11 ; execve syscall
mov ebx,program ; name of program
mov ecx,[esp+4] ; pointer to argument array
mov ebp,[esp] ; number of arguments
lea edx,[esp+4*ebp+2] ; pointer to environ array
int 0x80
section .data
program db '/bin/echo',0
For point #3, using the debugger you could have seen that:
ebx is okay
ebp is okay
ecx is wrong
edx is wrong
It's an easy fix. ecx should be loaded with the address, not the value and edx should be skipping 2 pointers which are 4 bytes each, so the offset should be 8 not 2. The fixed code could look like this:
section .text
global _start ;must be declared for linker (ld)
_start:
mov eax,11 ; execve syscall
mov ebx,program ; name of program
lea ecx,[esp+4] ; pointer to argument array
mov ebp,[esp] ; number of arguments
lea edx,[esp+4*ebp+8] ; pointer to environ array (skip argc and NULL)
int 0x80
section .data
program db '/bin/echo',0
man execve says this in the "ERRORS" section with regard to return code -14 (-EFAULT):
EFAULT filename points outside your accessible address space.
You passed a bad pointer to execve().

GDB complains No Source Available

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.

Resources