summaryrefslogtreecommitdiffstats
path: root/loki_tool/loki_find.c
blob: 151a309a1b891b255f89000cf64cb3b088a360ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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;
}