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
|
# Define paths
|
||||||
TMP_PATH="/tmp"
|
TMP_PATH="/tmp"
|
||||||
|
Binary file not shown.
@ -683,14 +683,14 @@ function make() {
|
|||||||
|
|
||||||
[ ! -f "${ORI_ZIMAGE_FILE}" -o ! -f "${ORI_RDGZ_FILE}" ] && extractDsmFiles
|
[ ! -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
|
if [ $? -ne 0 ]; then
|
||||||
dialog --backtitle "`backtitle`" --title "Error" --aspect 18 \
|
dialog --backtitle "`backtitle`" --title "Error" --aspect 18 \
|
||||||
--msgbox "zImage not patched:\n`<"${LOG_FILE}"`" 0 0
|
--msgbox "zImage not patched:\n`<"${LOG_FILE}"`" 0 0
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
/opt/arpl/ramdisk-patch.sh | tee -a "${LOG_FILE}"
|
/opt/arpl/ramdisk-patch.sh
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
dialog --backtitle "`backtitle`" --title "Error" --aspect 18 \
|
dialog --backtitle "`backtitle`" --title "Error" --aspect 18 \
|
||||||
--msgbox "Ramdisk not patched:\n`<"${LOG_FILE}"`" 0 0
|
--msgbox "Ramdisk not patched:\n`<"${LOG_FILE}"`" 0 0
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
. /opt/arpl/include/functions.sh
|
. /opt/arpl/include/functions.sh
|
||||||
. /opt/arpl/include/addons.sh
|
. /opt/arpl/include/addons.sh
|
||||||
|
|
||||||
|
set -o pipefail # Get exit code from process piped
|
||||||
|
|
||||||
# Sanity check
|
# 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"
|
echo -n "Patching Ramdisk"
|
||||||
|
|
||||||
@ -39,7 +41,7 @@ KVER="`readModelKey "${MODEL}" "builds.${BUILD}.kver"`"
|
|||||||
RD_COMPRESSED="`readModelKey "${MODEL}" "builds.${BUILD}.rd-compressed"`"
|
RD_COMPRESSED="`readModelKey "${MODEL}" "builds.${BUILD}.rd-compressed"`"
|
||||||
|
|
||||||
# Sanity check
|
# 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 SYNOINFO
|
||||||
declare -A ADDONS
|
declare -A ADDONS
|
||||||
@ -125,7 +127,7 @@ fi
|
|||||||
for ADDON in ${!ADDONS[@]}; do
|
for ADDON in ${!ADDONS[@]}; do
|
||||||
PARAMS=${ADDONS[${ADDON}]}
|
PARAMS=${ADDONS[${ADDON}]}
|
||||||
if ! installAddon ${ADDON}; then
|
if ! installAddon ${ADDON}; then
|
||||||
echo "ADDON ${ADDON} not found!" | tee "${LOG_FILE}"
|
echo "ADDON ${ADDON} not found!" | tee -a "${LOG_FILE}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "/addons/${ADDON}.sh \${1} ${PARAMS}" >> "${RAMDISK_PATH}/addons/addons.sh" 2>"${LOG_FILE}" || dieLog
|
echo "/addons/${ADDON}.sh \${1} ${PARAMS}" >> "${RAMDISK_PATH}/addons/addons.sh" 2>"${LOG_FILE}" || dieLog
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
. /opt/arpl/include/functions.sh
|
. /opt/arpl/include/functions.sh
|
||||||
|
|
||||||
|
set -o pipefail # Get exit code from process piped
|
||||||
|
|
||||||
# Sanity check
|
# 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"
|
echo -n "Patching zImage"
|
||||||
|
|
||||||
@ -17,7 +19,6 @@ echo -n "."
|
|||||||
echo -n "."
|
echo -n "."
|
||||||
# rebuild zImage
|
# rebuild zImage
|
||||||
/opt/arpl/vmlinux-to-bzImage.sh "${TMP_PATH}/vmlinux-mod" "${MOD_ZIMAGE_FILE}" >"${LOG_FILE}" 2>&1 || dieLog
|
/opt/arpl/vmlinux-to-bzImage.sh "${TMP_PATH}/vmlinux-mod" "${MOD_ZIMAGE_FILE}" >"${LOG_FILE}" 2>&1 || dieLog
|
||||||
|
|
||||||
echo -n "."
|
echo -n "."
|
||||||
# Update HASH of new DSM zImage
|
# Update HASH of new DSM zImage
|
||||||
HASH="`sha256sum ${ORI_ZIMAGE_FILE} | awk '{print$1}'`"
|
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.
107
kpatch/main.c
107
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -28,10 +28,7 @@
|
|||||||
* - values of ORs are 1/2/4/8 respectively
|
* - values of ORs are 1/2/4/8 respectively
|
||||||
* - [const-ptr] is always the same
|
* - [const-ptr] is always the same
|
||||||
*
|
*
|
||||||
*/
|
* Added patch for CMOS_WRITE by Fabio Belavenuto
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -44,22 +41,25 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <gelf.h>
|
#include <gelf.h>
|
||||||
|
|
||||||
const int DIR_FWD = 1;
|
const int DIR_FWD = 1;
|
||||||
const int DIR_RWD = -1;
|
const int DIR_RWD = -1;
|
||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
int fd;
|
int fd, verbose = 1, read_only = 0;
|
||||||
int verbose = 1, read_only = 0;
|
|
||||||
Elf *elfHandle;
|
Elf *elfHandle;
|
||||||
GElf_Ehdr elfExecHeader;
|
GElf_Ehdr elfExecHeader;
|
||||||
uint64_t orPos[4], fileSize, rodataAddr, rodataOffs, initTextOffs;
|
uint64_t orPos[4], fileSize, rodataAddr, rodataOffs, initTextOffs;
|
||||||
unsigned char *fileData;
|
unsigned char *fileData;
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void errorMsg(char *message) {
|
void errorMsg(char *fmt, ...) {
|
||||||
fprintf(stderr, "%s\n", message);
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,8 +125,8 @@ void patchBootParams() {
|
|||||||
uint64_t newPtrOffset, ptrOffset;
|
uint64_t newPtrOffset, ptrOffset;
|
||||||
int n;
|
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
|
//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) {
|
while (initTextOffs < fileSize) {
|
||||||
addr = findPUSH_R12_R15_SEQ(initTextOffs);
|
addr = findPUSH_R12_R15_SEQ(initTextOffs);
|
||||||
if (addr == -1)
|
if (addr == -1)
|
||||||
@ -160,8 +160,8 @@ void patchBootParams() {
|
|||||||
} else if (ptrOffset == newPtrOffset) {
|
} else if (ptrOffset == newPtrOffset) {
|
||||||
++ec;
|
++ec;
|
||||||
}
|
}
|
||||||
printf("\t[+] Found LOCK-OR#$idx sequence @ %lX => %02X %02X %02X %02X %02X %02X %02X %02X [RIP+%lX]\n",
|
printf("\t[+] Found LOCK-OR#%d 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],
|
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);
|
fileData[pos+5], fileData[pos+6], fileData[pos+7], newPtrOffset);
|
||||||
}
|
}
|
||||||
if (ec != 4) {
|
if (ec != 4) {
|
||||||
@ -175,7 +175,7 @@ void patchBootParams() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (addr == -1) {
|
if (addr == -1) {
|
||||||
errorMsg("\nFailed to find matching sequences");
|
errorMsg("\nFailed to find matching sequences\n");
|
||||||
} else {
|
} else {
|
||||||
//Patch offsets
|
//Patch offsets
|
||||||
for (n = 0; n < 4; n++) {
|
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 findSeq(const char* seq, int len, uint32_t pos, int dir, uint64_t max) {
|
||||||
uint64_t i;
|
uint64_t i = pos;
|
||||||
|
|
||||||
i = pos;
|
|
||||||
do {
|
do {
|
||||||
if (strncmp((const char*)fileData+i, seq, len) == 0) {
|
if (memcmp((const char*)fileData+i, seq, len) == 0) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
i += dir;
|
i += dir;
|
||||||
@ -216,9 +215,9 @@ void patchRamdiskCheck() {
|
|||||||
uint64_t printkPos, testPos, jzPos;
|
uint64_t printkPos, testPos, jzPos;
|
||||||
const char str[] = "3ramdisk corrupt";
|
const char str[] = "3ramdisk corrupt";
|
||||||
|
|
||||||
printf("Patching ramdisk check\n");
|
printf("Patching ramdisk check.\n");
|
||||||
for (pos = rodataOffs; pos < fileSize; pos++) {
|
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;
|
pos -= rodataOffs;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -227,17 +226,15 @@ void patchRamdiskCheck() {
|
|||||||
printf("LE arg addr: %08lX\n", errPrintAddr);
|
printf("LE arg addr: %08lX\n", errPrintAddr);
|
||||||
printkPos = findSeq((const char*)&errPrintAddr, 4, 0, DIR_FWD, -1);
|
printkPos = findSeq((const char*)&errPrintAddr, 4, 0, DIR_FWD, -1);
|
||||||
if (printkPos == -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)
|
//double check if it's a MOV reg,VAL (where reg is EAX/ECX/EDX/EBX/ESP/EBP/ESI/EDI)
|
||||||
printkPos -= 3;
|
printkPos -= 3;
|
||||||
if (strncmp((const char*)fileData+printkPos, "\x48\xc7", 2) != 0) {
|
if (memcmp((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("Expected MOV=>reg before printk error, got %02X %02X\n", fileData[printkPos], fileData[printkPos+1]);
|
||||||
errorMsg("");
|
|
||||||
}
|
}
|
||||||
if (fileData[printkPos+2] < 0xC0 || fileData[printkPos+2] > 0xC7) {
|
if (fileData[printkPos+2] < 0xC0 || fileData[printkPos+2] > 0xC7) {
|
||||||
printf("Expected MOV w/reg operand [C0-C7], got %02X\n", fileData[printkPos+2]);
|
errorMsg("Expected MOV w/reg operand [C0-C7], got %02X\n", fileData[printkPos+2]);
|
||||||
errorMsg("");
|
|
||||||
}
|
}
|
||||||
printf("Found printk MOV @ %08lX\n", printkPos);
|
printf("Found printk MOV @ %08lX\n", printkPos);
|
||||||
|
|
||||||
@ -256,6 +253,54 @@ void patchRamdiskCheck() {
|
|||||||
fileData[jzPos] = 0xEB;
|
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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
struct stat fileInf;
|
struct stat fileInf;
|
||||||
@ -264,7 +309,7 @@ int main(int argc, char *argv[]) {
|
|||||||
char *sectionName;
|
char *sectionName;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
errorMsg("Use: kpatch <vmlinux> <output>");
|
errorMsg("Use: kpatch <vmlinux> <output>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elf_version(EV_CURRENT) == EV_NONE)
|
if (elf_version(EV_CURRENT) == EV_NONE)
|
||||||
@ -281,13 +326,13 @@ int main(int argc, char *argv[]) {
|
|||||||
switch(elf_kind(elfHandle)) {
|
switch(elf_kind(elfHandle)) {
|
||||||
case ELF_K_NUM:
|
case ELF_K_NUM:
|
||||||
case ELF_K_NONE:
|
case ELF_K_NONE:
|
||||||
errorMsg("file type unknown");
|
errorMsg("file type unknown\n");
|
||||||
break;
|
break;
|
||||||
case ELF_K_COFF:
|
case ELF_K_COFF:
|
||||||
errorMsg("COFF binaries not supported");
|
errorMsg("COFF binaries not supported\n");
|
||||||
break;
|
break;
|
||||||
case ELF_K_AR:
|
case ELF_K_AR:
|
||||||
errorMsg("AR archives not supported");
|
errorMsg("AR archives not supported\n");
|
||||||
break;
|
break;
|
||||||
case ELF_K_ELF:
|
case ELF_K_ELF:
|
||||||
break;
|
break;
|
||||||
@ -319,8 +364,12 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
close(fd);
|
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();
|
patchBootParams();
|
||||||
patchRamdiskCheck();
|
patchRamdiskCheck();
|
||||||
|
patchCmosWrite();
|
||||||
if ((fd = open(argv[2], O_WRONLY | O_CREAT, 0644)) == -1) {
|
if ((fd = open(argv[2], O_WRONLY | O_CREAT, 0644)) == -1) {
|
||||||
errorNum();
|
errorNum();
|
||||||
}
|
}
|
||||||
@ -328,6 +377,6 @@ int main(int argc, char *argv[]) {
|
|||||||
errorNum();
|
errorNum();
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
printf("\n");
|
printf("Finish!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user