]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
1.0.64 release
authorlongpanda <admin@ventoy.net>
Sat, 8 Jan 2022 15:07:04 +0000 (23:07 +0800)
committerlongpanda <admin@ventoy.net>
Sat, 8 Jan 2022 15:07:04 +0000 (23:07 +0800)
38 files changed:
BUSYBOX/chmod/build.sh
BUSYBOX/chmod/vtchmod.c
BUSYBOX/chmod/vtchmod32
BUSYBOX/chmod/vtchmod64
BUSYBOX/chmod/vtchmod64_musl
BUSYBOX/chmod/vtchmodaa64
BUSYBOX/chmod/vtchmodm64e
DMPATCH/Makefile [new file with mode: 0644]
DMPATCH/dmpatch.c [new file with mode: 0644]
DMPATCH/readme.txt [new file with mode: 0644]
EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.c
EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c
EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h
IMG/cpio/sbin/init
IMG/cpio/ventoy/hook/ventoy-hook-lib.sh
IMG/cpio_arm64/ventoy/busybox/vtchmodaa64
IMG/cpio_mips64/ventoy/busybox/vtchmodm64e
IMG/cpio_x86/ventoy/busybox/vtchmod32
IMG/cpio_x86/ventoy/busybox/vtchmod64
IMG/cpio_x86/ventoy/busybox/vtchmod64_musl
IMG/cpio_x86/ventoy/tool/dm_patch_64.ko [new file with mode: 0644]
INSTALL/grub/grub.cfg
Plugson/src/Web/ventoy_http.c
Plugson/src/Web/ventoy_http.h
Plugson/vs/VentoyPlugson/Release/VentoyPlugson.exe
Plugson/www/buildtime
Plugson/www/index.html
Plugson/www/plugson_control.html
README.md
VtoyTool/vtoykmod.c [new file with mode: 0644]
VtoyTool/vtoyksym.c [new file with mode: 0644]
VtoyTool/vtoytool.c
VtoyTool/vtoytool/00/vtoytool_32
VtoyTool/vtoytool/00/vtoytool_64
VtoyTool/vtoytool/00/vtoytool_aa64
VtoyTool/vtoytool/00/vtoytool_m64e

index 5db2ae74db5007ceb2af0a2f88c5ccf70e4af205..e72bc10a5790f514e0ce2a3a6376e0933a395157 100644 (file)
@@ -1,9 +1,11 @@
 #!/bin/sh
 
-DSTDIR=../../IMG/cpio/ventoy/busybox
+DSTDIR1=../../IMG/cpio_x86/ventoy/busybox
+DSTDIR2=../../IMG/cpio_arm64/ventoy/busybox
+DSTDIR3=../../IMG/cpio_mips64/ventoy/busybox
 
 rm -f vtchmod32 vtchmod64 vtchmod64_musl vtchmodaa64
-rm -f $DSTDIR/vtchmod32 $DSTDIR/vtchmod64 $DSTDIR/vtchmodaa64 $DSTDIR/vtchmodm64e
+rm -f $DSTDIR1/vtchmod32 $DSTDIR1/vtchmod64 $DSTDIR2/vtchmodaa64 $DSTDIR3/vtchmodm64e
 
 /opt/diet32/bin/diet  gcc  -Os -m32  vtchmod.c -o  vtchmod32
 /opt/diet64/bin/diet  gcc  -Os       vtchmod.c -o  vtchmod64
@@ -23,9 +25,9 @@ chmod 777 vtchmodaa64
 chmod 777 vtchmod64_musl
 chmod 777 vtchmodm64e
 
-cp -a vtchmod32 $DSTDIR/
-cp -a vtchmod64 $DSTDIR/
-cp -a vtchmodaa64 $DSTDIR/
-cp -a vtchmod64_musl $DSTDIR/
-cp -a vtchmodm64e $DSTDIR/
+cp -a vtchmod32 $DSTDIR1/
+cp -a vtchmod64 $DSTDIR1/
+cp -a vtchmod64_musl $DSTDIR1/
+cp -a vtchmodaa64 $DSTDIR2/
+cp -a vtchmodm64e $DSTDIR3/
 
index 5a9d833f58fe7ecb1a3d402f987e83665dbb94ea..ad10d0e8291cde9ac750aa21522ad128d7440ec0 100644 (file)
@@ -1,5 +1,8 @@
+#include <stdio.h>
+#include <string.h>
 #include <sys/types.h>  
 #include <sys/stat.h>
+#include <sys/utsname.h>
 
 int main(int argc, char **argv)
 {
@@ -7,7 +10,25 @@ int main(int argc, char **argv)
     {
         return 1;
     }
-    
+
+    if (argv[1][0] == '-' && argv[1][1] == '6')
+    {
+        struct utsname buf;
+        if (0 == uname(&buf))
+        {
+            if (strstr(buf.machine, "amd64"))
+            {
+                return 0;
+            }
+            
+            if (strstr(buf.machine, "x86_64"))
+            {
+                return 0;
+            }
+        }
+        return 1;
+    }
+
     return chmod(argv[1], 0777);
 }
 
