X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/Ventoy.git/blobdiff_plain/879a7592bdd58d1788e952efde9895fc48a3484e..a326b13fc33aa2e424ce38ea0cee76eb73179d0f:/VtoyTool/vtoykmod.c diff --git a/VtoyTool/vtoykmod.c b/VtoyTool/vtoykmod.c index 5ffd962..5cc42a5 100644 --- a/VtoyTool/vtoykmod.c +++ b/VtoyTool/vtoykmod.c @@ -24,6 +24,9 @@ #include #include #include +#ifdef VTOY_X86_64 +#include +#endif #define _ull unsigned long long @@ -161,6 +164,13 @@ struct modversion_info { char name[64 - sizeof(unsigned long)]; }; +struct modversion_info2 { + /* Offset of the next modversion entry in relation to this one. */ + uint32_t next; + uint32_t crc; + char name[0]; +}; + typedef struct ko_param { @@ -177,7 +187,8 @@ typedef struct ko_param unsigned long sym_put_addr; unsigned long sym_put_size; unsigned long kv_major; - unsigned long padding[2]; + unsigned long ibt; + unsigned long padding[1]; }ko_param; #pragma pack() @@ -290,14 +301,15 @@ static int vtoykmod_find_section32(char *buf, char *section, int *offset, int *l return 1; } -static int vtoykmod_update_modcrc(char *oldmodver, int oldcnt, char *newmodver, int newcnt) +static int vtoykmod_update_modcrc1(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; + debug("module update modver format 1\n"); for (i = 0; i < oldcnt; i++) { for (j = 0; j < newcnt; j++) @@ -314,6 +326,51 @@ static int vtoykmod_update_modcrc(char *oldmodver, int oldcnt, char *newmodver, return 0; } + +static int vtoykmod_update_modcrc2(char *oldmodver, int oldlen, char *newmodver, int newlen) +{ + struct modversion_info2 *pold, *pnew, *pnewend; + + pold = (struct modversion_info2 *)oldmodver; + pnew = (struct modversion_info2 *)newmodver; + pnewend = (struct modversion_info2 *)(newmodver + newlen); + + debug("module update modver format 2\n"); + /* here we think that there is only module_layout in oldmodver */ + + for (; pnew < pnewend && pnew->next; pnew = (struct modversion_info2 *)((char *)pnew + pnew->next)) + { + if (strcmp(pnew->name, "module_layout") == 0) + { + debug("CRC 0x%08x --> 0x%08x %s\n", pold->crc, pnew->crc, pnew->name); + memset(pold, 0, oldlen); + pold->next = 0x18; /* 8 + module_layout align 8 */ + pold->crc = pnew->crc; + strcpy(pold->name, pnew->name); + break; + } + } + + return 0; +} + + +static int vtoykmod_update_modcrc(char *oldmodver, int oldlen, char *newmodver, int newlen) +{ + uint32_t uiCrc = 0; + + memcpy(&uiCrc, newmodver + 4, 4); + + if (uiCrc > 0) + { + return vtoykmod_update_modcrc2(oldmodver, oldlen, newmodver, newlen); + } + else + { + return vtoykmod_update_modcrc1(oldmodver, oldlen / 64, newmodver, newlen / 64); + } +} + static int vtoykmod_update_vermagic(char *oldbuf, int oldsize, char *newbuf, int newsize, int *modver) { int i = 0; @@ -389,7 +446,7 @@ int vtoykmod_update(char *oldko, char *newko) if (rc == 0) { - vtoykmod_update_modcrc(oldbuf + oldoff, oldlen / 64, newbuf + newoff, newlen / 64); + vtoykmod_update_modcrc(oldbuf + oldoff, oldlen, newbuf + newoff, newlen); } } else @@ -486,6 +543,7 @@ int vtoykmod_fill_param(char **argv) param->reg_kprobe_addr = strtoul(argv[9], NULL, 16); param->unreg_kprobe_addr = strtoul(argv[10], NULL, 16); param->kv_major = (unsigned long)(argv[11][0] - '0'); + param->ibt = strtoul(argv[12], NULL, 16);; debug("pgsize=%lu (%s)\n", param->pgsize, argv[1]); debug("printk_addr=0x%lx (%s)\n", param->printk_addr, argv[2]); @@ -498,6 +556,7 @@ int vtoykmod_fill_param(char **argv) 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]); debug("kv_major=%lu (%s)\n", param->kv_major, argv[11]); + debug("ibt=0x%lx (%s)\n", param->ibt, argv[12]); break; } @@ -514,6 +573,26 @@ int vtoykmod_fill_param(char **argv) return 0; } +#ifdef VTOY_X86_64 +static int vtoykmod_check_ibt(void) +{ + uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; + + __cpuid_count(7, 0, eax, ebx, ecx, edx); + + if (edx & (1 << 20)) + { + return 0; + } + return 1; +} +#else +static int vtoykmod_check_ibt(void) +{ + return 1; +} +#endif + int vtoykmod_main(int argc, char **argv) { int i; @@ -535,6 +614,10 @@ int vtoykmod_main(int argc, char **argv) { return vtoykmod_update(argv[2], argv[3]); } + else if (argv[1][0] == '-' && argv[1][1] == 'I') + { + return vtoykmod_check_ibt(); + } return 0; }