What’s the purpose put a .so file before execution file? - linux

I saw a execution method today.
/lib/ld-linux-x86-64.so ./foo
I know when putting a bash variable before execution command means to set that environment variable before execute command.
But now, it is a share lib, what’s the purpose and function to put there?

The dynamic linker /lib/ld-linux-x86-64.so is special in that it can be run as an executable or linked to another executable to use as a library itself. This isn't something you can do with an arbitrary .so file, though.
Either way, its purpose is to allow ./foo to load other shared libraries at run time. For more information, see its manpage.

Related

Passively inject shared object to a specific executable

I'm interested on injecting my own shared object to any future to run instance of a specific executable.
This executable gives me hard time since it is executed a lot and quite frequently which makes me reluctant to inject my code actively (using ptrace()).
The best option I thought of is to use some kind of ELF patcher (maybe https://github.com/NixOS/patchelf ?) in order to make the executable depends on my code. This option discourages me since I'm afraid any bug in the code will lead to an executable corruption.
Any other suggestion?
Rules:
Root permissions are granted
I can't load a kernel module
The injection must be inline - meaning, before the executable entry point was called (main())

How to use mod_exec proftpd linux

i used this code to execute external script, from mod_exec proftpd.
ExecEngine on
ExecLog /opt/proftpd_mod_exec.log
ExecOptions logStderr logStdout
<IfUser yogi>
ExecBeforeCommand STOR,RETR /home/yogi/Desktop/kab.sh EVENT=BeforeCommand FILE='%f'
ExecOnCommand STOR,RETR /home/yogi/Desktop/kab.sh EVENT=OnCommand FILE='%f'
</IfUser>
but i get error code like this on proftpd_mod_exec.log file. STOR ExecBeforeCommand '/home/yogi/Desktop/kab.sh' failed: Exec format error
how can i fix it?
from http://www.proftpd.org/docs/contrib/mod_exec.html
This module will not work properly for logins, or for logins that are affected by DefaultRoot. These directives use the chroot(2) system call, which wreaks havoc when it comes to scripts. The path to script/shell interpreters often assume a certain location that is no longer valid within a chroot. In addition, most modern operating systems use dynamically loaded libraries (.so libraries) for many binaries, including script/shell interpreters. The location of these libraries, when they come to be loaded, are also assumed; those assumptions break within a chroot. Perl, in particular, is so wrought with filesystem location assumptions that it's almost impossible to get a Perl script to work within a chroot, short of installing Perl itself into the chroot environment.
From the error message it sounds like that just that. You have enabled chroot and the script cannot get executed because of files not available at expected places within chroot.
Author suggest not to use the module because of this.
To get it work You need to figure out the dependencies You need in the chroot target and set them up there at the appropriate places. Or disable chroot for the users and try again. Third possibility: build a statically linked binary with almost no dependencies.
Or try, as the author of the module suggest, to use a FIFO and proftpd logging functionality to trigger the scripts outside of the chroot environment.

What is the difference between an executable and a shared library

The properties of ls show it is an executable.
And properties of kmod show it is a shared library.
Im trying to check for executables and hash them in ubuntu 14.04 LTS. Is there any way to differentiate executables from the other types? Thanks in advance
Executable is a Load file which executes directly in system as a program. As per your question, "ls" is a executable which is used to
list the current directory contents. The load for "ls" is placed in "/bin" or you can check using command "which ls". Shared library are the one which do some task that is commonly accessed or used by many executables. These library are loaded into the memory only once and accessed by many programs(executables) at runtime.

Interposing part of a shared object by soname

I’ve written a shared object that modifies the arguments to FreeType’s FT_Load_Glyph and FT_Render_Glyph functions, currently by interposing it with LD_PRELOAD and dlsym.
This works fine, but I’m curious to know whether or not there’s a way to make these changes:
to all programs that use FreeType on a given host (running e.g. Debian);
without clobbering any programs that aren’t actually linked to FreeType;
without simply applying an LD_PRELOAD to all programs on the host;
without requiring any maintenance unless FreeType’s soname is changed; and
without modifying any of FreeType’s files, nor those of any programs on the host.
The only two “solutions” that I’ve been able to come up with are ugly hacks:
to LD_PRELOAD all programs, all of the time, which seems slow and fragile; or
to copy e.g. libfreetype.so.6.12.3 to libxxxxtype.so.6.12.3; then
patch the soname in libxxxxtype.so.6.12.3 to libxxxxtype.so.6;
link the interposing shared object against libxxxxtype.so.6; and
install the shared object as e.g. libfreetype.so.6.999.
I’d essentially like to transparently patch a couple of functions in a shared object, while letting the remaining functions through, without necessarily having access to the source of the shared object or the programs that use it, but if I make a fake shared object with the soname libfreetype.so.6, I can’t see a clean way to link it to (or dlopen) the real libfreetype.so.6.
This is my first real experiment with shared libraries, so please bear with me if this question makes some incorrect assumptions, or just makes no sense.
Can you try to use uprobes to dynamically steal control from some functions?
Check http://www.brendangregg.com/blog/2015-06-28/linux-ftrace-uprobe.html
uprobes: user-level dynamic tracing, which was added to Linux 3.5 and improved in Linux 3.14. It lets you trace user-level functions; for example, the return of the readline() function from all running bash shells, with the returned string:
# ./uprobe 'r:bash:readline +0($retval):string'
Tracing uprobe readline (r:readline /bin/bash:0x8db60 +0($retval):string). Ctrl-C to end.
bash-11886 [003] d... 19601837.001935: readline: (0x41e876 <- 0x48db60) arg1="ls -l"
bash-11886 [002] d... 19601851.008409: readline: (0x41e876 <- 0x48db60) arg1="echo "hello world""
bash-11886 [002] d... 19601854.099730: readline: (0x41e876 <- 0x48db60) arg1="df -h"
bash-11886 [002] d... 19601858.805740: readline: (0x41e876 <- 0x48db60) arg1="cd .."
bash-11886 [003] d... 19601898.378753: readline: (0x41e876 <- 0x48db60) arg1="foo bar"
^C
Ending tracing...
And http://www.brendangregg.com/blog/2015-07-03/hacking-linux-usdt-ftrace.html
There were also other solutions of tracing user-space functions, like ftrace, systemtap, dtrace, lttng. Some of them need recompilation and defining tracing points statically in the program; and uprobes are "user-level dynamic tracing".
Some links about uprobes:
https://events.linuxfoundation.org/slides/lfcs2010_keniston.pdf Uprobes: User-Space Probes (2010)
https://www.kernel.org/doc/Documentation/trace/uprobetracer.txt
https://lwn.net/Articles/499190/ "Uprobes in 3.5", Jonathan Corbet (2012)
There is handler of uprobes which has pt_regs. As said in last link: "Uprobes thus implements a mechanism by which a kernel function can be invoked whenever a process executes a specific instruction location." and it suggests that uprobes may replace some ptrace/gdb based solutions; so there is a possibility to change execution of any program hitting active uprobe, by changing its eip/rip (PC) register.
You may try some other dynamic instrumentation tools, like pin or dyninst; but they are designed for per-process usage.
Another solution would be to make system wide "overlay" for lib, with custom libfreetype and then proxying unmodified methods to real lib.
You have to make custom lib compatible with real one. You can to that by using dlopen with absolute path (eg. dlopen("/usr/lib64/libfreetype.so.6")),
copying definitions of real, exported functions and proxying them with dlsym.
It think that for ease of maintenance you could event replace proxied argument types with simple void*. You would only need to make changes when freetype functions change (arguments count, function names).
To create lib "overlay", you could install custom lib into eg. "/opt/myapp/lib64/libfreetype.so.6", then add this path to dynamic linker run time paths.
You may have to create symlinks for other versions or compile new custom lib if original implementation changes. Whatever is needed to shadow real lib and keep other apps working :)
Google says that to change run time loading paths on Debian you have to simply edit /etc/ld.so.conf. Add /opt/myapp/lib64 path at the beginning so it will be checked first.
Now any app searching for freetype should load your lib, you can check it with ldd <path to app>.
I can think of just one case when this solution will not work: if app is loading bundled libfreetype or loading it by full path, not by name.
to LD_PRELOAD all programs, all of the time, which seems slow and fragile
That's a good solution (for what you want). I don't see a better one.
It's not fragile. It provides information to the runtime linker in a documented way. You're not bonking on anything, pretending something isn't what it is. You're just altering the preference hierarchy for function-name resolution.
It's not slow. The linker has to do something sometime. It's got to check if LD_PRELOAD is defined, which in any case is a user-space operation. So it will follow that path, and load your library before doing a bunch of other work. I'd be astonished if the time was even measurable under normal circumstances.
There are two concerns I'd have, but they're orthogonal to the technique. The code actually has to work in all cases, and you have to dig into the process-creation framework a bit to make sure LD_PRELOAD really is defined everywhere. Other than that, ld.so defines its environment variables precisely for your intended use. Who's to argue?

Understanding "intercepting" of commands in linux

Some commands in linux, eg. ssh-agent $BASH makes sure that certain actions from commands run in the present console is "intercepted" by another tool. How does this work in general ? What topics should I study in order to understand this ? Lets say I wanted to make a tool that would redirect all disk-write action from all processes started afterwards to a location I specify (tired of having all sorts of crap written to strange locations on my disk, eg ~/.adobe/Flash_Player/AssetCache), how would the fundamental structure of such an app look ? Would one have to go below RING3 level ?
ELF allows interposing shared objects. On Linux, you can interpose a shared object before everything else on the symbol lookup scope of dynamic executables using LD_PRELOAD, e.g:
export LD_PRELOAD=/lib/libSegFault.so

Resources