mirror of
https://github.com/RROrg/rr.git
synced 2025-06-21 05:51:05 +08:00
format
This commit is contained in:
parent
ab355f24ea
commit
19d142c2d8
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1 +1 @@
|
|||||||
*.sh eol=lf
|
*.sh eol=lf
|
||||||
|
8
.gitmodules
vendored
8
.gitmodules
vendored
@ -1,6 +1,6 @@
|
|||||||
[submodule "redpill-lkm"]
|
[submodule "redpill-lkm"]
|
||||||
path = redpill-lkm
|
path = redpill-lkm
|
||||||
url = https://github.com/wjz304/redpill-lkm
|
url = https://github.com/wjz304/redpill-lkm
|
||||||
[submodule "addons"]
|
[submodule "addons"]
|
||||||
path = addons
|
path = addons
|
||||||
url = https://github.com/wjz304/arpl-addons
|
url = https://github.com/wjz304/arpl-addons
|
||||||
|
@ -15,11 +15,11 @@ BOARD_PATH="${CONFIG_DIR}/board/arpl"
|
|||||||
|
|
||||||
echo "Creating image file"
|
echo "Creating image file"
|
||||||
# unzip base image
|
# unzip base image
|
||||||
gzip -dc "${BOARD_PATH}/grub.img.gz" > "${IMAGE_FILE}"
|
gzip -dc "${BOARD_PATH}/grub.img.gz" >"${IMAGE_FILE}"
|
||||||
# fdisk
|
# fdisk
|
||||||
fdisk -l "${IMAGE_FILE}"
|
fdisk -l "${IMAGE_FILE}"
|
||||||
# Find idle of loop device
|
# Find idle of loop device
|
||||||
LOOPX=`sudo losetup -f`
|
LOOPX=$(sudo losetup -f)
|
||||||
# Setup the ${LOOPX} loop device
|
# Setup the ${LOOPX} loop device
|
||||||
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
|
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ set -e
|
|||||||
|
|
||||||
. scripts/func.sh
|
. scripts/func.sh
|
||||||
|
|
||||||
|
|
||||||
if [ ! -d .buildroot ]; then
|
if [ ! -d .buildroot ]; then
|
||||||
echo "Downloading buildroot"
|
echo "Downloading buildroot"
|
||||||
git clone --single-branch -b 2023.02.x https://github.com/buildroot/buildroot.git .buildroot
|
git clone --single-branch -b 2023.02.x https://github.com/buildroot/buildroot.git .buildroot
|
||||||
@ -25,15 +24,15 @@ rm -rf ".buildroot/board/arpl/p3"
|
|||||||
|
|
||||||
# Copy files
|
# Copy files
|
||||||
echo "Copying files"
|
echo "Copying files"
|
||||||
VERSION=`cat VERSION`
|
VERSION=$(cat VERSION)
|
||||||
sed 's/^ARPL_VERSION=.*/ARPL_VERSION="'${VERSION}'"/' -i files/board/arpl/overlayfs/opt/arpl/include/consts.sh
|
sed 's/^ARPL_VERSION=.*/ARPL_VERSION="'${VERSION}'"/' -i files/board/arpl/overlayfs/opt/arpl/include/consts.sh
|
||||||
echo "${VERSION}" > files/board/arpl/p1/ARPL-VERSION
|
echo "${VERSION}" >files/board/arpl/p1/ARPL-VERSION
|
||||||
cp -Ru files/* .buildroot/
|
cp -Ru files/* .buildroot/
|
||||||
|
|
||||||
cd .buildroot
|
cd .buildroot
|
||||||
echo "Generating default config"
|
echo "Generating default config"
|
||||||
make BR2_EXTERNAL=../external -j`nproc` arpl_defconfig
|
make BR2_EXTERNAL=../external -j$(nproc) arpl_defconfig
|
||||||
echo "Version: ${VERSION}"
|
echo "Version: ${VERSION}"
|
||||||
echo "Building... Drink a coffee and wait!"
|
echo "Building... Drink a coffee and wait!"
|
||||||
make BR2_EXTERNAL=../external -j`nproc`
|
make BR2_EXTERNAL=../external -j$(nproc)
|
||||||
cd -
|
cd -
|
||||||
|
347
kpatch/main.c
347
kpatch/main.c
@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Converted from php code by Fabio Belavenuto <belavenuto@gmail.com>
|
* Converted from php code by Fabio Belavenuto <belavenuto@gmail.com>
|
||||||
*
|
*
|
||||||
* A quick tool for patching the boot_params check in the DSM kernel image
|
* A quick tool for patching the boot_params check in the DSM kernel image
|
||||||
* This lets you tinker with the initial ramdisk contents without disabling mount() features and modules loading
|
* This lets you tinker with the initial ramdisk contents without disabling mount() features and modules loading
|
||||||
*
|
*
|
||||||
@ -29,7 +29,7 @@
|
|||||||
* - [const-ptr] is always the same
|
* - [const-ptr] is always the same
|
||||||
*
|
*
|
||||||
* Added patch for CMOS_WRITE by Fabio Belavenuto
|
* Added patch for CMOS_WRITE by Fabio Belavenuto
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -48,14 +48,15 @@ const int DIR_FWD = 1;
|
|||||||
const int DIR_RWD = -1;
|
const int DIR_RWD = -1;
|
||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
int fd, verbose = 1, read_only = 0;
|
int fd, 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 *fmt, ...) {
|
void errorMsg(char *fmt, ...)
|
||||||
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vfprintf(stderr, fmt, args);
|
vfprintf(stderr, fmt, args);
|
||||||
@ -65,32 +66,38 @@ void errorMsg(char *fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void errorNum() {
|
void errorNum()
|
||||||
|
{
|
||||||
char str[100] = {0};
|
char str[100] = {0};
|
||||||
perror(str);
|
perror(str);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void elfErrno() {
|
void elfErrno()
|
||||||
int err;
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
if ((err = elf_errno()) != 0) {
|
if ((err = elf_errno()) != 0)
|
||||||
|
{
|
||||||
fprintf(stderr, "%s\n", elf_errmsg(err));
|
fprintf(stderr, "%s\n", elf_errmsg(err));
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
//Finding a function boundary is non-trivial really as patters can vary, we can have multiple exit points, and in CISC
|
// Finding a function boundary is non-trivial really as patters can vary, we can have multiple exit points, and in CISC
|
||||||
// there are many things which may match e.g. "PUSH EBP". Implementing even a rough disassembler is pointless.
|
// there are many things which may match e.g. "PUSH EBP". Implementing even a rough disassembler is pointless.
|
||||||
//However, we can certainly cheat here as we know with CDECL a non-empty function will always contain one or more
|
// However, we can certainly cheat here as we know with CDECL a non-empty function will always contain one or more
|
||||||
// PUSH (0x41) R12-R15 (0x54-57) sequences. Then we can search like a 1K forward for these characteristic LOCK OR.
|
// PUSH (0x41) R12-R15 (0x54-57) sequences. Then we can search like a 1K forward for these characteristic LOCK OR.
|
||||||
uint64_t findPUSH_R12_R15_SEQ(uint64_t start) {
|
uint64_t findPUSH_R12_R15_SEQ(uint64_t start)
|
||||||
|
{
|
||||||
uint64_t i;
|
uint64_t i;
|
||||||
|
|
||||||
for (i = start; i < fileSize; i++) {
|
for (i = start; i < fileSize; i++)
|
||||||
if (fileData[i] == 0x41 && (fileData[i+1] >= 0x54 && fileData[i+1] <= 0x57)) {
|
{
|
||||||
|
if (fileData[i] == 0x41 && (fileData[i + 1] >= 0x54 && fileData[i + 1] <= 0x57))
|
||||||
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,21 +106,26 @@ uint64_t findPUSH_R12_R15_SEQ(uint64_t start) {
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
//[0xF0, 0x80, null, null, null, null, null, 0xXX],
|
//[0xF0, 0x80, null, null, null, null, null, 0xXX],
|
||||||
uint64_t findORs(uint64_t start, uint32_t maxCheck) {
|
uint64_t findORs(uint64_t start, uint32_t maxCheck)
|
||||||
|
{
|
||||||
uint64_t i;
|
uint64_t i;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
uint8_t lb = 0x01;
|
uint8_t lb = 0x01;
|
||||||
|
|
||||||
for (i = start; i < fileSize; i++) {
|
for (i = start; i < fileSize; i++)
|
||||||
if (fileData[i] == 0xF0 && fileData[i+1] == 0x80 && fileData[i+7] == lb) {
|
{
|
||||||
|
if (fileData[i] == 0xF0 && fileData[i + 1] == 0x80 && fileData[i + 7] == lb)
|
||||||
|
{
|
||||||
orPos[c++] = i;
|
orPos[c++] = i;
|
||||||
i += 7;
|
i += 7;
|
||||||
lb <<= 1;
|
lb <<= 1;
|
||||||
}
|
}
|
||||||
if (c == 4) {
|
if (c == 4)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (--maxCheck == 0) {
|
if (--maxCheck == 0)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,66 +133,79 @@ uint64_t findORs(uint64_t start, uint32_t maxCheck) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void patchBootParams() {
|
void patchBootParams()
|
||||||
|
{
|
||||||
uint64_t addr, pos;
|
uint64_t addr, pos;
|
||||||
uint64_t newPtrOffset, ptrOffset;
|
uint64_t newPtrOffset, ptrOffset;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
printf("Patching boot params.\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
|
||||||
while (initTextOffs < fileSize) {
|
while (initTextOffs < fileSize)
|
||||||
|
{
|
||||||
addr = findPUSH_R12_R15_SEQ(initTextOffs);
|
addr = findPUSH_R12_R15_SEQ(initTextOffs);
|
||||||
if (addr == -1)
|
if (addr == -1)
|
||||||
break; //no more "functions" left
|
break; // no more "functions" left
|
||||||
printf("\rAnalyzing f() candidate @ %lX, PUSH @ %lX", initTextOffs, addr);
|
printf("\rAnalyzing f() candidate @ %lX, PUSH @ %lX", initTextOffs, addr);
|
||||||
//we found something looking like PUSH R12-R15, now find the ORs
|
// we found something looking like PUSH R12-R15, now find the ORs
|
||||||
n = findORs(initTextOffs, 1024);
|
n = findORs(initTextOffs, 1024);
|
||||||
if (n != 4) {
|
if (n != 4)
|
||||||
//We can always move forward by the function token length (obvious) but if we couldn't find any LOCK-OR tokens
|
{
|
||||||
// we can skip the whole look ahead distance. We CANNOT do that if we found even a single token because the next one
|
// We can always move forward by the function token length (obvious) but if we couldn't find any LOCK-OR tokens
|
||||||
// might have been just after the look ahead distance
|
// we can skip the whole look ahead distance. We CANNOT do that if we found even a single token because the next one
|
||||||
|
// might have been just after the look ahead distance
|
||||||
initTextOffs += 2;
|
initTextOffs += 2;
|
||||||
if (n == 0) {
|
if (n == 0)
|
||||||
|
{
|
||||||
initTextOffs += 1024;
|
initTextOffs += 1024;
|
||||||
}
|
}
|
||||||
continue; //Continue the main search loop to find next function candidate
|
continue; // Continue the main search loop to find next function candidate
|
||||||
}
|
}
|
||||||
//We found LOCK(); OR ptr sequences so we can print some logs and collect ptrs (as this is quite expensive)
|
// We found LOCK(); OR ptr sequences so we can print some logs and collect ptrs (as this is quite expensive)
|
||||||
printf("\n[?] Found possible f() @ %lX\n", initTextOffs);
|
printf("\n[?] Found possible f() @ %lX\n", initTextOffs);
|
||||||
ptrOffset=0;
|
ptrOffset = 0;
|
||||||
int ec = 0;
|
int ec = 0;
|
||||||
for (n = 0; n < 4; n++) {
|
for (n = 0; n < 4; n++)
|
||||||
//data will have the following bytes:
|
{
|
||||||
// [0-LOCK()] [1-OR()] [2-BYTE-PTR] [3-OFFS-b3] [4-OFFS-b2] [5-OFFS-b1] [6-OFFS-b1] [7-NUMBER]
|
// data will have the following bytes:
|
||||||
|
// [0-LOCK()] [1-OR()] [2-BYTE-PTR] [3-OFFS-b3] [4-OFFS-b2] [5-OFFS-b1] [6-OFFS-b1] [7-NUMBER]
|
||||||
pos = orPos[n];
|
pos = orPos[n];
|
||||||
//how far it "jumps"
|
// how far it "jumps"
|
||||||
newPtrOffset = pos + (fileData[pos+6] << 24 | fileData[pos+5] << 16 | fileData[pos+4] << 8 | fileData[pos+3]);
|
newPtrOffset = pos + (fileData[pos + 6] << 24 | fileData[pos + 5] << 16 | fileData[pos + 4] << 8 | fileData[pos + 3]);
|
||||||
if (ptrOffset == 0) {
|
if (ptrOffset == 0)
|
||||||
|
{
|
||||||
ptrOffset = newPtrOffset;
|
ptrOffset = newPtrOffset;
|
||||||
++ec;
|
++ec;
|
||||||
} else if (ptrOffset == newPtrOffset) {
|
}
|
||||||
|
else if (ptrOffset == newPtrOffset)
|
||||||
|
{
|
||||||
++ec;
|
++ec;
|
||||||
}
|
}
|
||||||
printf("\t[+] Found LOCK-OR#%d 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",
|
||||||
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)
|
||||||
|
{
|
||||||
printf("\t[-] LOCK-OR PTR offset mismatch - %d/4 matched\n", ec);
|
printf("\t[-] LOCK-OR PTR offset mismatch - %d/4 matched\n", ec);
|
||||||
//If the pointer checking failed we can at least move beyond the last LOCK-OR found as we know there's no valid
|
// If the pointer checking failed we can at least move beyond the last LOCK-OR found as we know there's no valid
|
||||||
// sequence of LOCK-ORs there
|
// sequence of LOCK-ORs there
|
||||||
initTextOffs = orPos[3];
|
initTextOffs = orPos[3];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
printf("\t[+] All %d LOCK-OR PTR offsets equal - match found!\n", ec);
|
printf("\t[+] All %d LOCK-OR PTR offsets equal - match found!\n", ec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (addr == -1) {
|
if (addr == -1)
|
||||||
|
{
|
||||||
errorMsg("\nFailed to find matching sequences\n");
|
errorMsg("\nFailed to find matching sequences\n");
|
||||||
} else {
|
}
|
||||||
//Patch offsets
|
else
|
||||||
for (n = 0; n < 4; n++) {
|
{
|
||||||
//The offset will point at LOCK(), we need to change the OR (0x80 0x0d) to AND (0x80 0x25) so the two bytes after
|
// Patch offsets
|
||||||
|
for (n = 0; n < 4; n++)
|
||||||
|
{
|
||||||
|
// The offset will point at LOCK(), we need to change the OR (0x80 0x0d) to AND (0x80 0x25) so the two bytes after
|
||||||
pos = orPos[n] + 2;
|
pos = orPos[n] + 2;
|
||||||
printf("Patching OR to AND @ %lX\n", pos);
|
printf("Patching OR to AND @ %lX\n", pos);
|
||||||
fileData[pos] = 0x25;
|
fileData[pos] = 0x25;
|
||||||
@ -189,121 +214,142 @@ void patchBootParams() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
uint32_t changeEndian(uint32_t num) {
|
uint32_t changeEndian(uint32_t num)
|
||||||
return ((num>>24)&0xff) | // move byte 3 to byte 0
|
{
|
||||||
((num<<8)&0xff0000) | // move byte 1 to byte 2
|
return ((num >> 24) & 0xff) | // move byte 3 to byte 0
|
||||||
((num>>8)&0xff00) | // move byte 2 to byte 1
|
((num << 8) & 0xff0000) | // move byte 1 to byte 2
|
||||||
((num<<24)&0xff000000); // move byte 0 to byte 3
|
((num >> 8) & 0xff00) | // move byte 2 to byte 1
|
||||||
|
((num << 24) & 0xff000000); // move byte 0 to byte 3
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
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 = pos;
|
uint64_t i = pos;
|
||||||
|
|
||||||
do {
|
do
|
||||||
if (memcmp((const char*)fileData+i, seq, len) == 0) {
|
{
|
||||||
|
if (memcmp((const char *)fileData + i, seq, len) == 0)
|
||||||
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
i += dir;
|
i += dir;
|
||||||
--max;
|
--max;
|
||||||
} while(i > 0 && i < fileSize && max > 0);
|
} while (i > 0 && i < fileSize && max > 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void patchRamdiskCheck() {
|
void patchRamdiskCheck()
|
||||||
|
{
|
||||||
uint64_t pos, errPrintAddr;
|
uint64_t pos, errPrintAddr;
|
||||||
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 (memcmp(str, (const char*)(fileData + pos), 16) == 0) {
|
{
|
||||||
|
if (memcmp(str, (const char *)(fileData + pos), 16) == 0)
|
||||||
|
{
|
||||||
pos -= rodataOffs;
|
pos -= rodataOffs;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
errPrintAddr = rodataAddr + pos - 1;
|
errPrintAddr = rodataAddr + pos - 1;
|
||||||
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!\n");
|
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 (memcmp((const char*)fileData+printkPos, "\x48\xc7", 2) != 0) {
|
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]);
|
{
|
||||||
|
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) {
|
if (fileData[printkPos + 2] < 0xC0 || fileData[printkPos + 2] > 0xC7)
|
||||||
errorMsg("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]);
|
||||||
}
|
}
|
||||||
printf("Found printk MOV @ %08lX\n", printkPos);
|
printf("Found printk MOV @ %08lX\n", printkPos);
|
||||||
|
|
||||||
//now we should seek a reasonable amount (say, up to 32 bytes) for a sequence of CALL x => TEST EAX,EAX => JZ
|
// now we should seek a reasonable amount (say, up to 32 bytes) for a sequence of CALL x => TEST EAX,EAX => JZ
|
||||||
testPos = findSeq("\x85\xc0", 2, printkPos, DIR_RWD, 32);
|
testPos = findSeq("\x85\xc0", 2, printkPos, DIR_RWD, 32);
|
||||||
if (testPos == -1) {
|
if (testPos == -1)
|
||||||
|
{
|
||||||
errorMsg("Failed to find TEST eax,eax\n");
|
errorMsg("Failed to find TEST eax,eax\n");
|
||||||
}
|
}
|
||||||
printf("Found TEST eax,eax @ %08lX\n", testPos);
|
printf("Found TEST eax,eax @ %08lX\n", testPos);
|
||||||
jzPos = testPos + 2;
|
jzPos = testPos + 2;
|
||||||
if (fileData[jzPos] != 0x74) {
|
if (fileData[jzPos] != 0x74)
|
||||||
|
{
|
||||||
errorMsg("Failed to find JZ\n");
|
errorMsg("Failed to find JZ\n");
|
||||||
}
|
}
|
||||||
printf("OK - patching %02X%02X (JZ) to %02X%02X (JMP) @ %08lX\n",
|
printf("OK - patching %02X%02X (JZ) to %02X%02X (JMP) @ %08lX\n",
|
||||||
fileData[jzPos], fileData[jzPos+1], 0xEB, fileData[jzPos+1], jzPos);
|
fileData[jzPos], fileData[jzPos + 1], 0xEB, fileData[jzPos + 1], jzPos);
|
||||||
fileData[jzPos] = 0xEB;
|
fileData[jzPos] = 0xEB;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void patchCmosWrite() {
|
void patchCmosWrite()
|
||||||
|
{
|
||||||
uint64_t pos, errPrintAddr;
|
uint64_t pos, errPrintAddr;
|
||||||
uint64_t pr_errPos, testPos, callPos;
|
uint64_t pr_errPos, testPos, callPos;
|
||||||
const char str[] = "3smpboot: %s: this boot have memory training";
|
const char str[] = "3smpboot: %s: this boot have memory training";
|
||||||
|
|
||||||
printf("Patching call to rtc_cmos_write.\n");
|
printf("Patching call to rtc_cmos_write.\n");
|
||||||
for (pos = rodataOffs; pos < fileSize; pos++) {
|
for (pos = rodataOffs; pos < fileSize; pos++)
|
||||||
if (memcmp(str, (const char*)(fileData + pos), 16) == 0) {
|
{
|
||||||
|
if (memcmp(str, (const char *)(fileData + pos), 16) == 0)
|
||||||
|
{
|
||||||
pos -= rodataOffs;
|
pos -= rodataOffs;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
errPrintAddr = rodataAddr + pos - 1;
|
errPrintAddr = rodataAddr + pos - 1;
|
||||||
printf("LE arg addr: %08lX\n", errPrintAddr);
|
printf("LE arg addr: %08lX\n", errPrintAddr);
|
||||||
pr_errPos = findSeq((const char*)&errPrintAddr, 4, 0, DIR_FWD, -1);
|
pr_errPos = findSeq((const char *)&errPrintAddr, 4, 0, DIR_FWD, -1);
|
||||||
if (pr_errPos == -1) {
|
if (pr_errPos == -1)
|
||||||
printf("pr_err pos not found - ignoring.\n"); // Some kernels do not have the call, exit without error
|
{
|
||||||
|
printf("pr_err pos not found - ignoring.\n"); // Some kernels do not have the call, exit without error
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//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)
|
||||||
pr_errPos -= 3;
|
pr_errPos -= 3;
|
||||||
if (memcmp((const char*)fileData+pr_errPos, "\x48\xc7", 2) != 0) {
|
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]);
|
{
|
||||||
|
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) {
|
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]);
|
{
|
||||||
|
errorMsg("Expected MOV w/reg operand [C0-C7], got %02X\n", fileData[pr_errPos + 2]);
|
||||||
}
|
}
|
||||||
printf("Found pr_err MOV @ %08lX\n", pr_errPos);
|
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
|
// 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
|
// 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);
|
testPos = findSeq("\xBE\x48\x00\x00\x00\xBF\xFF\x00\x00\x00\x89\xC3", 12, pr_errPos, DIR_RWD, 64);
|
||||||
if (testPos == -1) {
|
if (testPos == -1)
|
||||||
|
{
|
||||||
printf("Failed to find MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX\n");
|
printf("Failed to find MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("Found MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX @ %08lX\n", testPos);
|
printf("Found MOV ESI, 0x48 => MOV EDI, 0xFF => MOV EBX, EAX @ %08lX\n", testPos);
|
||||||
callPos = testPos + 12;
|
callPos = testPos + 12;
|
||||||
if (fileData[callPos] != 0xE8) {
|
if (fileData[callPos] != 0xE8)
|
||||||
|
{
|
||||||
errorMsg("Failed to find CALL\n");
|
errorMsg("Failed to find CALL\n");
|
||||||
}
|
}
|
||||||
printf("OK - patching %02X (CALL) to 0x90.. (NOPs) @ %08lX\n",
|
printf("OK - patching %02X (CALL) to 0x90.. (NOPs) @ %08lX\n",
|
||||||
fileData[callPos], callPos);
|
fileData[callPos], callPos);
|
||||||
for(uint64_t i = 0; i < 5; i++)
|
for (uint64_t i = 0; i < 5; i++)
|
||||||
fileData[callPos+i] = 0x90;
|
fileData[callPos + i] = 0x90;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
struct stat fileInf;
|
struct stat fileInf;
|
||||||
Elf_Scn *section;
|
Elf_Scn *section;
|
||||||
GElf_Shdr sectionHeader;
|
GElf_Shdr sectionHeader;
|
||||||
@ -311,29 +357,42 @@ int main(int argc, char *argv[]) {
|
|||||||
char *fileIn = NULL, *fileOut = NULL;
|
char *fileIn = NULL, *fileOut = NULL;
|
||||||
int onlyBoot = 0, onlyRD = 0, onlyCMOS = 0, c;
|
int onlyBoot = 0, onlyRD = 0, onlyCMOS = 0, c;
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3)
|
||||||
|
{
|
||||||
errorMsg("Use: kpatch (option) <vmlinux> <output>\nOptions:\n -b Only bootparams\n -r Only ramdisk\n -c Only CMOS");
|
errorMsg("Use: kpatch (option) <vmlinux> <output>\nOptions:\n -b Only bootparams\n -r Only ramdisk\n -c Only CMOS");
|
||||||
}
|
}
|
||||||
c = 1;
|
c = 1;
|
||||||
while (c < argc) {
|
while (c < argc)
|
||||||
if (strcmp(argv[c], "-b") == 0) {
|
{
|
||||||
onlyBoot = 1;
|
if (strcmp(argv[c], "-b") == 0)
|
||||||
} else if (strcmp(argv[c], "-r") == 0) {
|
{
|
||||||
onlyRD = 1;
|
onlyBoot = 1;
|
||||||
} else if (strcmp(argv[c], "-c") == 0) {
|
}
|
||||||
onlyCMOS = 1;
|
else if (strcmp(argv[c], "-r") == 0)
|
||||||
} else if (fileIn == NULL) {
|
{
|
||||||
fileIn = argv[c];
|
onlyRD = 1;
|
||||||
} else {
|
}
|
||||||
fileOut = argv[c];
|
else if (strcmp(argv[c], "-c") == 0)
|
||||||
break;
|
{
|
||||||
}
|
onlyCMOS = 1;
|
||||||
++c;
|
}
|
||||||
|
else if (fileIn == NULL)
|
||||||
|
{
|
||||||
|
fileIn = argv[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileOut = argv[c];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++c;
|
||||||
}
|
}
|
||||||
if (NULL == fileIn) {
|
if (NULL == fileIn)
|
||||||
|
{
|
||||||
errorMsg("Please give a input filename");
|
errorMsg("Please give a input filename");
|
||||||
}
|
}
|
||||||
if (NULL == fileOut) {
|
if (NULL == fileOut)
|
||||||
|
{
|
||||||
errorMsg("Please give a output filename");
|
errorMsg("Please give a output filename");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,30 +407,35 @@ int main(int argc, char *argv[]) {
|
|||||||
if (gelf_getehdr(elfHandle, &elfExecHeader) == NULL)
|
if (gelf_getehdr(elfHandle, &elfExecHeader) == NULL)
|
||||||
elfErrno();
|
elfErrno();
|
||||||
|
|
||||||
switch(elf_kind(elfHandle)) {
|
switch (elf_kind(elfHandle))
|
||||||
case ELF_K_NUM:
|
{
|
||||||
case ELF_K_NONE:
|
case ELF_K_NUM:
|
||||||
errorMsg("file type unknown\n");
|
case ELF_K_NONE:
|
||||||
break;
|
errorMsg("file type unknown\n");
|
||||||
case ELF_K_COFF:
|
break;
|
||||||
errorMsg("COFF binaries not supported\n");
|
case ELF_K_COFF:
|
||||||
break;
|
errorMsg("COFF binaries not supported\n");
|
||||||
case ELF_K_AR:
|
break;
|
||||||
errorMsg("AR archives not supported\n");
|
case ELF_K_AR:
|
||||||
break;
|
errorMsg("AR archives not supported\n");
|
||||||
case ELF_K_ELF:
|
break;
|
||||||
break;
|
case ELF_K_ELF:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
section = NULL;
|
section = NULL;
|
||||||
while ((section = elf_nextscn(elfHandle, section)) != NULL) {
|
while ((section = elf_nextscn(elfHandle, section)) != NULL)
|
||||||
|
{
|
||||||
if (gelf_getshdr(section, §ionHeader) != §ionHeader)
|
if (gelf_getshdr(section, §ionHeader) != §ionHeader)
|
||||||
elfErrno();
|
elfErrno();
|
||||||
if ((sectionName = elf_strptr(elfHandle, elfExecHeader.e_shstrndx, sectionHeader.sh_name)) == NULL)
|
if ((sectionName = elf_strptr(elfHandle, elfExecHeader.e_shstrndx, sectionHeader.sh_name)) == NULL)
|
||||||
elfErrno();
|
elfErrno();
|
||||||
if (strcmp(sectionName, ".init.text") == 0) {
|
if (strcmp(sectionName, ".init.text") == 0)
|
||||||
|
{
|
||||||
initTextOffs = sectionHeader.sh_offset;
|
initTextOffs = sectionHeader.sh_offset;
|
||||||
} else if (strcmp(sectionName, ".rodata") == 0) {
|
}
|
||||||
|
else if (strcmp(sectionName, ".rodata") == 0)
|
||||||
|
{
|
||||||
rodataAddr = sectionHeader.sh_addr & 0xFFFFFFFF;
|
rodataAddr = sectionHeader.sh_addr & 0xFFFFFFFF;
|
||||||
rodataOffs = sectionHeader.sh_offset;
|
rodataOffs = sectionHeader.sh_offset;
|
||||||
}
|
}
|
||||||
@ -384,7 +448,8 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
fileSize = fileInf.st_size;
|
fileSize = fileInf.st_size;
|
||||||
fileData = malloc(fileSize);
|
fileData = malloc(fileSize);
|
||||||
if (fileSize != read(fd, fileData, fileSize)) {
|
if (fileSize != read(fd, fileData, fileSize))
|
||||||
|
{
|
||||||
errorNum();
|
errorNum();
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -392,25 +457,33 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("Found .init.text offset @ %lX\n", initTextOffs);
|
printf("Found .init.text offset @ %lX\n", initTextOffs);
|
||||||
printf("Found .rodata address @ %lX\n", rodataAddr);
|
printf("Found .rodata address @ %lX\n", rodataAddr);
|
||||||
printf("Found .rodata offset @ %lX\n", rodataOffs);
|
printf("Found .rodata offset @ %lX\n", rodataOffs);
|
||||||
if (onlyBoot == 0 && onlyCMOS == 0 && onlyRD == 0) {
|
if (onlyBoot == 0 && onlyCMOS == 0 && onlyRD == 0)
|
||||||
|
{
|
||||||
patchBootParams();
|
patchBootParams();
|
||||||
patchRamdiskCheck();
|
patchRamdiskCheck();
|
||||||
patchCmosWrite();
|
patchCmosWrite();
|
||||||
} else {
|
}
|
||||||
if (onlyBoot == 1) {
|
else
|
||||||
|
{
|
||||||
|
if (onlyBoot == 1)
|
||||||
|
{
|
||||||
patchBootParams();
|
patchBootParams();
|
||||||
}
|
}
|
||||||
if (onlyRD == 1) {
|
if (onlyRD == 1)
|
||||||
|
{
|
||||||
patchRamdiskCheck();
|
patchRamdiskCheck();
|
||||||
}
|
}
|
||||||
if (onlyCMOS == 1) {
|
if (onlyCMOS == 1)
|
||||||
|
{
|
||||||
patchCmosWrite();
|
patchCmosWrite();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((fd = open(fileOut, O_WRONLY | O_CREAT, 0644)) == -1) {
|
if ((fd = open(fileOut, O_WRONLY | O_CREAT, 0644)) == -1)
|
||||||
|
{
|
||||||
errorNum();
|
errorNum();
|
||||||
}
|
}
|
||||||
if (fileSize != write(fd, fileData, fileSize)) {
|
if (fileSize != write(fd, fileData, fileSize))
|
||||||
|
{
|
||||||
errorNum();
|
errorNum();
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
215
scripts/func.sh
215
scripts/func.sh
@ -1,144 +1,133 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
# Copyright (C) 2022 Ing <https://github.com/wjz304>
|
# Copyright (C) 2022 Ing <https://github.com/wjz304>
|
||||||
#
|
#
|
||||||
# This is free software, licensed under the MIT License.
|
# This is free software, licensed under the MIT License.
|
||||||
# See /LICENSE for more information.
|
# See /LICENSE for more information.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
# Convert po2mo
|
# Convert po2mo
|
||||||
# $1 path
|
# $1 path
|
||||||
function convertpo2mo() {
|
function convertpo2mo() {
|
||||||
echo "Convert po2mo begin"
|
echo "Convert po2mo begin"
|
||||||
local DEST_PATH="${1:-lang}"
|
local DEST_PATH="${1:-lang}"
|
||||||
if [ `find ${DEST_PATH}/ -name "*.po" | wc -l` -gt 0 ]; then
|
if [ $(find ${DEST_PATH}/ -name "*.po" | wc -l) -gt 0 ]; then
|
||||||
for P in `ls ${DEST_PATH}/*.po`
|
for P in $(ls ${DEST_PATH}/*.po); do
|
||||||
do
|
# Use msgfmt command to compile the .po file into a binary .mo file
|
||||||
# Use msgfmt command to compile the .po file into a binary .mo file
|
echo "msgfmt ${P} to ${P/.po/.mo}"
|
||||||
echo "msgfmt ${P} to ${P/.po/.mo}"
|
msgfmt ${P} -o ${P/.po/.mo}
|
||||||
msgfmt ${P} -o ${P/.po/.mo}
|
done
|
||||||
done
|
fi
|
||||||
fi
|
echo "Convert po2mo end"
|
||||||
echo "Convert po2mo end"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Get extractor
|
# Get extractor
|
||||||
# $1 path
|
# $1 path
|
||||||
function getExtractor(){
|
function getExtractor() {
|
||||||
echo "Getting syno extractor begin"
|
echo "Getting syno extractor begin"
|
||||||
local DEST_PATH="${1:-extractor}"
|
local DEST_PATH="${1:-extractor}"
|
||||||
local CACHE_DIR="/tmp/pat"
|
local CACHE_DIR="/tmp/pat"
|
||||||
rm -rf "${CACHE_DIR}"; mkdir -p "${CACHE_DIR}"
|
rm -rf "${CACHE_DIR}"
|
||||||
# Download pat file
|
mkdir -p "${CACHE_DIR}"
|
||||||
# global.synologydownload.com, global.download.synology.com, cndl.synology.cn
|
# Download pat file
|
||||||
local PAT_URL="https://global.synologydownload.com/download/DSM/release/7.0.1/42218/DSM_DS3622xs%2B_42218.pat"
|
# global.synologydownload.com, global.download.synology.com, cndl.synology.cn
|
||||||
local PAT_FILE="DSM_DS3622xs+_42218.pat"
|
local PAT_URL="https://global.synologydownload.com/download/DSM/release/7.0.1/42218/DSM_DS3622xs%2B_42218.pat"
|
||||||
local STATUS=`curl -# -w "%{http_code}" -L "${PAT_URL}" -o "${CACHE_DIR}/${PAT_FILE}"`
|
local PAT_FILE="DSM_DS3622xs+_42218.pat"
|
||||||
if [ $? -ne 0 -o ${STATUS} -ne 200 ]; then
|
local STATUS=$(curl -# -w "%{http_code}" -L "${PAT_URL}" -o "${CACHE_DIR}/${PAT_FILE}")
|
||||||
echo "[E] DSM_DS3622xs%2B_42218.pat download error!"
|
if [ $? -ne 0 -o ${STATUS} -ne 200 ]; then
|
||||||
rm -rf ${CACHE_DIR}
|
echo "[E] DSM_DS3622xs%2B_42218.pat download error!"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "${CACHE_DIR}/ramdisk"
|
|
||||||
tar -C "${CACHE_DIR}/ramdisk/" -xf "${CACHE_DIR}/${PAT_FILE}" rd.gz 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "[E] extractor rd.gz error!"
|
|
||||||
rm -rf ${CACHE_DIR}
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
(cd "${CACHE_DIR}/ramdisk"; xz -dc < rd.gz | cpio -idm) >/dev/null 2>&1 || true
|
|
||||||
|
|
||||||
rm -rf "${DEST_PATH}"; mkdir -p "${DEST_PATH}"
|
|
||||||
|
|
||||||
# Copy only necessary files
|
|
||||||
for f in libcurl.so.4 libmbedcrypto.so.5 libmbedtls.so.13 libmbedx509.so.1 libmsgpackc.so.2 libsodium.so libsynocodesign-ng-virtual-junior-wins.so.7; do
|
|
||||||
cp "${CACHE_DIR}/ramdisk/usr/lib/${f}" "${DEST_PATH}"
|
|
||||||
done
|
|
||||||
cp "${CACHE_DIR}/ramdisk/usr/syno/bin/scemd" "${DEST_PATH}/syno_extract_system_patch"
|
|
||||||
|
|
||||||
# Clean up
|
|
||||||
rm -rf ${CACHE_DIR}
|
rm -rf ${CACHE_DIR}
|
||||||
echo "Getting syno extractor end"
|
exit 1
|
||||||
}
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${CACHE_DIR}/ramdisk"
|
||||||
|
tar -C "${CACHE_DIR}/ramdisk/" -xf "${CACHE_DIR}/${PAT_FILE}" rd.gz 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "[E] extractor rd.gz error!"
|
||||||
|
rm -rf ${CACHE_DIR}
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
(
|
||||||
|
cd "${CACHE_DIR}/ramdisk"
|
||||||
|
xz -dc <rd.gz | cpio -idm
|
||||||
|
) >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
rm -rf "${DEST_PATH}"
|
||||||
|
mkdir -p "${DEST_PATH}"
|
||||||
|
|
||||||
|
# Copy only necessary files
|
||||||
|
for f in libcurl.so.4 libmbedcrypto.so.5 libmbedtls.so.13 libmbedx509.so.1 libmsgpackc.so.2 libsodium.so libsynocodesign-ng-virtual-junior-wins.so.7; do
|
||||||
|
cp "${CACHE_DIR}/ramdisk/usr/lib/${f}" "${DEST_PATH}"
|
||||||
|
done
|
||||||
|
cp "${CACHE_DIR}/ramdisk/usr/syno/bin/scemd" "${DEST_PATH}/syno_extract_system_patch"
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
rm -rf ${CACHE_DIR}
|
||||||
|
echo "Getting syno extractor end"
|
||||||
|
}
|
||||||
|
|
||||||
# Get latest LKMs
|
# Get latest LKMs
|
||||||
# $1 path
|
# $1 path
|
||||||
function getLKMs() {
|
function getLKMs() {
|
||||||
echo "Getting LKMs begin"
|
echo "Getting LKMs begin"
|
||||||
local DEST_PATH="${1:-lkms}"
|
local DEST_PATH="${1:-lkms}"
|
||||||
local CACHE_FILE="/tmp/rp-lkms.zip"
|
local CACHE_FILE="/tmp/rp-lkms.zip"
|
||||||
rm -f "${CACHE_FILE}"
|
rm -f "${CACHE_FILE}"
|
||||||
TAG=`curl -s "https://api.github.com/repos/wjz304/redpill-lkm/releases/latest" | grep -oP '"tag_name": "\K(.*)(?=")'`
|
TAG=$(curl -s "https://api.github.com/repos/wjz304/redpill-lkm/releases/latest" | grep -oP '"tag_name": "\K(.*)(?=")')
|
||||||
STATUS=`curl -w "%{http_code}" -L "https://github.com/wjz304/redpill-lkm/releases/download/${TAG}/rp-lkms.zip" -o "${CACHE_FILE}"`
|
STATUS=$(curl -w "%{http_code}" -L "https://github.com/wjz304/redpill-lkm/releases/download/${TAG}/rp-lkms.zip" -o "${CACHE_FILE}")
|
||||||
echo "TAG=${TAG}; Status=${STATUS}"
|
echo "TAG=${TAG}; Status=${STATUS}"
|
||||||
[ ${STATUS} -ne 200 ] && exit 1
|
[ ${STATUS} -ne 200 ] && exit 1
|
||||||
# Unzip LKMs
|
# Unzip LKMs
|
||||||
rm -rf "${DEST_PATH}"; mkdir -p "${DEST_PATH}"
|
rm -rf "${DEST_PATH}"
|
||||||
unzip "${CACHE_FILE}" -d "${DEST_PATH}"
|
mkdir -p "${DEST_PATH}"
|
||||||
rm -f "${CACHE_FILE}"
|
unzip "${CACHE_FILE}" -d "${DEST_PATH}"
|
||||||
echo "Getting LKMs end"
|
rm -f "${CACHE_FILE}"
|
||||||
|
echo "Getting LKMs end"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Get latest addons and install its
|
# Get latest addons and install its
|
||||||
# $1 path
|
# $1 path
|
||||||
function getAddons() {
|
function getAddons() {
|
||||||
echo "Getting Addons begin"
|
echo "Getting Addons begin"
|
||||||
local DEST_PATH="${1:-addons}"
|
local DEST_PATH="${1:-addons}"
|
||||||
local CACHE_DIR="/tmp/addons"
|
local CACHE_DIR="/tmp/addons"
|
||||||
local CACHE_FILE="/tmp/addons.zip"
|
local CACHE_FILE="/tmp/addons.zip"
|
||||||
TAG=`curl -s https://api.github.com/repos/wjz304/arpl-addons/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")'`
|
TAG=$(curl -s https://api.github.com/repos/wjz304/arpl-addons/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')
|
||||||
STATUS=`curl -w "%{http_code}" -L "https://github.com/wjz304/arpl-addons/releases/download/${TAG}/addons.zip" -o "${CACHE_FILE}"`
|
STATUS=$(curl -w "%{http_code}" -L "https://github.com/wjz304/arpl-addons/releases/download/${TAG}/addons.zip" -o "${CACHE_FILE}")
|
||||||
echo "TAG=${TAG}; Status=${STATUS}"
|
echo "TAG=${TAG}; Status=${STATUS}"
|
||||||
[ ${STATUS} -ne 200 ] && exit 1
|
[ ${STATUS} -ne 200 ] && exit 1
|
||||||
rm -rf "${DEST_PATH}"; mkdir -p "${DEST_PATH}"
|
rm -rf "${DEST_PATH}"
|
||||||
# Install Addons
|
mkdir -p "${DEST_PATH}"
|
||||||
rm -rf "${CACHE_DIR}"; mkdir -p "${CACHE_DIR}"
|
# Install Addons
|
||||||
unzip "${CACHE_FILE}" -d "${CACHE_DIR}"
|
rm -rf "${CACHE_DIR}"
|
||||||
echo "Installing addons to ${DEST_PATH}"
|
mkdir -p "${CACHE_DIR}"
|
||||||
[ -f /tmp/addons/VERSION ] && cp -f /tmp/addons/VERSION ${DEST_PATH}/
|
unzip "${CACHE_FILE}" -d "${CACHE_DIR}"
|
||||||
for PKG in `ls ${CACHE_DIR}/*.addon`; do
|
echo "Installing addons to ${DEST_PATH}"
|
||||||
ADDON=`basename "${PKG}" .addon`
|
[ -f /tmp/addons/VERSION ] && cp -f /tmp/addons/VERSION ${DEST_PATH}/
|
||||||
mkdir -p "${DEST_PATH}/${ADDON}"
|
for PKG in $(ls ${CACHE_DIR}/*.addon); do
|
||||||
echo "Extracting ${PKG} to ${DEST_PATH}/${ADDON}"
|
ADDON=$(basename "${PKG}" .addon)
|
||||||
tar -xaf "${PKG}" -C "${DEST_PATH}/${ADDON}"
|
mkdir -p "${DEST_PATH}/${ADDON}"
|
||||||
done
|
echo "Extracting ${PKG} to ${DEST_PATH}/${ADDON}"
|
||||||
echo "Getting Addons end"
|
tar -xaf "${PKG}" -C "${DEST_PATH}/${ADDON}"
|
||||||
|
done
|
||||||
|
echo "Getting Addons end"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Get latest modules
|
# Get latest modules
|
||||||
# $1 path
|
# $1 path
|
||||||
function getModules() {
|
function getModules() {
|
||||||
echo "Getting Modules begin"
|
echo "Getting Modules begin"
|
||||||
local DEST_PATH="${1:-addons}"
|
local DEST_PATH="${1:-addons}"
|
||||||
local CACHE_FILE="/tmp/modules.zip"
|
local CACHE_FILE="/tmp/modules.zip"
|
||||||
rm -f "${CACHE_FILE}"
|
rm -f "${CACHE_FILE}"
|
||||||
TAG=`curl -s https://api.github.com/repos/wjz304/arpl-modules/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")'`
|
TAG=$(curl -s https://api.github.com/repos/wjz304/arpl-modules/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')
|
||||||
STATUS=`curl -w "%{http_code}" -L "https://github.com/wjz304/arpl-modules/releases/download/${TAG}/modules.zip" -o "${CACHE_FILE}"`
|
STATUS=$(curl -w "%{http_code}" -L "https://github.com/wjz304/arpl-modules/releases/download/${TAG}/modules.zip" -o "${CACHE_FILE}")
|
||||||
echo "TAG=${TAG}; Status=${STATUS}"
|
echo "TAG=${TAG}; Status=${STATUS}"
|
||||||
[ ${STATUS} -ne 200 ] && exit 1
|
[ ${STATUS} -ne 200 ] && exit 1
|
||||||
# Unzip Modules
|
# Unzip Modules
|
||||||
rm -rf "${DEST_PATH}"; mkdir -p "${DEST_PATH}"
|
rm -rf "${DEST_PATH}"
|
||||||
unzip "${CACHE_FILE}" -d "${DEST_PATH}"
|
mkdir -p "${DEST_PATH}"
|
||||||
rm -f "${CACHE_FILE}"
|
unzip "${CACHE_FILE}" -d "${DEST_PATH}"
|
||||||
echo "Getting Modules end"
|
rm -f "${CACHE_FILE}"
|
||||||
|
echo "Getting Modules end"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
# Copyright (C) 2022 Ing <https://github.com/wjz304>
|
# Copyright (C) 2022 Ing <https://github.com/wjz304>
|
||||||
#
|
#
|
||||||
# This is free software, licensed under the MIT License.
|
# This is free software, licensed under the MIT License.
|
||||||
# See /LICENSE for more information.
|
# See /LICENSE for more information.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
GRUB=${1:-"grub-2.06"}
|
GRUB=${1:-"grub-2.06"}
|
||||||
BIOS=${2:-"i386-pc i386-efi x86_64-efi"}
|
BIOS=${2:-"i386-pc i386-efi x86_64-efi"}
|
||||||
|
|
||||||
@ -14,8 +13,7 @@ curl -#kLO https://ftp.gnu.org/gnu/grub/${GRUB}.tar.gz
|
|||||||
tar -zxvf ${GRUB}.tar.gz
|
tar -zxvf ${GRUB}.tar.gz
|
||||||
|
|
||||||
pushd ${GRUB}
|
pushd ${GRUB}
|
||||||
for B in ${BIOS}
|
for B in ${BIOS}; do
|
||||||
do
|
|
||||||
b=${B}
|
b=${B}
|
||||||
b=(${b//-/ })
|
b=(${b//-/ })
|
||||||
echo "Make ${b[@]} ..."
|
echo "Make ${b[@]} ..."
|
||||||
@ -29,13 +27,12 @@ do
|
|||||||
done
|
done
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
|
||||||
rm -f grub.img
|
rm -f grub.img
|
||||||
dd if=/dev/zero of=grub.img bs=1M seek=1024 count=0
|
dd if=/dev/zero of=grub.img bs=1M seek=1024 count=0
|
||||||
echo -e "n\np\n1\n\n+50M\nn\np\n2\n\n+50M\nn\np\n3\n\n\na\n1\nw\nq\n" | fdisk grub.img
|
echo -e "n\np\n1\n\n+50M\nn\np\n2\n\n+50M\nn\np\n3\n\n\na\n1\nw\nq\n" | fdisk grub.img
|
||||||
fdisk -l grub.img
|
fdisk -l grub.img
|
||||||
|
|
||||||
LOOPX=`sudo losetup -f`
|
LOOPX=$(sudo losetup -f)
|
||||||
sudo losetup -P ${LOOPX} grub.img
|
sudo losetup -P ${LOOPX} grub.img
|
||||||
sudo mkdosfs -F32 -n ARPL1 ${LOOPX}p1
|
sudo mkdosfs -F32 -n ARPL1 ${LOOPX}p1
|
||||||
sudo mkfs.ext2 -F -L ARPL2 ${LOOPX}p2
|
sudo mkfs.ext2 -F -L ARPL2 ${LOOPX}p2
|
||||||
@ -47,19 +44,18 @@ sudo mount ${LOOPX}p1 ARPL1
|
|||||||
|
|
||||||
sudo mkdir -p ARPL1/EFI
|
sudo mkdir -p ARPL1/EFI
|
||||||
sudo mkdir -p ARPL1/boot/grub
|
sudo mkdir -p ARPL1/boot/grub
|
||||||
cat > device.map <<EOF
|
cat >device.map <<EOF
|
||||||
(hd0) ${LOOPX}
|
(hd0) ${LOOPX}
|
||||||
EOF
|
EOF
|
||||||
sudo mv device.map ARPL1/boot/grub/device.map
|
sudo mv device.map ARPL1/boot/grub/device.map
|
||||||
|
|
||||||
for B in ${BIOS}
|
for B in ${BIOS}; do
|
||||||
do
|
|
||||||
args=""
|
args=""
|
||||||
args+=" ${LOOPX} --target=${B} --no-floppy --recheck --grub-mkdevicemap=ARPL1/boot/grub/device.map --boot-directory=ARPL1/boot"
|
args+=" ${LOOPX} --target=${B} --no-floppy --recheck --grub-mkdevicemap=ARPL1/boot/grub/device.map --boot-directory=ARPL1/boot"
|
||||||
if [[ "${B}" == *"efi" ]]; then
|
if [[ "${B}" == *"efi" ]]; then
|
||||||
args+=" --efi-directory=ARPL1 --removable --no-nvram"
|
args+=" --efi-directory=ARPL1 --removable --no-nvram"
|
||||||
else
|
else
|
||||||
args+=" --root-directory=ARPL1"
|
args+=" --root-directory=ARPL1"
|
||||||
fi
|
fi
|
||||||
sudo ${GRUB}/${B}/grub-install ${args}
|
sudo ${GRUB}/${B}/grub-install ${args}
|
||||||
done
|
done
|
||||||
|
@ -9,7 +9,10 @@ if loaderIsConfigured; then
|
|||||||
if [ -f "${ORI_RDGZ_FILE}" ]; then
|
if [ -f "${ORI_RDGZ_FILE}" ]; then
|
||||||
rm -rf "${RAMDISK_PATH}"
|
rm -rf "${RAMDISK_PATH}"
|
||||||
mkdir -p "${RAMDISK_PATH}"
|
mkdir -p "${RAMDISK_PATH}"
|
||||||
(cd "${RAMDISK_PATH}"; xz -dc <"${ORI_RDGZ_FILE}" | cpio -idm) >/dev/null 2>&1
|
(
|
||||||
|
cd "${RAMDISK_PATH}"
|
||||||
|
xz -dc <"${ORI_RDGZ_FILE}" | cpio -idm
|
||||||
|
) >/dev/null 2>&1
|
||||||
. "${RAMDISK_PATH}/etc/VERSION"
|
. "${RAMDISK_PATH}/etc/VERSION"
|
||||||
[ -n "$(readConfigKey "build" "${USER_CONFIG_FILE}")" ] && deleteConfigKey "build" "${USER_CONFIG_FILE}"
|
[ -n "$(readConfigKey "build" "${USER_CONFIG_FILE}")" ] && deleteConfigKey "build" "${USER_CONFIG_FILE}"
|
||||||
[ -n "$(readConfigKey "smallfixnumber" "${USER_CONFIG_FILE}")" ] && deleteConfigKey "smallfixnumber" "${USER_CONFIG_FILE}"
|
[ -n "$(readConfigKey "smallfixnumber" "${USER_CONFIG_FILE}")" ] && deleteConfigKey "smallfixnumber" "${USER_CONFIG_FILE}"
|
||||||
@ -21,4 +24,4 @@ if loaderIsConfigured; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user