Wednesday, 11 November 2015

Restoring previous Perl library in El Capitan

Because I need an historic Perl 5.10 library for a program I use (GPSPhotoLinker), after upgrading to El Capitan I wanted to recover the old libraries in /System/Library/Perl/5.10 from Time Machine. Unlike the previous times I did this, Time Machine refused. So I restored the folder elsewhere and was in for a surprise.

$ sudo mv 5.10 /System/Library/Perl
mv: rename 5.10 to /System/Library/Perl/5.10: Operation not permitted

Hmmm, that's not supposed to happen. A bit of googling revealed the cause.

$ ls -lO /System/Library/Perl/      
total 0
drwxr-xr-x  130 root  wheel  restricted 4420 23 Aug 02:09 5.16/
drwxr-xr-x  130 root  wheel  restricted 4420 23 Aug 02:08 5.18/
drwxr-xr-x    4 root  wheel  restricted  136 23 Aug 05:49 Extras/

There's a new restricted flag at work that's not documented in chflags(1).

Some more googling produced the video that explains it all, including how to disable the system integrity protection from Recovery as a developer.

Rather than jumping through all the hoops of installing perl in the expected location only to lose it again after the next OS upgrade, I decided to copy perl into the application bundle instead.

Playing with otool(1) and install_name_tool(1) let me change the binary's search path, but as soon as the perl code attempted to load a library it failed. In the end my solution was to create a small wrapper script to set PERL5LIB and DYLD_LIBRARY_PATH to the perl embedded into the application bundle.

$ cd /Applications/GPSPhotoLinker.app/Contents/MacOS
$ mv GPSPhotoLinker GPSPhotoLinker.bin
$ cat >GPSPhotoLinker <<EOF
#!/bin/sh