index 4b66db3ca7cf7876f82e3849c523ac8d768f1325..2647afb687d06c065e062763cadf2b4498f7cadb 100644 (file)
Binary files a/BUSYBOX/chmod/vtchmod32 and b/BUSYBOX/chmod/vtchmod32 differ
index 9c799581559cf7b18771e594822e632584618ebf..4d27c578cb82b28e448d9d89403dbb65d9ff566f 100644 (file)
Binary files a/BUSYBOX/chmod/vtchmod64 and b/BUSYBOX/chmod/vtchmod64 differ
index d4cd5c6bfad949dab51e7b1c4ce7bdab11f24686..01c80f214e2cdbe834ff2cc9bd07bee99abd12ed 100644 (file)
Binary files a/BUSYBOX/chmod/vtchmod64_musl and b/BUSYBOX/chmod/vtchmod64_musl differ
index 593c021f65ee5415f644e0ae1acf04a6e575b315..6c3811a16bb0c9144d35bef7991d8719846e1547 100644 (file)
Binary files a/BUSYBOX/chmod/vtchmodaa64 and b/BUSYBOX/chmod/vtchmodaa64 differ
index 47e84be6fe0e055052c9691988f17af299fc230e..dc623d5259e4d35baf38735c4aab5e80a89309c7 100644 (file)
Binary files a/BUSYBOX/chmod/vtchmodm64e and b/BUSYBOX/chmod/vtchmodm64e differ
diff --git a/DMPATCH/Makefile b/DMPATCH/Makefile
new file mode 100644 (file)
index 0000000..9a4243f
--- /dev/null
@@ -0,0 +1,7 @@
+
+obj-m += dm_patch.o
+
+EXTRA_CFLAGS := -Wall
+
+dm_patch-objs := dmpatch.o
+
diff --git a/DMPATCH/dmpatch.c b/DMPATCH/dmpatch.c
new file mode 100644 (file)
index 0000000..1106d79
--- /dev/null
@@ -0,0 +1,179 @@
+/******************************************************************************
+ * dmpatch.c  ---- patch for device-mapper
+ *
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>
+ *
+ * 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 the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/mutex.h>
+#include <linux/mempool.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+
+#define MAX_PATCH   4
+
+#define magic_sig 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF
+
+typedef int (*kprobe_reg_pf)(void *);
+typedef void (*kprobe_unreg_pf)(void *);
+typedef int (*printk_pf)(const char *fmt, ...);
+typedef int (*set_memory_attr_pf)(unsigned long addr, int numpages);
+
+#pragma pack(1)
+typedef struct ko_param
+{
+    unsigned char magic[16];
+    unsigned long struct_size;
+    unsigned long pgsize;
+    unsigned long printk_addr;
+    unsigned long ro_addr;
+    unsigned long rw_addr;
+    unsigned long reg_kprobe_addr;
+    unsigned long unreg_kprobe_addr;
+    unsigned long sym_get_addr;
+    unsigned long sym_get_size;
+    unsigned long sym_put_addr;
+    unsigned long sym_put_size;
+    unsigned long padding[3];
+}ko_param;
+
+#pragma pack()
+
+static printk_pf kprintf = NULL;
+static set_memory_attr_pf set_mem_ro = NULL;
+static set_memory_attr_pf set_mem_rw = NULL;
+static kprobe_reg_pf reg_kprobe = NULL;
+static kprobe_unreg_pf unreg_kprobe = NULL;
+
+static volatile ko_param g_ko_param = 
+{
+    { magic_sig },
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+#define CODE_MATCH(code, i) \
+    (code[i] == 0x40 && code[i + 1] == 0x80 && code[i + 2] == 0xce && code[i + 3] == 0x80)
+
+#define vdebug(fmt, args...) if(kprintf) kprintf(KERN_ERR fmt, ##args)
+
+static int notrace dmpatch_replace_code(unsigned long addr, unsigned long size, int expect, const char *desc)
+{
+    int i = 0;
+    int cnt = 0;
+    unsigned long align;
+    unsigned char *patch[MAX_PATCH];
+    unsigned char *opCode = (unsigned char *)addr;
+
+    vdebug("patch for %s 0x%lx %d\n", desc, addr, (int)size);
+
+    for (i = 0; i < (int)size - 4; i++)
+    {
+        if (CODE_MATCH(opCode, i) && cnt < MAX_PATCH)
+        {
+            patch[cnt] = opCode + i + 3;
+            cnt++;
+        }
+    }
+
+    if (cnt != expect || cnt >= MAX_PATCH)
+    {
+        vdebug("patch error: cnt=%d expect=%d\n", cnt, expect);
+        return 1;
+    }
+
+
+    for (i = 0; i < cnt; i++)
+    {
+        opCode = patch[i];
+        align = (unsigned long)opCode / g_ko_param.pgsize * g_ko_param.pgsize;
+
+        set_mem_rw(align, 1);
+        *opCode = 0;
+        set_mem_ro(align, 1);
+    }
+
+    return 0;
+}
+
+static int notrace dmpatch_init(void)
+{
+    int r = 0;
+    int rc = 0;
+
+    kprintf = (printk_pf)(g_ko_param.printk_addr); 
+
+    vdebug("dmpatch_init start pagesize=%lu ...\n", g_ko_param.pgsize);
+    
+    if (g_ko_param.struct_size != sizeof(ko_param))
+    {
+        vdebug("Invalid struct size %d %d\n", (int)g_ko_param.struct_size, (int)sizeof(ko_param));
+        return -EINVAL;
+    }
+    
+    if (g_ko_param.sym_get_addr == 0 || g_ko_param.sym_put_addr == 0 || 
+        g_ko_param.ro_addr == 0 || g_ko_param.rw_addr == 0)
+    {
+        return -EINVAL;
+    }
+
+    set_mem_ro = (set_memory_attr_pf)(g_ko_param.ro_addr);
+    set_mem_rw = (set_memory_attr_pf)(g_ko_param.rw_addr);
+    reg_kprobe = (kprobe_reg_pf)g_ko_param.reg_kprobe_addr;
+    unreg_kprobe = (kprobe_unreg_pf)g_ko_param.unreg_kprobe_addr;
+
+    r = dmpatch_replace_code(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 2, "dm_get_table_device");
+    if (r)
+    {
+        rc = -EINVAL;
+        goto out;
+    }
+    vdebug("patch dm_get_table_device success\n");
+
+    r = dmpatch_replace_code(g_ko_param.sym_put_addr, g_ko_param.sym_put_size, 1, "dm_put_table_device");
+    if (r)
+    {
+        rc = -EINVAL;
+        goto out;
+    }
+    vdebug("patch dm_put_table_device success\n");
+
+    vdebug("#####################################\n");
+    vdebug("######## dm patch success ###########\n");
+    vdebug("#####################################\n");
+
+out:
+
+       return rc;
+}
+
+static void notrace dmpatch_exit(void)
+{
+
+}
+
+module_init(dmpatch_init);
+module_exit(dmpatch_exit);
+
+
+MODULE_DESCRIPTION("dmpatch driver");
+MODULE_AUTHOR("longpanda <admin@ventoy.net>");
+MODULE_LICENSE("GPL");
+
diff --git a/DMPATCH/readme.txt b/DMPATCH/readme.txt
new file mode 100644 (file)
index 0000000..866dc90
--- /dev/null
@@ -0,0 +1,35 @@
+1. install ubuntu 21.10\r
+2. apt-get install build-essential flex ncurse linux-headers-generic linux-source ...... and so on\r
+3. cp /lib/modules/5.13.0-23-generic/build/Module.symvers ./\r
+4. /boot/config-5.13.0-23-generic as .config   make oldconfig\r
+5. make menuconfig \r
+    1. close CONFIG_STACKPROTECTOR\r
+    2. close CONFIG_RETPOLINE\r
+\r
+6. modify ./scripts/mod/modpost.c\r
+    1. skip add_srcversion (just return)\r
+    2. force add_retpoline (#ifdef --> #ifndef)\r
+\r
+7. make modules_prepare LOCALVERSION=-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r
+\r
+8. Append padding at the end of struct module <include/linux/module.h>\r
+struct module {\r
+    enum module_state state;\r
+\r
+       /* Member of list of modules */\r
+       struct list_head list;\r
+\r
+       /* Unique handle for this module */\r
+       char name[MODULE_NAME_LEN];\r
+    \r
+    ....\r
+    \r
+    char padding[1024];\r
+};\r
+\r
+This is because struct module size is different in different kernel versions or with different CONFIG item.\r
+\r
+\r
+9. make modules M=/home/dmpatch\r
+10. strip --strip-debug /home/dmpatch/dm_patch.ko\r
+\r
index f3d8d458e46e0f5d0caf177e11ebfb400f48cfe5..cc978a1bde2f07fc926dbb5e4f4e312aa0772df1 100644 (file)
@@ -249,6 +249,12 @@ EFI_STATUS EFIAPI vdisk_exit_boot_service_wrapper
     IN  UINTN                        MapKey
 )
 {
+    if (g_org_get_variable)
+    {
+        gRT->GetVariable = g_org_get_variable;
+        g_org_get_variable = NULL;
+    }
+
     return g_org_exit_boot_service(ImageHandle, MapKey);
 }
 
index cfcf41059dfd8d6b9b137731a3b7e4ff0c8ef98d..5d9972259e54d7d9448726ef00db294eef074ca0 100644 (file)
@@ -71,6 +71,9 @@ STATIC BOOLEAN g_hook_keyboard = FALSE;
 
 CHAR16 gFirstTryBootFile[256] = {0};
 
+STATIC EFI_GET_VARIABLE g_org_get_variable = NULL;
+STATIC EFI_EXIT_BOOT_SERVICES g_org_exit_boot_service = NULL;
+
 /* Boot filename */
 UINTN gBootFileStartIndex = 1;
 CONST CHAR16 *gEfiBootFileName[] = 
@@ -739,6 +742,77 @@ STATIC EFI_STATUS ventoy_proc_img_replace_name(ventoy_grub_param_file_replace *r
     return EFI_SUCCESS;
 }
 
+EFI_STATUS EFIAPI ventoy_get_variable_wrapper
+(
+    IN     CHAR16                      *VariableName,
+    IN     EFI_GUID                    *VendorGuid,
+    OUT    UINT32                      *Attributes,    OPTIONAL
+    IN OUT UINTN                       *DataSize,
+    OUT    VOID                        *Data           OPTIONAL
+)
+{
+    EFI_STATUS Status = EFI_SUCCESS;
+    
+    Status = g_org_get_variable(VariableName, VendorGuid, Attributes, DataSize, Data);
+    if (StrCmp(VariableName, L"SecureBoot") == 0)
+    {
+        if ((*DataSize == 1) && Data)
+        {
+            *(UINT8 *)Data = 0;
+        }
+    }
+
+    return Status;
+}
+
+EFI_STATUS EFIAPI ventoy_exit_boot_service_wrapper
+(
+    IN  EFI_HANDLE                   ImageHandle,
+    IN  UINTN                        MapKey
+)
+{
+    if (g_org_get_variable)
+    {
+        gRT->GetVariable = g_org_get_variable;
+        g_org_get_variable = NULL;
+    }
+    
+    return g_org_exit_boot_service(ImageHandle, MapKey);
+}
+
+STATIC EFI_STATUS EFIAPI ventoy_disable_secure_boot(IN EFI_HANDLE ImageHandle)
+{
+    UINT8 Value = 0;
+    UINTN DataSize = 1;
+    EFI_STATUS Status = EFI_SUCCESS;
+
+    Status = gRT->GetVariable(L"SecureBoot", &gEfiGlobalVariableGuid, NULL, &DataSize, &Value);
+    if (!EFI_ERROR(Status))
+    {
+        if (DataSize == 1 && Value == 0)
+        {
+            debug("Current secure boot is off, no need to disable");
+            return EFI_SUCCESS;
+        }
+    }
+
+    debug("ventoy_disable_secure_boot");
+
+    /* step1: wrapper security protocol. */
+    /* Do we still need it since we have been loaded ? */
+    
+    
+    /* step2: fake SecureBoot variable */
+    g_org_exit_boot_service = gBS->ExitBootServices;
+    gBS->ExitBootServices = ventoy_exit_boot_service_wrapper;
+    
+    g_org_get_variable = gRT->GetVariable;
+    gRT->GetVariable = ventoy_get_variable_wrapper;
+
+    return EFI_SUCCESS;
+}
+
+
 STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
 {   
     UINT32 i = 0;
@@ -909,6 +983,11 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
         {
             g_hook_keyboard = TRUE;
         }
+        
+        if (g_os_param_reserved[5] == 1 && g_os_param_reserved[2] == ventoy_chain_linux)
+        {
+            ventoy_disable_secure_boot(ImageHandle);
+        }
 
         debug("internal param: secover:%u keyboard:%u", g_fixup_iso9660_secover_enable, g_hook_keyboard);
 
index 892d8c77ed14ef3862cf04fca781ec0525181e17..374efdd76802332ec1d6d76eeea267075707dfc1 100644 (file)
@@ -42,6 +42,7 @@
   DebugLib\r
 \r
 [Guids]\r
+  gEfiGlobalVariableGuid\r
   gShellVariableGuid\r
   gEfiVirtualCdGuid\r
   gEfiFileInfoGuid\r
index 5adcdc65ec99b155834cec12426794fcbc8b1497..b5233ccedcc3b15667d39220c07ccdca232ffce3 100644 (file)
@@ -2748,6 +2748,7 @@ void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param)
 {
     char *pos;
     const char *fs = NULL;
+    const char *val = NULL;
     const char *cdprompt = NULL;
     grub_uint32_t i;
     grub_uint8_t  chksum = 0;
@@ -2794,6 +2795,13 @@ void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param)
         param->vtoy_reserved[3] = 1;
     }
 
