Skip to content

Commit

Permalink
mkbootimg: Add Loki support
Browse files Browse the repository at this point in the history
* I want my target-files built images to be Loki'd if the device
  needs Loki.
* With this, devices that rely on Loki can ship Lineage Recovery
  officially.
* Import loki_tool from: https://github.com/Stricted/android_external_loki.

Change-Id: I45ef363e05566268c8f24f7e8939a2d785478fbe
  • Loading branch information
npjohnson committed Aug 11, 2019
1 parent 7ffb495 commit 802fd00
Show file tree
Hide file tree
Showing 12 changed files with 1,395 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ include $(SAM_ROOT)/macloader/Android.mk
include $(SAM_ROOT)/wifiloader/Android.mk
endif

# Loki
ifeq ($(TAGET_NEEDS_LOKI),true)
include $(SAM_ROOT)/loki_tool/Android.mk
endif

ifeq ($(BOARD_VENDOR),samsung)
include $(SAM_ROOT)/AdvancedDisplay/Android.mk
include $(SAM_ROOT)/audio/Android.mk
Expand Down
17 changes: 17 additions & 0 deletions loki_tool/Android.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
LOCAL_PATH := $(call my-dir)

# build static binary
include $(CLEAR_VARS)
LOCAL_CFLAGS := -Wno-pointer-arith -Wno-unused-result -Wno-sign-compare
LOCAL_SRC_FILES := loki_flash.c loki_patch.c loki_find.c loki_unlok.c main.c
LOCAL_MODULE := loki_tool_static
LOCAL_MODULE_STEM := loki_tool
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)

# build host binary
include $(CLEAR_VARS)
LOCAL_CFLAGS := -Wno-pointer-arith -Wno-unused-result -Wno-sign-compare
LOCAL_SRC_FILES := loki_flash.c loki_patch.c loki_find.c loki_unlok.c main.c
LOCAL_MODULE := loki_tool
include $(BUILD_HOST_EXECUTABLE)
25 changes: 25 additions & 0 deletions loki_tool/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Copyright (c) 2013 Dan Rosenberg. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INFRAE OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 changes: 30 additions & 0 deletions loki_tool/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
SRC_LOKI := loki_flash.c loki_patch.c loki_find.c loki_unlok.c main.c
OBJ_LOKI = $(SRC_LOKI:.c=.o)
MODULE_LOKI := loki_tool

CC := arm-linux-androideabi-gcc
CC_STRIP := arm-linux-androideabi-strip

CFLAGS += -g -static -Wall
#$(LDFLAGS) +=

all: $(MODULE_LOKI)

host: CC := gcc
host: $(MODULE_LOKI)

%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)

$(MODULE_LOKI): $(OBJ_LOKI)
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)

strip:
$(CC_STRIP) --strip-unneeded $(MODULE_LOKI)
$(CC_STRIP) --strip-debug $(MODULE_LOKI)

clean:
rm -f *.o
rm -f loki_tool

.phony: host all
81 changes: 81 additions & 0 deletions loki_tool/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@

WARNING:

This project is no longer actively maintained, because the vulnerability that
it leverages was patched several years ago. No new updates will be provided.
The current codebase will remain here for reference purposes.


=============================
Loki
by Dan Rosenberg (@djrbliss)
=============================

Loki is a set of tools for creating and flashing custom kernels and recoveries
on the AT&T and Verizon branded Samsung Galaxy S4, the Samsung Galaxy Stellar,
and various locked LG devices. For an explanation of how the exploit works,
please see the technical blog post at:

http://blog.azimuthsecurity.com/2013/05/exploiting-samsung-galaxy-s4-secure-boot.html

Devices must be rooted in order to flash custom kernels and recoveries.

loki_tool:
[patch] option is primarily intended for developers to create custom
kernels and recoveries. It's designed to take a specific aboot image and an
unmodified boot or recovery image, and it generates an output image in a new
file format, ".lok". The resulting .lok image is specifically tailored for the
device build it was created with, and can be flashed directly to the recovery
or boot partition on the target device.

[flash] option can be used to flash a .lok image to an actual device.
It will verify that the provided .lok image is safe to flash for a given target
and then perform the flashing if validation is successful. It is also possible
to simply use "dd" to flash a .lok image directly to the boot or recovery partition,
but using [flash] option is recommended in order to validate that the .lok matches
the target device.


=============
Sample usage
=============

