Coder Social home page Coder Social logo

samsung-firmware-magic's Introduction

Samsung Firmware Magic

Samsung distributes firmware updates for their SSDs for either "Windows" or "Mac". Ironically, both of these are bootable Linux .iso files, containing the actual firmware and update program.

The .iso files can be unpacked, but ultimately we end up with an obfuscated binary blob, even for the meta information.

For the upstream file downloads, see

https://www.samsung.com/semiconductor/minisite/ssd/download/tools/

Out of curiosity, I decided to create a decryption tool for this obfuscated format, which is found in this repository.

Unpacking iso image to firmware blob

First, we download a firmware iso:

`wget http://downloadcenter.samsung.com/content/FM/201711/20171102105105735/Samsung_SSD_850_PRO_EXM04B6Q_Win.iso`

Next, we unpack the relevant file from the iso, the initrd:

`7z x Samsung_SSD_850_PRO_EXM04B6Q_Win.iso initrd`

This file is a gzip-compressed cpio archive, so use 7z to strip gzip:

`7z x initrd`

This produces initrd~, containing the uncompressed contents. From here we extract the directory of interest, root/fumagician:

`7z -ofw x 'initrd~' root/fumagician`

This creates fw/root/fumagician in the current directory:

$ cd fw/root/fumagician
$ ls -l
total 5408
-rw-rw-r-- 1 user user    2124 1971-03-22 19:52 DSRD.enc
-rw-rw-r-- 1 user user 4752867 1971-03-22 19:52 EXM04B6Q.enc
-rw-rw-r-- 1 user user  772516 2016-10-14 10:42 fumagician
-rw-rw-r-- 1 user user     290 2016-10-14 10:42 fumagician.sh

The files DSRD.enc (xml list of firmwares) and EXM04B6Q.enc (firmwares) are the obfuscated files, that we can now decrypt.

Decrypting firmware blob

The included decode.py script will unpack these .enc files, like so:

## show xml on stdout:
$ ./samsung-magic.py < fw/root/fumagician/DSRD.enc

## decrypt firmware to file:
$ ./samsung-magic.py < fw/root/fumagician/EXM04B6Q.enc > EXM04B6Q.bin

Seemingly, the folks at Samsung are huge fans of nesting things, because the decrypted EXM04B6Q.bin file is actually a zip file, containing encrypted firmware files:

$ unzip -l EXM04B6Q.bin
Archive:  EXM04B6Q.bin
  Length      Date    Time    Name
---------  ---------- -----   ----
  1048576  2017-02-19 10:41   EXM04B6Q_10170217.enc
  1048576  2017-02-19 10:41   EXM04B6Q_20170203.enc
  1048576  2017-02-19 10:41   EXM04B6Q_30170203.enc
  1048576  2017-02-19 10:41   EXM04B6Q_40170902.enc
  1048576  2017-02-19 10:41   EXM04B6Q_50170208.enc
  1048576  2017-02-19 10:41   EXM04B6Q_60170208.enc
---------                     -------
  6291456                     6 files

Luckily, the encryption is exactly the same, so samsung-magic.py can decrypt these as well:

$ unzip EXM04B6Q.bin
$ ./samsung-magic.py < EXM04B6Q_10170217.enc > EXM04B6Q_10170217.bin

Now, at last, we have the raw firmware.

Enjoy!

samsung-firmware-magic's People

Contributors

chrivers avatar xyzzy42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

samsung-firmware-magic's Issues

how to flash the extracted firmware?

Hello, pardon my ignorance, but is it possible to flash the extracted firmware using some common tool like fwupd?

Do you know any other software to flash the firmware, not fumagician?

AttributeError: 'str' object has no attribute 'decode'

Hi,

I wanted to try this out under Linux & Python 3.8.5, but I'm facing the following issue:

[tolga@estheim Samsung]$ ./samsung-magic.py < DSRD.enc 
Traceback (most recent call last):
  File "./samsung-magic.py", line 48, in <module>
    iv0 = "8ce82eefbea0da3c44699ed7".decode("hex")
AttributeError: 'str' object has no attribute 'decode'

As always with Python stuff, I suspect it's an issue with the Python version. What's the recommended version or the version you use?

Thanks!

