alexandernst
alexandernst

Reputation: 15109

Getting the address of a function

I'm playing around with ASM, byte code and executable memory.

I'm using echo -e "<asm instruction here>" | as -o /dev/null -64 -al -msyntax=att to "compile" my code. Anyways, I noticed that movq 2, %rax will result in 0000 488B0425 02000000, but both call printk and call printf will result in 0000 E8000000 00, which I believe is because of the fact that as doesn't know anything about printk or printf.

My question is how can I get the address of those functions so I can use them in my byte code?

Upvotes: 2

Views: 413

Answers (2)

Eric Postpischil
Eric Postpischil

Reputation: 222660

The assembler does not know the values of external symbols. It writes a file with multiple sets of data in it. One set of data is the bytes to put into a program’s text section. Another set of data is information about external symbols used and what adjustments to make to the bytes in the text section when those external symbols are resolved. The file produced by the assembler does not contain any information about the values of symbols that come from external libraries.

The linker resolves external symbols. When producing a statically linked executable, it will fully resolve the external symbols. When producing dynamically linked executable, resolution of external symbols is completed during program execution.

After you statically link an executable, you can use a tool such as nm to see the values of symbols in it (if they have not been stripped). Then you could use those values in assembly. However, hardcoding those values into assembly will fail if the program is ever linked in a different way, that puts the routines at different locations.

If you dynamically link an executable, you would have to inspect the executing program to determine where its external symbols were placed. Again, you could in theory use those values in assembly, but this would be even more prone to failure than doing so with static linking, especially on systems that deliberately change the addresses used in executables to thwart malicious code.

Hard-coding symbol values into assembly is not the normal way of writing assembly language or other code and should not be done except for learning or special-purpose debugging or system inspection.

Upvotes: 2

Jens
Jens

Reputation: 72639

Use the proper tool to inspect your object files. Assuming any Unix, use

 nm -AP file.o

to see the addresses of all symbols (functions and variables). Since printf is likely in a library, run nm on that library for the same effect.

Upvotes: 0

Related Questions