You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.2 KiB
92 lines
2.2 KiB
5 years ago
|
#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;
|
||
|
}
|