error

file: Samsung_SSD_850_EVO_EMT02B6Q_Win.iso

$ python3 ~/samsung-magic.py <DSRD.enc >DSRD.xml
Traceback (most recent call last):
  File "/home/zibri/samsung-magic.py", line 51, in <module>
    aes = AES.new(key, AES.MODE_ECB)
  File "/home/zibri/.local/lib/python3.10/site-packages/Crypto/Cipher/AES.py", line 95, in new
    return AESCipher(key, *args, **kwargs)
  File "/home/zibri/.local/lib/python3.10/site-packages/Crypto/Cipher/AES.py", line 59, in __init__
    blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs)
  File "/home/zibri/.local/lib/python3.10/site-packages/Crypto/Cipher/blockalgo.py", line 141, in __init__
    self._cipher = factory.new(key, *args, **kwargs)
SystemError: PY_SSIZE_T_CLEAN macro must be defined for '#' formats

Re-Encoding

Hello, sorry for my ignorance on the developer side of things, but by chance how can I re-encode the firmware after updating the DSRD with ANY so I can push it to a corrupt drive? I was able to do it with the available scripts out there for the older version EXM02B6Q but this drive was already running EXM04B6Q when it corrupted. I can access safe mode on the drive but since the EXM04B6Q firmware actually consists of multiple 1MB pieces, I can't use the old ISOLINUX dos updater since the BTDSK.IMG has to stay the same size and EXM04B6Q has multiple 1MB pieces.

Can not decode firmware for Evo 860

Hello, I;ve tried to decode firmware for SSD EVO 860 but didn't manage to do so, could you please help?
Here is the reproducible script:

#!/bin/env bash
set -x 
echo 'Go to /tmp dir'
cd /tmp
echo 'Download iso'
wget https://s3.ap-northeast-2.amazonaws.com/global.semi.static/SAMSUNG_SSD_860_EVO_200217/FW/F1EACA63909EC0059B675B9E5CDE3AA96C4A2D752FB6B7B27C8E0CC4025411BA/Samsung_SSD_860_EVO_RVT04B6Q_Win.iso
echo 'Extract initrd'
7z x Samsung_SSD_860_EVO_RVT04B6Q_Win.iso initrd
echo 'Extract initrd~'
7z x initrd
echo 'Extract root/fumagician'
7z -ofw x 'initrd~' root/fumagician
cd fw/root/fumagician
echo 'Download samsung-magic.py'
wget https://raw.githubusercontent.com/chrivers/samsung-firmware-magic/master/samsung-magic.py
echo 'Decode firmware'
python2 ./samsung-magic.py < DSRD.enc > DSRD.bin
hexdump -C DSRD.bin
echo -e '\n\n'
echo 'Decoding failed: file is binary'
file DSRD.bin

And also I have a question: what is the target arh of extracted binary?
Thanks

Ported to C

I have ported this to C. Now, we are utilizing the Windows Crypto API, however it fails to import key. Win32 console application. If anyone knows how to resolve this, by all means let me know. At this point, I really have no idea. Perhaps a difference between Python3's AES implementation, and the Crypto API. Here it is. Compiled with Pelles C v12 (C17 standard).

#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <windows.h>
#include <wincrypt.h>

/* Define the shuffle map that Samsung uses */
const uint8_t shuffle[] = {
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
    0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x30, 0x31, 0x32, 0x33,
    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
    0x3E, 0x3F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x70, 0x71,
    0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B,
    0x7C, 0x7D, 0x7E, 0x7F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
    0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
    0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xD0, 0xD1, 0xD2, 0xD3,
    0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD,
    0xDE, 0xDF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
    0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xE0, 0xE1,
    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB,
    0xEC, 0xED, 0xEE, 0xEF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5,
    0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9,
    0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0x80, 0x81, 0x82, 0x83,
    0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D,
    0x8E, 0x8F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x40, 0x41,
    0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
    0x4C, 0x4D, 0x4E, 0x4F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
    0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
    0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};

/* Generate reverse map */
uint8_t lookup[256];

/* Generate reverse map */
uint8_t lookup[256];

