Reverse Engineering for Beginners

(avery) #1
CHAPTER 67. LINUX CHAPTER 67. LINUX
By the way, that is the reason why the AMD64 instruction set supports RIP^1 -relative addressing—to simplify PIC-code.

Let’s compile the same C code using the same GCC version, but for x64.

IDAwould simplify the resulting code but would suppress the RIP-relative addressing details, so we are going to useobjdump
instead of IDA to see the everything:

0000000000000720 <f1>:
720: 48 8b 05 b9 08 20 00 mov rax,QWORD PTR [rip+0x2008b9] # 200fe0 <_DYNAMIC+0⤦
Çx1d0>
727: 53 push rbx
728: 89 fb mov ebx,edi
72a: 48 8d 35 20 00 00 00 lea rsi,[rip+0x20] # 751 <_fini+0x9>
731: bf 01 00 00 00 mov edi,0x1
736: 03 18 add ebx,DWORD PTR [rax]
738: 31 c0 xor eax,eax
73a: 89 da mov edx,ebx
73c: e8 df fe ff ff call 620 <__printf_chk@plt>
741: 89 d8 mov eax,ebx
743: 5b pop rbx
744: c3 ret

0x2008b9is the difference between the address of the instruction at0x720andglobal_variable, and0x20is the difference
between the address of the instruction at0x72Aand the«returning %d\n»string.
As you might see, the need to recalculate addresses frequently makes execution slower (it is better in x64, though). So it is
probably better to link statically if you care about performance [Fog13a].

67.1.1 Windows


The PIC mechanism is not used in Windows DLLs. If the Windows loader needs to load DLL on another base address, it
“patches” the DLL in memory (at theFIXUPplaces) in order to correct all addresses. This implies that several Windows
processes cannot share an once loaded DLL at different addresses in different process’ memory blocks—since each instance
that’s loaded in memory isfixedto work only at these addresses..


67.2 LD_PRELOADhack in Linux


This allows us to load our own dynamic libraries before others, even before system ones, like libc.so.6.

This, in turn, allows us to “substitute” our written functions before the original ones in the system libraries. For example, it
is easy to intercept all calls to time(), read(), write(), etc.

Let’s see if we can fool theuptimeutility. As we know, it tells how long the computer has been working. With the help of
strace(71 on page 704), it is possible to see that the utility takes this information the/proc/uptimefile:

$ strace uptime
...
open("/proc/uptime", O_RDONLY) = 3
lseek(3, 0, SEEK_SET) = 0
read(3, "416166.86 414629.38\n", 2047) = 20
...

It is not a real file on disk, it is a virtual one and its contents are generated on fly in the Linux kernel. There are just two
numbers:

$ cat /proc/uptime
416690.91 415152.03

What we can learn from Wikipedia^2 :

The first number is the total number of seconds the system has been up. The second number is how
much of that time the machine has spent idle, in seconds.

(^1) program counter in AMD64
(^2) wikipedia

Free download pdf