From 665d28976ea8252dc0bf70f416e1760200466b9a Mon Sep 17 00:00:00 2001 From: Richard Antony Burton Date: Fri, 1 Jul 2016 16:37:38 +0100 Subject: [PATCH] initial code upload --- README.md | 19 +++++ jni/Android.mk | 14 +++ jni/evoplus_cid.c | 180 +++++++++++++++++++++++++++++++++++++++ jni/ioctl.h | 49 +++++++++++ jni/major.h | 174 +++++++++++++++++++++++++++++++++++++ jni/mmc.h | 53 ++++++++++++ libs/armeabi/evoplus_cid | Bin 0 -> 13540 bytes 7 files changed, 489 insertions(+) create mode 100644 README.md create mode 100644 jni/Android.mk create mode 100644 jni/evoplus_cid.c create mode 100644 jni/ioctl.h create mode 100644 jni/major.h create mode 100644 jni/mmc.h create mode 100644 libs/armeabi/evoplus_cid diff --git a/README.md b/README.md new file mode 100644 index 0000000..8edbb0e --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# evoplus_cid +Tool to change the CID on Samsung Evo Plus SD Cards. +See http://richard.burtons.org/2016/07/01/changing-the-cid-on-an-sd-card/ +for more details. + +USE AT OWN RISK! + +Usage: ./evoplus_cid [serial] +device - sd card block device e.g. /dev/block/mmcblk1 +cid - new cid, must be in hex (without 0x prefix) + it can be 32 chars with checksum or 30 chars without, it will + be updated with new serial number if supplied, the checksum is + always recalculated +serial - optional, can be hex (0x prefixed) or decimal + and will be applied to the supplied cid before writing + +Based on the reverse engineering and code of Sean Beaupre +See: https://github.com/beaups/SamsungCID + diff --git a/jni/Android.mk b/jni/Android.mk new file mode 100644 index 0000000..9ac5674 --- /dev/null +++ b/jni/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_ARM_MODE := arm +APP_ABI := armeabi-v7a +APP_PLATFORM := android-18 +LOCAL_CFLAGS += -fPIE -pie +LOCAL_MODULE := evoplus_cid +LOCAL_LDFLAGS := -pie + +LOCAL_SRC_FILES := evoplus_cid.c +LOCAL_LDLIBS += +include $(BUILD_EXECUTABLE) + diff --git a/jni/evoplus_cid.c b/jni/evoplus_cid.c new file mode 100644 index 0000000..925f51c --- /dev/null +++ b/jni/evoplus_cid.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include "mmc.h" + +#define CID_SIZE 16 +#define PROGRAM_CID_OPCODE 26 +#define SAMSUNG_VENDOR_OPCODE 62 + +int mmc_movi_vendor_cmd(unsigned int arg, int fd) { + int ret = 0; + struct mmc_ioc_cmd idata = {0}; + + idata.data_timeout_ns = 0x10000000; + idata.write_flag = 1; + idata.opcode = SAMSUNG_VENDOR_OPCODE; + idata.arg = arg; + idata.flags = MMC_RSP_R1B | MMC_CMD_AC; + + ret = ioctl(fd, MMC_IOC_CMD, &idata); + + return ret; +} + +int cid_backdoor(int fd) { + int ret; + + ret = mmc_movi_vendor_cmd(0xEFAC62EC, fd); + if (ret) { + printf("Failed to enter vendor mode. Genuine Samsung Evo Plus?\n"); + } else { + ret = mmc_movi_vendor_cmd(0xEF50, fd); + if (ret) { + printf("Unlock command failed.\n"); + } else { + ret = mmc_movi_vendor_cmd(0x00DECCEE, fd); + if (ret) { + printf("Failed to exit vendor mode.\n"); + } + } + } + + return ret; +} + +int program_cid(int fd, char *cid) { + int ret; + struct mmc_ioc_cmd idata = {0}; + + idata.data_timeout_ns = 0x10000000; + idata.write_flag = 1; + idata.opcode = PROGRAM_CID_OPCODE; + idata.arg = 0; + idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + idata.blksz = CID_SIZE; + idata.blocks = 1; + idata.data_ptr = (__u64)(unsigned int)cid; + + ret = ioctl(fd, MMC_IOC_CMD, &idata); + if (ret) { + printf("Success! Remove and reinsert SD card to check new CID.\n"); + } + + return ret; +} + +void show_cid(char *cid) { + int i; + for(i = 0; i < CID_SIZE; i++){ + printf("%02x", cid[i]); + } + printf("\n"); +} + +unsigned char crc7(unsigned char data[], int len) { + + int count; + unsigned char crc = 0; + + for (count = 0; count <= len; count++) { + unsigned char dat; + unsigned char bits; + if (count == len) { + dat = 0; + bits = 7; + } else { + dat = data[count]; + bits = 8; + } + for (; bits > 0; bits--) { + crc = (crc << 1) + ( (dat & 0x80) ? 1 : 0 ); + if (crc & 0x80) crc ^= 0x09; + dat <<= 1; + } + crc &= 0x7f; + } + + return ((crc << 1) + 1); +} + +int parse_serial(const char *str) { + + long val; + + // accept decimal or hex, but not octal + if ((strlen(str) > 2) && (str[0] == '0') && + (((str[1] == 'x')) || ((str[1] == 'X')))) { + val = strtol(str, NULL, 16); + } else { + val = strtol(str, NULL, 10); + } + + return (int)val; +} + +void main(int argc, const char **argv) { + int fd, ret, i, len; + char cid[CID_SIZE] = {0}; + + if(argc != 3 && argc != 4) { + printf("Usage: ./evoplus_cid [serial]\n"); + printf("device - sd card block device e.g. /dev/block/mmcblk1\n"); + printf("cid - new cid, must be in hex (without 0x prefix)\n"); + printf(" it can be 32 chars with checksum or 30 chars without, it will\n"); + printf(" be updated with new serial number if supplied, the checksum is\n"); + printf(" always recalculated\n"); + printf("serial - optional, can be hex (0x prefixed) or decimal\n"); + printf(" and will be applied to the supplied cid before writing\n"); + printf("\n"); + printf("Warning: use at own risk!\n"); + return; + } + + len = strlen(argv[2]); + if(len != 30 && len != 32) { + printf("cid should be 30 or 32 chars long\n"); + return; + } + + // parse cid + for(i = 0; i < (len/2); i++){ + ret = sscanf(&argv[2][i*2], "%2hhx", &cid[i]); + if(!ret){ + printf("cid should be hex (without 0x prefix)!\n"); + return; + } + } + + // incorporate optional serial number + if (argc == 4) { + *((int*)&cid[9]) = htonl(parse_serial(argv[3])); + } + + // calculate checksum + cid[15] = crc7(cid, 15); + + // open device + fd = open(argv[1], O_RDWR); + if(fd < 0){ + printf("[-] wtf\n"); + return; + } + + // unlock card + //ret = 0; + ret = cid_backdoor(fd); + if (!ret){ + // write new cid + printf("Writing new CID: "); + show_cid(cid); + ret = program_cid(fd, cid); + if(!ret){ + printf("Success! Remove and reinsert SD card to check new CID.\n"); + } + } + close(fd); + +} + diff --git a/jni/ioctl.h b/jni/ioctl.h new file mode 100644 index 0000000..4a7cd15 --- /dev/null +++ b/jni/ioctl.h @@ -0,0 +1,49 @@ +#ifndef LINUX_MMC_IOCTL_H +#define LINUX_MMC_IOCTL_H +#ifdef CONFIG_MMC_CPRM_SUPPORT +#include "card.h" +#endif + +#include + +struct mmc_ioc_cmd { + + int write_flag; + + + int is_acmd; + + __u32 opcode; + __u32 arg; + __u32 response[4]; + unsigned int flags; + unsigned int blksz; + unsigned int blocks; + + unsigned int postsleep_min_us; + unsigned int postsleep_max_us; + + unsigned int data_timeout_ns; + unsigned int cmd_timeout_ms; + + __u32 __pad; + + + __u64 data_ptr; +}; +#define mmc_ioc_cmd_set_data(ic, ptr) ic.data_ptr = (__u64)(unsigned long) ptr + +#define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd) +#ifdef CONFIG_MMC_CPRM_SUPPORT +struct mmc_ioc_cmd_extend { + struct sd_ssr ssr; + u32 ccs; + u32 capacity_of_protected_area_in_byte; + u32 card_status; + u32 capacity; +}; +#define MMC_IOC_CMD_EXTEND _IOR(MMC_BLOCK_MAJOR, 1, struct mmc_ioc_cmd_extend) +#endif +#define MMC_IOC_MAX_BYTES (512L * 256) +#endif + diff --git a/jni/major.h b/jni/major.h new file mode 100644 index 0000000..c72f162 --- /dev/null +++ b/jni/major.h @@ -0,0 +1,174 @@ +#ifndef _LINUX_MAJOR_H +#define _LINUX_MAJOR_H + + +#define UNNAMED_MAJOR 0 +#define MEM_MAJOR 1 +#define RAMDISK_MAJOR 1 +#define FLOPPY_MAJOR 2 +#define PTY_MASTER_MAJOR 2 +#define IDE0_MAJOR 3 +#define HD_MAJOR IDE0_MAJOR +#define PTY_SLAVE_MAJOR 3 +#define TTY_MAJOR 4 +#define TTYAUX_MAJOR 5 +#define LP_MAJOR 6 +#define VCS_MAJOR 7 +#define LOOP_MAJOR 7 +#define SCSI_DISK0_MAJOR 8 +#define SCSI_TAPE_MAJOR 9 +#define MD_MAJOR 9 +#define MISC_MAJOR 10 +#define SCSI_CDROM_MAJOR 11 +#define MUX_MAJOR 11 +#define XT_DISK_MAJOR 13 +#define INPUT_MAJOR 13 +#define SOUND_MAJOR 14 +#define CDU31A_CDROM_MAJOR 15 +#define JOYSTICK_MAJOR 15 +#define GOLDSTAR_CDROM_MAJOR 16 +#define OPTICS_CDROM_MAJOR 17 +#define SANYO_CDROM_MAJOR 18 +#define CYCLADES_MAJOR 19 +#define CYCLADESAUX_MAJOR 20 +#define MITSUMI_X_CDROM_MAJOR 20 +#define MFM_ACORN_MAJOR 21 +#define SCSI_GENERIC_MAJOR 21 +#define IDE1_MAJOR 22 +#define DIGICU_MAJOR 22 +#define DIGI_MAJOR 23 +#define MITSUMI_CDROM_MAJOR 23 +#define CDU535_CDROM_MAJOR 24 +#define STL_SERIALMAJOR 24 +#define MATSUSHITA_CDROM_MAJOR 25 +#define STL_CALLOUTMAJOR 25 +#define MATSUSHITA_CDROM2_MAJOR 26 +#define QIC117_TAPE_MAJOR 27 +#define MATSUSHITA_CDROM3_MAJOR 27 +#define MATSUSHITA_CDROM4_MAJOR 28 +#define STL_SIOMEMMAJOR 28 +#define ACSI_MAJOR 28 +#define AZTECH_CDROM_MAJOR 29 +#define FB_MAJOR 29 +#define CM206_CDROM_MAJOR 32 +#define IDE2_MAJOR 33 +#define IDE3_MAJOR 34 +#define Z8530_MAJOR 34 +#define XPRAM_MAJOR 35 +#define NETLINK_MAJOR 36 +#define PS2ESDI_MAJOR 36 +#define IDETAPE_MAJOR 37 +#define Z2RAM_MAJOR 37 +#define APBLOCK_MAJOR 38 +#define DDV_MAJOR 39 +#define NBD_MAJOR 43 +#define RISCOM8_NORMAL_MAJOR 48 +#define DAC960_MAJOR 48 +#define RISCOM8_CALLOUT_MAJOR 49 +#define MKISS_MAJOR 55 +#define DSP56K_MAJOR 55 + +#define IDE4_MAJOR 56 +#define IDE5_MAJOR 57 + +#define SCSI_DISK1_MAJOR 65 +#define SCSI_DISK2_MAJOR 66 +#define SCSI_DISK3_MAJOR 67 +#define SCSI_DISK4_MAJOR 68 +#define SCSI_DISK5_MAJOR 69 +#define SCSI_DISK6_MAJOR 70 +#define SCSI_DISK7_MAJOR 71 + +#define COMPAQ_SMART2_MAJOR 72 +#define COMPAQ_SMART2_MAJOR1 73 +#define COMPAQ_SMART2_MAJOR2 74 +#define COMPAQ_SMART2_MAJOR3 75 +#define COMPAQ_SMART2_MAJOR4 76 +#define COMPAQ_SMART2_MAJOR5 77 +#define COMPAQ_SMART2_MAJOR6 78 +#define COMPAQ_SMART2_MAJOR7 79 + +#define SPECIALIX_NORMAL_MAJOR 75 +#define SPECIALIX_CALLOUT_MAJOR 76 + +#define AURORA_MAJOR 79 + +#define I2O_MAJOR 80 + +#define SHMIQ_MAJOR 85 +#define SCSI_CHANGER_MAJOR 86 + +#define IDE6_MAJOR 88 +#define IDE7_MAJOR 89 +#define IDE8_MAJOR 90 +#define IDE9_MAJOR 91 + +#define DASD_MAJOR 94 + +#define MDISK_MAJOR 95 + +#define UBD_MAJOR 98 + +#define PP_MAJOR 99 +#define JSFD_MAJOR 99 + +#define PHONE_MAJOR 100 + +#define COMPAQ_CISS_MAJOR 104 +#define COMPAQ_CISS_MAJOR1 105 +#define COMPAQ_CISS_MAJOR2 106 +#define COMPAQ_CISS_MAJOR3 107 +#define COMPAQ_CISS_MAJOR4 108 +#define COMPAQ_CISS_MAJOR5 109 +#define COMPAQ_CISS_MAJOR6 110 +#define COMPAQ_CISS_MAJOR7 111 + +#define VIODASD_MAJOR 112 +#define VIOCD_MAJOR 113 + +#define ATARAID_MAJOR 114 + +#define SCSI_DISK8_MAJOR 128 +#define SCSI_DISK9_MAJOR 129 +#define SCSI_DISK10_MAJOR 130 +#define SCSI_DISK11_MAJOR 131 +#define SCSI_DISK12_MAJOR 132 +#define SCSI_DISK13_MAJOR 133 +#define SCSI_DISK14_MAJOR 134 +#define SCSI_DISK15_MAJOR 135 + +#define UNIX98_PTY_MASTER_MAJOR 128 +#define UNIX98_PTY_MAJOR_COUNT 8 +#define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT) + +#define DRBD_MAJOR 147 +#define RTF_MAJOR 150 +#define RAW_MAJOR 162 + +#define USB_ACM_MAJOR 166 +#define USB_ACM_AUX_MAJOR 167 +#define USB_CHAR_MAJOR 180 + +#define MMC_BLOCK_MAJOR 179 + +#define VXVM_MAJOR 199 +#define VXSPEC_MAJOR 200 +#define VXDMP_MAJOR 201 + +#define XENVBD_MAJOR 202 + +#define MSR_MAJOR 202 +#define CPUID_MAJOR 203 + +#define OSST_MAJOR 206 + +#define IBM_TTY3270_MAJOR 227 +#define IBM_FS3270_MAJOR 228 + +#define VIOTAPE_MAJOR 230 + +#define BLOCK_EXT_MAJOR 259 +#define SCSI_OSD_MAJOR 260 + +#endif + diff --git a/jni/mmc.h b/jni/mmc.h new file mode 100644 index 0000000..baa4a41 --- /dev/null +++ b/jni/mmc.h @@ -0,0 +1,53 @@ +#ifndef MMC_H_ +#define MMC_H_ + +#include + +/* + * EXT_CSD field definitions + */ +#define EXT_CSD_HPI_SUPP (1<<0) +#define EXT_CSD_HPI_IMPL (1<<1) +#define EXT_CSD_CMD_SET_NORMAL (1<<0) +#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40) +#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10) +#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04) +#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01) +#define EXT_CSD_BOOT_INFO_HS_MODE (1<<2) +#define EXT_CSD_BOOT_INFO_DDR_DDR (1<<1) +#define EXT_CSD_BOOT_INFO_ALT (1<<0) +#define EXT_CSD_BOOT_CFG_ACK (1<<6) +#define EXT_CSD_BOOT_CFG_EN (0x38) +#define EXT_CSD_BOOT_CFG_ACC (0x03) +#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7) +#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1) +#define EXT_CSD_PART_CONFIG_ACC_BOOT1 (0x2) +#define EXT_CSD_PART_CONFIG_ACC_USER_AREA (0x7) +#define EXT_CSD_PART_CONFIG_ACC_ACK (0x40) + +#define MMC_RSP_PRESENT (1 << 0) +#define MMC_RSP_136 (1 << 1) +#define MMC_RSP_CRC (1 << 2) +#define MMC_RSP_BUSY (1 << 3) +#define MMC_RSP_OPCODE (1 << 4) +#define MMC_CMD_AC (0 << 5) +#define MMC_CMD_ADTC (1 << 5) + +#define MMC_RSP_SPI_S1 (1 << 7) +#define MMC_RSP_SPI_BUSY (1 << 10) + +#define MMC_CMD_BCR (3 << 5) + +#define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1) +#define MMC_RSP_SPI_R1B (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY) + +#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) +#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) +#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) + +#include "ioctl.h" +#include "major.h" + + +#endif /* MMC_H_ */ + diff --git a/libs/armeabi/evoplus_cid b/libs/armeabi/evoplus_cid new file mode 100644 index 0000000000000000000000000000000000000000..f7908956967e506924ef3e4dfb68ab40cc806f5e GIT binary patch literal 13540 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