E
I have not really tried this, but a possible approach would be following the steps a custom recovery would perform when installing ("flashing") the .zip file – which can be found in META-INF/com/google/android/updater-script (after extracting the archive). For the Kitkat GApps archive, this looks like:
ui_print("Installing files...");
run_program("/sbin/busybox", "mount", "/system");
show_progress(1, 15);
delete("/system/app/Provision.apk","/system/app/QuickSearchBox.apk","/system/app/priv-app/SetupWizard.apk","/system/app/priv-app/Velvet.apk","/system/app/Vending.apk","/system/app
package_extract_dir("system", "/system");
set_perm(0, 0, 0755, "/system/addon.d/70-gapps.sh");
package_extract_dir("optional", "/tmp");
package_extract_file("install-optional.sh", "/tmp/install-optional.sh");
set_perm(0, 0, 0777, "/tmp/install-optional.sh");
run_program("/tmp/install-optional.sh", "");
show_progress(1, 15);
ui_print("Cleaning up and setting metadata...");
set_metadata_recursive("/system/addon.d", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0755, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata_recursive("/system/app", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0644, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata_recursive("/system/priv-app", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0644, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata_recursive("/system/etc/permissions", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0755, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata_recursive("/system/etc/preferred-apps", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0755, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata("/system/etc/g.prop", "uid", 0, "gid", 0, "mode", 0755, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata_recursive("/system/framework", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0644, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata_recursive("/system/lib", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0644, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata_recursive("/system/usr/srec/en-US", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0644, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
set_metadata_recursive("/system/vendor/pittpatt", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0644, "capabilities", 0x0, "selabel", "u:object_r:system_file:s0");
run_program("/sbin/busybox", "umount", "/system");
ui_print("Installation complete!");
We of course can skip the comments/debug-output, and thus essentially end up with these steps. I assume you've unpacked the .zip file's contents somewhere on your device, and are sitting in a shell (terminal or adb shell) with root permissions (su) to start with:
mount -o remount,rw /system (line 2)
if the files listed in line 4 exist: rm -f for each of them
copy all contents of the .zip file's system/ directory to /system (line 5)
chmod 0755 /system/addon.d/70-gapps.sh (line 6)
( apply the previous 2 steps on lines 7-9 )
sh /tmp/install-optional.sh (line 10)
Now it gets a little more difficult (for beginners) interpreting the set_metadata_recursive commands. I'll explain this on the first one (line 13):
/system/addon.d must be owned by uid 0 and gid 0, file permissions should be 0755 (dmode is directory mode, fmode file mode), SELinux attributes are u:object_r:system_file:s0. You might have noticed I've skipped two columns: I have no idea what the "capabilities", 0x0 stands for, so I cannot explain it (if anyone does, please comment). So let's do that:
chown -R root:root /system/addon.d # -R is recursive, root is user/group id 0
chmod -R 755 /system/addon.d # as dmode and fmode are the same, we can do that
# at this place missing: SELinux properties. I've never dealt with those
If like in line 14 fmode and dmode are different, you'll have to take care for that as well. Apply dmode as above, and follow it by a find -type f -print0 | xargs chmod , replacing by the first argument of set_metadata_recursive, and by the corresponding fmode.
Finally, remount /system read-only again: mount -o remount,ro /system – or simply reboot (you'll have to anyway), which takes care for that as well.
I have skipped the SELinux stuff due to missing knowledge. It will most likely work without – but might be good to do for additional security