* Unable to access memory address.
@ 2005-03-24 23:08 J.
2005-03-25 9:46 ` Frank Kotler
2005-04-11 3:39 ` Bug in Gas? Randall Hyde
0 siblings, 2 replies; 12+ messages in thread
From: J. @ 2005-03-24 23:08 UTC (permalink / raw)
To: linux-assembly
Thursday, March 24 23:54:49
Hello,
I am totally new to asm and have a question. I trying the following
nasm program from the document http://www.leto.net/writing/nasm.txt .
section .text
global main
main:
pop ebx
dec ebx
pop ebp
pop ebp
When I try to execute it this is what happends.
~: ./program 12 7
Illegal instruction
Some searches on the Internet the only clou's turned up are type of `howto
bufferoverflow' ... Hmmzz.. :( So I decided to use GDB.
The debugger says:
Cannot access memory at address 0x6d6f682f
What am I doing wrong and how do I make sure that I use the right memory
addresses ?
Thanks a lot..
J.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Unable to access memory address.
@ 2005-03-25 1:44 TheReader06
0 siblings, 0 replies; 12+ messages in thread
From: TheReader06 @ 2005-03-25 1:44 UTC (permalink / raw)
To: linux-assembly
Try _start instead of main?
Joshua Roys
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Unable to access memory address.
@ 2005-03-25 1:57 TheReader06
2005-03-25 11:46 ` J.
0 siblings, 1 reply; 12+ messages in thread
From: TheReader06 @ 2005-03-25 1:57 UTC (permalink / raw)
To: linux-assembly
Also might want an exit call on the end.. otherwise it'll keep on executing whatever is after the code you load in to memory.. keep reading down a bit in that article, it mentions this and shows you how to do an exit syscall in asm..
; for the program to properly exit instead of segfaulting right here
; ( it doesn't seem to like to fall off the end of a program ), call
; a sys_exit
mov eax,1
mov ebx,0
int 80h
Joshua Roys
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Unable to access memory address.
2005-03-24 23:08 Unable to access memory address J.
@ 2005-03-25 9:46 ` Frank Kotler
2005-03-26 11:18 ` J.
2005-04-11 3:39 ` Bug in Gas? Randall Hyde
1 sibling, 1 reply; 12+ messages in thread
From: Frank Kotler @ 2005-03-25 9:46 UTC (permalink / raw)
To: linux-assembly
"J." wrote:
>
> Thursday, March 24 23:54:49
>
> Hello,
>
> I am totally new to asm and have a question.
Hehe! More than one, I'll bet! :)
> I trying the following
> nasm program from the document http://www.leto.net/writing/nasm.txt .
Nice tutorial. I like it. But reading over it again, I
notice that Jonathan doesn't mention the linking stage.
After assembling with "nasm -f elf myprog.asm", you've got
"myprog.o". This needs to be linked to an executable with
(for programs like Jonathan shows) "ld -o myprog myprog.o".
Now "myprog" should be an executable we can run...
> section .text
> global main
>
> main:
As TheReader06 observes, you've changed Jonathan's "_start:"
label to "main:". What's the difference? Well, ld knows
"_start" as the default entrypoint - where your code starts
executing. In asm, "main" isn't anything special, but it
*is* special to C, of course. In a C program, the "_start"
entrypoint occurs in the "startup code" - which does some
stuff and then calls "main". The "_start" label is jumped
to, not called. What's the difference? The stack is in a
different condition when your code begins. Jonathan's tut
assumes the entrypoint is in our code - it won't work if
we've been called by C startup code!
Having changed "_start" to "main", if you link with "ld -o
myprog myprog.o", I would expect ld to complain about not
being able to find the entrypoint - but it'll produce an
executable... which may segfault. You could link with "ld -o
myprog myprog.o --entry main" - I would expect that to work.
Or, you could link with "gcc -o myprog myprog.o". Since
there's no .c file to compile, gcc just calls ld - but with
a command line that links with the "startup code"... which
calls "main". So far, so good, but the code Jonathan shows
will pop the return address off the stack, instead of the
expected "argc", etc. Hilarity ensues.
> pop ebx
> dec ebx
> pop ebp
So far, so good... we've popped the argument count,
decremented it to skip over "argv[0]" - the program name,
and popped the (pointer to a zero-terminated string) program
name.
> pop ebp
If the victim... "user", I mean... started the program
without any command-line arguments, we really wouldn't want
to pop this (it would be zero, and attempting to do anything
with it would be an error!). We should have checked to see
if the "dec ebx" resulted in zero ("jz we_done"). If so, we
don't want to try to pop any more arguments!
As TheReader06 also observes, you need an "exit" of some
kind (HLLs provide this for you automatically). The CPU
doesn't know to "stop", and just keeps fetching instructions
and trying to execute them. This is likely to result in an
error of some kind in short order... but it *could* do real
damage first, so we like to avoid it!
mov ebx, ???
mov eax, 1 ; __NR_sys_exit
int 80h
What goes in ebx is the "exit code" returned to the OS.
Traditionally, zero indicates "no error". Since we aren't
going to do anything about an error, if one occurs, we might
as well return zero. If a sys_call fails, the error-code is
returned in eax (as a negative number) so we might want to
return that - "mov ebx, eax" instead of zero. You *can*
return anything you please, but zero is probably best. So
the above code isn't really suitable for a "runnable"
executable, as it's given.
> When I try to execute it this is what happends.
> ~: ./program 12 7
> Illegal instruction
I've never seen that exact error-message, but for one or
another of the reasons above, it's not too surprising.
> Some searches on the Internet the only clou's turned up are type of `howto
> bufferoverflow' ... Hmmzz.. :(
Hope it was howto avoid 'em, not howto exploit 'em! The
"professionals" produce plenty of software with buffer
overflows. *We* want to try to avoid 'em!!!
> So I decided to use GDB.
There are a couple things you should do, if using gdb, and
(at least) one thing you shouldn't do. You should be using a
recent version of Nasm - at least 0.98.38 (debugging info
for ELF output was introduced in 0.98.37, but it's *badly*
broken! Earlier versions silently ignore the "-g" switch),
preferably 0.98.39 (earlier versions include those infamous
buffer overflows!). You should add the "-g" switch to the
Nasm command line. You should start your code with a "nop" -
right after the "_start:" label.
You shouldn't add the "-s" switch to the ld command-line. I
didn't show that above, but it results in a much smaller
executable - it removes some symbol information that isn't
strictly necessary, *including* the debug info (if any) that
you want for gdb. This will make gdb much happier!
> The debugger says:
> Cannot access memory at address 0x6d6f682f
I don't know just where in your code this is happening, but
it's a sure sign the program has gotten "twisted" - probably
for one or another of the reasons above, and is trying to do
something we don't intend.
> What am I doing wrong and how do I make sure that I use the right memory
> addresses ?
You shouldn't need to worry about "numeric" memory
addresses. If you either swap back to "_start" or tell ld
"--entry start", and add a proper "exit", you should be
okay. I personally think it's "potentially misleading" to
use "main" if it isn't a "C-style main" - but perhaps you've
got your reasons to do it. It's perfectly legitimate to
write your "main" in asm and link it with C startup code,
too, but you need to follow different rules, and access the
command line parameters in a different way. If that's what
you want to do, let us know.
Popping "argc" etc. off the stack works okay, but once
they're popped they're no longer available for "future
reference", unless you save 'em. Here's a slightly different
way to access the command-line parameters - and it goes on
to show environment strings (which are on the stack above
the args, separated by a NULL pointer) - which leaves them
in place. This'll scroll off the screen, so you probably
want to run it as "./cmdline 12 7 | less". There's lots of
room for improvement, but this "worksforme".
Best,
Frank
;-----------------------------------
; fetches command-line parameters off stack
; and displays them
;
; nasm -f elf cmdline.asm [-g]
; ld -o cmdline cmdline.o [-s] (but not both)
;------------------------------
global _start ; default entry point used by ld
section .data
msg1 db 'The program "',0
msg2 db '" was invoked with parameters:',0Ah,0
newline db 0Ah,0
section .text
_start:
nop ; parking place for gdb
mov ebx, esp
mov ecx, [ebx] ; count of command-line parameters
mov esi, msg1 ; "program"
call putz
add ebx, byte 4
mov esi, [ebx] ; first one is program name
call putz
mov esi, msg2 ; "parameters"
call putz
get_clparam: ; fetch parameters and display
dec ecx
jz get_env ; 'til done
add ebx, 4
mov esi, [ebx]
call putz
mov esi, newline
call putz
jmp get_clparam
get_env:
mov esi, newline
call putz
call putz
add ebx, 4
more_env:
add ebx, 4
mov esi, [ebx]
or esi, esi
jz exit
call putz
mov esi, newline
call putz
jmp short more_env
exit:
mov eax, 1 ; system call number (sys_exit)
xor ebx, ebx ; return value
int 80h ; call kernel
;-------------------------------------------
;-------------------------------------------
; expects - esi poined to zero-terminated string
; returns - nothing
;--------------------------------------------
putz:
push eax
push ebx
push ecx
push edx
mov eax, 4 ; system call number (sys_write)
mov ebx, 1 ; file descriptor (stdout)
mov ecx, esi ; message to write
mov edx, esi
getlen:
test byte[edx], 0FFh
jz gotlen
inc edx
jmp getlen
gotlen:
sub edx, esi ; length to write
int 80h ; call kernel
pop edx
pop ecx
pop ebx
pop eax
ret
;------------------------------------------------
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Unable to access memory address.
2005-03-25 1:57 TheReader06
@ 2005-03-25 11:46 ` J.
0 siblings, 0 replies; 12+ messages in thread
From: J. @ 2005-03-25 11:46 UTC (permalink / raw)
To: linux-assembly
On Fri, 25 Mar 2005 TheReader06@comcast.net wrote:
> Also might want an exit call on the end.. otherwise it'll keep on executing
> whatever is after the code you load in to memory.. keep reading down a bit in
> that article, it mentions this and shows you how to do an exit syscall in asm..
>
> ; for the program to properly exit instead of segfaulting right here
> ; ( it doesn't seem to like to fall off the end of a program ), call
> ; a sys_exit
>
> mov eax,1
> mov ebx,0
> int 80h
>
> Joshua Roys
I changed `_start' to `main' because during the linking fase it keeps
complaining about define's.
~: cat prog.asm
section .text ; declaring our .text segment
global _start ; telling where program execution should start
_start: ; this is where code starts getting exec'ed
pop ebx ; get first thing off of stack and put into ebx
dec ebx ; decrement the value of ebx by one
pop ebp ; get next 2 things off stack and put into ebx
pop ebp
mov eax,1 ; exit
mov ebx,0
int 80h
~: nasm -f elf prog.asm
~: gcc prog.o -o prog
prog.o: In function `_start':
prog.o(.text+0x0): multiple definition of `_start'
/usr/lib/crt1.o(.text+0x0): first defined here
/usr/lib/crt1.o: In function `_start':
/usr/lib/crt1.o(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
I'm a bit lost here I guess.. ;-)
J.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Unable to access memory address.
@ 2005-03-25 12:00 TheReader06
0 siblings, 0 replies; 12+ messages in thread
From: TheReader06 @ 2005-03-25 12:00 UTC (permalink / raw)
To: linux-assembly
You don't need to use gcc to link
gcc will try to add it's own _start label, so use ld instead
ld -o prog prog.o
Joshua Roys
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Unable to access memory address.
2005-03-25 9:46 ` Frank Kotler
@ 2005-03-26 11:18 ` J.
2005-03-26 21:15 ` Problem with nasm Mateusz Kocielski
0 siblings, 1 reply; 12+ messages in thread
From: J. @ 2005-03-26 11:18 UTC (permalink / raw)
To: linux-assembly
On Fri, 25 Mar 2005, Frank Kotler wrote:
> "J." wrote:
> >
> > Thursday, March 24 23:54:49
> >
> > Hello,
> >
> > I am totally new to asm and have a question.
>
> Hehe! More than one, I'll bet! :)
Yep.. You certainly got that right ;)
Listen, thank you for the complete answer. It really made a difference.
After reading more about this subject I did two things; put my old 486DX
back to life and I bought a Linux asm book. Both should keep me from
destroying to many things. ;-)
I am left with just one more question, What's the best asm interface to
start with ? at&t, nasm or edlinas ?
Thankx again.
J.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Problem with nasm
2005-03-26 11:18 ` J.
@ 2005-03-26 21:15 ` Mateusz Kocielski
2005-03-26 22:15 ` Frank Kotler
2005-03-26 23:50 ` Brian Raiter
0 siblings, 2 replies; 12+ messages in thread
From: Mateusz Kocielski @ 2005-03-26 21:15 UTC (permalink / raw)
To: linux-assembly
Hello.
---
bash-2.05b# cat exit.s
global _start:
_start:
xor ebx, ebx
mov eax, 1
int 80h
$ uname -srp
Linux 2.6.11-gentoo-r3 AMD Duron(tm) Processor
bash-2.05b# nasm -f elf -o exit.o exit.s
bash-2.05b# ld -o exit exit.o
bash-2.05b# ./exit
Naruszenie ochrony pamieci ( seg fault )
bash-2.05b# strace ./exit
execve("./exit", ["./exit"], [/* 45 vars */]) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
# objdump -D exit
exit: file format elf32-i386
Disassembly of section .text:
080480a0 <_start>:
80480a0: 31 db xor %ebx,%ebx
80480a2: b8 01 00 00 00 mov $0x1,%eax
80480a7: cd 80 int $0x80
Disassembly of section .comment:
00000000 <.comment>:
0: 00 54 68 65 add %dl,0x65(%eax,%ebp,2)
4: 20 4e 65 and %cl,0x65(%esi)
7: 74 77 je 80 <_start-0x8048020>
9: 69 64 65 20 41 73 73 imul $0x65737341,0x20(%ebp,2),%esp
10: 65
11: 6d insl (%dx),%es:(%edi)
12: 62 6c 65 72 bound %ebp,0x72(%ebp,2)
16: 20 30 and %dh,(%eax)
18: 2e 39 38 cmp %edi,%cs:(%eax)
1b: 2e 33 38 xor %cs:(%eax),%edi
# objdump -x exit
exit: file format elf32-i386
exit
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x080480a0
The same code under as:
bash-2.05b# cat exit.s
.global _start
_start:
xor %ebx, %ebx
mov $1, %eax
int $0x80
bash-2.05b# as -o exit.o exit.s
bash-2.05b# ld -o exit exit.o
bash-2.05b# ./exit
bash-2.05b# strace ./exit
execve("./exit", ["./exit"], [/* 45 vars */]) = 0
_exit(0)
# objdump -D exit
exit: file format elf32-i386
Disassembly of section .text:
08048094 <_start>:
8048094: 31 db xor %ebx,%ebx
8048096: b8 01 00 00 00 mov $0x1,%eax
804809b: cd 80 int $0x80
---
Any ideas why the same code doesn't work under asm?
# nasm -v
NASM version 0.98.38 compiled on Mar 26 2005
( installed from gentoo portage )
i've tried to rebuild nasm but it didn't solve my problem.
Any ideas what's wrong?
Thanks.
--
Shm - shm ( at ) irc7 ( dot ) pl
EKG: 2099452 JID: shm@chrome.pl
homepage : http://shm.nation.pl/
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Problem with nasm
2005-03-26 21:15 ` Problem with nasm Mateusz Kocielski
@ 2005-03-26 22:15 ` Frank Kotler
2005-03-26 23:50 ` Brian Raiter
1 sibling, 0 replies; 12+ messages in thread
From: Frank Kotler @ 2005-03-26 22:15 UTC (permalink / raw)
To: shm; +Cc: linux-assembly
Mateusz Kocielski wrote:
>
> Hello.
Hi Mateusz,
> global _start:
Strictly speaking, this shouldn't have the colon on the end
of it, but that seems to make no difference...
... [Nasm code]
> 080480a0 <_start>:
... [Gas code]
> 08048094 <_start>:
> Any ideas why the same code doesn't work under asm?
Something to do with that start address, I'm guessing. When
I try to duplicate your experiment, I get the same results,
but with a start address of 08048080, which is the
"expected" thing, I think(?). I'm inclined to suspect a
problem with ld, not with Nasm (...but I always think that).
You might try "global _start" without the colon, and maybe
specify "section .text", just to see if it makes any
difference - maybe try specifying "--entry _start" to ld...
That start address is the only thing that looks "funny" to
me...
Best,
Frank
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Problem with nasm
2005-03-26 21:15 ` Problem with nasm Mateusz Kocielski
2005-03-26 22:15 ` Frank Kotler
@ 2005-03-26 23:50 ` Brian Raiter
2005-03-26 23:58 ` Mateusz Kocielski
1 sibling, 1 reply; 12+ messages in thread
From: Brian Raiter @ 2005-03-26 23:50 UTC (permalink / raw)
To: shm; +Cc: linux-assembly
> bash-2.05b# cat exit.s
> global _start:
>
> _start:
> xor ebx, ebx
> mov eax, 1
> int 80h
>
>
> $ uname -srp
> Linux 2.6.11-gentoo-r3 AMD Duron(tm) Processor
I tried your file (both with and without the erroneous colon) and it
worked fine. This was on a 2.4 Linux, however, using Nasm 0.98.38.
> bash-2.05b# nasm -f elf -o exit.o exit.s
> bash-2.05b# ld -o exit exit.o
Try compiling with "gcc -nostartfiles -o exit exit.o" instead, and see
if you get different results. If so, then gcc probably knows of some
extra arguments that ld needs to produce a proper executable. Whenever
feasible, you should let gcc do the linking for you instead of
invoking ld directly. ld can take a lot of cmdline arguments.
The "-nostartfiles" option will tell gcc not to supply a _start
routine, and not to link in the usual C libraries. You will probably
still get a slightly bigger executable than if you invoked ld
directly, but not by much.
b
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Problem with nasm
2005-03-26 23:50 ` Brian Raiter
@ 2005-03-26 23:58 ` Mateusz Kocielski
0 siblings, 0 replies; 12+ messages in thread
From: Mateusz Kocielski @ 2005-03-26 23:58 UTC (permalink / raw)
To: Brian Raiter; +Cc: linux-assembly
Brian Raiter wrote:
> Try compiling with "gcc -nostartfiles -o exit exit.o" instead, and see
> if you get different results. If so, then gcc probably knows of some
> extra arguments that ld needs to produce a proper executable. Whenever
> feasible, you should let gcc do the linking for you instead of
> invoking ld directly. ld can take a lot of cmdline arguments.
>
> The "-nostartfiles" option will tell gcc not to supply a _start
> routine, and not to link in the usual C libraries. You will probably
> still get a slightly bigger executable than if you invoked ld
> directly, but not by much.
$ nasm -felf -o exit.o exit.s
$ gcc -nostartfiles -o exit exit.o
$ strace ./exit
.
.
.
_exit(0) = ?
It works ok, thank you very much.
--
Shm - shm ( at ) irc7 ( dot ) pl
EKG: 2099452 JID: shm@chrome.pl
homepage : http://shm.nation.pl/
^ permalink raw reply [flat|nested] 12+ messages in thread
* Bug in Gas?
2005-03-24 23:08 Unable to access memory address J.
2005-03-25 9:46 ` Frank Kotler
@ 2005-04-11 3:39 ` Randall Hyde
1 sibling, 0 replies; 12+ messages in thread
From: Randall Hyde @ 2005-04-11 3:39 UTC (permalink / raw)
To: linux-assembly
Hi All,
I have been tracing down an insidious bug in HLA for a while and I believe I
found a code generation problem in Gas. The problem (obviously, since it's a
Gas bug) only manifests itself under Linux. Over the past several months
I've been getting reports of problems with floating point code in the HLA
standard library. The code generally works fine (under Linux, it always
works fine under Windows), but recently I've noticed that the HLA compiler
emits some strange looking constants when you statically initialize real64
variables. Most of the time, it seems to work, even with the weird
constants, but not always.
To make a long story short, I've discovered that whenever you initialize a
floating point constant with a literal real value, the HLA compiler actually
stores the real32 value of the constant into memory rather than the real64
value. I couldn't figure out why: (1) it was doing this, and (2) why we'd
get correct results most of the time (we should be getting errors all the
time). Well, (2) turns out to be explanable: when the HLA stdlib is compiled
with this bug in the compiler, all the real64 conversion routines wind up
doing real32 conversions. Ugh. (1) was a bit more challenging to figure out
what's going on, because if you look at the HLA compiler's output, it *is*
correct.
The problem turns out to be the Gas fld and fstp instructions. To convert
from real80 to real64, I use an HLA sequence like this:
fld( someReal80Value );
fstp( aReal64Variable );
HLA (correctly, I presume) emits the following Gas code:
fld [ someReal80Value ]
fstpd aReal64Variable
Note that "fstpd" (presumably) stands for "floating point store and pop,
double-precision" (that is, a real64 value. Note that "fstps" is how you
would store away a single-precision (32-bit) value. However, when I
*disassemble* the code assembled by Gas, it shows the following sequence:
fld someReal80Value
fstps aReal64Variable
IOW, either fstpd is *not* a double precision store and pop, or Gas is
generating the wrong code here.
Anyone have a clue?
Cheers,
Randy Hyde
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2005-04-11 3:39 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-24 23:08 Unable to access memory address J.
2005-03-25 9:46 ` Frank Kotler
2005-03-26 11:18 ` J.
2005-03-26 21:15 ` Problem with nasm Mateusz Kocielski
2005-03-26 22:15 ` Frank Kotler
2005-03-26 23:50 ` Brian Raiter
2005-03-26 23:58 ` Mateusz Kocielski
2005-04-11 3:39 ` Bug in Gas? Randall Hyde
-- strict thread matches above, loose matches on Subject: below --
2005-03-25 1:44 Unable to access memory address TheReader06
2005-03-25 1:57 TheReader06
2005-03-25 11:46 ` J.
2005-03-25 12:00 TheReader06
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).