Scriptje om de timer "60 sec" van de afsluitdialoog van Ubuntu 9.10 (Karmic) makkelijk aan te passen:De instelling "60 sec" van de afsluitteller bij Karmic Koala (en blijkbaar ook Lucid Lynx) zit vast in de code geprogrammeerd.
Niks aan te doen ? Toch wél ...
Om dit te veranderen zijn er 3 mogelijkheden:
1. Je haalt het desbetreffende bronbestand binnen, patcht hem en compileert hem.
Dat kan, maar het valt niet echt mee. Een handleiding staat op de Duitse wiki:
http://wiki.ubuntuusers.de/GNOME_Logouttimer_entfernen_oder_anpassen#Timer-anpassen2. Je patcht het binaire bestand dmv een hex-editor.
Dat is wél te doen, de handleiding had ik ooit hier neergezet:
http://forum.ubuntu-nl.org/software-en-configuratie/pjotr-delay-bij-afsluiten-weghalen/msg529318/#msg5293183. Je doet het patchen van het binaire bestand dmv. een scriptje. Dat is natuurlijk het makkelijkst.
En hier komt de handleiding:
Logout-timer patchen met het script timer60patchIn principe doet dit scriptje ook maar hetzelfde als je met de hex-editor zou doen.
Er wordt de CPU-opdracht opgezocht die de "60" in een variabele opslaat, en aangepast.
InstallerenJe kunt het scriptje
timer60patch gewoon
hier vanuit de bijlage binnenhalen en opslaan.
Dan moet je het nog wél eerst uitvoerbaar maken. (gewoon via rechtsklik - eigenschappen - rechten:
[√] uitvoerbaar aanvinken)
ToepassenIn ieder geval moet je het scriptje in de terminal uitvoeren, anders werkt het niet.
Het makkelijkst gaat het in Gnome met een (dubbele) klik - [uitvoeren in de terminal].
Paswort [Enter] moet je in de terminal "blind" intikken, dat is zo.
De rest wordt in de terminal uitgelegd:
- Er wordt een backup aangemaakt (als die er nog niet is)
- Je kunt de timer instellen via [
+] en [-] tussen 1 en 999 seconden en met [Enter] toepassen.
- De wijzigingen in het binaire bestand worden nog een keer gecontroleerd. Een [Toets] drukken om te sluiten en klaar.
Beschrijving van het scriptAls je wil weten wat dit scriptje feitelijk doet, hier is de uitleg:
Het eerst kijkt het scriptje of het bestand
/usr/lib/indicator-session/gtk-logout-helper überhaupt aanwezig is.
(anders is het soms geen Karmic of Lucid ? ...)
Dan wordt het originele bestand als
/usr/lib/indicator-session/gtk-logout-helper0 gebackupd, rechtenpatroon en tijdstempel incluis.
Daarna kun je instelling van 10 seconden met [
+] en [-] veranderen en met [Enter] toepassen.
Dit getal wordt opgesplitst in 2 bytes (de PC gebruikt intern immers de "little endian" volgorde,
dus het éérst de waarde 1 , dan 256 , 65536 , enz., zie
http://nl.wikipedia.org/wiki/Endianness )
en hexadecimaal geformatteerd.
Om het binaire bestand te patchen wordt het originele bestand via
xxd naar hexadecimale notatie geconverteerd, de storende linefeeds met
tr verwijderd,
in het zoekpatroon met
sed het getal "60" (= 3C hex) door het nieuw ingestelde vervangenen aan het eind alles weer via
xxd terug geconverteerd naar een nieuw binair bestand.
(zie het idee op
http://forum.ubuntu-nl.org/programmeren/hoe-kan-ik-een-binair-bestand-patchen/ )
Tot slot worden het originele bestand en het nieuwe bestand binair vergeleken.
Als het goed is wordt er een resultaat getoond zoals dit:
11603 74 12
Mits er iets mis was gegaan zou dit patroon helemaal anders uitzien - je ziet het meteen.
Op die manier heb je heel effectief een extra controle dat alles goed is gegaan.
Het scriptje wacht nog even totdat je een toets drukt. Op die manier kun je in ieder geval nog alles lezen.
Zoekpatroon: de CPU-opdrachtWat je moet opzoeken is precies die CPU-opdracht die de compiler vanuit de broncode
logout_dialog->timeout = 60;
produceert.
Feitelijk wordt hier het constante getal 60 rechtstreeks aan een 32 bit integer-variabele toegewezen. (en die zit normaal gewoon ergens op de stack)
De compiler doet zoiets normaal via een MOV-commando met een relatieve offset (voor de variabele), gerelateerd op register EBX, ESI of EDI (voor de basis van de stack),
die het getal 60 (= hex 3C) onmiddelijk laadt.
Inderdaad vind je in het binaire betand exact dit patroon (bij 32-bit Karmic):
C7 83 CC 00 00 00 3C 00 00 00 = mov DS:[ebx+000000CC],0000003C
( En bij 64-bit Karmic vind je natuurlijk een andere offset, en een andere register:
C7 87 60 01 00 00 3C 00 00 00 = mov DS:[edi+00000160],0000003C )
Algemeen is het binaire patroon dus: C7 8y xx xx xx xx 3C 00 00 00
met y = kennummer van het register (3,6 of 7) en xxxxxxxx = offset
(Je kunt er zelf een beetje mee spelen -> online-Disassembler:
http://pvdasm.reverse-engineering.net/PVPHP.php )
Dit moet dus het zoekpatroon voor de
sed - opdracht zijn.
Listing van het script:#! /bin/bash
# timer60patch
# patcht vanaf Ubuntu 9.10 de hard gecodeerde logoutteller van 60 seconden naar een instelbare tijd in het binaire bestand.
# auteur: [track]
sec=10
name=timer60patch
fpath=/usr/lib/indicator-session/
fname=gtk-logout-helper
# bestand aanwezig ?
if [ -f "$fpath$fname" ]; then
echo ">$name: == Je kunt het script altijd afbreken met [Ctrl]-C =="
else
echo ">$name: Waar is het bestand $fname ?"
echo "> Dit script werkt pas vanaf Ubuntu 9.10 (Karmic). [toets]"
read -sn1
exit 1
fi
# kopie al aanwezig ?
if [ -f "$fpath$fname"0 ]; then
echo
echo "kopie is al aanwezig: $fpath$fname""0"
echo
else
echo " ( om kopie op te slaan: even paswoord invoeren )"
sudo cp -p $fpath$fname $fpath$fname""0
if [ $? -gt 0 ]; then
echo "- afgebroken, kon niet kopiëren. [toets]"
read -sn1
exit 2
fi
echo "kopie werd opgeslaan: $fpath$fname""0"
echo
fi
# tijd instellen:
kb=0
until [ "$kb" == "" ]; do
echo -en "\rafteller: [$sec]sec instellen: [+][-] en toepassen: [Enter]"
read -akb -sn1
if [ "$kb" == "+" ]; then
if [ $sec -lt 999 ]; then sec=$(( $sec + 1 )) ; fi
elif [ "$kb" == "-" ]; then
if [ $sec -gt 1 ]; then sec=$(( $sec - 1 )) ; fi
fi
done
echo
sec1=$(( $sec % 256 ))
sec2=$(( $sec / 256 ))
# echo [ $sec1 / $sec2 ] # optie: toon de byte-indeling
# patchpatroon:
# Het getal "60" wordt direct in een 32 bit stack-variabele opgeslaan
# bij 64-bit systeem Uby 9.10:
# C7 87 60 01 00 00 3C 00 00 00 = mov DS:[edi+00000160],0000003C
# bij 32-bit systeem Uby 9.10:
# C7 83 CC 00 00 00 3C 00 00 00 = mov DS:[ebx+000000CC],0000003C
# Dit wordt bepaald door de compiler, het kan zoiets worden:
# C7 83 xx xx xx xx 3C 00 00 00 = mov DS:[ebx+xxxxxxxx],0000003C
# of: C7 86 xx xx xx xx 3C 00 00 00 = mov DS:[esi+xxxxxxxx],0000003C
# of: C7 87 xx xx xx xx 3C 00 00 00 = mov DS:[edi+xxxxxxxx],0000003C
p0=c78\\\([367]........\\\)3c00 # allgemeen zoekpatroon
p2=$( printf "c78\\\1%2.2x%2.2x" $sec1 $sec2 ) # doelpatroon
# patch toepassen:
# (perl -pi -e 's/pattern/replacement/g' file werkt niet met binaire patronen)
# ander idee: http://www.mail-archive.com/peterboro@mailman.lug.org.uk/msg00204.html
# (+ mod.: samengevat in één regel door de LF's weg te halen: "tr -d \n" )
echo
echo " ( om te patchen: even paswoord invoeren )"
# echo "sed \"s/$p0/$p2/\"" # optie: toon de sed-opdracht
xxd -p $fpath$fname""0 | tr -d "\n" | sed "s/$p0/$p2/" | sudo xxd -r -p - $fpath$fname
if [ $? -gt 0 ]; then
echo "- afgebroken, kon niet patchen. Tikfout in het paswoord ? [toets]"
read -sn1
exit 3
else
echo " .. en gepatchd."
echo
fi
# tot slot binair vergelijken:
cmp -l $fpath$fname""0 $fpath$fname | head
echo "De afteller is nu op $sec seconden ingesteld. [toets]"
read -sn1
exit 0