What to submit: Upload a tar archive that contains a text file answers.txt with your
answers for the questions not requiring code, as well as individual files for those that do,
as listed below.
This exercise is intended to reinforce the content of the lectures related to linking using
small examples.
As some answers are specific to our current environment, you must again do this exercise
on our rlogin cluster.
Our verification system will reject your submission if any of the required files are not in
your submission. If you want to submit for a partial credit, you still need to include all
the above files.
1. Understanding Static Linking
To understand the process of static linking of multiple relocatable object files (.o) files into
a single executable, we ask that you do a recreational programming exercise that simu-
lates what a real linker does. Your program will be given the concatenated symbol tables
of n .o files and should output the symbol table of the resulting relocated executable.
Consider the result of linking the following two .c files:
#include "code.h"
#include
static double data[20];
static int temp = -2;
int
main()
{
for (int i = 0; i
int invocationcount;
static int temp = -1;
int sum(double *data, int datalen)
{
invocationcount++;
int rc = 0;
for (int i = 0; i
char a[8];
int
main()
{
printf("%s\n", a);
}
double a = ..place a floating point number here..;
As discussed, the linker does not check if the types of a strongly defined symbol coincides
with the type of a weak symbol of the same name. Change file2.c such that the program
outputs CS3214!:
$ gcc -o file file1.c file2.c
$ ./file
CS3214!
$
6
CS3214 Fall 2017 Exercise 2
4. Observing Dynamic Linking.
When a program starts, the dynamic linker ld-linux.so resolves the program’s dynamic
dependencies. On Linux, the function of the dynamic linker can be controlled using var-
ious environment variables, as described in ld.so(8). The shell script. ldd displays an
executable’s shared library dependencies by performing a “dry-run” that resolves the ex-
ecutable’s dynamic dependencies without actually running the program.
The environment variable LD DEBUG provides information about what the dynamic
linker is doing. Run the following program and answer the following questions
env LD_DEBUG=all stat .
1. Which is the first shared library that is needed to dynamically link the stat pro-
gram?
2. Give the full path of the actual (.so) file being used!
5. Hiding Files.
A rootkit is a set of programs, libraries, and scripts designed to hide the fact that a system
was compromised. Some rootkits use a system’s dynamic loading facilities to hide their
presence. For instance, an attacker may wish to hide the presence of certain files in a
directory.
The LD PRELOAD environment variable instructs the dynamic linker to load one or more
libraries before loading the shared libraries referenced in an executable. Thus, if a symbol
is defined in such a library, the program’s reference will be resolved against the preloaded
symbol, allowing it to intercept calls.
In this exercise, create a shared library ”invisible.so” which, when added to LD PRELOAD,
will hide the existence of files whose name starts with the prefix invisible .
Although a real rootkit would need to make sure that no call reveal the presence of this
file, for the purposes of this exercise, you need to intercept only the readdir function
that is used, for instance, by /bin/ls. Consult the manpage for readdir(3). The following
file provides a skeleton you should fill in.
#include
#include
#define __USE_GNU 1
#define __USE_LARGEFILE64 1
#include
#include
/* Skip files with this prefix */
7
CS3214 Fall 2017 Exercise 2
#define INVISIBLE "invisible_"
/* Define function pointer type that matches the signature of readdir */
typedef struct dirent * (*readdir_t)(DIR *dir);
/* Intercept readdir. If the call would return a directory entry
* whose name starts with INVISIBLE, return the next entry instead.
* Otherwise, return the original directory entry.
*/
struct dirent *readdir(DIR *dir)
{
#include "readdirsolution.c"
}
Submit readdirsolution.c!
To obtain the value to which readdir would have resolved without interposition, use
the dlsym() function, passing the special handle RTLD NEXT.
To following sample session shows how invisible.so should work
$ mkdir readdir-test
$ touch readdir-test/a_file
$ ls readdir-test
a_file
$ touch readdir-test/invisible_file
$ ls readdir-test
a_file invisible_file
$ env LD_PRELOAD=./invisible.so ls readdir-test
a_file
Submit readdirsolution.c and a script. makeinvisible.sh that builds invisible.so
from readdir.c.