blob: 16bdd4d5201b409cb2d0e758f14e8953f492ef62 [file] [log] [blame]
Nolen Johnson802fd002019-08-07 23:56:48 -04001/*
2 * loki_flash
3 *
4 * A sample utility to validate and flash .lok files
5 *
6 * by Dan Rosenberg (@djrbliss)
7 *
8 */
9
10#include <stdio.h>
11#include <fcntl.h>
12#include <sys/mman.h>
13#include <sys/stat.h>
14#include <string.h>
15#include <stdlib.h>
16#include <unistd.h>
17#include "loki.h"
18
19int loki_flash(const char* partition_label, const char* loki_image)
20{
21 int ifd, aboot_fd, ofd, recovery, offs, match;
22 void *orig, *aboot, *patch;
23 struct stat st;
24 struct boot_img_hdr *hdr;
25 struct loki_hdr *loki_hdr;
26 char outfile[1024];
27
28 if (!strcmp(partition_label, "boot")) {
29 recovery = 0;
30 } else if (!strcmp(partition_label, "recovery")) {
31 recovery = 1;
32 } else {
33 printf("[+] First argument must be \"boot\" or \"recovery\".\n");
34 return 1;
35 }
36
37 /* Verify input file */
38 aboot_fd = open(ABOOT_PARTITION, O_RDONLY);
39 if (aboot_fd < 0) {
40 printf("[-] Failed to open aboot for reading.\n");
41 return 1;
42 }
43
44 ifd = open(loki_image, O_RDONLY);
45 if (ifd < 0) {
46 printf("[-] Failed to open %s for reading.\n", loki_image);
47 return 1;
48 }
49
50 /* Map the image to be flashed */
51 if (fstat(ifd, &st)) {
52 printf("[-] fstat() failed.\n");
53 return 1;
54 }
55
56 orig = mmap(0, (st.st_size + 0x2000 + 0xfff) & ~0xfff, PROT_READ, MAP_PRIVATE, ifd, 0);
57 if (orig == MAP_FAILED) {
58 printf("[-] Failed to mmap Loki image.\n");
59 return 1;
60 }
61
62 hdr = orig;
63 loki_hdr = orig + 0x400;
64
65 /* Verify this is a Loki image */
66 if (memcmp(loki_hdr->magic, "LOKI", 4)) {
67 printf("[-] Input file is not a Loki image.\n");
68 return 1;
69 }
70
71 /* Verify this is the right type of image */
72 if (loki_hdr->recovery != recovery) {
73 printf("[-] Loki image is not a %s image.\n", recovery ? "recovery" : "boot");
74 return 1;
75 }
76
77 /* Verify the to-be-patched address matches the known code pattern */
78 aboot = mmap(0, 0x40000, PROT_READ, MAP_PRIVATE, aboot_fd, 0);
79 if (aboot == MAP_FAILED) {
80 printf("[-] Failed to mmap aboot.\n");
81 return 1;
82 }
83
84 match = 0;
85
86 for (offs = 0; offs < 0x10; offs += 0x4) {
87
88 patch = NULL;
89
90 if (hdr->ramdisk_addr > ABOOT_BASE_LG)
91 patch = hdr->ramdisk_addr - ABOOT_BASE_LG + aboot + offs;
92 else if (hdr->ramdisk_addr > ABOOT_BASE_SAMSUNG)
93 patch = hdr->ramdisk_addr - ABOOT_BASE_SAMSUNG + aboot + offs;
94 else if (hdr->ramdisk_addr > ABOOT_BASE_VIPER)
95 patch = hdr->ramdisk_addr - ABOOT_BASE_VIPER + aboot + offs;
96 else if (hdr->ramdisk_addr > ABOOT_BASE_G2)
97 patch = hdr->ramdisk_addr - ABOOT_BASE_G2 + aboot + offs;
98
99 if (patch < aboot || patch > aboot + 0x40000 - 8) {
100 printf("[-] Invalid .lok file.\n");
101 return 1;
102 }
103
104 if (!memcmp(patch, PATTERN1, 8) ||
105 !memcmp(patch, PATTERN2, 8) ||
106 !memcmp(patch, PATTERN3, 8) ||
107 !memcmp(patch, PATTERN4, 8) ||
108 !memcmp(patch, PATTERN5, 8) ||
109 !memcmp(patch, PATTERN6, 8)) {
110
111 match = 1;
112 break;
113 }
114 }
115
116 if (!match) {
117 printf("[-] Loki aboot version does not match device.\n");
118 return 1;
119 }
120
121 printf("[+] Loki validation passed, flashing image.\n");
122
123 snprintf(outfile, sizeof(outfile),
124 "%s",
125 recovery ? RECOVERY_PARTITION : BOOT_PARTITION);
126
127 ofd = open(outfile, O_WRONLY);
128 if (ofd < 0) {
129 printf("[-] Failed to open output block device.\n");
130 return 1;
131 }
132
133 if (write(ofd, orig, st.st_size) != st.st_size) {
134 printf("[-] Failed to write to block device.\n");
135 return 1;
136 }
137
138 printf("[+] Loki flashing complete!\n");
139
140 close(ifd);
141 close(aboot_fd);
142 close(ofd);
143
144 return 0;
145}