First, a developer must pull the aboot image from a target device:


dan@pc:~$ adb shell
shell@android:/ $ su
shell@android:/ # dd if=/dev/block/platform/msm_sdcc.1/by-name/aboot of=/data/local/tmp/aboot.img
shell@android:/ # chmod 644 /data/local/tmp/aboot.img
shell@android:/ # exit
shell@android:/ $ exit
dan@pc:~$ adb pull /data/local/tmp/aboot.img
3293 KB/s (2097152 bytes in 0.621s)


Next, a .lok image can be prepared using loki_tool [patch]:


dan@pc:~$ loki_tool patch
Usage: ./loki_tool [patch] [boot|recovery] [aboot.img] [in.img] [out.lok]
dan@pc:~$ loki_tool patch recovery aboot.img cwm.img cwm.lok
[+] Detected target AT&T build JDQ39.I337UCUAMDB or JDQ39.I337UCUAMDL
[+] Output file written to cwm.lok


Finally, the .lok image can be flashed using loki_tool [flash]:


dan@pc:~$ adb push cwm.lok /data/local/tmp
dan@pc:~$ adb push loki_tool /data/local/tmp
dan@pc:~$ adb shell
shell@android:/ $ su
shell@android:/ # chmod 755 /data/local/tmp/loki_tool
shell@android:/ # /data/local/tmp/loki_tool
Usage: /data/local/tmp/loki_tool [flash] [boot|recovery] [in.lok]
shell@android:/ # /data/local/tmp/loki_tool flash recovery /data/local/tmp/cwm.lok
[+] Loki validation passed, flashing image.
2253+1 records in
2253+1 records out
9230848 bytes transferred in 0.656 secs (14071414 bytes/sec)
[+] Loki flashing complete!
88 changes: 88 additions & 0 deletions loki_tool/loki.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#ifndef __LOKI_H_
#define __LOKI_H_

#define VERSION "2.1"

#define BOOT_MAGIC_SIZE 8
#define BOOT_NAME_SIZE 16
#define BOOT_ARGS_SIZE 512

#define BOOT_PARTITION "/dev/block/platform/msm_sdcc.1/by-name/boot"
#define RECOVERY_PARTITION "/dev/block/platform/msm_sdcc.1/by-name/recovery"
#define ABOOT_PARTITION "/dev/block/platform/msm_sdcc.1/by-name/aboot"

#define PATTERN1 "\xf0\xb5\x8f\xb0\x06\x46\xf0\xf7"
#define PATTERN2 "\xf0\xb5\x8f\xb0\x07\x46\xf0\xf7"
#define PATTERN3 "\x2d\xe9\xf0\x41\x86\xb0\xf1\xf7"
#define PATTERN4 "\x2d\xe9\xf0\x4f\xad\xf5\xc6\x6d"
#define PATTERN5 "\x2d\xe9\xf0\x4f\xad\xf5\x21\x7d"
#define PATTERN6 "\x2d\xe9\xf0\x4f\xf3\xb0\x05\x46"

#define ABOOT_BASE_SAMSUNG 0x88dfffd8
#define ABOOT_BASE_LG 0x88efffd8
#define ABOOT_BASE_G2 0xf7fffd8
#define ABOOT_BASE_VIPER 0x40100000

struct boot_img_hdr {
unsigned char magic[BOOT_MAGIC_SIZE];
unsigned kernel_size; /* size in bytes */
unsigned kernel_addr; /* physical load addr */
unsigned ramdisk_size; /* size in bytes */
unsigned ramdisk_addr; /* physical load addr */
unsigned second_size; /* size in bytes */
unsigned second_addr; /* physical load addr */
unsigned tags_addr; /* physical addr for kernel tags */
unsigned page_size; /* flash page size we assume */
unsigned dt_size; /* device_tree in bytes */
unsigned unused; /* future expansion: should be 0 */
unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
unsigned char cmdline[BOOT_ARGS_SIZE];
unsigned id[8]; /* timestamp / checksum / sha1 / etc */
};

struct loki_hdr {
unsigned char magic[4]; /* 0x494b4f4c */
unsigned int recovery; /* 0 = boot.img, 1 = recovery.img */
char build[128]; /* Build number */

unsigned int orig_kernel_size;
unsigned int orig_ramdisk_size;
unsigned int ramdisk_addr;
};

