Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

You are wise, witty, and wonderful, but you spend too much time reading this sort of trash.


comp / comp.unix.programmer / (interposers): How to workaround the "strong symbols" problem?

SubjectAuthor
* (interposers): How to workaround the "strong symbols" problem?Kenny McCormack
+* Re: (interposers): How to workaround the "strong symbols" problem?Kenny McCormack
|`- Re: (interposers): How to workaround the "strong symbols" problem?Kaz Kylheku
`* Re: (interposers): How to workaround the "strong symbols" problem?Richard Kettlewell
 `- Re: (interposers): How to workaround the "strong symbols" problem?Kenny McCormack

1
Subject: (interposers): How to workaround the "strong symbols" problem?
From: Kenny McCormack
Newsgroups: comp.unix.programmer
Organization: The official candy of the new Millennium
Date: Fri, 17 Jan 2025 21:33 UTC
Path: news.eternal-september.org!eternal-september.org!feeder3.eternal-september.org!xmission!nnrp.xmission!.POSTED.shell.xmission.com!not-for-mail
From: gazelle@shell.xmission.com (Kenny McCormack)
Newsgroups: comp.unix.programmer
Subject: (interposers): How to workaround the "strong symbols" problem?
Date: Fri, 17 Jan 2025 21:33:45 -0000 (UTC)
Organization: The official candy of the new Millennium
Message-ID: <vmeibp$33sam$1@news.xmission.com>
Injection-Date: Fri, 17 Jan 2025 21:33:45 -0000 (UTC)
Injection-Info: news.xmission.com; posting-host="shell.xmission.com:166.70.8.4";
logging-data="3273046"; mail-complaints-to="abuse@xmission.com"
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
Originator: gazelle@shell.xmission.com (Kenny McCormack)
View all headers

Context is Linux (and only Linux).

Over the years, I have written many "interposers" - that is, a shared
library loaded with LD_PRELOAD that hooks some system or library call
(e.g., "read"). The interposer usually ends up calling the "real"
function, then doing something special either before or after the call.

Generally, it all works fine - or at least, it did - until they started
having "strong symbols" (I think that's the right term). Anyway, some
number of years back, I noticed that it became kind of hit and miss as to
whether or not you could get your hooked version of the function to be
called. Generally, it seemed, the more "low level" the function, the less
likely it was that the interposer would work.

So, I am wondering, is there a fix for this? I'm assuming that somebody
decided that interposers were evil and thus, they came up with this as a
way to foil us, but there should be fix to the fix, so to speak. Is there?

Note: I am not showing code at the moment, because I'd like (if possible) a
simple "Yes, it can be done" or "No, they got you" type answer. If there
is sufficient interest, I can post code in a followup.

--
Marshall: 10/22/51
Jessica: 4/4/79

Subject: Re: (interposers): How to workaround the "strong symbols" problem?
From: Kenny McCormack
Newsgroups: comp.unix.programmer
Organization: The official candy of the new Millennium
Date: Fri, 17 Jan 2025 21:53 UTC
References: 1
Path: news.eternal-september.org!eternal-september.org!feeder3.eternal-september.org!xmission!nnrp.xmission!.POSTED.shell.xmission.com!not-for-mail
From: gazelle@shell.xmission.com (Kenny McCormack)
Newsgroups: comp.unix.programmer
Subject: Re: (interposers): How to workaround the "strong symbols" problem?
Date: Fri, 17 Jan 2025 21:53:32 -0000 (UTC)
Organization: The official candy of the new Millennium
Message-ID: <vmejgs$33sam$2@news.xmission.com>
References: <vmeibp$33sam$1@news.xmission.com>
Injection-Date: Fri, 17 Jan 2025 21:53:32 -0000 (UTC)
Injection-Info: news.xmission.com; posting-host="shell.xmission.com:166.70.8.4";
logging-data="3273046"; mail-complaints-to="abuse@xmission.com"
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
Originator: gazelle@shell.xmission.com (Kenny McCormack)
View all headers

In article <vmeibp$33sam$1@news.xmission.com>,
Kenny McCormack <gazelle@shell.xmission.com> wrote:
>Context is Linux (and only Linux).
>
>Over the years, I have written many "interposers" - that is, a shared
>library loaded with LD_PRELOAD that hooks some system or library call
>(e.g., "read"). The interposer usually ends up calling the "real"
>function, then doing something special either before or after the call.

Also, wanted to state that the function I am trying to hook is "openat".

"open" I can hook, but "openat" doesn't work. I think most programs just
call "open", which eventually ends up calling "openat", so that (hooking
"open") works. But some programs call "openat" directly, and that doesn't
work.

And, also, just to clarify, the whole point of this is to modify the
behavior of a program without the bother of re-compiling it.

--
The randomly chosen signature file that would have appeared here is more than 4
lines long. As such, it violates one or more Usenet RFCs. In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
http://user.xmission.com/~gazelle/Sigs/Pearls

Subject: Re: (interposers): How to workaround the "strong symbols" problem?
From: Richard Kettlewell
Newsgroups: comp.unix.programmer
Organization: terraraq NNTP server
Date: Fri, 17 Jan 2025 23:10 UTC
References: 1
Path: news.eternal-september.org!eternal-september.org!feeder3.eternal-september.org!nntp-feed.chiark.greenend.org.uk!ewrotcd!nntp.terraraq.uk!.POSTED.tunnel.sfere.anjou.terraraq.org.uk!not-for-mail
From: invalid@invalid.invalid (Richard Kettlewell)
Newsgroups: comp.unix.programmer
Subject: Re: (interposers): How to workaround the "strong symbols" problem?
Date: Fri, 17 Jan 2025 23:10:10 +0000
Organization: terraraq NNTP server
Message-ID: <wwved112g19.fsf@LkoBDZeT.terraraq.uk>
References: <vmeibp$33sam$1@news.xmission.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Info: innmantic.terraraq.uk; posting-host="tunnel.sfere.anjou.terraraq.org.uk:172.17.207.6";
logging-data="37744"; mail-complaints-to="usenet@innmantic.terraraq.uk"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux)
Cancel-Lock: sha1:ByMV/lyErfxoUCyiDM3cO3udTmk=
X-Face: h[Hh-7npe<<b4/eW[]sat,I3O`t8A`(ej.H!F4\8|;ih)`7{@:A~/j1}gTt4e7-n*F?.Rl^
F<\{jehn7.KrO{!7=:(@J~]<.[{>v9!1<qZY,{EJxg6?Er4Y7Ng2\Ft>Z&W?r\c.!4DXH5PWpga"ha
+r0NzP?vnz:e/knOY)PI-
X-Boydie: NO
View all headers

gazelle@shell.xmission.com (Kenny McCormack) writes:
> Context is Linux (and only Linux).

Glibc? If so what distribution and what version?

> Over the years, I have written many "interposers" - that is, a shared
> library loaded with LD_PRELOAD that hooks some system or library call
> (e.g., "read"). The interposer usually ends up calling the "real"
> function, then doing something special either before or after the
> call.
>
> Generally, it all works fine - or at least, it did - until they
> started having "strong symbols" (I think that's the right term).

I think you mean STB_WEAK vs STB_GLOBAL, in the naming used in Glibc and
the ELF spec.

> Anyway, some number of years back, I noticed that it became kind of
> hit and miss as to whether or not you could get your hooked version of
> the function to be called. Generally, it seemed, the more "low level"
> the function, the less likely it was that the interposer would work.
>
> So, I am wondering, is there a fix for this? I'm assuming that
> somebody decided that interposers were evil and thus, they came up
> with this as a way to foil us, but there should be fix to the fix, so
> to speak. Is there?

I can interpose both weak and global symbols from Debian’s Glibc 2.39
without doing anything unusual.

> Note: I am not showing code at the moment, because I'd like (if
> possible) a simple "Yes, it can be done" or "No, they got you" type
> answer. If there is sufficient interest, I can post code in a
> followup.

Yes, it can be done.

$ make check
gcc -Wall -Wextra -Wno-unused -Werror -o t.so -shared t.c -ldl -lc
gcc -Wall -Wextra -Wno-unused -Werror -o u u.c
readelf -Ts /lib/x86_64-linux-gnu/libc.so.6 | grep -wE 'open|openat|memfrob'
1701: 00000000000f7f30 296 FUNC WEAK DEFAULT 16 open@@GLIBC_2.2.5
2274: 00000000000f80c0 280 FUNC WEAK DEFAULT 16 openat@@GLIBC_2.4
3039: 000000000009bf40 30 FUNC GLOBAL DEFAULT 16 memfrob@@GLIBC_2.2.5
LD_PRELOAD=./t.so ./u memfrob
interposed memfrob
0x7ffc04c4560f
LD_PRELOAD=./t.so ./u open /dev/null
interposed open
3
LD_PRELOAD=./t.so ./u openat /dev/null
interposed openat
3

My interposing versions are not doing anything special. Representative
example:

void *memfrob(void *s, size_t n) {
void *(*real_memfrob)(void *s, size_t n);
real_memfrob = dlsym(RTLD_NEXT, "memfrob");
write(2, "interposed memfrob\n", 19);
return real_memfrob(s, n);
}

Something tha tripped me up: a program shows a call to openat() in
strace output, so one tries to interpose openat(). But in fact the
program is calling the Glibc open() function, which calls the openat()
syscall.

$ strace -etrace=open,openat cat /dev/null
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/dev/null", O_RDONLY) = 3
+++ exited with 0 +++
$ LD_PRELOAD=./t.so cat /dev/null
interposed open

However I think from your other post that you’ve already considered this
possibility.

--
https://www.greenend.org.uk/rjk/

Subject: Re: (interposers): How to workaround the "strong symbols" problem?
From: Kenny McCormack
Newsgroups: comp.unix.programmer
Organization: The official candy of the new Millennium
Date: Sat, 18 Jan 2025 00:42 UTC
References: 1 2
Path: news.eternal-september.org!eternal-september.org!feeder3.eternal-september.org!xmission!nnrp.xmission!.POSTED.shell.xmission.com!not-for-mail
From: gazelle@shell.xmission.com (Kenny McCormack)
Newsgroups: comp.unix.programmer
Subject: Re: (interposers): How to workaround the "strong symbols" problem?
Date: Sat, 18 Jan 2025 00:42:35 -0000 (UTC)
Organization: The official candy of the new Millennium
Message-ID: <vmetdr$341gl$1@news.xmission.com>
References: <vmeibp$33sam$1@news.xmission.com> <wwved112g19.fsf@LkoBDZeT.terraraq.uk>
Injection-Date: Sat, 18 Jan 2025 00:42:35 -0000 (UTC)
Injection-Info: news.xmission.com; posting-host="shell.xmission.com:166.70.8.4";
logging-data="3278357"; mail-complaints-to="abuse@xmission.com"
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
Originator: gazelle@shell.xmission.com (Kenny McCormack)
View all headers

In article <wwved112g19.fsf@LkoBDZeT.terraraq.uk>,
Richard Kettlewell <invalid@invalid.invalid> wrote:
....
>> Generally, it all works fine - or at least, it did - until they
>> started having "strong symbols" (I think that's the right term).
>
>I think you mean STB_WEAK vs STB_GLOBAL, in the naming used in Glibc and
>the ELF spec.

Maybe so. I am not familiar with these terms. Could you explain further?

Anyway, and FWIW, I think it turns out this is not relevant to my problem
(see below).

....

>I can interpose both weak and global symbols from Debians Glibc 2.39
>without doing anything unusual.

Good to hear. So, does this (weak vs. global) have any connection at all
to whether or not you can interpose them?

....

>Yes, it can be done.
....
>Something that tripped me up: a program shows a call to openat() in
>strace output, so one tries to interpose openat(). But in fact the
>program is calling the Glibc open() function, which calls the openat()
>syscall.
....
>However I think from your other post that you've already considered this
>possibility.

Right. It seems to boil down to:

You can't interpose a syscall.

I.e., so if a library function calls the syscall directly (rather than
going through the Glibc wrapper), you can't interpose it. This is, of
course, as it should be.

Anyway, I got it working (so this thread can be considered solved) and I
think you gave me a push in the right direction. It turns out the function
I have to hook is "fopen64". I figured this out by using "ltrace" rather
than "strace". It turns out "strace" is too low-level.

So, thanks for your post.

--
When someone tells me he/she is a Christian I check to see if I'm
still in possession of my wallet.

Subject: Re: (interposers): How to workaround the "strong symbols" problem?
From: Kaz Kylheku
Newsgroups: comp.unix.programmer
Organization: A noiseless patient Spider
Date: Sat, 18 Jan 2025 01:22 UTC
References: 1 2
Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: 643-408-1753@kylheku.com (Kaz Kylheku)
Newsgroups: comp.unix.programmer
Subject: Re: (interposers): How to workaround the "strong symbols" problem?
Date: Sat, 18 Jan 2025 01:22:51 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 41
Message-ID: <20250117172121.963@kylheku.com>
References: <vmeibp$33sam$1@news.xmission.com>
<vmejgs$33sam$2@news.xmission.com>
Injection-Date: Sat, 18 Jan 2025 02:22:52 +0100 (CET)
Injection-Info: dont-email.me; posting-host="fa2dabe36f69dc055cdccb06e82cf7be";
logging-data="387415"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19sq+bQa2/oLqmeFDYgcxuAjSoExms2im8="
User-Agent: slrn/pre1.0.4-9 (Linux)
Cancel-Lock: sha1:9foswf+nslzvIGNz00li/h0GJAI=
View all headers

On 2025-01-17, Kenny McCormack <gazelle@shell.xmission.com> wrote:
> In article <vmeibp$33sam$1@news.xmission.com>,
> Kenny McCormack <gazelle@shell.xmission.com> wrote:
>>Context is Linux (and only Linux).
>>
>>Over the years, I have written many "interposers" - that is, a shared
>>library loaded with LD_PRELOAD that hooks some system or library call
>>(e.g., "read"). The interposer usually ends up calling the "real"
>>function, then doing something special either before or after the call.
>
> Also, wanted to state that the function I am trying to hook is "openat".
>
> "open" I can hook, but "openat" doesn't work. I think most programs just
> call "open", which eventually ends up calling "openat", so that (hooking
> "open") works. But some programs call "openat" directly, and that doesn't
> work.
>
> And, also, just to clarify, the whole point of this is to modify the
> behavior of a program without the bother of re-compiling it.

In one installation where glibc is 2.31 from 2021, I get this:

$ nm /lib64/libc.so.6 | grep '1444b0'
00000000001444b0 t __GI___openat
00000000001444b0 t __GI___openat64
00000000001444b0 t __libc_openat64
00000000001444b0 t __openat
00000000001444b0 W openat
00000000001444b0 t __openat64
00000000001444b0 W openat64

Where 1444b0 is the address I discovered by another grep, and
then used it to see what all the aliases are. The openat and
openat64 symbols are W (weak).

If you do the same exercise, what do you see?

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

1

rocksolid light 0.9.8
clearnet tor