+    param->vtoy_reserved[5] = 0;
+    val = ventoy_get_env("VTOY_LINUX_REMOUNT");
+    if (val && val[0] == '1' && val[1] == 0)
+    {
+        param->vtoy_reserved[5] = 1;
+    }
+
     /* calculate checksum */
     for (i = 0; i < sizeof(ventoy_os_param); i++)
     {
index 5cb04d8bccb6e6e8f8bf4832ade979820af595e4..0102ef59b91cc3a005c8d0055cd6cd0e62ebe7d7 100644 (file)
@@ -121,6 +121,7 @@ typedef struct ventoy_os_param
      * vtoy_reserved[2]: vtoy_chain_type     0:Linux    1:Windows  2:wimfile
      * vtoy_reserved[3]: vtoy_iso_format     0:iso9660  1:udf
      * vtoy_reserved[4]: vtoy_windows_cd_prompt
+     * vtoy_reserved[5]: vtoy_linux_remount
      *
      */
     grub_uint8_t   vtoy_reserved[32];    // Internal use by ventoy
index 17be33fb7c6fb33f46b00388bc8c191e36297cde..3fd3cc5ee0b18e256c3dd670d9a18851e18a8a5b 100644 (file)
@@ -48,6 +48,12 @@ else
     fi
 fi
 
+if [ "$VTOY_ARCH" = "i386" ]; then
+    if $BUSYBOX_PATH/vtchmod32 -6; then
+        export VTOY_ARCH=x86_64
+    fi
+fi
+
 echo $VTOY_ARCH > $VTOY_PATH/ventoy_arch
 
 
@@ -81,6 +87,7 @@ export PATH=$BUSYBOX_PATH/:$VTOY_PATH/tool
 
 export VTOY_BREAK_LEVEL=$(hexdump -n 1 -s 449 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param)
 export VTOY_DEBUG_LEVEL=$(hexdump -n 1 -s 450 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param)
+export VTOY_LINUX_REMOUNT=$(hexdump -n 1 -s 454 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param)
 
 #Fixme: busybox shell output redirect seems to have some bug in rhel5
 if uname -a | grep -q el5; then
index 881daef5a626424ece53c134087c9b515dddb601..a22314fc4d30408a791efebfaed96f602412acca 100644 (file)
@@ -30,6 +30,7 @@ SLEEP=$BUSYBOX_PATH/sleep
 HEAD=$BUSYBOX_PATH/head
 VTOY_DM_PATH=/dev/mapper/ventoy
 VTOY_DEBUG_LEVEL=$($BUSYBOX_PATH/hexdump -n 1 -s 450 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param)
+VTOY_LINUX_REMOUNT=$($BUSYBOX_PATH/hexdump -n 1 -s 454 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param)
 
 if [ "$VTOY_DEBUG_LEVEL" = "01" ]; then
     if [ -e /dev/console ]; then
@@ -220,6 +221,125 @@ ventoy_check_dm_module() {
     fi
 }
 
+ventoy_need_dm_patch() {
+    if [ "$VTOY_LINUX_REMOUNT" != "01" ]; then
+        $BUSYBOX_PATH/false; return
+    fi
+
+    if $GREP -q 'device-mapper' /proc/devices; then
+        :
+    else
+        $BUSYBOX_PATH/false; return
+    fi
+    
+    if $GREP -q 'dm_patch' /proc/modules; then
+        $BUSYBOX_PATH/false; return
+    fi
+    
+    vtMajorVer=$($BUSYBOX_PATH/uname -r | $AWK -F. '{print $1}')
+    vtMinorVer=$($BUSYBOX_PATH/uname -r | $AWK -F. '{print $2}')
+
+    if [ $vtMajorVer -lt 3 ]; then
+        $BUSYBOX_PATH/false; return
+    elif [ $vtMajorVer -eq 3 -a $vtMinorVer -lt 10 ]; then
+        $BUSYBOX_PATH/false; return
+    fi
+    
+    
+    $BUSYBOX_PATH/true
+}
+
+ventoy_dm_patch() {
+    vtMType=$($BUSYBOX_PATH/uname -m)
+
+    vtlog "######### ventoy_dm_patch ############"
+
+    if echo $vtMType | $EGREP -i -q "x86.64|amd64"; then
+        vtKoName=dm_patch_64.ko
+    else
+        vtlog "unsupported machine type $vtMType"
+        return
+    fi
+
+    if [ -f $VTOY_PATH/tool/$vtKoName ]; then
+        vtlog "/ventoy/tool/$vtKoName exist OK"
+    else
+        vtlog "/ventoy/tool/$vtKoName NOT exist"
+        return
+    fi
+    
+    $CAT /proc/kallsyms | $BUSYBOX_PATH/sort > $VTOY_PATH/kallsyms
+    
+    vtLine=$($VTOY_PATH/tool/vtoyksym dm_get_table_device $VTOY_PATH/kallsyms)
+    get_addr=$(echo $vtLine | $AWK '{print $1}')
+    get_size=$(echo $vtLine | $AWK '{print $2}')
+
+    vtLine=$($VTOY_PATH/tool/vtoyksym dm_put_table_device $VTOY_PATH/kallsyms)
+    put_addr=$(echo $vtLine | $AWK '{print $1}')
+    put_size=$(echo $vtLine | $AWK '{print $2}')
+    
+    ro_addr=$($GREP ' set_memory_ro$' /proc/kallsyms | $AWK '{print $1}')
+    rw_addr=$($GREP ' set_memory_rw$' /proc/kallsyms | $AWK '{print $1}')
+    kprobe_reg_addr=$($GREP ' register_kprobe$' /proc/kallsyms | $AWK '{print $1}')
+    kprobe_unreg_addr=$($GREP ' unregister_kprobe$' /proc/kallsyms | $AWK '{print $1}')
+    
+    if [ "$VTOY_DEBUG_LEVEL" = "01" ]; then
+        printk_addr=$($GREP ' printk$' /proc/kallsyms | $AWK '{print $1}')
+        vtDebug="-v"
+    else
+        printk_addr=0
+    fi
+    
+    #printk_addr=$($GREP ' printk$' /proc/kallsyms | $AWK '{print $1}')
+    #vtDebug="-v"
+    
+    vtlog get_addr=$get_addr  get_size=$get_size
+    vtlog put_addr=$put_addr  put_size=$put_size
+    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
+
+    if [ "$get_addr" = "0" -o "$put_addr" = "0" ]; then
+        vtlog "Invalid symbol address"
+        return
+    fi
+    if [ "$ro_addr" = "0" -o "$rw_addr" = "0" ]; then
+        vtlog "Invalid symbol address"
+        return
+    fi
+
+
+    vtKv=$($BUSYBOX_PATH/uname -r)
+    vtModPath=$($FIND /lib/modules/$vtKv/kernel/fs/ -name "*.ko*" | $HEAD -n1)
+    vtModName=$($BUSYBOX_PATH/basename $vtModPath)
+    
+    vtlog "template module is $vtModPath $vtModName"
+    
+    if echo $vtModPath | $GREP -q "[.]ko$"; then
+        $BUSYBOX_PATH/cp -a $vtModPath  $VTOY_PATH/$vtModName
+    elif echo $vtModPath | $GREP -q "[.]ko[.]xz$"; then
+        $BUSYBOX_PATH/xzcat $vtModPath > $VTOY_PATH/$vtModName
+    elif echo $vtModPath | $GREP -q "[.]ko[.]gz$"; then
+        $BUSYBOX_PATH/zcat $vtModPath > $VTOY_PATH/$vtModName
+    else
+        vtlog "unsupport module type"
+        return
+    fi
+    
+    #step1: modify vermagic/mod crc/relocation
+    $VTOY_PATH/tool/vtoykmod -u $VTOY_PATH/tool/$vtKoName $VTOY_PATH/$vtModName $vtDebug
+    
+    #step2: fill parameters
+    vtPgsize=$($VTOY_PATH/tool/vtoyksym -p)
+    $VTOY_PATH/tool/vtoykmod -f $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 $vtDebug
+
+    $BUSYBOX_PATH/insmod $VTOY_PATH/tool/$vtKoName
+    
+    if $GREP -q 'dm_patch' /proc/modules; then
+        echo "done" > $VTOY_PATH/dm_patch_done
+    fi
+    
+}
+
 create_ventoy_device_mapper() {
     vtlog "create_ventoy_device_mapper $*"
     
@@ -230,19 +350,36 @@ create_ventoy_device_mapper() {
     fi
     
     vtlog "dmsetup avaliable in system $VT_DM_BIN"
-        
+
     if ventoy_check_dm_module "$1"; then
         vtlog "device-mapper module check success"
     else
         vterr "Error: no dm module avaliable"
     fi
     
-    $VTOY_PATH/tool/vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table        
+    $VTOY_PATH/tool/vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table
+    
+    
+    vtLevel1=$($CAT /proc/sys/kernel/printk | $AWK '{print $1}')
+    vtLevel2=$($CAT /proc/sys/kernel/printk | $AWK '{print $2}')
+    vtLevel3=$($CAT /proc/sys/kernel/printk | $AWK '{print $3}')
+    vtLevel4=$($CAT /proc/sys/kernel/printk | $AWK '{print $4}')
+    if ventoy_need_dm_patch; then
+        ventoy_dm_patch
+        #suppress printk message
+        echo 0 $vtLevel2 0 $vtLevel4 > /proc/sys/kernel/printk
+    fi
+
     if [ -z "$2" ]; then
         $VT_DM_BIN create ventoy $VTOY_PATH/ventoy_dm_table >>$VTLOG 2>&1
     else
         $VT_DM_BIN "$2" create ventoy $VTOY_PATH/ventoy_dm_table >>$VTLOG 2>&1
-    fi    
+    fi
+
+    if ventoy_need_dm_patch; then    
+        #recover printk level
+        echo $vtLevel1 $vtLevel2 $vtLevel3 $vtLevel4 > /proc/sys/kernel/printk
+    fi
 }
 
 create_persistent_device_mapper() {
@@ -262,8 +399,24 @@ create_persistent_device_mapper() {
         vterr "Error: no dm module avaliable"
     fi
     
-    $VTOY_PATH/tool/vtoydm -p -f $VTOY_PATH/ventoy_persistent_map -d $1 > $VTOY_PATH/persistent_dm_table        
+    $VTOY_PATH/tool/vtoydm -p -f $VTOY_PATH/ventoy_persistent_map -d $1 > $VTOY_PATH/persistent_dm_table    
+
+
+    vtLevel1=$($CAT /proc/sys/kernel/printk | $AWK '{print $1}')
+    vtLevel2=$($CAT /proc/sys/kernel/printk | $AWK '{print $2}')
+    vtLevel3=$($CAT /proc/sys/kernel/printk | $AWK '{print $3}')
+    vtLevel4=$($CAT /proc/sys/kernel/printk | $AWK '{print $4}')
+    if [ -f $VTOY_PATH/dm_patch_done ]; then
+        #suppress printk message
+        echo 0 $vtLevel2 0 $vtLevel4 > /proc/sys/kernel/printk
+    fi
+    
     $VT_DM_BIN create vtoy_persistent $VTOY_PATH/persistent_dm_table >>$VTLOG 2>&1
+    
+    if [ -f $VTOY_PATH/dm_patch_done ]; then
+        #recover printk level
+        echo $vtLevel1 $vtLevel2 $vtLevel3 $vtLevel4 > /proc/sys/kernel/printk
+    fi
 }
 
 
@@ -493,6 +646,22 @@ ventoy_create_persistent_link() {
     fi    
 }
 
+ventoy_partname_to_diskname() {
+    if echo $1 | $EGREP -q "nvme.*p[0-9]$|mmc.*p[0-9]$|nbd.*p[0-9]$"; then
+        echo -n "${1:0:-2}"    
+    else
+        echo -n "${1:0:-1}"
+    fi
+}
+
+ventoy_diskname_to_partname() {
+    if echo $1 | $EGREP -q "nvme.*p[0-9]$|mmc.*p[0-9]$|nbd.*p[0-9]$"; then
+        echo -n "${1}p$2"
+    else
+        echo -n "${1}$2"
+    fi
+}
+
 ventoy_udev_disk_common_hook() {    
     if echo $1 | $EGREP -q "nvme.*p[0-9]$|mmc.*p[0-9]$|nbd.*p[0-9]$"; then
         VTDISK="${1:0:-2}"    
@@ -541,6 +710,10 @@ ventoy_udev_disk_common_hook() {
         create_persistent_device_mapper "/dev/$VTDISK"
         ventoy_create_persistent_link
     fi
+    
+    if $GREP -q 'dm_patch' /proc/modules; then
+        $BUSYBOX_PATH/rmmod dm_patch
+    fi
 }
 
 ventoy_create_dev_ventoy_part() {   
@@ -550,6 +723,15 @@ ventoy_create_dev_ventoy_part() {
     if [ -e /vtoy_dm_table ]; then
         vtPartid=1
         
+        vtLevel1=$($CAT /proc/sys/kernel/printk | $AWK '{print $1}')
+        vtLevel2=$($CAT /proc/sys/kernel/printk | $AWK '{print $2}')
+        vtLevel3=$($CAT /proc/sys/kernel/printk | $AWK '{print $3}')
+        vtLevel4=$($CAT /proc/sys/kernel/printk | $AWK '{print $4}')
+        if [ -f $VTOY_PATH/dm_patch_done ]; then
+            #suppress printk message
+            echo 0 $vtLevel2 0 $vtLevel4 > /proc/sys/kernel/printk
+        fi
+        
         $CAT /vtoy_dm_table | while read vtline; do
             echo $vtline > /ventoy/dm_table_part${vtPartid}
             $VTOY_PATH/tool/dmsetup create ventoy${vtPartid} /ventoy/dm_table_part${vtPartid}
@@ -558,7 +740,12 @@ ventoy_create_dev_ventoy_part() {
             $BUSYBOX_PATH/mknod -m 0666 /dev/ventoy${vtPartid} b $blkdev_num
             
             vtPartid=$(expr $vtPartid + 1)
-        done        
+        done   
+
+        if [ -f $VTOY_PATH/dm_patch_done ]; then
+            #recover printk level
+            echo $vtLevel1 $vtLevel2 $vtLevel3 $vtLevel4 > /proc/sys/kernel/printk
+        fi
     fi
 }
 
index 593c021f65ee5415f644e0ae1acf04a6e575b315..6c3811a16bb0c9144d35bef7991d8719846e1547 100644 (file)
Binary files a/IMG/cpio_arm64/ventoy/busybox/vtchmodaa64 and b/IMG/cpio_arm64/ventoy/busybox/vtchmodaa64 differ
index 47e84be6fe0e055052c9691988f17af299fc230e..dc623d5259e4d35baf38735c4aab5e80a89309c7 100644 (file)
Binary files a/IMG/cpio_mips64/ventoy/busybox/vtchmodm64e and b/IMG/cpio_mips64/ventoy/busybox/vtchmodm64e differ
index 4b66db3ca7cf7876f82e3849c523ac8d768f1325..2647afb687d06c065e062763cadf2b4498f7cadb 100644 (file)
Binary files a/IMG/cpio_x86/ventoy/busybox/vtchmod32 and b/IMG/cpio_x86/ventoy/busybox/vtchmod32 differ
index 9c799581559cf7b18771e594822e632584618ebf..4d27c578cb82b28e448d9d89403dbb65d9ff566f 100644 (file)
Binary files a/IMG/cpio_x86/ventoy/busybox/vtchmod64 and b/IMG/cpio_x86/ventoy/busybox/vtchmod64 differ
index d4cd5c6bfad949dab51e7b1c4ce7bdab11f24686..01c80f214e2cdbe834ff2cc9bd07bee99abd12ed 100644 (file)
Binary files a/IMG/cpio_x86/ventoy/busybox/vtchmod64_musl and b/IMG/cpio_x86/ventoy/busybox/vtchmod64_musl differ
diff --git a/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko b/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko
new file mode 100644 (file)
index 0000000..789e359
Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko differ
index c32ef94720f025af1fe625417c00d8b3c0c1657a..d84a9d38f74297d0f72acd00df02112f181b4f51 100644 (file)
@@ -2022,7 +2022,7 @@ function img_unsupport_menuentry {
 #############################################################
 #############################################################
 
-set VENTOY_VERSION="1.0.63"
+set VENTOY_VERSION="1.0.64"
 
 #ACPI not compatible with Window7/8, so disable by default
 set VTOY_PARAM_NO_ACPI=1
index 7f17a4b5bfccb7d7ea7d617d6eff304505164344..96a6fa51589930db652db33ac674371b74659dfe 100644 (file)
@@ -505,6 +505,7 @@ int ventoy_data_cmp_control(data_control *data1, data_control *data2)
         data1->filter_vhd != data2->filter_vhd ||
         data1->filter_vtoy != data2->filter_vtoy ||
         data1->win11_bypass_check != data2->win11_bypass_check ||
+        data1->linux_remount != data2->linux_remount ||
         data1->menu_timeout != data2->menu_timeout)
     {
         return 1;
@@ -549,6 +550,7 @@ int ventoy_data_save_control(data_control *data, const char *title, char *buf, i
     VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_VHD", filter_vhd);
     VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_VTOY", filter_vtoy);
     VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_WIN11_BYPASS_CHECK",  win11_bypass_check);
+    VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_LINUX_REMOUNT",  linux_remount);
     VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_MENU_TIMEOUT",  menu_timeout);
 
     VTOY_JSON_FMT_CTRL_STRN(L2, "VTOY_DEFAULT_KBD_LAYOUT", default_kbd_layout);        
@@ -593,6 +595,7 @@ int ventoy_data_json_control(data_control *ctrl, char *buf, int buflen)
     VTOY_JSON_FMT_SINT("filter_vhd", ctrl->filter_vhd);
     VTOY_JSON_FMT_SINT("filter_vtoy", ctrl->filter_vtoy);
     VTOY_JSON_FMT_SINT("win11_bypass_check",  ctrl->win11_bypass_check);
+    VTOY_JSON_FMT_SINT("linux_remount",  ctrl->linux_remount);
     VTOY_JSON_FMT_SINT("menu_timeout",  ctrl->menu_timeout);
     VTOY_JSON_FMT_STRN("default_kbd_layout",  ctrl->default_kbd_layout);
     VTOY_JSON_FMT_STRN("help_text_language",  ctrl->help_text_language);
@@ -658,6 +661,7 @@ static int ventoy_api_save_control(struct mg_connection *conn, VTOY_JSON *json)
     VTOY_JSON_INT("filter_vhd", ctrl->filter_vhd);
     VTOY_JSON_INT("filter_vtoy", ctrl->filter_vtoy);
     VTOY_JSON_INT("win11_bypass_check", ctrl->win11_bypass_check);
+    VTOY_JSON_INT("linux_remount", ctrl->linux_remount);
     VTOY_JSON_INT("menu_timeout", ctrl->menu_timeout);
 
     VTOY_JSON_STR("default_image", ctrl->default_image);
@@ -3790,6 +3794,10 @@ static int ventoy_parse_control(VTOY_JSON *json, void *p)
             {
                 CONTROL_PARSE_INT(child, data->win11_bypass_check);
             }
+            else if (strcmp(child->pcName, "VTOY_LINUX_REMOUNT") == 0)
+            {
+                CONTROL_PARSE_INT(child, data->linux_remount);
+            }
             else if (strcmp(child->pcName, "VTOY_TREE_VIEW_MENU_STYLE") == 0)
             {
                 CONTROL_PARSE_INT(child, data->treeview_style);
index d5607df1c17795cf929fa694a04f91148fea2104..17b21bf0e9a2fc5ce4a8daae9c2062373c5fb312 100644 (file)
@@ -58,6 +58,7 @@ typedef struct data_control
     int filter_vtoy;
     int win11_bypass_check;
     int menu_timeout;
+    int linux_remount;
     char default_search_root[MAX_PATH];
     char default_image[MAX_PATH];
     char default_kbd_layout[32];
index 79fbbbefa29ebcef28eaa4335b52ab85c3e9af7d..8efd516bf621c5e6703bff95d994bfed8873cdc0 100644 (file)
Binary files a/Plugson/vs/VentoyPlugson/Release/VentoyPlugson.exe and b/Plugson/vs/VentoyPlugson/Release/VentoyPlugson.exe differ
index 483a8bfcdc67600bc1efdae6172efed8784e1402..bbcb4d7cc4a7da8ff66572d386ef253ec9032496 100644 (file)
@@ -1 +1 @@
-20211203 17:44:10
\ No newline at end of file
+20220108 22:41:02
\ No newline at end of file
index ed601cdaf2bd7305dae88b023e37449828dc700d..45731a0c594a9b3594eaeaa06dbf1a6ea86f36ec 100644 (file)
 \r
         <footer class="main-footer">\r
             <div class="pull-right hidden-xs">\r
-                <b id="plugson_build_date">20211203 17:44:10</b>
+                <b id="plugson_build_date">20220108 22:41:02</b>
             </div>\r
             <strong><a href="https://www.ventoy.net" target="_blank">https://www.ventoy.net</a></strong>\r
         </footer>\r
index 6c39190a304f3504e2e499a686023c0558ab5ce9..60c8fc75443d79e43536b3271432f0ab9f65e9ab 100644 (file)
         </div><!-- /.box -->\r
     \r
     \r
+\r
+        <div class="box box-primary box-solid">\r
+          <div class="box-header with-border">\r
+            <h3 class="box-title" style="font-size: 14px;font-weight: bold;">VTOY_LINUX_REMOUNT\r
+              <span id="id_span_desc_cn"> —— Linux 启动后继续访问ISO文件所在分区</span></h3>\r
+            <div class="box-tools pull-right">\r
+              <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>\r
+            </div><!-- /.box-tools -->\r
+          </div><!-- /.box-header -->\r
+          <div class="box-body no-padding">\r
+              <table class="table table-bordered  no-padding">\r
+                  <tr style="font-weight:bold;">\r
+                    <td class="td_ctrl_col" id="td_title_setting">选项设置</td>\r
+                    <td>\r
+                      <label class="radio-inline">\r
+                          <input type="radio" id="id_ctrl_linux_remount_radio0" name="id_ctrl_linux_remount_radio" data-type="0" value="0"/> <span style="font-weight:bold;">0</span>\r
+                      </label>&nbsp;&nbsp;&nbsp;&nbsp;\r
+                      <label class="radio-inline">\r
+                          <input type="radio" id="id_ctrl_linux_remount_radio1" name="id_ctrl_linux_remount_radio" data-type="1" value="1"/> <span style="font-weight:bold;">1</span>\r
+                      </label>\r
+                    </td>\r
+                  </tr>\r
+                  <tr id="tr_title_desc_cn">\r
+                    <td class="td_ctrl_col" id="td_title_desc">选项说明</td>\r
+                    <td>\r
+                      <code style="font-weight: bold;">0</code> Linux启动后不需要继续访问ISO文件所在的分区。<br/>\r
+                      <code style="font-weight: bold;">1</code> Linux启动后需要继续访问ISO文件所在的分区。<br/><br/>\r
+                      该选项只对 Linux 系统镜像有效。<br/>\r
+                      默认情况下,受Linux内核相关功能的限制,对于Linux系统,在启动后无法继续访问ISO文件所在的分区。在mount的时候会提示 device busy。<br/>\r
+                      如果这里选择 1,则 Ventoy 会尝试通过一些特殊的手段绕过内核的这个限制,但是这个功能是实验性质的,没有经过大规模和长时间的验证。                      \r
+                    </td>\r
+                  </tr>\r
+                  <tr id="tr_title_desc_en">\r
+                    <td class="td_ctrl_col" id="td_title_desc">Option Description</td>\r
+                    <td>\r
+                      <code style="font-weight: bold;">0</code> I don't need to access the image partition after boot.<br/>\r
+                      <code style="font-weight: bold;">1</code> I need to access the image partition after boot. <br/><br/>\r
+                      This option is only avaliable for Linux distro image files. <br/>\r
+\r
+                      By default, the image partition where the ISO files locate can not be accessed after boot. When you try to mount it you will get device busy error.\r
+                      This is due to linux kernel restriction (device-mapper module).<br/>\r
+                      If you select 1 here, Ventoy will try to bypass the restriction with some special mechanism.<br/>\r
+                      But it should be noted that, this is an experimental feature and is not fully tested.\r
+                      \r
+                    </td>\r
+                  </tr>\r
+              </table>\r
+          </div><!-- /.box-body -->\r
+        </div><!-- /.box -->\r
+\r
+\r
     \r
     \r
         <div class="box box-primary box-solid">\r
     var level;\r
 \r
     data.win11_bypass_check = parseInt($('input:radio[name=id_ctrl_bypass_win11_radio]:checked').val());\r
+    data.linux_remount = parseInt($('input:radio[name=id_ctrl_linux_remount_radio]:checked').val());\r
     data.default_search_root = $('input:text[id=id_ctrl_text_search_root]').val();\r
     data.menu_timeout = parseInt($('input:text[id=id_ctrl_text_timeout]').val());\r
     data.default_image = $('input:text[id=id_ctrl_text_default_img]').val();\r
   function VtoyFillCurrentPageItem(data) {\r
     //VTOY_WIN11_BYPASS_CHECK\r
     $('input:radio[name=id_ctrl_bypass_win11_radio]')[data.win11_bypass_check].checked = true;\r
+    $('input:radio[name=id_ctrl_linux_remount_radio]')[data.linux_remount].checked = true;\r
 \r
     //VTOY_DEFAULT_SEARCH_ROOT\r
     $('input:text[id=id_ctrl_text_search_root]').val(data.default_search_root);\r
       method : 'save_control',\r
       index: current_tab_index,\r
       win11_bypass_check: data.win11_bypass_check,\r
+      linux_remount:data.linux_remount,\r
       default_search_root: data.default_search_root,\r
       menu_timeout: data.menu_timeout,\r
       default_image: data.default_image,\r
index 6d30a1cddc469fdbfec9f665b6a05ca1a575c120..863da1d03148decfc2921c73f6ef06a4626a7b93 100644 (file)
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ You can copy many image files at a time and ventoy will give you a boot menu to
 x86 Legacy BIOS, IA32 UEFI, x86_64 UEFI, ARM64 UEFI and MIPS64EL UEFI are supported in the same way.<br/>
 Both MBR and GPT partition style are supported in the same way.<br/>
 Most type of OS supported(Windows/WinPE/Linux/Unix/ChromeOS/Vmware/Xen...) <br/>
-  770+ ISO files are tested (<a href="https://www.ventoy.net/en/isolist.html">List</a>). 90%+ distros in <a href="https://distrowatch.com/">distrowatch.com</a> supported (<a href="https://www.ventoy.net/en/distrowatch.html">Details</a>). <br/>
+  780+ ISO files are tested (<a href="https://www.ventoy.net/en/isolist.html">List</a>). 90%+ distros in <a href="https://distrowatch.com/">distrowatch.com</a> supported (<a href="https://www.ventoy.net/en/distrowatch.html">Details</a>). <br/>
 <br/>Official Website: <a href=https://www.ventoy.net>https://www.ventoy.net</a>
 </h4>
 
@@ -58,7 +58,7 @@ A GUI Ventoy plugin configurator. [VentoyPlugson](https://www.ventoy.net/en/plug
 * FAT32/exFAT/NTFS/UDF/XFS/Ext2(3)(4) supported for main partition
 * ISO files larger than 4GB supported
 * Native boot menu style for Legacy & UEFI
-* Most type of OS supported, 770+ iso files tested
+* Most type of OS supported, 780+ iso files tested
 * Linux vDisk boot supported
 * Not only boot but also complete installation process
 * Menu dynamically switchable between List/TreeView mode
diff --git a/VtoyTool/vtoykmod.c b/VtoyTool/vtoykmod.c
new file mode 100644 (file)
index 0000000..b3519f3
--- /dev/null
@@ -0,0 +1,546 @@
+/******************************************************************************
+ * vtoykmod.c  ---- ventoy kmod
+ *
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>
+ *
+ * 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 the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#define _ull unsigned long long
+
+#define magic_sig 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF
+
+#define EI_NIDENT (16)
+
+#define        EI_MAG0         0               /* e_ident[] indexes */
+#define        EI_MAG1         1
+#define        EI_MAG2         2
+#define        EI_MAG3         3
+#define        EI_CLASS        4
+#define        EI_DATA         5
+#define        EI_VERSION      6
+#define        EI_OSABI        7
+#define        EI_PAD          8
+
+#define        ELFMAG0         0x7f            /* EI_MAG */
+#define        ELFMAG1         'E'
+#define        ELFMAG2         'L'
+#define        ELFMAG3         'F'
+#define        ELFMAG          "\177ELF"
+#define        SELFMAG         4
+
+#define        ELFCLASSNONE    0               /* EI_CLASS */
+#define        ELFCLASS32      1
+#define        ELFCLASS64      2
+#define        ELFCLASSNUM     3
+
+#define ELFDATANONE    0               /* e_ident[EI_DATA] */
+#define ELFDATA2LSB    1
+#define ELFDATA2MSB    2
+
+#define EV_NONE                0               /* e_version, EI_VERSION */
+#define EV_CURRENT     1
+#define EV_NUM         2
+
+#define ELFOSABI_NONE  0
+#define ELFOSABI_LINUX 3
+
+#define SHT_STRTAB     3
+
+#pragma pack(1)
+
+
+typedef struct
+{
+    unsigned char      e_ident[EI_NIDENT];     /* Magic number and other info */
+    uint16_t   e_type;                 /* Object file type */
+    uint16_t   e_machine;              /* Architecture */
+    uint32_t   e_version;              /* Object file version */
+    uint32_t   e_entry;                /* Entry point virtual address */
+    uint32_t   e_phoff;                /* Program header table file offset */
+    uint32_t   e_shoff;                /* Section header table file offset */
+    uint32_t   e_flags;                /* Processor-specific flags */
+    uint16_t   e_ehsize;               /* ELF header size in bytes */
+    uint16_t   e_phentsize;    /* Program header table entry size */
+    uint16_t   e_phnum;                /* Program header table entry count */
+    uint16_t   e_shentsize;    /* Section header table entry size */
+    uint16_t   e_shnum;                /* Section header table entry count */
+    uint16_t   e_shstrndx;             /* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+    unsigned char      e_ident[EI_NIDENT];     /* Magic number and other info */
+    uint16_t   e_type;                 /* Object file type */
+    uint16_t   e_machine;              /* Architecture */
+    uint32_t   e_version;              /* Object file version */
+    uint64_t   e_entry;                /* Entry point virtual address */
+    uint64_t   e_phoff;                /* Program header table file offset */
+    uint64_t   e_shoff;                /* Section header table file offset */
+    uint32_t   e_flags;                /* Processor-specific flags */
+    uint16_t   e_ehsize;               /* ELF header size in bytes */
+    uint16_t   e_phentsize;    /* Program header table entry size */
+    uint16_t   e_phnum;                /* Program header table entry count */
+    uint16_t   e_shentsize;    /* Section header table entry size */
+    uint16_t   e_shnum;                /* Section header table entry count */
+    uint16_t   e_shstrndx;             /* Section header string table index */
+} Elf64_Ehdr;
+
+typedef struct
+{
+    uint32_t   sh_name;                /* Section name (string tbl index) */
+    uint32_t   sh_type;                /* Section type */
+    uint32_t   sh_flags;               /* Section flags */
+    uint32_t   sh_addr;                /* Section virtual addr at execution */
+    uint32_t   sh_offset;              /* Section file offset */
+    uint32_t   sh_size;                /* Section size in bytes */
+    uint32_t   sh_link;                /* Link to another section */
+    uint32_t   sh_info;                /* Additional section information */
+    uint32_t   sh_addralign;   /* Section alignment */
+    uint32_t   sh_entsize;             /* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+    uint32_t   sh_name;                /* Section name (string tbl index) */
+    uint32_t   sh_type;                /* Section type */
+    uint64_t   sh_flags;               /* Section flags */
+    uint64_t   sh_addr;                /* Section virtual addr at execution */
+    uint64_t   sh_offset;              /* Section file offset */
+    uint64_t   sh_size;                /* Section size in bytes */
+    uint32_t   sh_link;                /* Link to another section */
+    uint32_t   sh_info;                /* Additional section information */
+    uint64_t   sh_addralign;   /* Section alignment */
+    uint64_t   sh_entsize;             /* Entry size if section holds table */
+} Elf64_Shdr;
+
+typedef struct elf32_rel {
+  uint32_t     r_offset;
+  uint32_t     r_info;
+} Elf32_Rel;
+
+typedef struct elf64_rel {
+  uint64_t r_offset;   /* Location at which to apply the action */
+  uint64_t r_info;         /* index and type of relocation */
+} Elf64_Rel;
+
+typedef struct elf32_rela{
+  uint32_t     r_offset;
+  uint32_t     r_info;
+  int32_t      r_addend;
+} Elf32_Rela;
+
+typedef struct elf64_rela {
+  uint64_t r_offset;   /* Location at which to apply the action */
+  uint64_t r_info;         /* index and type of relocation */
+  int64_t  r_addend;   /* Constant addend used to compute value */
+} Elf64_Rela;
+
+
+struct modversion_info {
+       unsigned long crc;
+       char name[64 - sizeof(unsigned long)];
+};
+
+
+typedef struct ko_param
+{
+    unsigned char magic[16];
+    unsigned long struct_size;
+    unsigned long pgsize;
+    unsigned long printk_addr;
+    unsigned long ro_addr;
+    unsigned long rw_addr;
+    unsigned long reg_kprobe_addr;
+    unsigned long unreg_kprobe_addr;
+    unsigned long sym_get_addr;
+    unsigned long sym_get_size;
+    unsigned long sym_put_addr;
+    unsigned long sym_put_size;
+    unsigned long padding[3];
+}ko_param;
+
+#pragma pack()
+
+static int verbose = 0;
+#define debug(fmt, ...) if(verbose) printf(fmt, ##__VA_ARGS__)
+
+static int vtoykmod_write_file(char *name, void *buf, int size)
+{
+    FILE *fp;
+
+    fp = fopen(name, "wb+");
+    if (!fp)
+    {
+        return -1;
+    }
+    
+    fwrite(buf, 1, size, fp);
+    fclose(fp);
+
+    return 0;
+}
+
+static int vtoykmod_read_file(char *name, char **buf)
+{
+    int size;
+    FILE *fp;
+    char *databuf;
+
+    fp = fopen(name, "rb");
+    if (!fp)
+    {
+        debug("failed to open %s %d\n", name, errno);
+        return -1;
+    }
+    
+    fseek(fp, 0, SEEK_END);
+    size = (int)ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+
+    databuf = malloc(size);
+    if (!databuf)
+    {
+        debug("failed to open malloc %d\n", size);
+        return -1;
+    }
+    
+    fread(databuf, 1, size, fp);
+    fclose(fp);
+
+    *buf = databuf;
+    return size;
+}
+
+static int vtoykmod_find_section64(char *buf, char *section, int *offset, int *len)
+{
+    uint16_t i;
+    int cmplen;
+    char *name = NULL;
+    char *strtbl = NULL;
+    Elf64_Ehdr *elf = NULL;
+    Elf64_Shdr *sec = NULL;
+
+    cmplen = (int)strlen(section);
+
+    elf = (Elf64_Ehdr *)buf;
+    sec = (Elf64_Shdr *)(buf + elf->e_shoff);
+    strtbl = buf + sec[elf->e_shstrndx].sh_offset;
+
+    for (i = 0; i < elf->e_shnum; i++)
+    {
+        name = strtbl + sec[i].sh_name;
+        if (name && strncmp(name, section, cmplen) == 0)
+        {
+            *offset = (int)(sec[i].sh_offset);
+            *len = (int)(sec[i].sh_size);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+static int vtoykmod_find_section32(char *buf, char *section, int *offset, int *len)
+{
+    uint16_t i;
+    int cmplen;
+    char *name = NULL;
+    char *strtbl = NULL;
+    Elf32_Ehdr *elf = NULL;
+    Elf32_Shdr *sec = NULL;
+
+    cmplen = (int)strlen(section);
+
+    elf = (Elf32_Ehdr *)buf;
+    sec = (Elf32_Shdr *)(buf + elf->e_shoff);
+    strtbl = buf + sec[elf->e_shstrndx].sh_offset;
+
+    for (i = 0; i < elf->e_shnum; i++)
+    {
+        name = strtbl + sec[i].sh_name;
+        if (name && strncmp(name, section, cmplen) == 0)
+        {
+            *offset = (int)(sec[i].sh_offset);
+            *len = (int)(sec[i].sh_size);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+static int vtoykmod_update_modcrc(char *oldmodver, int oldcnt, char *newmodver, int newcnt)
+{
+    int i, j;
+    struct modversion_info *pold, *pnew;
+    
+    pold = (struct modversion_info *)oldmodver;
+    pnew = (struct modversion_info *)newmodver;
+
+    for (i = 0; i < oldcnt; i++)
+    {
+        for (j = 0; j < newcnt; j++)
+        {
+            if (strcmp(pold[i].name, pnew[j].name) == 0)
+            {
+                debug("CRC  0x%08lx --> 0x%08lx  %s\n", pold[i].crc, pnew[i].crc, pold[i].name);
+                pold[i].crc = pnew[j].crc;
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+static int vtoykmod_update_vermagic(char *oldbuf, int oldsize, char *newbuf, int newsize, int *modver)
+{
+    int i = 0;
+    char *oldver = NULL;
+    char *newver = NULL;
+
+    *modver = 0;
+
+    for (i = 0; i < oldsize - 9; i++)
+    {
+        if (strncmp(oldbuf + i, "vermagic=", 9) == 0)
+        {
+            oldver = oldbuf + i + 9;
+            debug("Find old vermagic at %d <%s>\n", i, oldver);
+            break;
+        }
+    }
+    
+    for (i = 0; i < newsize - 9; i++)
+    {
+        if (strncmp(newbuf + i, "vermagic=", 9) == 0)
+        {
+            newver = newbuf + i + 9;
+            debug("Find new vermagic at %d <%s>\n", i, newver);
+            break;
+        }
+    }
+
+    if (oldver && newver)
+    {
+        memcpy(oldver, newver, strlen(newver) + 1);
+        if (strstr(newver, "modversions"))
+        {
+            *modver = 1;
+        }
+    }
+
+    return 0;
+}
+
+int vtoykmod_update(char *oldko, char *newko)
+{
+    int rc = 0;
+    int modver = 0;
+    int oldoff, oldlen;
+    int newoff, newlen;
+    int oldsize, newsize;
+    char *newbuf, *oldbuf;
+
+    oldsize = vtoykmod_read_file(oldko, &oldbuf);
+    newsize = vtoykmod_read_file(newko, &newbuf);
+    if (oldsize < 0 || newsize < 0)
+    {
+        return 1;
+    }
+
+    /* 1: update vermagic */
+    vtoykmod_update_vermagic(oldbuf, oldsize, newbuf, newsize, &modver);
+
+    /* 2: update modversion crc */
+    if (modver)
+    {
+        if (oldbuf[EI_CLASS] == ELFCLASS64)
+        {
+            rc  = vtoykmod_find_section64(oldbuf, "__versions", &oldoff, &oldlen);
+            rc += vtoykmod_find_section64(newbuf, "__versions", &newoff, &newlen);            
+        }
+        else
+        {
+            rc  = vtoykmod_find_section32(oldbuf, "__versions", &oldoff, &oldlen);
+            rc += vtoykmod_find_section32(newbuf, "__versions", &newoff, &newlen);
+        }
+
+        if (rc == 0)
+        {
+            vtoykmod_update_modcrc(oldbuf + oldoff, oldlen / 64, newbuf + newoff, newlen / 64);
+        }
+    }
+    else
+    {
+        debug("no need to proc modversions\n");
+    }
+    
+    /* 3: update relocate address */
+    if (oldbuf[EI_CLASS] == ELFCLASS64)
+    {
+        Elf64_Rela *oldRela, *newRela;
+        
+        rc  = vtoykmod_find_section64(oldbuf, ".rela.gnu.linkonce.this_module", &oldoff, &oldlen);
+        rc += vtoykmod_find_section64(newbuf, ".rela.gnu.linkonce.this_module", &newoff, &newlen);
+        if (rc == 0)
+        {
+            oldRela = (Elf64_Rela *)(oldbuf + oldoff);
+            newRela = (Elf64_Rela *)(newbuf + newoff);
+            
+            debug("init_module rela: 0x%llx --> 0x%llx\n", (_ull)(oldRela[0].r_offset), (_ull)(newRela[0].r_offset));
+            oldRela[0].r_offset = newRela[0].r_offset;
+            oldRela[0].r_addend = newRela[0].r_addend;
+            
+            debug("cleanup_module rela: 0x%llx --> 0x%llx\n", (_ull)(oldRela[1].r_offset), (_ull)(newRela[1].r_offset));
+            oldRela[1].r_offset = newRela[1].r_offset;
+            oldRela[1].r_addend = newRela[1].r_addend;
+        }
+        else
+        {
+            debug("section .rela.gnu.linkonce.this_module not found\n");
+        }
+    }
+    else
+    {
+        Elf32_Rel *oldRel, *newRel;
+        
+        rc  = vtoykmod_find_section32(oldbuf, ".rel.gnu.linkonce.this_module", &oldoff, &oldlen);
+        rc += vtoykmod_find_section32(newbuf, ".rel.gnu.linkonce.this_module", &newoff, &newlen);
+        if (rc == 0)
+        {
+            oldRel = (Elf32_Rel *)(oldbuf + oldoff);
+            newRel = (Elf32_Rel *)(newbuf + newoff);
+
+            debug("init_module rel: 0x%x --> 0x%x\n", oldRel[0].r_offset, newRel[0].r_offset);
+            oldRel[0].r_offset = newRel[0].r_offset;
+
+            debug("cleanup_module rel: 0x%x --> 0x%x\n", oldRel[0].r_offset, newRel[0].r_offset);
+            oldRel[1].r_offset = newRel[1].r_offset;
+        }
+        else
+        {
+            debug("section .rel.gnu.linkonce.this_module not found\n");
+        }
+    }
+
+    vtoykmod_write_file(oldko, oldbuf, oldsize);
+
+    free(oldbuf);
+    free(newbuf);
+
+    return 0;
+}
+
+int vtoykmod_fill_param(char **argv)
+{
+    int i;
+    int size;
+    char *buf = NULL;
+    ko_param *param;
+    unsigned char magic[16] = { magic_sig };
+    
+    size = vtoykmod_read_file(argv[0], &buf);
+    if (size < 0)
+    {
+        return 1;
+    }
+
+    for (i = 0; i < size; i++)
+    {
+        if (memcmp(buf + i, magic, 16) == 0)
+        {
+            debug("Find param magic at %d\n", i);
+            param = (ko_param *)(buf + i);
+            
+            param->struct_size = (unsigned long)sizeof(ko_param);
+            param->pgsize = strtoul(argv[1], NULL, 10);
+            param->printk_addr = strtoul(argv[2], NULL, 16);
+            param->ro_addr = strtoul(argv[3], NULL, 16);
+            param->rw_addr = strtoul(argv[4], NULL, 16);
+            param->sym_get_addr = strtoul(argv[5], NULL, 16);
+            param->sym_get_size = strtoul(argv[6], NULL, 10);
+            param->sym_put_addr = strtoul(argv[7], NULL, 16);
+            param->sym_put_size = strtoul(argv[8], NULL, 10);
+            param->reg_kprobe_addr = strtoul(argv[9], NULL, 16);
+            param->unreg_kprobe_addr = strtoul(argv[10], NULL, 16);
+
+            debug("pgsize=%lu (%s)\n", param->pgsize, argv[1]);
+            debug("printk_addr=0x%lx (%s)\n", param->printk_addr, argv[2]);
+            debug("ro_addr=0x%lx (%s)\n", param->ro_addr, argv[3]);
+            debug("rw_addr=0x%lx (%s)\n", param->rw_addr, argv[4]);
+            debug("sym_get_addr=0x%lx (%s)\n", param->sym_get_addr, argv[5]);
+            debug("sym_get_size=%lu (%s)\n", param->sym_get_size, argv[6]);
+            debug("sym_put_addr=0x%lx (%s)\n", param->sym_put_addr, argv[7]);
+            debug("sym_put_size=%lu (%s)\n", param->sym_put_size, argv[8]);
+            debug("reg_kprobe_addr=0x%lx (%s)\n", param->reg_kprobe_addr, argv[9]);
+            debug("unreg_kprobe_addr=0x%lx (%s)\n", param->unreg_kprobe_addr, argv[10]);
+            
+            break;
+        }
+    }
+
+    if (i >= size)
+    {
+        debug("### param magic not found \n");
+    }
+    
+    vtoykmod_write_file(argv[0], buf, size);
+
+    free(buf);
+    return 0;
+}
+
+int vtoykmod_main(int argc, char **argv)
+{
+    int i;
+
+    for (i = 0; i < argc; i++)
+    {
+        if (argv[i][0] == '-' && argv[i][1] == 'v')
+        {
+            verbose = 1;
+            break;
+        }
+    }
+
+    if (argv[1][0] == '-' && argv[1][1] == 'f')
+    {
+        return vtoykmod_fill_param(argv + 2);
+    }
+    else if (argv[1][0] == '-' && argv[1][1] == 'u')
+    {
+        return vtoykmod_update(argv[2], argv[3]);
+    }
+
+    return 0;
+}
+
+// wrapper main
+#ifndef BUILD_VTOY_TOOL
+int main(int argc, char **argv)
+{
+    return vtoykmod_main(argc, argv);
+}
+#endif
+
diff --git a/VtoyTool/vtoyksym.c b/VtoyTool/vtoyksym.c
new file mode 100644 (file)
index 0000000..187f54c
--- /dev/null
@@ -0,0 +1,113 @@
+/******************************************************************************
+ * vtoyksym.c  ---- ventoy ksym
+ *
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>
+ *
+ * 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 the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+static int verbose = 0;
+#define debug(fmt, ...) if(verbose) printf(fmt, ##__VA_ARGS__)
+
+int vtoyksym_main(int argc, char **argv)
+{
+    int i;
+    unsigned long long addr1 = 0;
+    unsigned long long addr2 = 0;
+    char sym[256];
+    char line[1024];
+    const char *name = NULL;
+    FILE *fp;
+
+    for (i = 0; i < argc; i++)
+    {
+        if (argv[i][0] == '-' && argv[i][1] == 'p')
+        {
+            printf("%d", getpagesize());
+            return 0;
+        }
+    }
+    
+    for (i = 0; i < argc; i++)
+    {
+        if (argv[i][0] == '-' && argv[i][1] == 'v')
+        {
+            verbose = 1;
+            break;
+        }
+    }
+
+    name = argv[2] ? argv[2] : "/proc/kallsyms";
+    fp = fopen(name, "r");
+    if (!fp)
+    {
+        fprintf(stderr, "Failed to open file %s err:%d\n", name, errno);
+        return 1;
+    }
+
+    debug("open %s success\n", name);
+
+    snprintf(sym, sizeof(sym), " %s", argv[1]);
+    debug("lookup for <%s>\n", sym);
+
+    while (fgets(line, sizeof(line), fp))
+    {
+        if (strstr(line, sym))
+        {
+            addr1 = strtoull(line, NULL, 16);
+            if (!fgets(line, sizeof(line), fp))
+            {
+                addr1 = 0;
+                fprintf(stderr, "Failed to read next line\n");
+            }
+            else
+            {
+                addr2 = strtoull(line, NULL, 16);                
+            }
+
+            debug("addr1=<0x%llx> addr2=<0x%llx>\n", addr1, addr2);
+            break;
+        }
+    }
+
+    if (addr1 > addr2)
+    {
+        debug("Invalid addr range\n");
+        printf("0 0\n");
+    }
+    else
+    {
+        printf("0x%llx %llu\n", addr1, addr2 - addr1);
+    }
+
+    fclose(fp);
+
+    return 0;
+}
+
+// wrapper main
+#ifndef BUILD_VTOY_TOOL
+int main(int argc, char **argv)
+{
+    return vtoyksym_main(argc, argv);
+}
+#endif
+
index 454063d2675ac318814af819a926c967e835f0bf..f6896860cf766d2d2ab537e5a830b6c2e012ffb7 100644 (file)
@@ -36,6 +36,8 @@ int vtoydm_main(int argc, char **argv);
 int vtoytool_install(int argc, char **argv);
 int vtoyloader_main(int argc, char **argv);
 int vtoyvine_main(int argc, char **argv);
+int vtoyksym_main(int argc, char **argv);
+int vtoykmod_main(int argc, char **argv);
 
 static char *g_vtoytool_name = NULL;
 static cmd_def g_cmd_list[] = 
@@ -44,6 +46,8 @@ static cmd_def g_cmd_list[] =
     { "vtoydump",    vtoydump_main    },
     { "vtoydm",      vtoydm_main      },
     { "loader",      vtoyloader_main  },
+    { "vtoyksym",    vtoyksym_main  },
+    { "vtoykmod",    vtoykmod_main  },
     { "--install",   vtoytool_install },
 };
 
index b4f1dd77363acecbf92f0b8b3e8d41355020cc89..0b430bd97527792550ae913fbe85ae4d10b5f98b 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_32 and b/VtoyTool/vtoytool/00/vtoytool_32 differ
index 4c52cb549acf5e6305fd32708747d87998c0d071..7680fe37dd35363faec0fc86bbd18b4d069008e3 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_64 and b/VtoyTool/vtoytool/00/vtoytool_64 differ
index c0284031e4eb953ab66a3db5e187d8158ac13b7e..c3ce4004e7fda51f7f95bfd2a0ae146d9eb0031c 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_aa64 and b/VtoyTool/vtoytool/00/vtoytool_aa64 differ
index 5deb5e77ca9745ce3754caa8f9a28205241169cc..d4d03d52b278952f704a9854f9eff472bfef9fe2 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_m64e and b/VtoyTool/vtoytool/00/vtoytool_m64e differ