This is a toy program that we want to monkeypatch. It really doesn’t do anything except call socket().
$ gcc -g -Wall -o vuln *.c
From here on we will just be dealing with the vuln binary.
$ ./vuln
calling socket
The program starts, calls socket, and then exits.
I then create a shared library:
Build it:
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libshm.so.1 -o libshm.so.1.0 *.o
$ ls libshm.so.1.0 shlib.c shlib.o
Now the trick is to use vuln with the new shared library, which is what the LD_PRELOAD command can force.
$ LD_PRELOAD=/path/to/my/shlib/libshm.so.1.0 ./vuln
calling socket
you're in my socket now.
And now, the program starts, calls what it thinks is socket, but is actually using my socket function.
Variation:
“But what if I didn’t have the source to vuln?”
Not a problem. We can use objdump to find out what functions the target will be calling and then write the shared library to redefinine those.
This is a partial output of objdump -D vuln:
080483f4:
80483f4: 8d 4c 24 04 lea 0x4(%esp),%ecx
80483f8: 83 e4 f0 and $0xfffffff0,%esp
80483fb: ff 71 fc pushl -0x4(%ecx)
80483fe: 55 push %ebp
80483ff: 89 e5 mov %esp,%ebp
8048401: 51 push %ecx
8048402: 83 ec 14 sub $0x14,%esp
8048405: c7 04 24 00 85 04 08 movl $0x8048500,(%esp)
804840c: e8 1b ff ff ff call 804832c
8048411: c7 44 24 08 03 00 00 movl $0x3,0x8(%esp)
8048418: 00
8048419: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp)
8048420: 00
8048421: c7 04 24 01 00 00 00 movl $0x1,(%esp)
8048428: e8 ef fe ff ff call 804831c
as we can see from the last line a call is made to socket at the procedure lookup table. We can infer that a call to libc’s socket occurs.