/* Utility function to perform XOR operation */
void xor_buffers(const uint8_t *s1, const uint8_t *s2, uint8_t *result, size_t length) {
    for (size_t i = 0; i < length; i++) {
        result[i] = s1[i] ^ s2[i];
    }
}

/* Unshuffle function */
void unshuffle_buffer(const uint8_t *input, uint8_t *output, size_t length) {
    for (size_t i = 0; i < length; i++) {
        output[i] = lookup[input[i]];
    }
}

static HCRYPTKEY hKey;
static HCRYPTHASH hHash;

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <input_file> <output_file>\n", argv[0]);
        return 1;
    }

    /* Initialize reverse lookup table */
    for (int i = 0; i < 256; i++) {
		lookup[(unsigned char)shuffle[i]] = (unsigned char)i;
    }

    /* Crypto constants */
    uint8_t iv0[] = { 0x8C, 0xE8, 0x2E, 0xEF, 0xBE, 0xA0, 0xDA, 0x3C, 0x44, 0x69, 0x9E, 0xD7 };
    uint8_t key[] = { 0x56, 0xE4, 0x7A, 0x38, 0xC5, 0x59, 0x89, 0x74, 0xBC, 0x46, 0x90, 0x3D, 0xBA, 0x29, 0x03, 0x49 };
    int ctr = 0;

    /* Initialize Windows Crypto API */
    HCRYPTPROV hCryptProv = 0;
    if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
        fprintf(stderr, "Error acquiring context.\n");
        return 1;
    }

    /* Import key */
    if (!CryptImportKey(hCryptProv, key, sizeof(key), 0, 0, &hKey)) {
        fprintf(stderr, "Error importing key.\n");
        CryptReleaseContext(hCryptProv, 0);
        return 1;
    }

    FILE *input_file = fopen(argv[1], "rb");
    if (!input_file) {
        perror("Error opening input file");
        CryptDestroyKey(hKey);
        CryptReleaseContext(hCryptProv, 0);
        return 1;
    }

    FILE *output_file = fopen(argv[2], "wb");
    if (!output_file) {
        perror("Error opening output file");
        fclose(input_file);
        CryptDestroyKey(hKey);
        CryptReleaseContext(hCryptProv, 0);
        return 1;
    }

    /* Main loop to process blocks */
    while (1) {
        uint8_t blk[16];
        size_t bytes_read = fread(blk, 1, sizeof(blk), input_file);

        if (bytes_read == 0) {
            break; // End of input file
        }

        /* Samsung arbitrarily resets the counter every 32 blocks */
        ctr = (ctr % 32) + 1;

        uint8_t iv[20];
        memcpy(iv, iv0, sizeof(iv0));
        iv[16] = (ctr >> 24) & 0xFF;
        iv[17] = (ctr >> 16) & 0xFF;
        iv[18] = (ctr >> 8) & 0xFF;
        iv[19] = ctr & 0xFF;

        /* Use AES encryption in ECB mode */
        uint8_t xblk[16];
        DWORD xblk_size = sizeof(xblk);
        if (!CryptEncrypt(hKey, 0, TRUE, 0, xblk, &xblk_size, sizeof(xblk))) {
            fprintf(stderr, "Error encrypting data.\n");
            fclose(input_file);
            fclose(output_file);
            CryptDestroyKey(hKey);
            CryptDestroyHash(hHash);
            CryptReleaseContext(hCryptProv, 0);
            return 1;
        }

        /* Decrypt and unshuffle to get the result */
        uint8_t res[16];
        xor_buffers(xblk, blk, res, sizeof(res));
        unshuffle_buffer(res, res, sizeof(res));

        fwrite(res, 1, sizeof(res), output_file);
    }

    /* Cleanup */
    fclose(input_file);
    fclose(output_file);
    CryptDestroyKey(hKey);
    CryptReleaseContext(hCryptProv, 0);

    return 0;
}

960 Evo firmware doesn't decode

Trying to decode the DSRD.enc and firmware file from Samsung_SSD_960_EVO_3B7QCXE7.iso didn't work for me. Output was just garbage, not XML or a zip file for the DSRD and firmware, respectively.

It did work for the contents of Samsung_SSD_850_PRO_EXM04B6Q_Win.iso used in the readme.

I guess Samsung are being jerks and changed their obfuscation again.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.