mirror of
https://github.com/RROrg/rr.git
synced 2025-06-21 05:51:05 +08:00
Merge pull request #186 from fbelavenuto/patch-cmos-write
Add patch rtc_cmos_write (issue #174)
This commit is contained in:
commit
e3594d5bdc
@ -1,5 +1,5 @@
|
||||
|
||||
ARPL_VERSION="0.4-alpha9"
|
||||
ARPL_VERSION="0.4-alpha10"
|
||||
|
||||
# Define paths
|
||||
TMP_PATH="/tmp"
|
||||
|
Binary file not shown.
@ -683,14 +683,14 @@ function make() {
|
||||
|
||||
[ ! -f "${ORI_ZIMAGE_FILE}" -o ! -f "${ORI_RDGZ_FILE}" ] && extractDsmFiles
|
||||
|
||||
/opt/arpl/zimage-patch.sh | tee -a "${LOG_FILE}"
|
||||
/opt/arpl/zimage-patch.sh
|
||||
if [ $? -ne 0 ]; then
|
||||
dialog --backtitle "`backtitle`" --title "Error" --aspect 18 \
|
||||
--msgbox "zImage not patched:\n`<"${LOG_FILE}"`" 0 0
|
||||
return 1
|
||||
fi
|
||||
|
||||
/opt/arpl/ramdisk-patch.sh | tee -a "${LOG_FILE}"
|
||||
/opt/arpl/ramdisk-patch.sh
|
||||
if [ $? -ne 0 ]; then
|
||||
dialog --backtitle "`backtitle`" --title "Error" --aspect 18 \
|
||||
--msgbox "Ramdisk not patched:\n`<"${LOG_FILE}"`" 0 0
|
||||
|
@ -3,8 +3,10 @@
|
||||
. /opt/arpl/include/functions.sh
|
||||
. /opt/arpl/include/addons.sh
|
||||
|
||||
set -o pipefail # Get exit code from process piped
|
||||
|
||||
# Sanity check
|
||||
[ -f "${ORI_RDGZ_FILE}" ] || die "${ORI_RDGZ_FILE} not found!"
|
||||
[ -f "${ORI_RDGZ_FILE}" ] || (die "${ORI_RDGZ_FILE} not found!" | tee -a "${LOG_FILE}")
|
||||
|
||||
echo -n "Patching Ramdisk"
|
||||
|
||||
@ -39,7 +41,7 @@ KVER="`readModelKey "${MODEL}" "builds.${BUILD}.kver"`"
|
||||
RD_COMPRESSED="`readModelKey "${MODEL}" "builds.${BUILD}.rd-compressed"`"
|
||||
|
||||
# Sanity check
|
||||
[ -z "${PLATFORM}" -o -z "${KVER}" ] && die "ERROR: Configuration for model ${MODEL} and buildnumber ${BUILD} not found."
|
||||
[ -z "${PLATFORM}" -o -z "${KVER}" ] && (die "ERROR: Configuration for model ${MODEL} and buildnumber ${BUILD} not found." | tee -a "${LOG_FILE}")
|
||||
|
||||
declare -A SYNOINFO
|
||||
declare -A ADDONS
|
||||
@ -125,7 +127,7 @@ fi
|
||||
for ADDON in ${!ADDONS[@]}; do
|
||||
PARAMS=${ADDONS[${ADDON}]}
|
||||
if ! installAddon ${ADDON}; then
|
||||
echo "ADDON ${ADDON} not found!" | tee "${LOG_FILE}"
|
||||
echo "ADDON ${ADDON} not found!" | tee -a "${LOG_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
echo "/addons/${ADDON}.sh \${1} ${PARAMS}" >> "${RAMDISK_PATH}/addons/addons.sh" 2>"${LOG_FILE}" || dieLog
|
||||
|
@ -2,8 +2,10 @@
|
||||
|
||||
. /opt/arpl/include/functions.sh
|
||||
|
||||
set -o pipefail # Get exit code from process piped
|
||||
|
||||
# Sanity check
|
||||
[ -f "${ORI_ZIMAGE_FILE}" ] || die "${ORI_ZIMAGE_FILE} not found!"
|
||||
[ -f "${ORI_ZIMAGE_FILE}" ] || (die "${ORI_ZIMAGE_FILE} not found!" | tee -a "${LOG_FILE}")
|
||||
|
||||
echo -n "Patching zImage"
|
||||
|
||||
@ -17,7 +19,6 @@ echo -n "."
|
||||
echo -n "."
|
||||
# rebuild zImage
|
||||
/opt/arpl/vmlinux-to-bzImage.sh "${TMP_PATH}/vmlinux-mod" "${MOD_ZIMAGE_FILE}" >"${LOG_FILE}" 2>&1 || dieLog
|
||||
|
||||
echo -n "."
|
||||
# Update HASH of new DSM zImage
|
||||
HASH="`sha256sum ${ORI_ZIMAGE_FILE} | awk '{print$1}'`"
|
||||
|
BIN
files/board/arpl/overlayfs/usr/lib/libdevmapper.so.1.02
Executable file
BIN
files/board/arpl/overlayfs/usr/lib/libdevmapper.so.1.02
Executable file
Binary file not shown.
BIN
files/board/arpl/overlayfs/usr/sbin/grub-editenv
Executable file
BIN
files/board/arpl/overlayfs/usr/sbin/grub-editenv
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
115
kpatch/main.c
115
kpatch/main.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Fabio Belavenuto <belavenuto@gmail.com>
|
||||
* Copyright (c) 2022 Fabio Belavenuto <belavenuto@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -28,11 +28,8 @@
|
||||
* - values of ORs are 1/2/4/8 respectively
|
||||
* - [const-ptr] is always the same
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* A quick tool for patching the ramdisk check in the DSM kernel image
|
||||
* This lets you tinker with the initial ramdisk contents without disabling mount() features and modules loading
|
||||
*
|
||||
* Added patch for CMOS_WRITE by Fabio Belavenuto
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -44,22 +41,25 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <gelf.h>
|
||||
|
||||
const int DIR_FWD = 1;
|
||||
const int DIR_RWD = -1;
|
||||
|
||||
/* Variables */
|
||||
int fd;
|
||||
int verbose = 1, read_only = 0;
|
||||
Elf *elfHandle;
|
||||
GElf_Ehdr elfExecHeader;
|
||||
uint64_t orPos[4], fileSize, rodataAddr, rodataOffs, initTextOffs;
|
||||
int fd, verbose = 1, read_only = 0;
|
||||
Elf *elfHandle;
|
||||
GElf_Ehdr elfExecHeader;
|
||||
uint64_t orPos[4], fileSize, rodataAddr, rodataOffs, initTextOffs;
|
||||
unsigned char *fileData;
|
||||
|
||||
/*****************************************************************************/
|
||||
void errorMsg(char *message) {
|
||||
fprintf(stderr, "%s\n", message);
|
||||
void errorMsg(char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -125,8 +125,8 @@ void patchBootParams() {
|
||||
uint64_t newPtrOffset, ptrOffset;
|
||||
int n;
|
||||
|
||||
printf("Patching boot params.\n");
|
||||
//The function will reside in init code part. We don't care we may potentially search beyond as we expect it to be found
|
||||
printf("Found .init.text at %lX\n", initTextOffs);
|
||||
while (initTextOffs < fileSize) {
|
||||
addr = findPUSH_R12_R15_SEQ(initTextOffs);
|
||||
if (addr == -1)
|
||||
@ -160,8 +160,8 @@ void patchBootParams() {
|
||||
} else if (ptrOffset == newPtrOffset) {
|
||||
++ec;
|
||||
}
|
||||
printf("\t[+] Found LOCK-OR#$idx sequence @ %lX => %02X %02X %02X %02X %02X %02X %02X %02X [RIP+%lX]\n",
|
||||
pos, fileData[pos], fileData[pos+1], fileData[pos+2], fileData[pos+3], fileData[pos+4],
|
||||
printf("\t[+] Found LOCK-OR#%d sequence @ %lX => %02X %02X %02X %02X %02X %02X %02X %02X [RIP+%lX]\n",
|
||||
n, pos, fileData[pos], fileData[pos+1], fileData[pos+2], fileData[pos+3], fileData[pos+4],
|
||||
fileData[pos+5], fileData[pos+6], fileData[pos+7], newPtrOffset);
|
||||
}
|
||||
if (ec != 4) {
|
||||
@ -175,7 +175,7 @@ void patchBootParams() {
|
||||
break;
|
||||
}
|
||||
if (addr == -1) {
|
||||
errorMsg("\nFailed to find matching sequences");
|
||||
errorMsg("\nFailed to find matching sequences\n");
|
||||
} else {
|
||||
//Patch offsets
|
||||
for (n = 0; n < 4; n++) {
|
||||
@ -197,11 +197,10 @@ uint32_t changeEndian(uint32_t num) {
|
||||
|
||||
/*****************************************************************************/
|
||||
uint64_t findSeq(const char* seq, int len, uint32_t pos, int dir, uint64_t max) {
|
||||
uint64_t i;
|
||||
uint64_t i = pos;
|
||||
|
||||
i = pos;
|
||||
do {
|
||||
if (strncmp((const char*)fileData+i, seq, len) == 0) {
|
||||
if (memcmp((const char*)fileData+i, seq, len) == 0) {
|
||||
return i;
|
||||
}
|
||||
i += dir;
|
||||
@ -216,9 +215,9 @@ void patchRamdiskCheck() {
|
||||
uint64_t printkPos, testPos, jzPos;
|
||||
const char str[] = "3ramdisk corrupt";
|
||||
|
||||
printf("Patching ramdisk check\n");
|
||||
printf("Patching ramdisk check.\n");
|
||||
for (pos = rodataOffs; pos < fileSize; pos++) {
|
||||
if (strncmp(str, (const char*)(fileData + pos), 16) == 0) {
|
||||
if (memcmp(str, (const char*)(fileData + pos), 16) == 0) {
|
||||
pos -= rodataOffs;
|
||||
break;
|
||||
}
|
||||
@ -227,17 +226,15 @@ void patchRamdiskCheck() {
|
||||
printf("LE arg addr: %08lX\n", errPrintAddr);
|
||||
printkPos = findSeq((const char*)&errPrintAddr, 4, 0, DIR_FWD, -1);
|
||||
if (printkPos == -1) {
|
||||
errorMsg("printk pos not found!");
|
||||
errorMsg("printk pos not found!\n");
|
||||
}
|
||||
//double check if it's a MOV reg,VAL (where reg is EAX/ECX/EDX/EBX/ESP/EBP/ESI/EDI)
|
||||
printkPos -= 3;
|
||||
if (strncmp((const char*)fileData+printkPos, "\x48\xc7", 2) != 0) {
|
||||
printf("Expected MOV=>reg before printk error, got %02X %02X\n", fileData[printkPos], fileData[printkPos+1]);
|
||||
errorMsg("");
|
||||
if (memcmp((const char*)fileData+printkPos, "\x48\xc7", 2) != 0) {
|
||||
errorMsg("Expected MOV=>reg before printk error, got %02X %02X\n", fileData[printkPos], fileData[printkPos+1]);
|
||||
}
|
||||
if (fileData[printkPos+2] < 0xC0 || fileData[printkPos+2] > 0xC7) {
|
||||
printf("Expected MOV w/reg operand [C0-C7], got %02X\n", fileData[printkPos+2]);
|
||||
errorMsg("");
|
||||
errorMsg("Expected MOV w/reg operand [C0-C7], got %02X\n", fileData[printkPos+2]);
|
||||
}
|
||||
printf("Found printk MOV @ %08lX\n", printkPos);
|
||||
|
||||
@ -256,6 +253,54 @@ void patchRamdiskCheck() {
|
||||
fileData[jzPos] = 0xEB;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void patchCmosWrite() {
|
||||
uint64_t pos, errPrintAddr;
|
||||
uint64_t pr_errPos, testPos, callPos;
|
||||
const char str[] = "3smpboot: %s: this boot have memory training";
|
||||
|
||||
printf("Patching call to rtc_cmos_write.\n");
|
||||
for (pos = rodataOffs; pos < fileSize; pos++) {
|
||||
if (memcmp(str, (const char*)(fileData + pos), 16) == 0) {
|
||||
pos -= rodataOffs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
errPrintAddr = rodataAddr + pos - 1;
|
||||
printf("LE arg addr: %08lX\n", errPrintAddr);
|
||||
pr_errPos = findSeq((const char*)&errPrintAddr, 4, 0, DIR_FWD, -1);
|
||||
if (pr_errPos == -1) {
|
||||
printf("pr_err pos not found - ignoring.\n"); // Some kernels do not have the call, exit without error
|
||||
return;
|
||||
}
|
||||
//double check if it's a MOV reg,VAL (where reg is EAX/ECX/EDX/EBX/ESP/EBP/ESI/EDI)
|
||||
pr_errPos -= 3;
|
||||
if (memcmp((const char*)fileData+pr_errPos, "\x48\xc7", 2) != 0) {
|
||||
errorMsg("Expected MOV=>reg before pr_err error, got %02X %02X\n", fileData[pr_errPos], fileData[pr_errPos+1]);
|
||||
}
|
||||
if (fileData[pr_errPos+2] < 0xC0 || fileData[pr_errPos+2] > 0xC7) {
|
||||
errorMsg("Expected MOV w/reg operand [C0-C7], got %02X\n", fileData[pr_errPos+2]);
|
||||
}
|
||||
printf("Found pr_err MOV @ %08lX\n", pr_errPos);
|
||||
|
||||
// now we should seek a reasonable amount (say, up to 64 bytes) for a sequence of
|
||||
// MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX
|
||||
testPos = findSeq("\xBE\x48\x00\x00\x00\xBF\xFF\x00\x00\x00\x89\xC3", 12, pr_errPos, DIR_RWD, 64);
|
||||
if (testPos == -1) {
|
||||
printf("Failed to find MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX\n");
|
||||
return;
|
||||
}
|
||||
printf("Found MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX @ %08lX\n", testPos);
|
||||
callPos = testPos + 12;
|
||||
if (fileData[callPos] != 0xE8) {
|
||||
errorMsg("Failed to find CALL\n");
|
||||
}
|
||||
printf("OK - patching %02X (CALL) to 0x90.. (NOPs) @ %08lX\n",
|
||||
fileData[callPos], callPos);
|
||||
for(uint64_t i = 0; i < 5; i++)
|
||||
fileData[callPos+i] = 0x90;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int main(int argc, char *argv[]) {
|
||||
struct stat fileInf;
|
||||
@ -264,7 +309,7 @@ int main(int argc, char *argv[]) {
|
||||
char *sectionName;
|
||||
|
||||
if (argc != 3) {
|
||||
errorMsg("Use: kpatch <vmlinux> <output>");
|
||||
errorMsg("Use: kpatch <vmlinux> <output>\n");
|
||||
}
|
||||
|
||||
if (elf_version(EV_CURRENT) == EV_NONE)
|
||||
@ -281,13 +326,13 @@ int main(int argc, char *argv[]) {
|
||||
switch(elf_kind(elfHandle)) {
|
||||
case ELF_K_NUM:
|
||||
case ELF_K_NONE:
|
||||
errorMsg("file type unknown");
|
||||
errorMsg("file type unknown\n");
|
||||
break;
|
||||
case ELF_K_COFF:
|
||||
errorMsg("COFF binaries not supported");
|
||||
errorMsg("COFF binaries not supported\n");
|
||||
break;
|
||||
case ELF_K_AR:
|
||||
errorMsg("AR archives not supported");
|
||||
errorMsg("AR archives not supported\n");
|
||||
break;
|
||||
case ELF_K_ELF:
|
||||
break;
|
||||
@ -319,8 +364,12 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
close(fd);
|
||||
|
||||
printf("Found .init.text offset @ %lX\n", initTextOffs);
|
||||
printf("Found .rodata address @ %lX\n", rodataAddr);
|
||||
printf("Found .rodata offset @ %lX\n", rodataOffs);
|
||||
patchBootParams();
|
||||
patchRamdiskCheck();
|
||||
patchCmosWrite();
|
||||
if ((fd = open(argv[2], O_WRONLY | O_CREAT, 0644)) == -1) {
|
||||
errorNum();
|
||||
}
|
||||
@ -328,6 +377,6 @@ int main(int argc, char *argv[]) {
|
||||
errorNum();
|
||||
}
|
||||
close(fd);
|
||||
printf("\n");
|
||||
printf("Finish!\n");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user