Re: Addresses in memory
- From: Frank Kotler <fbkotler@xxxxxxxxxxx>
- Date: Wed, 30 Apr 2008 21:13:06 GMT
ljhffmn@xxxxxxxxx wrote:
I'm a simple hobbiest programmer with no formal education who recently
started working in Linux, I was screwing around on the internet the
other day and found a tutorial on creating super tiny elf
executables.
Brian Raiter's "Teensy" tutorial, I presume. That, and the accompanying "elf.txt" ought to answer most of your questions. You might want to go to http://asm.sf.net and grab the "asmutils" package. Brian's "elf.inc" has a set of macros that may give you some information...
I did the tutorial and would now like to write a small
program that when run can print out the following list of things.
1. Exact place in memory where the program starts and what is found
there.
2. Exact memory location of the beginning of the elf header and how
it relates to #1.
3. Exact length of ehdr and the location of the end of ehdr in memory
and what comes directly after that.
4. Exact memory location of _start.
5. Exact memory location and size of phdr.
Now I understand how to figure the size of any of the sections without
knowing exact memory addresses:
--Code--
ehdr:
... ehdr stuff goes here ...
(at end of ehdr)
ehdrsize equ $ - ehdr
However, how would I look back into memory from within the .text
section and return the actual address of ehdr?
Is there any way of returning the actual address of the .text
section's beginning or maybe even the calling routine?
If there were a calling routine, it would be easy to pick the caller's address off the stack. In the case of a program that starts with "_start", there *is* no calling routine. We're jmp'ed to, not called. The first thing on your stack is the argument count, followed by the arguments, followed by environment variables. (we can arrange to display all that, too, if you want)
I have searched google pretty hard and I don't think I am going to
find any code examples there so I had hoped maybe one of you could
help.
Have you figured out the "how do I display a number?" trick yet? You'll probably want that. This is a very quick knock-off that demos how you might want to display some information about your file. There's a bunch of "lint" in it - routines that might come in handy later, so I left 'em in. No attempt at nice formatting... too lazy right now.
Chuck Crayne posted a nice "elfinfo.asm" a while back. Thought I might find it on his website:
<http://www.pacificsites.com/~ccrayne/charles.html>
.... but no. (there are some other examples there) It's in Fasm syntax - easily converted to Nasm, if you care to. You can also find some examples in the "files" section of the "nasm-linux-users" group on !Yahoo!. This is sloppy, but it may get you going...
Best,
Frank
; nasm elfexam.asm (note "-f bin" mode!)
; chmod +x elfexam
; "Herbert's method" - similar to "Brian's method"
; but has a ".data" and ".bss" section
[map all elfexam.map]
;===========================================================================
bits 32
ORIGIN equ 8048000h
org ORIGIN
section .text
code_offset equ 0
code_addr:
;--------------------------- ELF header -----------------------------------
dd $464c457f,$00010101,0,0,$00030002,1,_start,$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
_start:
;--------- your code goes here ------------------------------------------
nop
; display the address where the header starts
mov eax, code_addr
call showeaxh
mov al, 'h'
call putc
mov al, 10
call putc
; dump the header
mov ecx, _start - code_addr
mov esi, code_addr
top:
lodsb
call showalh
loop top
mov al, 10
call putc
; display address where code starts
mov eax, _start
call showeaxh
mov al, 'h'
call putc
mov al, 10
call putc
; display first byte of code
mov al, [_start]
call showalh
mov al, 10
call putc
; etc...
; that's enough for now...
exit:
mov eax, 1
int 80h
;--------------
;---------------------------
; print the character in al
putc:
push edx
push ecx
push ebx
push eax
mov eax, 4
mov ebx, 1
mov ecx, esp
mov edx, 1
int 80h
pop eax
pop ebx
pop ecx
pop edx
ret
;-----------------------------
;-------------------------
putz:
; print zero-terminated string
; pointed to by esi
push eax
push ebx
push ecx
push edx
mov ecx, esi
or edx, byte -1
..top:
cmp byte [ecx + edx + 1], 1
inc edx
jnc .top
mov ebx, 1
mov eax, 4
int 80h
pop edx
pop ecx
pop ebx
pop eax
ret
;---------------------------------
;---------------------------------
showeaxd:
; display eax as decimal
push eax
push ebx
push ecx
push edx
push esi
sub esp, 10h
lea ecx, [esp + 12]
mov ebx, 10
xor esi, esi
mov byte [ecx], 0
..top:
dec ecx
xor edx, edx
div ebx
add dl, '0'
mov [ecx], dl
inc esi
or eax, eax
jnz .top
mov edx, esi
mov ebx, 1
mov eax, 4
int 80h
add esp, 10h
pop esi
pop edx
pop ecx
pop ebx
pop eax
ret
;---------------------------------
;------------------------------
showeaxh:
; display eax in hex
push eax
push ebx
push ecx
push edx
sub esp, 10h
mov ecx, esp
xor edx, edx
mov ebx, eax
..top:
rol ebx, 4
mov al, bl
and al, 0Fh
cmp al, 0Ah
sbb al, 69h
das
mov [ecx + edx], al
inc edx
cmp edx, 8
jnz .top
mov ebx, 1
mov eax, 4
int 80h
add esp, 10h
pop edx
pop ecx
pop ebx
pop eax
ret
;------------------------------
;------------------------
; display al in hex - and a space
; thanks Ben
; thanks TAD
showalh:
aam 16 ; 2
hex: xchg ah,al ; 2
cmp al,0Ah ; 2
sbb al,69h ; 2
das ; 1
call putc ; 5
mov al,89h ; 2 (thanks Ruud)
jc short hex ; 2
ret ; return to caller
;------------------------
;------------ constant data ---------------------------------
; (note that we're in .text, not .rdata)
align 4
; we have none
;---------------------------------------------------------------------------
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 ------------------------------
; we have none
;---------------------------------------------------------------------------
idat_memsz equ $ - $$
bss_addr equ data_addr + ($ - $$)
section .bss vstart=bss_addr
;--------------------------- uninitialized data ----------------------------
; we have none
;---------------------------------------------------------------------------
udat_memsz equ $ - $$
data_memsz equ idat_memsz + udat_memsz
data_filez equ idat_memsz
;===========================================================================
.
- References:
- Addresses in memory
- From: ljhffmn
- Addresses in memory
- Prev by Date: Addresses in memory
- Previous by thread: Addresses in memory
- Index(es):
Relevant Pages
|