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 0000000..f790895 Binary files /dev/null and b/libs/armeabi/evoplus_cid differ