got
---> global offset table
virtual address space
(VAS) or address space
---> is the set of ranges of virtual addresses
that an operating system makes available to a process
.
memory management unit
(MMU) or paged memory management unit
(PMMU) ---> is a computer hardware unit having all memory references passed through itself, primarily performing the translation of virtual memory addresses
to physical addresses
.
PIE
is made to support ASLR(address space layout randomization)
Position-independent executables
(PIE)
are executable binaries made entirely from position-independent code
PIC
PIE
works very much like what PIC
does for dynamic libraries
, the difference is that a Procedure Linkage Table (PLT)
is not created, instead PC-relative relocation
is used.
-
the .drawio file: Open
Static_and_dynamic_Query_flowchart.drawio
in [email protected] account Follow Tutorial to open this .drawio file. -
Position Independent Code (PIC) in shared libraries, GOT, PLT
-
IAT vs PLT&GOT ---> See malware Anlysis notes for the working of IAT
-
Stackoverflow: What is the purpose of the procedure linkage table?
Note that ASLR predates PIE binaries
, and does not in any way require PIE. When ASLR was introduced
, it randomized placement of stack, heap, and shared libraries
. The placement of (non-PIE) main executable
could not
be randomized.
--> In fact, Windows only attempts to randomize 8 bits of a 32-bit address
. Those are bits 16 through 23
, affecting only the page directory entry and page table entry portion of the address
- ASLR and DEP
- On the effectiveness of DEP and ASLR
- What Is ASLR, and How Does It Keep Your Computer Secure?
- Differences Between ASLR on Windows and Linux
--> For this reason, there really is no reason to link anything without the /DYNAMICBASE option, which enables ASLR. With /DYNAMICBASE enabled, a module's load address is randomized, which means that it cannot easily be used in Return Oriented Programming (ROP) attacks.
--> If a goal of ASLR is to have executable code at an unpredictable address, why is there such a difference between the Windows and Linux implementations? It's important to note that ASLR compatibility
- on
Windows
is alink-time option
, while - on
Linux
it's acompile-time option
.
Surface lvl difference:
- ASLR in Windows:
---> The code is patched at run time for relocation purposes.
- ASLR in Linux/Unix:
The relocation technique is known as text relocation.
With Linux, ASLR is achieved in a different way.
In linux, unlike Windows (i.e. patching the code at runtime), code is compiled in a way that makes it position independent.
That is, it can be loaded at any memory address and still function properly.
--> As with most things security, there is a tradeoff. Because text relocations involve patching, loading such a module would trigger copy-on-write, which subsequently increases the memory footprint of a system. Position-independent code does not require patching, and therefore does not trigger copy-on-write. For a much more detailed look into the position-independent code implementation on Linux, as well as a comparison to load-time relocation, see Eli Bendersky's blog entry: Position Independent Code (PIC) in shared libraries
-->
- ASLR is not as prevalent in most Linux distributions as it is on modern Windows systems.
- ASLR cannot be force-enabled for applications on Linux, as EMET can do on Windows.
One thing to consider is that the x86 architecture is becoming less relevant as time passes. The x86_64 architecture doesn't have a significant performance penalty for position-independent code. This smaller penalty is because
x86_64
hastwice
as manygeneral-purpose registers
asx86
and because unlikex86
, it supports a PC-relative addressing scheme.
- Playlist: "All the Youtube videos I followed"
- Playlist: Virtual Memory
- Playlist: Information Security - 5 - Secure Systems Engineering
$ man gcc
-fpic
+ Generate position-independent code (PIC) suitable for use in a shared library
Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine.
Such code accesses all constant addresses through a global offset table (GOT). The dynamic loader resolves the GOT
entries when the program starts (the dynamic loader is not part of GCC; it is part of the operating system).
+ If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error message
+ from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead.
(These maximums are 8k on the SPARC, 28k on AArch64 and 32k on the m68k and RS/6000. The x86 has no such limit.)
Position-independent code requires special support, and therefore works only on certain machines. For the x86,
GCC supports PIC for System V but not for the Sun 386i. Code generated for the IBM RS/6000 is always
position-independent.
When this flag is set, the macros "__pic__" and "__PIC__" are defined to 1.
-fPIC
+ If supported for the target machine, emit position-independent code(PIC), suitable for dynamic linking and avoiding any
+ limit on the size of the global offset table(GOT)
If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any
limit on the size of the global offset table. This option makes a difference on
AArch64, m68k, PowerPC and SPARC.
Position-independent code requires special support, and therefore works only on certain machines.
When this flag is set, the macros "__pic__" and "__PIC__" are defined to 2.
-fpie
-fPIE
+ These options are similar to -fpic and -fPIC, but the generated position-independent code(PIC) can be
+ only linked into executables. Usually these options are used to compile code that will be linked using the GCC option:
`-pie`
-fpie and -fPIE both define the macros "__pie__" and "__PIE__". The macros have the value 1 for -fpie and 2 for -fPIE.
-fno-plt
Do not use the PLT for external function calls in position-independent code(PIC). Instead, load the callee address
at call sites from the GOT and branch to it. This leads to more efficient code by eliminating PLT stubs and exposing
GOT loads to optimizations. On architectures such as 32-bit x86 where PLT stubs expect the GOT pointer in a
specific register, this gives more register allocation freedom to the compiler.
+ Lazy binding requires use of the PLT; with -fno-plt all external symbols are resolved at load time.
+ Alternatively, the function attribute "noplt" can be used to avoid calls through the PLT for specific external
+ functions.
+ In position-dependent code, a few targets also convert calls to functions that are marked to not use the PLT to use
+ the GOT instead.
-pie
+ Produce a dynamically linked position independent executable(PIC) on targets that support it.
+ For predictable results, you must also specify the same set of options used for compilation
+ (-fpie, -fPIE, or model suboptions) when you specify this linker option.
-no-pie
Don't produce a dynamically linked position independent executable(PIE).
=> dynamically linked executable (i.e. no shared object => no PIE) => I will show it with example later in this file
-static-pie
+ Produce a static position independent executable on targets that support it.
+ A static position independent executable is similar to a static executable, but can be loaded at any address
+ without a dynamic linker.
For predictable results, you must also specify the same set of options used for compilation
(-fpie, -fPIE, or model suboptions) when you specify this linker option.
-static
+ On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries. On other
+ systems, this option has no effect.
-shared
+ Produce a shared object which can then be linked with other objects to form an executable. Not all systems support
+ this option. For predictable results, you must also specify the same set of options used for compilation
+ (-fpic, -fPIC, or model suboptions) when you specify this linker option.[1]
-Wall
This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or
modify to prevent the warning), even in conjunction with macros. This also enables some language-specific warnings
described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options.
-Wall turns on the following warning flags:
-Waddress -Warray-bounds=1 (only with -O2) -Wbool-compare -Wbool-operation -Wc++11-compat -Wc++14-compat -Wcatch-value
(C++ and Objective-C++ only) -Wchar-subscripts -Wcomment -Wduplicate-decl-specifier (C and Objective-C only)
-Wenum-compare (in C/ObjC; this is on by default in C++) -Wformat -Wint-in-bool-context -Wimplicit (C and Objective-C
only) -Wimplicit-int (C and Objective-C only) -Wimplicit-function-declaration (C and Objective-C only) -Winit-self
(only for C++) -Wlogical-not-parentheses -Wmain (only for C/ObjC and unless -ffreestanding) -Wmaybe-uninitialized
-Wmemset-elt-size -Wmemset-transposed-args -Wmisleading-indentation (only for C/C++) -Wmissing-attributes
-Wmissing-braces (only for C/ObjC) -Wmultistatement-macros -Wnarrowing (only for C++) -Wnonnull -Wnonnull-compare
-Wopenmp-simd -Wparentheses -Wpessimizing-move (only for C++) -Wpointer-sign -Wreorder -Wrestrict -Wreturn-type
-Wsequence-point -Wsign-compare (only in C++) -Wsizeof-pointer-div -Wsizeof-pointer-memaccess -Wstrict-aliasing
-Wstrict-overflow=1 -Wswitch -Wtautological-compare -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunused-function
-Wunused-label -Wunused-value -Wunused-variable -Wvolatile-register-var
Note that some warning flags are not implied by -Wall. Some of them warn about constructions that users generally do
not consider questionable, but which occasionally you might wish to check for; others warn about constructions that are
necessary or hard to avoid in some cases, and there is no simple way to modify the code to suppress the warning. Some
of them are enabled by -Wextra but many of them must be enabled individually.
-Wextra
This enables some extra warning flags that are not enabled by -Wall. (This option used to be called -W. The older name
is still supported, but the newer name is more descriptive.)
-Wclobbered -Wcast-function-type -Wdeprecated-copy (C++ only) -Wempty-body -Wignored-qualifiers
-Wimplicit-fallthrough=3 -Wmissing-field-initializers -Wmissing-parameter-type (C only) -Wold-style-declaration (C
only) -Woverride-init -Wsign-compare (C only) -Wredundant-move (only for C++) -Wtype-limits -Wuninitialized
-Wshift-negative-value (in C++03 and in C99 and newer) -Wunused-parameter (only with -Wunused or -Wall)
-Wunused-but-set-parameter (only with -Wunused or -Wall)
The option -Wextra also prints warning messages for the following cases:
* A pointer is compared against integer zero with "<", "<=", ">", or ">=".
* (C++ only) An enumerator and a non-enumerator both appear in a conditional expression.
* (C++ only) Ambiguous virtual bases.
* (C++ only) Subscripting an array that has been declared "register".
* (C++ only) Taking the address of a variable that has been declared "register".
* (C++ only) A base class is not initialized in the copy constructor of a derived class.
+ ACC. to my research,
use of: "-static" and "-no-pie" together -----> statically Linked, LSB executable
=> I will show it with example later in this file
use of: only "-static" ------> dynamically linked, LSB executable
=> I will show it with example later in this file
Acc. to Medium
and Youtube
Codes are: lib_add.c
, lib_sub.c
, main.c
and calc.h
//Code 1: lib_add.c
#include<stdio.h>
void add(int a, int b)
{
printf("Addition result=%d\n", a+b);
}
//Code 2: lib_sub.c
#include<stdio.h>
void sub(int a, int b)
{
printf("Addition result=%d\n", a-b);
}
//Code 3: calc.h
void add(int a, int b);
void sub(int a, int b);
//Code 4: main.c
#include<stdio.h>
#include"calc.h"
int main()
{
int x=10, y=5;
add(x,y);
sub(x,y);
return 0;
}
// Creation of object files
$ gcc -c lib_add.c
$ gcc -c lib_sub.c
$ gcc -c main.c
// Creation of static library
$ gcc -rc lib_calc.a lib_add.o lib_sub.o
//Statically linking
$ gcc -o main_1st_static main.o -L. lib_calc.a
$ gcc -o main_2nd_static main.o -L. -l_calc
$ gcc -o main_3rd_static main.c -L. -l_calc
$ ./main_1st_static
Addition result=15
Substraction result=5
$ ./main_2nd_static
Addition result=15
Substraction result=5
$ ./main_3rd_static
Addition result=15
Substraction result=5
$ ll main*_static
-rwxrwxr-x 1 ubuntu ubuntu 17K May 5 01:31 main_1st_static*
-rwxrwxr-x 1 ubuntu ubuntu 17K May 5 01:31 main_2nd_static*
-rwxrwxr-x 1 ubuntu ubuntu 17K May 5 01:31 main_3rd_static*
Up here, above, there is one catch:
If in the same directory, lib_calc.a
(static library) and lib_calc.so
(shared object) is present, and we want to run the above 3
gcc scripts, -l_calc
will consider lib_calc.so
as the static library and will make a copy of it to the final executable. The result will be erronious
So before running those 3
scripts, please remove that shared library
.
+ Why it happens I don't know, till now, Do a bit reseach on it.
Also find out, what will happen, if I `lib_calc.so` gets copied to the final executable.
+ My intusions say something will come up...
$ file main_1st_static
main_1st_static: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9a492c858e7e3bd9e3ca51d3c93b0e6051f6397a, for GNU/Linux 3.2.0, not stripped
$ file main_2nd_static
main_2nd_static: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9a492c858e7e3bd9e3ca51d3c93b0e6051f6397a, for GNU/Linux 3.2.0, not stripped
$ file main_3rd_static
main_3rd_static: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9a492c858e7e3bd9e3ca51d3c93b0e6051f6397a, for GNU/Linux 3.2.0, not stripped
- Dynamically linked !!! X
$ readelf -a main_1st_static | grep Shared && readelf -a main_1st_static | grep interpreter
- Type: DYN (Shared object file) ----> we are seeing shared library,
- 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] ----> But this is said to be static X
- [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
$ readelf -a main_2nd_static | grep Shared && readelf -a main_2nd_static | grep interpreter
- Type: DYN (Shared object file) ----> we are seeing shared library,
- 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] ----> But this is said to be static X
- [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
$ readelf -a main_3rd_static | grep Shared && readelf -a main_3rd_static | grep interpreter
- Type: DYN (Shared object file) ----> we are seeing shared library,
- 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] ----> But this is said to be static X
- [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
$ ldd main_1st_static
- linux-vdso.so.1 (0x00007ffecf95d000) -----+
- libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f460ee8a000) |
- /lib64/ld-linux-x86-64.so.2 (0x00007f460f098000) |
|
|
$ ldd main_2nd_static |
- linux-vdso.so.1 (0x00007fff0cda4000) |
- libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe8f6a09000) |--------> Same result as readelf -a
- /lib64/ld-linux-x86-64.so.2 (0x00007fe8f6c17000) | => X
|
|
$ ldd main_3rd_static |
- linux-vdso.so.1 (0x00007ffdbb9a4000) |
- libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f039be7b000) |
- /lib64/ld-linux-x86-64.so.2 (0x00007f039c089000) |
- ------+
Acc. to Medium
and Youtube
Code is present in notes: lib_add.c
, lib_sub.c
, main.c
and calc.h
// Creating object files:
+ used -fpic: snapshot of the man page present at the top of this .md file
$ gcc -c lib_add.c lib_sub.c -fpic
$ gcc -c main.c
// Creating shared/ dynamic library:
$ gcc lib_add.o lib_sub.o -shared -o lib_calc.so
// Dynamically linking: gcc -g -wall -o app app.c liball.so
$ gcc -o main_1st_dynamic main.o -L. lib_calc.so
$ gcc -o main_2nd_dynamic main.o -L. -l_calc
$ gcc -o main_3rd_dynamic main.c -L. -l_calc
$ file main_1st_dynamic
main_1st_dynamic: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ceccf4b798dac2a20fdccde3f1c0684c5c1b1ae0, for GNU/Linux 3.2.0, not stripped
$ file main_2nd_dynamic
main_2nd_dynamic: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ceccf4b798dac2a20fdccde3f1c0684c5c1b1ae0, for GNU/Linux 3.2.0, not stripped
$ file main_3rd_dynamic
main_3rd_dynamic: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ceccf4b798dac2a20fdccde3f1c0684c5c1b1ae0, for GNU/Linux 3.2.0, not stripped
$ ./main_1st_dynamic
./main_1st_dynamic: error while loading shared libraries: lib_calc.so: cannot open shared object file: No such file or directory
$ ldd main_1st_dynamic
linux-vdso.so.1 (0x00007ffd8fdee000)
- lib_calc.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd90a4bb000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd90a6c9000)
$ readelf -a main_1st_dynamic | grep Shared
Type: DYN (Shared object file)
0x0000000000000001 (NEEDED) Shared library: [lib_calc.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ readelf -a main_1st_dynamic | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
$ ./main_2nd_dynamic
./main_2nd_dynamic: error while loading shared libraries: lib_calc.so: cannot open shared object file: No such file or directory
$ ldd main_2nd_dynamic
linux-vdso.so.1 (0x00007ffd353b9000)
- lib_calc.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7ed42c9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7ed44d7000)
$ readelf -a main_2nd_dynamic | grep Shared
Type: DYN (Shared object file)
0x0000000000000001 (NEEDED) Shared library: [lib_calc.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ readelf -a main_2nd_dynamic | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
$ ./main_3rd_dynamic
./main_3rd_dynamic: error while loading shared libraries: lib_calc.so: cannot open shared object file: No such file or directory
$ ldd main_3rd_dynamic
linux-vdso.so.1 (0x00007ffd604cd000)
- lib_calc.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcd3d63b000)
/lib64/ld-linux-x86-64.so.2 (0x00007fcd3d849000)
$ readelf -a main_3rd_dynamic | grep Shared
Type: DYN (Shared object file)
0x0000000000000001 (NEEDED) Shared library: [lib_calc.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ readelf -a main_3rd_dynamic | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
+ 1) We have to use: "export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH" to link `lib_calc.so` to the program
+ 2) Altervatively, We can also do it, by copying "lib_calc.so" to "/usr/lib" directory
$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
$ ./main_1st_dynamic
Addition result=15
Substraction result=5
$ ./main_2nd_dynamic
Addition result=15
Substraction result=5
$ ./main_3rd_dynamic
Addition result=15
Substraction result=5
$ ll main*_dynamic
-rwxrwxr-x 1 ubuntu ubuntu 17K May 5 05:38 main_1st_dynamic*
-rwxrwxr-x 1 ubuntu ubuntu 17K May 5 05:55 main_2nd_dynamic*
-rwxrwxr-x 1 ubuntu ubuntu 17K May 5 05:58 main_3rd_dynamic*
$ ll main*_static
-rwxrwxr-x 1 ubuntu ubuntu 17K May 5 01:31 main_1st_static*
-rwxrwxr-x 1 ubuntu ubuntu 17K May 5 01:31 main_2nd_static*
-rwxrwxr-x 1 ubuntu ubuntu 17K May 5 01:31 main_3rd_static*
- STRANGE THING:
- HERE,
+ Both, dynamically linked and statically files have 17k size...
+ Lets look deep into the matter.
+ One thing is, all of the 6 files (dynamically and statically linked) are
"dynamically linked, LSB Shared Object"
//Finding info within objdump files of Statically linked(so called, in this case) file:
+ from all 3 static files, these keywords( keyword does not have any special meaning here, just used it to mention those functions ) are found which are same for all.
- (There can be more, but I have given these keywords priority as these keywords came many times while getting my hands dirty with these stuffs)
.plt.got
.got
.dynamic
.plt.sec
<printf@plt>
<add>
<sub>
//Finding info within objdump files of Dynamically linked file:
+ from all 3 static files, these keywords( keyword does not have any special meaning here, just used it to mention those functions ) are found which are same for all.
- (There can be more, but I have given these keywords priority as these keywords came many times while getting my hands dirty with these stuffs)
.plt.got
.got
.dynamic
.plt.sec
<add@plt>
<sub@plt>
- Youtube: Introduction to Compiling
- Youtube: Static and Dynamic Linking using GCC for Linux
- Youtube: Creating and Linking Shared Libraries
// dynamic linking
$ gcc -o hello_dynamic hello.c -lm
$ gcc -o hello_dynamic_no-pie hello.c -lm
$ file hello_dynamic
hello_dynamic: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9feb7848a6933278a7a5150df4f4dad3e726812b, for GNU/Linux 3.2.0, not stripped
$ readelf -a hello_dynamic | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
$ readelf -a hello_dynamic | grep Shared
Type: DYN (Shared object file)
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ ldd hello_dynamic
linux-vdso.so.1 (0x00007ffc35156000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc895b71000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc89597f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc895cdc000)
+ //In objdump file:
.plt.got
.plt.sec
.dynamic
.got
<puts@plt>
<time@plt>
<srand@plt>
<rand@plt>
<sqrt@plt>
<printf@plt>
No presence of: .got.plt
//From objdump file:
call 10b0 <puts@plt>
+--> means directs to the `puts` section of the plt(procedure linkage table)
+ |
+ |---> Disassembly of section .plt.sec:
+ ----> This is how actually linkage happens
+ 1st printf ----> <puts@plt> => printf doesn't contain any format specifier
+ 2nd printf ----> <printf@plt> => Here, it contains format specifiers, so <printf@plt> was shown
- But actually, why?? => I don't the reason...
00000000000010b0 <puts@plt>:
10b0: f3 0f 1e fa endbr64
10b4: f2 ff 25 e5 2e 00 00 bnd jmp QWORD PTR [rip+0x2ee5] # 3fa0 <puts@GLIBC_2.2.5>
10bb: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0]
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | Each and everything is under .plt.sec |
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$ ll hello_dynamic*
-rwxrwxr-x 1 ubuntu ubuntu 17K May 4 10:22 hello_dynamic*
-rwxrwxr-x 1 ubuntu ubuntu 17K May 4 10:23 hello_dynamic_no-pie*
NOTE: hello_dynamic_no-pie
: Same file size as hello_dynamic
, same use of plt
.
$ file hello.o
+ hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
Explanation:
A
relocatable object file
holds sections containingcode and data
. This file is suitable to belinked
with otherrelocatable object files
to createdynamic executable files
,shared object files
, or anotherrelocatable object
. A dynamic executable file holds a program that is ready to execute.
$ file hello_dynamic_no-pie
hello_dynamic_no-pie: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=227a0d32d7a1d2c7630fa1d41238841acf041dc8, for GNU/Linux 3.2.0, not stripped
$ readelf -a hello_dynamic_no-pie | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
$ readelf -a hello_dynamic_no-pie | grep Shared
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ ldd hello_dynamic_no-pie
linux-vdso.so.1 (0x00007ffea03e2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f668c503000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f668c311000)
/lib64/ld-linux-x86-64.so.2 (0x00007f668c669000)
+ //In objdump file:
SAME "keywords" AS PREVOIUS: hello_dynamic
BUT: No presence of: .plt.got ; Intead has: .got.plt
+ DYNAMICALLY LINKED:
$ ll hello_dynamic*.dump
-rw-rw-r-- 1 ubuntu ubuntu 53K May 6 06:14 hello_dynamic.dump
-rw-rw-r-- 1 ubuntu ubuntu 47K May 6 06:15 hello_dynamic_no-pie.dump
- Youtube: Introduction to Compiling
- Youtube: Static and Dynamic Linking using GCC for Linux
- Youtube: Creating and Linking Static Libraries
//Code
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
int main(void)
{
printf("Hello World!\n"); //libc
//needed to create a random number
time_t t;
srand((unsigned) time(&t));
int rNum = rand();
double sr = sqrt(rNum); //libm -lm
printf("Square root of %d is %f\n", rNum, sr); //libc
return 0;
}
//Static linking
$ gcc -static -o hello_static hello.c -lm -----> static
$ gcc -no-pie -static -o hello_static_no-pie hello.c -lm ----> static (-no-pie)
$ $ file hello_static_no-pie
hello_static_no-pie: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=fb97b74e03cf365404be8a694c84c92f03f42409, for GNU/Linux 3.2.0, not stripped
$ readelf -a hello_static_no-pie | grep Shared
-----> X
$ readelf -a hello_static_no-pie | grep interpreter
-----> X
$ ldd hello_static_no-pie
not a dynamic executable
+ //In objdump file:
+ PRESENCE of: .got.plt
NOTE:
Nothing else has matched with dynamic objdump keywords(I have took this word "keyword" as indication
there is no special meaning related to it)
$ file hello_static
hello_static: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e38b4b4b318b1ead9910799d28cefc7b78e79ca3, for GNU/Linux 3.2.0, not stripped
$ readelf -a hello_static | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
$ readelf -a hello_static | grep Shared
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ ldd hello_static
linux-vdso.so.1 (0x00007ffdcd34d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9a223e1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9a221ef000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9a22547000)
+ //In objdump file:
.got.plt
.plt.sec
.dynamic
.got
<puts@plt>
<time@plt>
<srand@plt>
<rand@plt>
<sqrt@plt>
<printf@plt>
No presence of: .plt.got
+ HERE MOST OF THE THINGS HAVE MATCHED with:
+ ------------------------------------------
dynamic (with -no-pie) ----> gcc -no-pie -o hello_dynamic_no-pie hello.c -lm ---> (1)
static ----> gcc -static -o hello_static hello.c -lm ---> (2)
+ HENCE => (1) MATCHED (2)
+// SAME size
$ ll hello_dynamic_no-pie.dump hello_static.dump
-rw-rw-r-- 1 ubuntu ubuntu 47K May 6 06:15 hello_dynamic_no-pie.dump
-rw-rw-r-- 1 ubuntu ubuntu 47K May 6 07:01 hello_static.dump
+// SAME description
$ file hello_static && file hello_dynamic_no-pie
hello_static: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e38b4b4b318b1ead9910799d28cefc7b78e79ca3, for GNU/Linux 3.2.0, not stripped
hello_dynamic_no-pie: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=227a0d32d7a1d2c7630fa1d41238841acf041dc8, for GNU/Linux 3.2.0, not stripped
+// SAME presence of interpreter
$ readelf -a hello_static | grep interpreter && readelf -a hello_dynamic_no-pie | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
+// SAME presence Shared library
$ readelf -a hello_static | grep Shared && readelf -a hello_dynamic_no-pie | grep Shared
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
+// SAME result of ldd
$ ldd hello_static && ldd hello_dynamic_no-pie
linux-vdso.so.1 (0x00007ffdeb3c3000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5fe603e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5fe5e4c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5fe61a4000)
linux-vdso.so.1 (0x00007ffe49fe6000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0c61746000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0c61554000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0c618ac000)
+// According to these result,
(gcc -no-pie -o hello_dynamic_no-pie hello.c -lm) = (gcc -static -o hello_static hello.c -lm)
Is it True!!??
________________________________________________________________________________________________
+//STATICALLY LINKED:
$ ll hello_static*.dump
-rw-rw-r-- 1 ubuntu ubuntu 47K May 6 07:01 hello_static.dump
-rw-rw-r-- 1 ubuntu ubuntu 12M May 6 07:01 hello_static_no-pie.dump
________________________________________________________________________________________________
All files are COMPARED:
$ ll hello_dynamic*.dump
-rw-rw-r-- 1 ubuntu ubuntu 53K May 6 06:14 hello_dynamic.dump
-rw-rw-r-- 1 ubuntu ubuntu 47K May 6 06:15 hello_dynamic_no-pie.dump
$ ll hello_static*.dump
-rw-rw-r-- 1 ubuntu ubuntu 47K May 6 07:01 hello_static.dump
-rw-rw-r-- 1 ubuntu ubuntu 12M May 6 07:01 hello_static_no-pie.dump
________________________________________________________________________________________________
According to GCC man page:
"-no-pie:
Don't produce a dynamically linked position independent executable."
static ----> -no-pie ---> statically linked
static ----> without -no-pie -----> dynamic linked
normal (i.e. shared) ----> -no-pie -----> dynamic linked
normal (i.e. shared) ----> without -no-pie -----> dynamic linked