PERL5LIB=${PERL5LIB}:${0%/*}/../Perl/5.10 \
        DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${0%/*}/../Perl/5.10/darwin-thread-multi-2level/CORE \
        "${0}.bin"
EOF
$ chmod a+x GPSPhotoLinker

Monday, 9 November 2015

Installing CM13 on Moto G from OS X

Motorola having officially abandoned my Moto G XT1032 (Falcon), it was time to install CyanogenMod again…

First, I downloaded the Android SDK. After unzipping the folder, I ran tools/android sdk and selected just the Platform Tools.

Stupidly, I then decided to install Motorola Device Manager thinking I needed its USB driver when in reality just turning on USB debugging on the phone would have sufficed. I spent the next 15 minutes poring over BOMs in /var/db/receipts, unloading LaunchDaemons and removing kexts to get rid of everything that had installed…

This allowed me to run platform-tools/adb devices and see my phone show up in the list. Now it was time to actually start trying to install CM13.

$ ./platform-tools/adb reboot bootloader
$ ./platform-tools/fastboot flash recovery twrp-2.8.6.0-xt1032.img 
target reported max download size of 536870912 bytes
sending 'recovery' (8480 KB)...
OKAY [  0.287s]
writing 'recovery'...
(bootloader) Preflash validation failed
FAILED (remote failure)
finished. total time: 0.311s

The flashing failed as indicated by the »Preflash validation failed« message because my boot loader wasn't unlocked yet. Another indication is a line saying »Device is LOCKED« while in Fastboot. BE AWARE THAT THE FOLLOWING STEP WIPES THE ENTIRE DEVICE.

$ ./platform-tools/fastboot oem get_unlock_data        
...
(bootloader) 0000000000000000#00000000000000
(bootloader) 00000000000000000000000000#0000
(bootloader) 0000000000000000000000000000000
(bootloader) 00000#0000000000000000000000000
(bootloader) 0000000
OKAY [  0.147s]
finished. total time: 0.147s
$ ./platform-tools/fastboot oem unlock 000000000000000000
...
(bootloader) Unlock code = 000000000000000000

(bootloader) Unlock completed! Wait to reboot

ERROR: usb_read failed with status e00002ed
FAILED (status read failed (No such file or directory))
finished. total time: 27.398s

Despite all the error messages, this seems to have worked.

Then, we can finally install TWRP recovery (which supports encryption in contrast to ClockWorkMod).

$ ./platform-tools/fastboot flash recovery twrp-2.8.6.0-xt1032.img                            
target reported max download size of 536870912 bytes
sending 'recovery' (8480 KB)...
OKAY [  0.287s]
writing 'recovery'...
OKAY [  0.300s]
finished. total time: 0.587s

It is now imperative to choose the »Recovery« option from the Fastboot menu using Volume Down and selecting it using Volume Up. This is what prevents the recovery partition we have just flashed from being overwritten during the next boot.

The first thing I did was to backup the PDS partition because when it is lost or damaged the phone's IMEI is lost. We don't want that. In order for the following commands to work, root access via ADB must be enabled in the developer options.

$ ./platform-tools/adb root
restarting adbd as root
$ ./platform-tools/adb shell
# dd if=/dev/block/platform/msm_sdcc.1/by-name/pds of=/sdcard/pds.img
# ^D
$ ./platform-tools/adb pull -p /sdcard/pds.img
Transferring: 3145728/3145728 (100%)
5569 KB/s (3145728 bytes in 0.551s)

Afterwards, it's necessary to remove the warning message from the boot logo. In order to do that, you need to patch the partition containing the boot logos.

$ ./platform-tools/adb root
restarting adbd as root
$ ./platform-tools/adb shell
# dd if=/dev/block/platform/msm_sdcc.1/by-name/logo of=/sdcard/logo.img

If you look at the header of logo.img, you will notice there are four images named logo_boot, logo_battery, logo_unlocked and logo_charge. The names are followed by the offset and length of the image file. In my case, to replace the logo_unlocked image by logo_boot, I used the following command.

$ ./platform-tools/adb root
restarting adbd as root
$ ./platform-tools/adb shell
# dd bs=1 count=8 of=/dev/block/platform/msm_sdcc.1/by-name/logo seek=101 if=/sdcard/logo.img skip=37

Unfortunately, device encryption doesn't work yet with TWRP v2.8.6.0 and I'm not the only one having the problem. An unofficial version of TWRP v2.6.7.0 at least asks for the password, but fails to decrypt the partition.

There is also currently a settings bug if you try to set a PIN for the screen lock. The PIN doesn't actually get set, but when you try to go back into settings to change the screen lock, the Settings app asks for the PIN and then crashes. I didn't find the password.key file in /system/data or anywhere else, so I wiped the data partition to get rid of the PIN.

However, Facebook Messenger keeps crashing and GPS isn't working for me yet, so maybe 20151108 is a little too early for Marshmallow on Falcon. Here are the commands to get back to stock. The system partition can only be written using the moto-fastboot tool from Motorola. When flashed with Android's fastboot, the boot never gets to the animation.

$ fastboot oem lock begin      
...
(bootloader) Ready to flash signed images

OKAY [  2.839s]
finished. total time: 2.839s
$ fastboot flash partition gpt.bin
$ fastboot flash motoboot motoboot.img
$ fastboot flash logo logo.bin
$ fastboot flash boot boot.img
$ fastboot flash recovery recovery.img
$ moto-fastboot-osx64 flash system system.img_sparsechunk.0
$ moto-fastboot-osx64 flash system system.img_sparsechunk.1
$ moto-fastboot-osx64 flash system system.img_sparsechunk.2
$ moto-fastboot-osx64 flash system system.img_sparsechunk.3
$ fastboot flash modem NON-HLOS.bin
$ fastboot erase modemst1
$ fastboot erase modemst2
$ fastboot flash fsg fsg.mbn
$ fastboot erase cache
$ fastboot erase userdata
$ fastboot oem lock

The last command might prompt an error to be shown in Fastboot unless all partitions are signed. When it succeeds, it reboots the device.

I only had to do logo, boot, recovery and system which was enough to make the oem lock command succeed.

Wednesday, 4 November 2015

SocketTimeoutException when sending with K-9 Mail via smtp.gmail.com

Today I noticed an odd problem: K-9 Mail reported SocketTimeoutException when sending mails from an account configured to use smtp.gmail.com. When I set the server to smtp.googlemail.com without changing any of the credentials, it started working again. I didn't dig deeper, but I assume it might have something to do with certificates. It's still odd though because smtp.gmail.com and smtp.googlemail.com resolve to different addresses.