diff --git a/DMPATCH/dmpatch.c b/DMPATCH/dmpatch.c index e4ed6f9a..f91648f1 100644 --- a/DMPATCH/dmpatch.c +++ b/DMPATCH/dmpatch.c @@ -56,6 +56,8 @@ typedef struct ko_param unsigned long kv_minor; unsigned long blkdev_get_addr; unsigned long blkdev_put_addr; + unsigned long bdev_open_addr; + unsigned long kv_subminor; unsigned long padding[1]; }ko_param; @@ -157,6 +159,26 @@ static unsigned int g_claim_ptr = 0; static unsigned char *g_get_patch[MAX_PATCH] = { NULL }; static unsigned char *g_put_patch[MAX_PATCH] = { NULL }; +static int notrace dmpatch_kv_above(unsigned long Major, unsigned long Minor, unsigned long SubMinor) +{ + if (g_ko_param.kv_major != Major) + { + return (g_ko_param.kv_major > Major) ? 1 : 0; + } + + if (g_ko_param.kv_minor != Minor) + { + return (g_ko_param.kv_minor > Minor) ? 1 : 0; + } + + if (g_ko_param.kv_subminor != SubMinor) + { + return (g_ko_param.kv_subminor > SubMinor) ? 1 : 0; + } + + return 1; +} + static void notrace dmpatch_restore_code(int bytes, unsigned char *opCode, unsigned int code) { unsigned long align; @@ -246,7 +268,7 @@ static int notrace dmpatch_replace_code return 0; } -static unsigned long dmpatch_find_call_offset(unsigned long addr, unsigned long size, unsigned long func) +static unsigned long notrace dmpatch_find_call_offset(unsigned long addr, unsigned long size, unsigned long func) { unsigned long i = 0; unsigned long dest; @@ -275,18 +297,15 @@ static unsigned long dmpatch_find_call_offset(unsigned long addr, unsigned long return 0; } -static unsigned int dmpatch_patch_claim_ptr(void) +static unsigned int notrace dmpatch_patch_claim_ptr(void) { unsigned long i = 0; unsigned long t = 0; - unsigned long offset1; - unsigned long offset2; - unsigned long align; + unsigned long offset1 = 0; + unsigned long offset2 = 0; + unsigned long align = 0; unsigned char *opCode = NULL; - vdebug("Get addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr); - vdebug("Put addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr); - opCode = (unsigned char *)g_ko_param.sym_get_addr; for (i = 0; i < 4; i++) { @@ -297,13 +316,30 @@ static unsigned int dmpatch_patch_claim_ptr(void) opCode[i + 12], opCode[i + 13], opCode[i + 14], opCode[i + 15]); } - offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr); - offset2 = dmpatch_find_call_offset(g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr); - if (offset1 == 0 || offset2 == 0) + if (dmpatch_kv_above(6, 7, 0)) /* >= 6.7 kernel */ { - vdebug("call blkdev_get or blkdev_put Not found, %lu %lu\n", offset1, offset2); - return 1; + vdebug("Get addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_open_addr); + offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_open_addr); + if (offset1 == 0) + { + vdebug("call bdev_open_addr Not found\n"); + return 1; + } } + else + { + vdebug("Get addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr); + vdebug("Put addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr); + + offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr); + offset2 = dmpatch_find_call_offset(g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr); + if (offset1 == 0 || offset2 == 0) + { + vdebug("call blkdev_get or blkdev_put Not found, %lu %lu\n", offset1, offset2); + return 1; + } + } + vdebug("call addr1:0x%lx call addr2:0x%lx\n", g_ko_param.sym_get_addr + offset1, g_ko_param.sym_put_addr + offset2); @@ -327,36 +363,41 @@ static unsigned int dmpatch_patch_claim_ptr(void) return 1; } - opCode = (unsigned char *)g_ko_param.sym_put_addr; - for (i = offset2 - 1, t = 0; (i > 0) && (t < 24); i--, t++) - { - /* rsi */ - if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc6) - { - if (*(unsigned int *)(opCode + i + 3) == g_claim_ptr) - { - vdebug("claim_ptr found at put addr 0x%lx\n", g_ko_param.sym_put_addr + i + 3); - g_put_patch[0] = opCode + i + 3; - break; - } - } - } - - if (g_put_patch[0] == 0) - { - vdebug("Claim_ptr not found in put\n"); - return 1; - } - + align = (unsigned long)g_get_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize; set_mem_rw(align, 1); *(unsigned int *)(g_get_patch[0]) = 0; set_mem_ro(align, 1); - align = (unsigned long)g_put_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize; - set_mem_rw(align, 1); - *(unsigned int *)(g_put_patch[0]) = 0; - set_mem_ro(align, 1); + + if (offset2 > 0) + { + opCode = (unsigned char *)g_ko_param.sym_put_addr; + for (i = offset2 - 1, t = 0; (i > 0) && (t < 24); i--, t++) + { + /* rsi */ + if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc6) + { + if (*(unsigned int *)(opCode + i + 3) == g_claim_ptr) + { + vdebug("claim_ptr found at put addr 0x%lx\n", g_ko_param.sym_put_addr + i + 3); + g_put_patch[0] = opCode + i + 3; + break; + } + } + } + + if (g_put_patch[0] == 0) + { + vdebug("Claim_ptr not found in put\n"); + return 1; + } + + align = (unsigned long)g_put_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize; + set_mem_rw(align, 1); + *(unsigned int *)(g_put_patch[0]) = 0; + set_mem_ro(align, 1); + } return 0; } @@ -382,7 +423,7 @@ static __always_inline void dmpatch_wrmsr(unsigned int msr, u32 low, u32 high) : : "c" (msr), "a"(low), "d" (high) : "memory"); } -static u64 dmpatch_ibt_save(void) +static u64 notrace dmpatch_ibt_save(void) { u64 msr = 0; u64 val = 0; @@ -394,7 +435,7 @@ static u64 dmpatch_ibt_save(void) return msr; } -static void dmpatch_ibt_restore(u64 save) +static void notrace dmpatch_ibt_restore(u64 save) { u64 msr; @@ -406,8 +447,8 @@ static void dmpatch_ibt_restore(u64 save) dmpatch_wrmsr(MSR_IA32_S_CET, (u32)(msr & 0xffffffffULL), (u32)(msr >> 32)); } #else -static u64 dmpatch_ibt_save(void) { return 0; } -static void dmpatch_ibt_restore(u64 save) { (void)save; } +static u64 notrace dmpatch_ibt_save(void) { return 0; } +static void notrace dmpatch_ibt_restore(u64 save) { (void)save; } #endif static int notrace dmpatch_init(void) @@ -423,8 +464,8 @@ static int notrace dmpatch_init(void) kprintf = (printk_pf)(g_ko_param.printk_addr); - vdebug("dmpatch_init start pagesize=%lu kernel=%lu.%lu ...\n", - g_ko_param.pgsize, g_ko_param.kv_major, g_ko_param.kv_minor); + vdebug("dmpatch_init start pagesize=%lu kernel=%lu.%lu.%lu ...\n", + g_ko_param.pgsize, g_ko_param.kv_major, g_ko_param.kv_minor, g_ko_param.kv_subminor); if (g_ko_param.struct_size != sizeof(ko_param)) { @@ -443,7 +484,7 @@ static int notrace dmpatch_init(void) reg_kprobe = (kprobe_reg_pf)g_ko_param.reg_kprobe_addr; unreg_kprobe = (kprobe_unreg_pf)g_ko_param.unreg_kprobe_addr; - if (g_ko_param.kv_major > 6 || (g_ko_param.kv_major == 6 && g_ko_param.kv_minor >= 5)) + if (dmpatch_kv_above(6, 5, 0)) /* >= kernel 6.5 */ { vdebug("new interface patch dm_get_table_device...\n"); r = dmpatch_patch_claim_ptr(); @@ -466,25 +507,25 @@ static int notrace dmpatch_init(void) if (r) { - rc = -EINVAL; + rc = -EFAULT; goto out; } vdebug("patch dm_get_table_device success\n"); - if (g_ko_param.kv_major >= 6 && g_ko_param.kv_minor >= 5) + if (dmpatch_kv_above(6, 5, 0)) { r = 0; } else { r = dmpatch_replace_code(1, g_ko_param.sym_put_addr, g_ko_param.sym_put_size, 1, "dm_put_table_device", g_put_patch); + if (r) + { + rc = -EFAULT; + goto out; + } + vdebug("patch dm_put_table_device success\n"); } - if (r) - { - rc = -EINVAL; - goto out; - } - vdebug("patch dm_put_table_device success\n"); vdebug("#####################################\n"); vdebug("######## dm patch success ###########\n"); @@ -513,7 +554,10 @@ static void notrace dmpatch_exit(void) if (g_claim_ptr) { dmpatch_restore_code(4, g_get_patch[0], g_claim_ptr); - dmpatch_restore_code(4, g_put_patch[0], g_claim_ptr); + if (g_put_patch[0]) + { + dmpatch_restore_code(4, g_put_patch[0], g_claim_ptr); + } } else { diff --git a/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh index b77934cb..99badaf1 100644 --- a/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh +++ b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh @@ -352,6 +352,10 @@ ventoy_dm_patch() { vtlog "get blkdev_put address $vtLine" blkdev_put_addr=$(echo $vtLine | $AWK '{print $1}') + vtLine=$($VTOY_PATH/tool/vtoyksym bdev_open_by_dev $VTOY_PATH/kallsyms) + vtlog "get bdev_open_by_dev address $vtLine" + bdev_open_addr=$(echo $vtLine | $AWK '{print $1}') + if $GREP -m1 -q 'close_table_device.isra' $VTOY_PATH/kallsyms; then vtLine=$($VTOY_PATH/tool/vtoyksym close_table_device.isra $VTOY_PATH/kallsyms) @@ -394,7 +398,7 @@ ventoy_dm_patch() { vtlog put_addr=$put_addr put_size=$put_size vtlog blkdev_get_addr=$blkdev_get_addr blkdev_put_addr=$blkdev_put_addr vtlog kprobe_reg_addr=$kprobe_reg_addr kprobe_unreg_addr=$kprobe_unreg_addr - vtlog ro_addr=$ro_addr rw_addr=$rw_addr printk_addr=$printk_addr + vtlog ro_addr=$ro_addr rw_addr=$rw_addr printk_addr=$printk_addr bdev_open_addr=$bdev_open_addr if [ "$get_addr" = "0" -o "$put_addr" = "0" ]; then vtlog "Invalid symbol address" @@ -409,6 +413,7 @@ ventoy_dm_patch() { vtKv=$($BUSYBOX_PATH/uname -r) vtKVMajor=$(echo $vtKv | $AWK -F. '{print $1}') vtKVMinor=$(echo $vtKv | $AWK -F. '{print $2}') + vtKVSubMinor=$(echo $vtKv | $AWK -F. '{print $3}') if [ ! -d /lib/modules/$vtKv ]; then vtlog "No modules directory found" @@ -455,7 +460,7 @@ ventoy_dm_patch() { #step2: fill parameters vtPgsize=$($VTOY_PATH/tool/vtoyksym -p) - vtPrams="$VTOY_PATH/tool/$vtKoName $vtPgsize 0x$printk_addr 0x$ro_addr 0x$rw_addr $get_addr $get_size $put_addr $put_size 0x$kprobe_reg_addr 0x$kprobe_unreg_addr $vtKVMajor $vtIBT $vtKVMinor $blkdev_get_addr $blkdev_put_addr $vtDebug" + vtPrams="$VTOY_PATH/tool/$vtKoName $vtPgsize 0x$printk_addr 0x$ro_addr 0x$rw_addr $get_addr $get_size $put_addr $put_size 0x$kprobe_reg_addr 0x$kprobe_unreg_addr $vtKVMajor $vtIBT $vtKVMinor $blkdev_get_addr $blkdev_put_addr $vtKVSubMinor $bdev_open_addr $vtDebug" vtlog "$VTOY_PATH/tool/vtoykmod -f $vtPrams" diff --git a/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko b/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko index 0be14b37..a224f561 100644 Binary files a/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko and b/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko differ diff --git a/IMG/cpio_x86/ventoy/tool/dm_patch_ibt_64.ko b/IMG/cpio_x86/ventoy/tool/dm_patch_ibt_64.ko index 714db343..7b90e4f3 100644 Binary files a/IMG/cpio_x86/ventoy/tool/dm_patch_ibt_64.ko and b/IMG/cpio_x86/ventoy/tool/dm_patch_ibt_64.ko differ diff --git a/VtoyTool/vtoykmod.c b/VtoyTool/vtoykmod.c index 8560fbc9..06c20608 100644 --- a/VtoyTool/vtoykmod.c +++ b/VtoyTool/vtoykmod.c @@ -191,6 +191,8 @@ typedef struct ko_param unsigned long kv_minor; unsigned long blkdev_get_addr; unsigned long blkdev_put_addr; + unsigned long bdev_open_addr; + unsigned long kv_subminor; unsigned long padding[1]; }ko_param; @@ -577,6 +579,8 @@ int vtoykmod_fill_param(char **argv) param->kv_minor = strtoul(argv[13], NULL, 10); param->blkdev_get_addr = strtoul(argv[14], NULL, 16); param->blkdev_put_addr = strtoul(argv[15], NULL, 16); + param->kv_subminor = strtoul(argv[16], NULL, 10); + param->bdev_open_addr = strtoul(argv[17], NULL, 16); debug("pgsize=%lu (%s)\n", param->pgsize, argv[1]); debug("printk_addr=0x%lx (%s)\n", param->printk_addr, argv[2]); @@ -593,6 +597,8 @@ int vtoykmod_fill_param(char **argv) debug("kv_minor=%lu (%s)\n", param->kv_minor, argv[13]); debug("blkdev_get_addr=0x%lx (%s)\n", param->blkdev_get_addr, argv[14]); debug("blkdev_put_addr=0x%lx (%s)\n", param->blkdev_put_addr, argv[15]); + debug("kv_subminor=%lu (%s)\n", param->kv_subminor, argv[16]); + debug("bdev_open_addr=0x%lx (%s)\n", param->bdev_open_addr, argv[17]); break; } diff --git a/VtoyTool/vtoytool/00/vtoytool_32 b/VtoyTool/vtoytool/00/vtoytool_32 index 9bb98d44..8ce94e98 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_32 and b/VtoyTool/vtoytool/00/vtoytool_32 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_64 b/VtoyTool/vtoytool/00/vtoytool_64 index ab123621..3edbed59 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_64 and b/VtoyTool/vtoytool/00/vtoytool_64 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_aa64 b/VtoyTool/vtoytool/00/vtoytool_aa64 index 9c33c882..7229c3a3 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_aa64 and b/VtoyTool/vtoytool/00/vtoytool_aa64 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_m64e b/VtoyTool/vtoytool/00/vtoytool_m64e index a453d78e..db997a15 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_m64e and b/VtoyTool/vtoytool/00/vtoytool_m64e differ