Last active
June 22, 2026 08:54
-
-
Save Troll338cz/75b06b8cc8756bd4513aa19e3bf5fcee to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <stdint.h> | |
| #include <fcntl.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <sys/ioctl.h> | |
| // =============== WARNING! WARNING! WARNING! =============== | |
| // This tool is UNSAFE, no check no second chance, one wrong write and your device could be permanently bricked! | |
| // If you are going to try this, make a full backup of NAND and save information from ATCK & ATBL commands | |
| // Only tested on VMG4005-B60A with CFE 1.0.38-164.255 | |
| // =============== WARNING! WARNING! WARNING! =============== | |
| // How to: | |
| // 1. You probably need to be root on the device already ( generated from SN or exploit ) | |
| // 2. Edit main to firstly save nvram | |
| // 3. Build this "arm-linux-gnueabi-gcc -static Zyxel_CFE_nvram_EngDebugFlag.c -o nvramcfe" | |
| // 4. Upload to /tmp/ and run | |
| // 5. Edit nvram with whatever you want, Debug flag was byte before "Default Country Code" on my device (find in ATSH output) | |
| // 6. Edit main to write nvram | |
| // 7. Rebuild & upload tool and .bin | |
| // 8. Run to write your new nvram.bin to device | |
| // 9. Reboot and pray i guess.... | |
| // CRC32 OpenSSH table | |
| static const uint32_t crc32tab[] = { | |
| 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, | |
| 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, | |
| 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, | |
| 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, | |
| 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, | |
| 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, | |
| 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, | |
| 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, | |
| 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, | |
| 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, | |
| 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, | |
| 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, | |
| 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, | |
| 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, | |
| 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, | |
| 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, | |
| 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, | |
| 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, | |
| 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, | |
| 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, | |
| 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, | |
| 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, | |
| 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, | |
| 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, | |
| 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, | |
| 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, | |
| 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, | |
| 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, | |
| 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, | |
| 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, | |
| 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, | |
| 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, | |
| 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, | |
| 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, | |
| 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, | |
| 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, | |
| 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, | |
| 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, | |
| 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, | |
| 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, | |
| 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, | |
| 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, | |
| 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, | |
| 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, | |
| 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, | |
| 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, | |
| 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, | |
| 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, | |
| 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, | |
| 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, | |
| 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, | |
| 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, | |
| 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, | |
| 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, | |
| 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, | |
| 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, | |
| 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, | |
| 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, | |
| 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, | |
| 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, | |
| 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, | |
| 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, | |
| 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, | |
| 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL | |
| }; | |
| // Straight from libzyutil.so pseudocode by IDA w/ minor tweaks | |
| int nvramDataGet(int a1) | |
| { | |
| int v2; // r0 | |
| int v3; // r4 | |
| int v4; // r6 | |
| uint32_t v6[6]; // [sp+4h] [bp-2Ch] BYREF | |
| v2 = open("/dev/brcmboard", 2); | |
| v3 = v2; | |
| if ( v2 != -1 ) | |
| { | |
| v6[0] = a1; | |
| v6[2] = 1024; | |
| v6[3] = 0; | |
| v6[4] = 1; | |
| v6[1] = 0; | |
| v6[5] = -1; | |
| v4 = ioctl(v2, 0xC0184201, v6); | |
| close(v3); | |
| if ( v4 < 0 ) | |
| { | |
| printf("%s Get NVRAM Failure\n", "nvramDataGet"); | |
| return -1; | |
| } | |
| else | |
| { | |
| return 0; | |
| } | |
| } | |
| return v3; | |
| } | |
| int nvramDataWrite(int a1) | |
| { | |
| char *v2; // r1 | |
| unsigned int v3; // r2 | |
| char v4; // t1 | |
| int v5; // r0 | |
| int v6; // r6 | |
| int v7; // r4 | |
| uint32_t v9[6]; // [sp+4h] [bp-2Ch] BYREF | |
| // Calc CRC | |
| *(uint32_t *)(a1 + 1020) = 0; | |
| v2 = (char *)a1; | |
| v3 = -1; | |
| do | |
| { | |
| v4 = *v2++; | |
| v3 = crc32tab[(uint8_t)(v4 ^ v3)] ^ (v3 >> 8); | |
| } | |
| while ( v2 != (char *)(a1 + 1024) ); | |
| *(uint32_t *)(a1 + 1020) = v3; | |
| v5 = open("/dev/brcmboard", 2); | |
| v6 = v5; | |
| if ( v5 != -1 ) | |
| { | |
| v9[0] = a1; | |
| v9[2] = 1024; | |
| v9[3] = 0; | |
| v9[4] = 1; | |
| v9[1] = 0; | |
| v9[5] = -1; | |
| v7 = ioctl(v5, 0xC0184200, v9); | |
| close(v6); | |
| if ( v7 < 0 ) | |
| { | |
| printf("%s Set NVRAM Failure\n", "nvramDataWrite"); | |
| return -1; | |
| } | |
| else | |
| { | |
| return 0; | |
| } | |
| } | |
| return v6; | |
| } | |
| // Stuff to load arrays | |
| int save_array(const char *filename, const uint8_t v3[1024]) { | |
| FILE *f = fopen(filename, "wb"); | |
| if (!f) return -1; | |
| size_t written = fwrite(v3, sizeof(uint8_t), 1024, f); | |
| fclose(f); | |
| return (written == 1024) ? 0 : -1; | |
| } | |
| int load_array(const char *filename, uint8_t v3[1024]) { | |
| FILE *f = fopen(filename, "rb"); | |
| if (!f) return -1; | |
| size_t read = fread(v3, sizeof(uint8_t), 1024, f); | |
| fclose(f); | |
| return (read == 1024) ? 0 : -1; | |
| } | |
| void main() { | |
| #if 1 | |
| // Save nvram | |
| uint8_t v3[1024]; | |
| nvramDataGet((int)v3); | |
| save_array("nvram.bin", v3); | |
| // Test read few known values from libzyutil | |
| printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", v3[288], v3[289], v3[290], v3[291], v3[292], v3[293]); | |
| printf("Debug flag: %x\n", v3[979]); | |
| #else | |
| // Write nvram | |
| uint8_t v4[1024]; | |
| load_array("nvram.bin", v4); | |
| nvramDataWrite((int)v4); | |
| #endif | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment