Mail Archives: geda-user/2023/03/27/21:33:29
On Mon, 27 Mar 2023, Girvin Herr (gherrl2 AT fastmail DOT com) [via
geda-user AT delorie DOT com] wrote:
> That is what I was afraid of. I was hoping it could be done in a
> configuration file somewhere. Thanks for the info, though.
Well ... if you don't want do re-build gEDA/gaf from source, you could
always binary-patch the library.
Go to the directory (e.g., /usr/local) where you installed gEDA/gaf.
Make a backup copy of your libgeda library:
$ cp -i lib/libgeda.so.47.0.0 lib/libgeda.so.47.0.0.backup
Look at the disassembled library to find the relevant code location:
$ objdump -d lib/libgeda.so.47.0.0 | less
You can use "/f_save<RET>" to search for the function name and "n" to skip
over the procedure linkage table entry (we are not interested in that)
until you get to the actual function. This should look something like
this:
0000000000023a20 <f_save>:
23a20: 41 57 push %r15
23a22: 41 56 push %r14
23a24: 41 55 push %r13
(and so on)
Now, look for the AND instruction ("/and<RET>") that clears the write bits
in the permissions (ug-wx o-x = 0446 = 0x126). There are two AND
instructions in f_save; in my case, the relevant one is the second one.
It should look something like this:
23e44: 31 ff xor %edi,%edi
23e46: e8 15 1a ff ff callq 15860 <umask AT plt>
23e4b: 48 8b 7c 24 10 mov 0x10(%rsp),%rdi
23e50: 89 c6 mov %eax,%esi
23e52: 89 44 24 1c mov %eax,0x1c(%rsp)
23e56: f7 d6 not %esi
23e58: 81 e6 26 01 00 00 and $0x126,%esi
23e5e: e8 1d f2 fe ff callq 13080 <chmod AT plt>
The previous umask is stored in %esi, inverted, masked with 0x126, and
passed to chmod. We want to change the permission mask, so it is the
address of the AND instruction we are interested in (0x23e58 in my case,
but yours will be different), as well as the exact machine text (81 e6 26
01 00 00 in my case).
Copy that information, close the disassembly ("q") and run Python. Open
the shared library, seek to the position you determined and see if you get
the bytes you saw in the disassembly (make sure to enter the extra newline
after the third line of code to tell Python the block is over):
$ python3
>>> with open('lib/libgeda.so.47.0.0', 'rb') as f:
... f.seek(0x23e58) # <-- replace with your value
... f.read(6)
...
147032
b'\x81\xe6&\x01\x00\x00'
Looks good! The ampersand is ASCII 0x26, so it's displayed as a visual
character, but it is the correct value. Now replace the mask with the one
we want (ugo-x = 0666 = 0x1b6), otherwise using the exact same bytes as
seen in your disassembly:
>>> with open('lib/libgeda.so.47.0.0', 'r+b') as f:
... f.seek(0x23e58) # <-- replace with your value
... f.write(b'\x81\xe6\xb6\x01\x00\x00') # <-- this too
...
147032
6
>>> ^D
(For Python 2, you need to omit the "b" before the byte string.)
You're done! Now verify that you did indeed change the correct
instruction. You should see exactly one changed byte (from 26 to b6):
$ diff <(objdump -d lib/libgeda.so.47.0.0.backup) <(objdump -d lib/libgeda.so.47.0.0)
2c2
< lib/libgeda.so.47.0.0.backup: file format elf64-x86-64
---
> lib/libgeda.so.47.0.0: file format elf64-x86-64
19164c19164
< 23e58: 81 e6 26 01 00 00 and $0x126,%esi
---
> 23e58: 81 e6 b6 01 00 00 and $0x1b6,%esi
If this is what you see, the binary patch has succeeded, and you should
have the file permissions you want the next time you run gschem. If you
see changes different than that (or no changes at all), DELETE the botched
library and restore it from the backup.
Hope that helps!
Roland
- Raw text -