├── Makefile ├── README.md ├── dumpimages.c └── xvic.c /Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-I/opt/local/include/ -L/opt/local/lib/ 3 | all: 4 | $(CC) -o xvic -m32 $(CFLAGS) xvic.c 5 | $(CC) -o dumpimages $(CFLAGS) -lgd dumpimages.c 6 | 7 | clean: 8 | rm xvic dumpimages 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | xVic 2 | ==== 3 | 4 | eVic electronic cigarette firmware decryptor/encryptor (and maybe uploader...) 5 | 6 | Currently just decrypts, but only because Im going to sleep 7 | -------------------------------------------------------------------------------- /dumpimages.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef struct { 6 | int width; 7 | int height; 8 | unsigned char *data; //(height + width) / 8 9 | } FWImage; 10 | 11 | int dumpImage(FWImage *img, char *name) { 12 | gdImagePtr im; 13 | int white, black, x, y; 14 | FILE *fp; 15 | unsigned char row, printPixel; 16 | int datalen = (img->height * img->width) / 8; 17 | 18 | 19 | //Create our image 20 | im = gdImageCreate(img->width, img->height); 21 | if (!im) { 22 | fprintf(stderr, "can't create image"); 23 | return 1; 24 | } 25 | 26 | fp = fopen(name, "wb"); 27 | if (!fp) { 28 | fprintf(stderr, "can't create file %s", name); 29 | return 1; 30 | } 31 | 32 | white = gdImageColorAllocate(im, 255, 255, 255); 33 | black = gdImageColorAllocate(im, 0, 0, 0); 34 | 35 | //Loop through the data 36 | for (x = 0; x < datalen; x++) { 37 | row = img->data[x]; 38 | for (y = 0; y < 8; y++) { 39 | //Shift the data to see if we print this pixel 40 | printPixel = row << (7 - y); 41 | printPixel = printPixel >> 7; 42 | if (printPixel) { //Fill a pixel 43 | //Swap every 2 rows (No idea why they do this) 44 | int fixX = x; 45 | if (fixX == 0 || fixX % 2 == 0) { 46 | fixX++; 47 | } else { 48 | fixX--; 49 | } 50 | gdImageFilledRectangle(im, fixX, y, fixX, y, black); 51 | } 52 | } 53 | } 54 | gdImagePng(im, fp); 55 | fclose(fp); 56 | } 57 | 58 | 59 | int main(int argc, char **args) { 60 | FWImage img; 61 | char name[255]; 62 | unsigned char bytes[9]; 63 | int datalen; 64 | unsigned int location = 0; 65 | FILE *fp = fopen(args[1], "rb"); 66 | if (!fp) 67 | { 68 | printf("Can't open file: %s\n", args[1]); 69 | return -1; 70 | } 71 | 72 | while (location < 64000) 73 | { 74 | fread(bytes, 1, 8, fp); 75 | // Locate image "0": 06 08 7E 00 81 81 7E 81 76 | if (bytes[0] == 0x06 && bytes[1] == 0x08 && bytes[2] == 0x7e && bytes[3] == 0x00 && 77 | bytes[4] == 0x81 && bytes[5] == 0x81 && bytes[6] == 0x7e && bytes[7] == 0x81) 78 | { 79 | break; 80 | } 81 | location++; 82 | fseek(fp, location, SEEK_SET); 83 | } 84 | 85 | printf("Location found: %04x\n", location); 86 | fseek(fp, location, SEEK_SET); 87 | 88 | do { 89 | location = ftell(fp); 90 | img.width = fgetc(fp); 91 | img.height = fgetc(fp); 92 | 93 | datalen = (img.height * img.width) / 8; 94 | 95 | img.data = (char *)malloc(datalen); 96 | fread(img.data, 1, datalen, fp); 97 | 98 | sprintf(&name, "%X.png\0", location); 99 | //sprintf(&name, "%X.png\0", ftell(fp)); 100 | 101 | printf("Dumping image %s (%dx%d)\n", name, img.width, img.height); 102 | dumpImage(&img, name); 103 | } while (ftell(fp) < 0x3D0D); 104 | 105 | return 0; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /xvic.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct { 5 | unsigned char unk_1[16]; 6 | int checksum; 7 | unsigned char unk_2[12]; 8 | unsigned char key[32]; 9 | } FWHeader; 10 | 11 | void decrypt(char *inPath, char *outPath) { 12 | //Set up our data 13 | FWHeader header; 14 | unsigned char hardKey[] = "sinowealth chenshaofan 20121101 "; 15 | unsigned char encryptionKey[32]; 16 | unsigned char data[0x10000]; 17 | int i, j; 18 | //Open our input file 19 | FILE *fp = fopen(inPath, "r"); 20 | 21 | //Read the header 22 | if (fread(&header, 1, 64, fp) != 64) { 23 | printf("Error reading header\n"); 24 | return; 25 | } 26 | 27 | //Copy our encoded key into encryptionKey for decoding 28 | memcpy(&encryptionKey, &header.key, 32); 29 | 30 | //Decode the encryption key 31 | for (i = 0; i < 32; i++) { 32 | j = i & 0xf; 33 | encryptionKey[i] = (encryptionKey[i] - hardKey[j + 16]) ^ hardKey[j]; 34 | } 35 | 36 | //Read the rest of the data 37 | int size = fread(&data, 1, 0x10000, fp); 38 | 39 | //Decrypt it with our key 40 | for (i = 0; i < size; i++) { 41 | j = i & 0xF; 42 | data[i] = encryptionKey[j] ^ (data[i] - encryptionKey[j + 16]); 43 | } 44 | fclose(fp); 45 | 46 | //Open the output file 47 | fp = fopen(outPath, "w"); 48 | //fwrite(&header, 1, sizeof(header), fp); 49 | fwrite(&data, 1, size, fp); 50 | 51 | fclose(fp); 52 | 53 | } 54 | 55 | int main(int argc, char **args) { 56 | decrypt(args[1], args[2]); 57 | return 0; 58 | } 59 | 60 | --------------------------------------------------------------------------------