int loki_patch(const char* partition_label, const char* aboot_image, const char* in_image, const char* out_image);
int loki_flash(const char* partition_label, const char* loki_image);
int loki_find(const char* aboot_image);
int loki_unlok(const char* in_image, const char* out_image);

#define PATCH "\xfe\xb5" \
"\x0d\x4d" \
"\xd5\xf8" \
"\x88\x04" \
"\xab\x68" \
"\x98\x42" \
"\x12\xd0" \
"\xd5\xf8" \
"\x90\x64" \
"\x0a\x4c" \
"\xd5\xf8" \
"\x8c\x74" \
"\x07\xf5\x80\x57" \
"\x0f\xce" \
"\x0f\xc4" \
"\x10\x3f" \
"\xfb\xdc" \
"\xd5\xf8" \
"\x88\x04" \
"\x04\x49" \
"\xd5\xf8" \
"\x8c\x24" \
"\xa8\x60" \
"\x69\x61" \
"\x2a\x61" \
"\x00\x20" \
"\xfe\xbd" \
"\xff\xff\xff\xff" \
"\xee\xee\xee\xee"

#endif //__LOKI_H_
91 changes: 91 additions & 0 deletions loki_tool/loki_find.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>

#include "loki.h"

#define BOOT_PATTERN1 "\x4f\xf4\x70\x40\xb3\x49\x2d\xe9" /* Samsung GS4 */
#define BOOT_PATTERN2 "\x2d\xe9\xf0\x4f\xad\xf5\x82\x5d" /* LG */
#define BOOT_PATTERN3 "\x2d\xe9\xf0\x4f\x4f\xf4\x70\x40" /* LG */
#define BOOT_PATTERN4 "\x2d\xe9\xf0\x4f\xad\xf5\x80\x5d" /* LG G2 */

int loki_find(const char* aboot_image)
{
int aboot_fd;
struct stat st;
void *aboot, *ptr;
unsigned long aboot_base, check_sigs, boot_mmc;

aboot_fd = open(aboot_image, O_RDONLY);
if (aboot_fd < 0) {
printf("[-] Failed to open %s for reading.\n", aboot_image);
return 1;
}

if (fstat(aboot_fd, &st)) {
printf("[-] fstat() failed.\n");
return 1;
}

aboot = mmap(0, (st.st_size + 0xfff) & ~0xfff, PROT_READ, MAP_PRIVATE, aboot_fd, 0);
if (aboot == MAP_FAILED) {
printf("[-] Failed to mmap aboot.\n");
return 1;
}

check_sigs = 0;
aboot_base = *(unsigned int *)(aboot + 12) - 0x28;

/* Do a pass to find signature checking function */
for (ptr = aboot; ptr < aboot + st.st_size - 0x1000; ptr++) {
if (!memcmp(ptr, PATTERN1, 8) ||
!memcmp(ptr, PATTERN2, 8) ||
!memcmp(ptr, PATTERN3, 8) ||
!memcmp(ptr, PATTERN4, 8) ||
!memcmp(ptr, PATTERN5, 8)) {

check_sigs = (unsigned long)ptr - (unsigned long)aboot + aboot_base;
break;
}

if (!memcmp(ptr, PATTERN6, 8)) {

check_sigs = (unsigned long)ptr - (unsigned long)aboot + aboot_base;

/* Don't break, because the other LG patterns override this one */
continue;
}
}

if (!check_sigs) {
printf("[-] Could not find signature checking function.\n");
return 1;
}

printf("[+] Signature check function: %.08lx\n", check_sigs);

boot_mmc = 0;

/* Do a second pass for the boot_linux_from_emmc function */
for (ptr = aboot; ptr < aboot + st.st_size - 0x1000; ptr++) {
if (!memcmp(ptr, BOOT_PATTERN1, 8) ||
!memcmp(ptr, BOOT_PATTERN2, 8) ||
!memcmp(ptr, BOOT_PATTERN3, 8) ||
!memcmp(ptr, BOOT_PATTERN4, 8)) {

boot_mmc = (unsigned long)ptr - (unsigned long)aboot + aboot_base;
break;
}
}

if (!boot_mmc) {
printf("[-] Could not find boot_linux_from_mmc.\n");
return 1;
}

printf("[+] boot_linux_from_mmc: %.08lx\n", boot_mmc);

return 0;
}
Loading

0 comments on commit 802fd00

Please sign in to comment.