├── .gitattributes ├── .gitignore ├── README.md ├── jni ├── Android.mk └── modulecrcpatch.c └── libs └── armeabi └── modulecrcpatch /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must ends with two \r. 29 | Icon 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | modulecrcpatch 2 | =============== 3 | 4 | This is a tool to patch kernel symbol crcs in a kernel module. 5 | The usage is as follows: 6 | ``` 7 | modulecrcpatch [readfile] [writefile] 8 | ``` 9 | 10 | The tool will find all kernel symbols in [writefile]. It will search the corresponding symbols 11 | in [readfile] and copy the crc from [readfile] to [writefile]. 12 | 13 | This is for example useful if you have a kernel module and want to use it in 14 | different Android versions / firmwares (usually module_layout symbol crc is different). 15 | 16 | You can compile the code with Android NDK for example, there is a pre-compiled binary in libs/armeabi. -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := modulecrcpatch 6 | LOCAL_SRC_FILES := modulecrcpatch.c 7 | 8 | include $(BUILD_EXECUTABLE) 9 | -------------------------------------------------------------------------------- /jni/modulecrcpatch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * modulecrcpatch by zxz0O0 3 | * 4 | * reads a symbol crc from input file and patches the crc in output file 5 | * another way would be to create a kernel module for reading crc from kallsyms 6 | * but usually it's only required to patch module_layout, so this is easier 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | //symbols *should* be in the first 16384 bytes, maybe it's more if there are many 14 | #define FILEBUFSIZE 16384 15 | #define isascii(c) ((c & ~0x7F) == 0) 16 | //#define DEBUG 17 | 18 | typedef struct { 19 | char crc32[4]; 20 | char symbolname[60]; 21 | } KOSymbol; 22 | 23 | void debugprintf(const char* format, ...) 24 | { 25 | #ifdef DEBUG 26 | va_list argptr; 27 | va_start(argptr, format); 28 | vfprintf(stdout, format, argptr); 29 | va_end(argptr); 30 | #endif 31 | } 32 | 33 | int memsearch(const char* buf, const int buflength, const char* pattern, int patternlength) 34 | { 35 | int i; 36 | debugprintf("searching for: 0x%08x\n", *(unsigned int*)pattern); 37 | 38 | for(i = 0; i < (buflength - patternlength); i++) 39 | { 40 | if(memcmp(pattern, &buf[i], patternlength) == 0) 41 | return i; 42 | } 43 | 44 | debugprintf("error: memcmp didn't find anything\n"); 45 | return 0; 46 | } 47 | 48 | int main(int argc, char** argv) 49 | { 50 | int retvalue = 0; 51 | printf("\nmodulecrcpatch (by zxz0O0)\n\n"); 52 | if(argc != 3) 53 | { 54 | printf("Usage: modulecrcpatch [readfile] [writefile]\n"); 55 | printf("Reads symbol crc from readfile and patches crc in writefile\n"); 56 | return 0; 57 | } 58 | 59 | char* arg_readfile = argv[1]; 60 | char* arg_writefile = argv[2]; 61 | 62 | FILE* readfile = fopen(arg_readfile, "rb"); 63 | if(readfile==NULL) 64 | { 65 | printf("Error: [readfile] %s does not exist\n", arg_readfile); 66 | return 1; 67 | } 68 | 69 | FILE* writefile = fopen(arg_writefile, "rb+"); 70 | if(writefile==NULL) 71 | { 72 | printf("Error: [writefile] %s does not exist\n", arg_writefile); 73 | return 1; 74 | } 75 | 76 | char* readbuf = malloc(FILEBUFSIZE); 77 | char* writebuf = malloc(FILEBUFSIZE); 78 | if(readbuf==NULL || writebuf==NULL) 79 | { 80 | printf("Error allocating memory\n"); 81 | return 1; 82 | } 83 | 84 | memset(readbuf, 0, FILEBUFSIZE); 85 | fread(readbuf, 1, FILEBUFSIZE, readfile); 86 | fclose(readfile); 87 | 88 | memset(writebuf, 0, FILEBUFSIZE); 89 | int bread = fread(writebuf, 1, FILEBUFSIZE, writefile); 90 | 91 | debugprintf("first 4 read 0x%08x\n", *(unsigned int*)readbuf); 92 | debugprintf("first 4 write 0x%08x\n", *(unsigned int*)writebuf); 93 | 94 | const char mlstr[] = "module_layout\0\0\0"; //it's char [60] but we don't really care 95 | const char gnustr[] = "GNU"; 96 | const int gnupos = memsearch(writebuf, FILEBUFSIZE, gnustr, sizeof(gnustr)) - 0x168; //module name is saved in this char mname[0x168]; 97 | //const since we use it as pointer for kosymbols 98 | const int mlpos = memsearch(writebuf, FILEBUFSIZE, mlstr, sizeof(mlstr)) - 4; //size of crc 99 | if(gnupos <= 0 || mlpos <= 0) 100 | { 101 | printf("Error finding pos\n"); 102 | retvalue = 1; 103 | goto _return; 104 | } 105 | 106 | //get length of all KO Symbols 107 | int kosymbolsize = (gnupos - mlpos); 108 | //at the end is some additional stuff we are not sure about the length so we round it down 109 | kosymbolsize = kosymbolsize - (kosymbolsize % sizeof(KOSymbol)); 110 | //now divide the length through length of KOSymbol struct to get the number of KO Symbols 111 | kosymbolsize = kosymbolsize / sizeof(KOSymbol); 112 | //there should be atleast module_layout 113 | if(kosymbolsize < 1) 114 | { 115 | printf("Error kosymbolsize\n"); 116 | retvalue = 1; 117 | goto _return; 118 | } 119 | 120 | KOSymbol* kosymbols = (KOSymbol*)&writebuf[mlpos]; 121 | int i; 122 | for(i = 0;i < kosymbolsize; i++) 123 | { 124 | printf("%s: ", kosymbols[i].symbolname); 125 | int inputpos = memsearch(readbuf, FILEBUFSIZE, kosymbols[i].symbolname, sizeof(kosymbols[i].symbolname)) - 4; //-4 to go to start of crc 126 | if(inputpos < 0) 127 | { 128 | printf("not found\n"); 129 | continue; 130 | } 131 | 132 | if(memcmp(kosymbols[i].crc32, &readbuf[inputpos], 4) == 0) 133 | { 134 | printf("match\n"); 135 | continue; 136 | } 137 | 138 | memcpy(kosymbols[i].crc32, &readbuf[inputpos], 4); 139 | printf("patched to 0x%08X\n", *(unsigned int*)&readbuf[inputpos]); 140 | } 141 | 142 | fseek(writefile, 0L, SEEK_SET); 143 | fwrite(writebuf, 1, bread, writefile); 144 | 145 | _return: 146 | free(readbuf); 147 | free(writebuf); 148 | fclose(writefile); 149 | return retvalue; 150 | } -------------------------------------------------------------------------------- /libs/armeabi/modulecrcpatch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dosomder/modulecrcpatch/474a6b72dea2a2ecd1c648a906b741e442b26435/libs/armeabi/modulecrcpatch --------------------------------------------------------------------------------