Skip to content

Instantly share code, notes, and snippets.

@wangbj
Created May 20, 2019 22:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wangbj/3fb7356286ee38755005cbde26ca84ae to your computer and use it in GitHub Desktop.
Save wangbj/3fb7356286ee38755005cbde26ca84ae to your computer and use it in GitHub Desktop.
LD_PRELOAD a binary compiled with `-static-pie`

Source code:

#include <stdio.h>
#include <time.h>

#ifndef TEST
time_t time(time_t* tp){
	if (tp)
		*tp = 744847200;
	return 744847200;
}
#endif

int main(int argc, char* argv[])
{
	time_t now = time(NULL);
	fputs(ctime(&now), stdout);
	return 0;
}
  • First, let's produce a binary:
$ gcc-8 time.c -o time -O2 -Wall -DTEST

$ ./time
Mon May 20 18:41:44 2019
  • And build a standard shared library for LD_PRELOAD, and it works as expected.
$ gcc-8 time.c -o libtime.so.0 -O2 -Wall -shared -fPIC -Wl,-soname,libtime.so.0

$ LD_PRELOAD=`pwd`/libtime.so.0 ./time

Sun Aug  8 18:00:00 1993
  • Build a -static-pie binary (gcc-8+ required), but it does not work with LD_PRELOAD
$ gcc-8 time.c -o libtime.so.1 -O2 -Wall -static-pie

$ objcopy -Gtime -Gmain time.so libtime.so.1    # keep `time` global

$ ./libtime.so.1
Sun Aug  8 18:00:00 1993

$ LD_PRELOAD=`pwd`/libtime.so.1 ./time
Mon May 20 18:46:51 2019

Note libtime.so.0 and libtime.so.1 both have elf->e_type = ET_DYN, why LD_PRELOAD doesn't work with libtime.so.1 (built with -static-pie)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment