[SOLVED] Help to root a Medion LifeTab X10302 (MD 60347)

Search This thread

Vince_02100

Member
Dec 25, 2016
10
12
Hi everyone,

Like the title said, I'm searching a way to root this tablet based on MediaTek.

Aida64 Information :
CPU : MT8783 (64 Bits ARMv8-A Cortex A53 octa-cores @ 1.3Ghz)
Platform : MT6753
Hardware : MT6735
Manufacturer : Lenovo
Brand : Medion
Display : Mali-T720 [email protected], 225 dpi
RAM : 2GB DDR3
ROM : 32GB MMC


After unlocking the bootloader :
  • I have tried some tools like iRoot, KingRoot, Kingo Root, Genius Root, and more that I can find with some search with google, but no one work.
  • I have tried to boot a TWRP/CWM Recovery image based on the same hardware or platform (fastboot boot myrecovery.img), the device reboot in normal mode, or I need to make these recovery for my hadware, but I think it need a rooted device...
  • I have tried to use MTK Droid Tools 2.5.3d, this software couldn't found the rom structure (this software doesn't found my IMEI too), and manualy with adb :
    • cat /proc/mtd
      file is empty
    • cat /proc/emmc
      file doesn't exist
    • cat /proc/partitions
      Code:
      major minor  #blocks  name
      
         7        0       1254 loop0
       254        0     975236 zram0
       179        0   30535680 mmcblk0
       179        1       3072 mmcblk0p1
       179        2       5120 mmcblk0p2
       179        3      10240 mmcblk0p3
       179        4      10240 mmcblk0p4
       179        5        512 mmcblk0p5
       179        6        512 mmcblk0p6
       179        7      16384 mmcblk0p7
       179        8      16384 mmcblk0p8
       179        9       8192 mmcblk0p9
       179       10      10240 mmcblk0p10
       179       11        512 mmcblk0p11
       179       12       2048 mmcblk0p12
       179       13       6144 mmcblk0p13
       179       14       8192 mmcblk0p14
       179       15       5120 mmcblk0p15
       179       16       5120 mmcblk0p16
       179       17       1024 mmcblk0p17
       179       18      32768 mmcblk0p18
       179       19      37888 mmcblk0p19
       179       20    2621440 mmcblk0p20
       179       21     409600 mmcblk0p21
       179       22   27307520 mmcblk0p22
       179       23      16384 mmcblk0p23
       179       96       4096 mmcblk0rpmb
       179       64       4096 mmcblk0boot1
       179       32       4096 mmcblk0boot0
       179      128    7565312 mmcblk1
       179      129    7564288 mmcblk1p1
       253        0    2600764 dm-0
       253        1   27307520 dm-1
    • cat /etc/recovery.fstab
      Code:
      # mount point   fstype          device                  [device2]
      
      /boot           emmc            boot
      /cache          ext4            /dev/block/mmcblk0p4
      /data           ext4            /dev/block/mmcblk0p5
      /misc           emmc            misc
      /recovery       emmc            recovery
      /sdcard         vfat            /dev/block/mmcblk0p6
      /system         ext4            /dev/block/mmcblk0p3
    • ls -l /dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name
      Permission denied

After some search, it's possible that this device has the same hardware like the Lenovo Phab 2 Plus (correct me if i'm wrong).
If anyone has some idea to root this device, It's would be great ^^

Regards

PS : Sorry if my english is wrong
 
Last edited:
  • Like
Reactions: derelse and bragih

Vince_02100

Member
Dec 25, 2016
10
12
I have follow a lot of "how to", create a scatter file and try to read-back with SPFT from Windows 7, 10 and Ubuntu 16.04 LTS all I have is
=> BROM_ERROR S_DL_GET_DRAM_SETTING_FAIL (5054)
With Miracle Box v2.27A, it don't find the device....

I have trying to boot a custom recovery based on same hardware / cpu, the device reboot in normal mode ^^'

So, now, we have just to see with Medion, they can send the source-code and maybe stock-rom.
(I don't know why it's not available on their support website... :/ )
 

bragih

Senior Member
Feb 19, 2008
194
21
I've been in contact with [email protected] and they stated, that they only release a recovery kit (what we need for safely rooting the tablet) when they release an update for the tablet that gives users problems and they need to go back/recover the tablet themselves.

I think it would be helpful if people who would like to root their tablet contact Medion at [email protected] to let them see that there is a demand for those files. Hopefully they will release it then.
 

diyabolic

Senior Member
Nov 27, 2011
214
36
Cologne
Xiaomi Poco F3
I got the same answer. After ota we will have recovery kit. But I am not sure we will have updates

Guys, can you see which app is using the battery? I only get the graph and battery usage data isn't available. I tried with hard reset and it didn't help
 
Last edited:

bragih

Senior Member
Feb 19, 2008
194
21
I got the same answer. After ota we will have recovery kit. But I am not sure we will have updates

Guys, can you see which app is using the battery? I only get the graph and battery usage data isn't available. I tried with hard reset and it didn't help

I didn't realise it before but I have the same bug. I also only have the graph.

Hey, maybe that's a reason for an OTA! :D:D
 

Vince_02100

Member
Dec 25, 2016
10
12
Hey guys :eek:

I have found a way to root this device and worked for me, and work certainly for all other un-rooted device.

For some curious, I explain below what I have doing to dump recovery partition and boot.
For other, you can find the ZIP link at the end of this post.

With the DirtyCow exploit, it's very easy to dump our boot or recovery partition but need a little time without a custom recovery working...
In a first step, read this : h**ps://github.com/jcadduono/android_external_dirtycow#running
(a big thank's to jcadduono ! ;))
Ok, it's need an Android OS Environnement and it's not for our device, but it's not realy a problem.

A little modification to this file < recowvery-applypatch.c > to dump our recovery or boot partition, like this :
Code:
#include <unistd.h>
#include <stdio.h>

#include <stdint.h>
#include <time.h>

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>

#define APP_NAME  "recowvery"
#define HOST_NAME "applypatch"

#ifdef DEBUG
#include <android/log.h>
#define LOGV(...) { __android_log_print(ANDROID_LOG_INFO,  APP_NAME, __VA_ARGS__); printf(__VA_ARGS__); printf("\n"); }
#define LOGE(...) { __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
#else
#define LOGV(...) { printf(__VA_ARGS__); printf("\n"); }
#define LOGE(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
#endif

#define SEP LOGV("------------")

#include "bootimg.h"

/* Time delay in microsecond for next loop (1000 = 1ms)
 * 1ms is good for every PC
 * (you can try less than 1ms to speed the process, but you can have an <unexpected EOF>)
 */
#define DELAY_T			1000

/* For Medion LifeTab X10302 (May work on same hardware MT6735/MT6753)
 * You can define BLOCK_EMMC to other path if needed.
 * Use < adb shell mount > for help.
 */
#define BLOCK_EMMC		"/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/boot"
//#define BLOCK_EMMC		"/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/recovery"
//#define BLOCK_EMMC		"/dev/block/platform/any-folder-point-to-by-name-folder/by-name/boot"

void delay(long t)
{
	long timens = t * 1000;
	nanosleep((const struct timespec[]){{0, timens}}, NULL);
}

int main(int argc, char **argv)
{
	int ret = 0;
	int i = 0;

	LOGV("Welcome to %s! (%s)", APP_NAME, HOST_NAME);
	
	for (i = 30; i > 0; i--)
	{
		LOGV("The process start in %is", i);
		sleep(1);
	}

	byte rb[32];
	char *content = malloc(256);
	FILE *filetest;
	size_t nread;
	
	filetest = fopen(BLOCK_EMMC, "r");
	if (filetest) {
		LOGV("*** DUMP START ***");
		LOGV("* BLOCK_EMMC = %s", BLOCK_EMMC);
		while ((nread = fread(rb, 1, sizeof rb, filetest)) > 0)
		{
			sprintf(content, "HEXDUMP = [");
			for (i = 0; i < (int)nread; i++)
			{
				if (i == 0)
					sprintf(content, "%s%.2x", content, rb[i]);
				else
					sprintf(content, "%s,%.2x", content, rb[i]);
			}
			sprintf(content, "%s];", content);
			LOGV("%s", content);
			
			/* sleep to prevent any unexpected EOF with with pipe stream
			 * ex : adb logcat | my-prg.exe
			 */
			delay(DELAY_T);
		}
    
		if (ferror(filetest)) {
			ret = 1;
			LOGE("*** DUMP ERROR ***");
			LOGE("Error while reading the file...");
		}
		
		LOGV("*** DUMP END ***");
		fclose(filetest);
	}
	else
	{
		LOGV("Can't read the file...");
		ret = 1;
		goto oops;
	}
	
	return 0;
oops:
	LOGE("*** DUMP ERROR ***");
	LOGE("Error %d: %s", ret, strerror(ret));
	LOGE("Exiting...");
	return ret;
}
(Edit : Added a delay in loop, there is some time an <unexpected EOF> during the process)

What it does ?
When launched by <recowvery-app_process>, it only open "/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/boot" (in my exemple) in read-only and do like a HexDump, or something else.
It's human readable, and visible from Windows or any Linux distribution via the command adb logcat -s recowvery. But, we need something to do the revert :silly:

To solve this issue, I have made a to do this for me :cool:
C# code version : (not opti)
Code:
/*
 * Created by SharpDevelop.
 * User: vince
 * Date: 16/01/2017
 * Time: 17:34
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace HexDumpReader
{
	class Program
	{
		private static string workingDir = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar;
		private static string outfile = null;
		private static List<string> datalist = new List<string>();
		
		public static int Main(string[] args)
		{
			int val = 0;
			int ncrash = 0;
			
			if (args.Length == 0 || Console.In.Peek() == -1)
			{
				DisplayUsage();
				return 1;
			}
			
			try
			{
				// Shorter regex is possible, but I prefer like that.
				// Used to start the process
				Regex rs = new Regex("\\*\\*\\* DUMP START \\*\\*\\*");
				// Used to match all data block, and populate < datalist >
				Regex rl = new Regex("^\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}\\s{1,2}\\d{3,5}\\s{1,2}\\d{3,5} I recowvery: HEXDUMP = \\[([^\\]].*)\\];$");
				// Used to break the infinite loop and start parsing all data
				Regex rf = new Regex("\\*\\*\\* DUMP END \\*\\*\\*");
				// Used to intercept error from < recowvery-applypatch >
				Regex re = new Regex("\\*\\*\\* DUMP ERROR \\*\\*\\*");
				
				outfile = args[0];
				bool start = false;
				bool reboot = false;
				
				/* If we want a reboot while finish */
				if (args.Length > 1)
					reboot = (args[1] == "-r");
				
				while (true)
				{
					string line = Console.In.ReadLine();
					
					/*
					 * If an unexpected EOF from recowvery-applypatch...
					 * We can't receive a null string, close fsout, set start to false and break the loop after 3 crashs.
					 */
					if (line == null)
					{
						
						Console.WriteLine("* < null > received !");
						Console.WriteLine("Try again...");
						break;
					}
					
					/*
 					 * *** DUMP START ***
 					 * set start = true, and init fsout FileStream
 					 */
					if (rs.IsMatch(line))
						start = true;
					
					/*
					 * Add all matched group from HEXDUMP line to datalist.
					 * Note :
					 *   It's possible to have matched line before intercept DUMP START,
					 *   If we convert now, it's a good idea to have a broken output file.
					 * Important :
					 *   Never try to parse all data on the fly, you can have a mysterious "unexpected EOF" error.
					 */
					if (start && rl.IsMatch(line))
					{
						datalist.Add(rl.Replace(line, "$1"));
						Console.CursorLeft = 0;
						Console.Write("Block read : " + datalist.Count);
					}
					/*
					 * Display the other lines (for debuging, logging...)
					 */
					else if (!rl.IsMatch(line) && (!rf.IsMatch(line) && !start) && line.Length > 1)
					{
						Console.WriteLine(line);
					}
					
					/*
					 * *** DUMP END ***
					 * Flush and close fsout, inform the user, and break the loop.
					 */
					if (start && rf.IsMatch(line))
						break;
					
					/*
					 * *** DUMP ERROR ***
					 * An error intercepted from ADB, close fsout, set start to false.
					 * < applypatch > will restart every 3 min.
					 * We break the loop after 3 errors.
					 */
					if (re.IsMatch(line))
					{
						Console.WriteLine("* Error received from ADB *");
						
						start = false;
						if (ncrash == 3)
						{
							Console.WriteLine("* Too many tries, please check your < recowvery-applypatch.c > and try again.");
							break;
						}
						Console.WriteLine("* Be patient, recowvery-applypatch will restart in a few minutes.");
						ncrash++;
					}
				}
				
				Console.WriteLine();
				Console.WriteLine("Parsing blocks...");
				
				/* recowvery-applypatch read by block of 32 bytes.
				 * so, we can calculate the final size.
				 */
				double finalSize = 32 * datalist.Count;
				/* used to display the new progression */
				int lastprogress = 0;
				
				FileStream fsout = File.OpenWrite(outfile);
				fsout.SetLength(0);
				foreach(string s in datalist)
				{
					string[] data = s.Split(',');
					
					for (int c = 0; c < data.Length; c++)
					{
						try
						{
							byte[] b = StringToByteArrayFastest(data[c]);
							fsout.Write(b, 0, b.Length);
							
							/* Calculate progression */
							int progress = (int)(((double)fsout.Position / finalSize) * 100);
							/* Display the progression if needed */
							if (progress != lastprogress)
							{
								Console.CursorLeft = 0;
								Console.Write("Processing... " + progress + "% ");
								lastprogress = progress;
							}
						}
						catch(Exception ex)
						{
							Console.WriteLine();
							Console.WriteLine("** Exception **");
							Console.WriteLine(" - When convert : " + data[c]);
							Console.WriteLine(" - Message      : " + ex.Message);
							Console.WriteLine(" - StackTrace   : " + ex.StackTrace);
						}
					}
				}
				fsout.Flush();
				fsout.Close();
				
				Console.WriteLine();
				Console.WriteLine("Finish !");
				
				if (reboot)
					rebootDevice();
				else
					Console.WriteLine("You can reboot your device.");
			}
			catch(Exception e)
			{
				Console.WriteLine("*** Exception ***");
				Console.WriteLine(" - Message    : " + e.Message);
				Console.WriteLine(" - Source     : " + e.Source);
				Console.WriteLine(" - StackTrace : " + e.StackTrace);
				val = e.HResult;
			}
			
			return val;
		}
		
		public static void DisplayUsage()
		{
			Console.WriteLine("Usage :");
			Console.WriteLine(" adb logcat -s recowvery | " + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe myImage-output.img [-r]");
			Console.WriteLine();
			Console.WriteLine(" -r : Reboot your device when finish.");
			Console.WriteLine("      (Run \"adb reboot\" for you)");
		}
		
		public static void rebootDevice()
		{
			ProcessStartInfo psi;
			Process p;
			string strout = "";
			string strerr = "";
			
			psi = new ProcessStartInfo("adb.exe", "reboot");
			psi.WorkingDirectory = workingDir;
			psi.RedirectStandardError = true;
			psi.RedirectStandardOutput = true;
			psi.UseShellExecute = false;
			
			Console.WriteLine("Rebooting your device...");
			
			p = new Process();
			p.StartInfo = psi;
			p.Start();
			
			if (!p.StandardError.EndOfStream)
				strerr = p.StandardError.ReadToEnd();
			if (!p.StandardOutput.EndOfStream)
				strout = p.StandardOutput.ReadToEnd();
			
			if (strout.Length > 0)
				Console.WriteLine(strout);
			if (strerr.Length > 0)
			{
				Console.WriteLine(strerr);
			}
			
			p.WaitForExit();
		}
		
		public static byte[] StringToByteArrayFastest(string hex) {
		    if (hex.Length % 2 == 1)
		        throw new Exception("The binary key cannot have an odd number of digits");
		
		    byte[] arr = new byte[hex.Length >> 1];
		
		    for (int i = 0; i < hex.Length >> 1; ++i)
		    {
		        arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
		    }
		
		    return arr;
		}
		
		public static int GetHexVal(char hex) {
		    int val = (int)hex;
		    //For uppercase A-F letters:
		    //return val - (val < 58 ? 48 : 55);
		    //For lowercase a-f letters:
		    return val - (val < 58 ? 48 : 87);
		    //Or the two combined, but a bit slower:
		    //return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
		}
	}
}

To compile the C# code, you need :
  • An IDE like SharpDevelop, MonoDevelop, or VisualStudio
  • Create a <New Project> and select <Console Application>
  • copy the code below, and replace all to your main.cs or program.cs.
  • Run it

C++ code version : (Working good on Ubuntu 16.04, Windows too but not tested)
Code:
#include <iostream>
#include <regex>
#include <stdio.h>

typedef unsigned char byte;

using namespace std;

void DisplayUsage()
{
    cout << string("Usage :") << endl;
    cout << string(" adb logcat -s recowvery | ") << string("HexDumpReader") << string(".exe myImage-output.img [-r]") << endl;
    cout << endl;
    cout << string(" -r : Reboot your device when finish.") << endl;
    cout << string("      (Run \"adb reboot\" for you)") << endl;
}

void split(const string &s, char delim, vector<string> &elems) {
    stringstream ss;
    ss.str(s);
    string item;
    while (getline(ss, item, delim)) {
        elems.push_back(item);
    }
}

vector<string> split(const string &s, char delim) {
    vector<string> elems;
    split(s, delim, elems);
    return elems;
}

void string_to_bytearray(std::string str, unsigned char* &array, int& size)
{
	int length = str.length();
	// make sure the input string has an even digit numbers
	if(length%2 == 1)
	{
		str = "0" + str;
		length++;
	}

	// allocate memory for the output array
	array = new unsigned char[length/2];
	size = length/2;

	std::stringstream sstr(str);
	for(int i=0; i < size; i++)
	{
		char ch1, ch2;
		sstr >> ch1 >> ch2;
		int dig1, dig2;
		if(isdigit(ch1)) dig1 = ch1 - '0';
		else if(ch1>='A' && ch1<='F') dig1 = ch1 - 'A' + 10;
		else if(ch1>='a' && ch1<='f') dig1 = ch1 - 'a' + 10;
		if(isdigit(ch2)) dig2 = ch2 - '0';
		else if(ch2>='A' && ch2<='F') dig2 = ch2 - 'A' + 10;
		else if(ch2>='a' && ch2<='f') dig2 = ch2 - 'a' + 10;
		array[i] = dig1*16 + dig2;
	}
}

void rebootDevice()
{
    system("adb reboot");
}

int main(int argc, char** argv)
{
    /* Display help if no argument */
    if (argc == 1)
    {
        DisplayUsage();
        return 1;
    }

    cout << string("*** HexDumpReader ***") << endl;

    int val = 0;
    vector<string> datalist;
    string outfile = string(argv[1]);
    bool reboot = false;
    int ncrash = 0;

    /* Output image file */
    cout << string("* Output file : ") << outfile << endl;
    /* If we want a reboot while finish */
    if (argc > 2)
    {
        reboot = (string(argv[2]) == "-r");
    }
    cout << string("* Reboot device : ") << reboot << endl;

    try
    {
        // Shorter regex is possible, but I prefer like that.
        // Used to start the process
        regex rs("^.+I recowvery: (\\*\\*\\* DUMP START \\*\\*\\*)\\s+");
        // Used to match all data block, and populate < datalist >
        regex rl("^.+I recowvery: HEXDUMP = \\[([^\\]]+)\\];\\s+");
        // Used to break the infinite loop and start parsing all data
        regex rf("^.+I recowvery: (\\*\\*\\* DUMP END \\*\\*\\*)\\s+");
        // Used to intercept error from < recowvery-applypatch >
        regex re("^.+I recowvery: (\\*\\*\\* DUMP ERROR \\*\\*\\*)\\s+");

        /* write or not to output file */
        bool start = false;

        FILE *fsout;
        fsout = fopen(outfile.c_str(), "wb");
        int nBlock = 0;
        long currentSize = 0;

        while (true)
        {
            string line;
            getline(cin, line);

            /*
             * If an unexpected EOF from recowvery-applypatch or if no <pipe>...
             * We can't receive a null string, so break the loop, close fsout, and exit the program.
             */
            if (line.empty())
            {
                cout << string("* < null > received !") << endl;
                cout << string("Try again...") << endl;
                break;
            }

            /*
              * *** DUMP START ***
              * set start = true to write parsed data to fsout
              */
            if (regex_match(line, rs))
            {
                start = true;
            }

            /*
             * Parse all string received if match
             * Note :
             *   It's possible to have matched string before intercept DUMP START,
             *   If we convert now, it's a good idea to have a broken output file.
             */
            if (start && regex_match(line, rl))
            {
                string s = regex_replace(line, rl, "$1");
                vector<string> data = split(s, ',');
                for (int c = 0; c < (int)data.size(); c++)
                {
                    try
                    {
                        byte *b = NULL;
                        int sb;
                        string_to_bytearray(data[c], b, sb);
                        fwrite(b, 1, sb, fsout);
                    }
                    catch (const std::exception &ex)
                    {
                        std::cout << std::endl;
                        std::cout << std::string("** Exception **") << std::endl;
                        std::cout << std::string(" - When convert : ") << data[c] << std::endl;
                        std::cout << std::string(" - Message      : ") << ex.what() << std::endl;
                    }
                }
                nBlock++;
                currentSize = nBlock * 32;

                std::cout << "\r";
                std::cout << std::string("Block read : ") << nBlock << string(" (Size : ") << currentSize << string(")");
            }
            /*
             * Display the other lines (for debuging, logging...)
             */
            else if (!regex_match(line, rl) && (!regex_match(line, rf) && !start) && line.length() > 1)
            {
                std::cout << line << std::endl;
            }

            /*
             * *** DUMP END ***
             * Flush and close fsout, inform the user, and break the loop.
             */
            if (start && regex_match(line, rf))
            {
                break;
            }

            /*
             * *** DUMP ERROR ***
             * An error intercepted from ADB, close fsout, set start to false.
             * < applypatch > will restart every 3 min.
             * We break the loop after 3 errors.
             */
            if (regex_match(line, re))
            {
                cout << std::string("* Error received from ADB *") << std::endl;

                start = false;
                if (ncrash == 3)
                {
                    cout << std::string("* Too many tries, please check your < recowvery-applypatch.c > and try again.") << std::endl;
                    break;
                }
                cout << std::string("* Be patient, recowvery-applypatch will restart in a few minutes.") << std::endl;
                ncrash++;
            }
        }

        cout << endl;

        fclose(fsout);

        cout << std::endl;
        cout << std::string("Finish !") << std::endl;

        if (reboot)
        {
            rebootDevice();
        }
        else
        {
            std::cout << std::string("You can reboot your device.") << std::endl;
        }
    }
    catch (const std::exception &e)
    {
        std::cout << std::string("*** Exception ***") << std::endl;
        std::cout << std::string(" - Message    : ") << e.what() << std::endl;
    }

    return val;
}
To build it, you need these CFLAGS : -m32 -std=C++11 -Wall (maybe -g for debug)
Ex :
g++ -Wall -fexceptions -g -Wall -std=c++11 -m32 -g -c main.cpp -o main.o
g++ -o HexDumpReader main.o -m32


Now, how It work ?
How can I dump my boot or recovery partition and make my own TWRP ? :crying:
It's like jcadduono explain here : h**ps://github.com/jcadduono/android_external_dirtycow
Follow only this steps :
Code:
adb push dirtycow /data/local/tmp
adb push recowvery-applypatch /data/local/tmp
adb push recowvery-app_process64 /data/local/tmp
adb push recowvery-run-as /data/local/tmp

adb shell

$ cd /data/local/tmp
$ chmod 0777 *
$ ./dirtycow /system/bin/applypatch recowvery-applypatch
"<wait for completion>"
$ ./dirtycow /system/bin/app_process64 recowvery-app_process64
"<wait for completion, your phone will look like it's crashing>"
$ exit

(It's change here =>)
adb logcat -s recowvery | HexDumpReader %USERPROFILE%\Documents\my-image-output.img -r

Wait a moment, you will see that it's finish, and you may see <my-image-output.img> in <%USERPROFILE%\Documents> folder.
You can try to extract your image from MKTool or any Kitchen tools, it's work, and finally make your TWRP, boot from it, backup your roms (if you have never doing this) and finally root your device.

I know that some of you can't do all these steps, or need simply the final image, you can download it from this url :
ZIP File : h**ps://goo.gl/IT7dpl (Contains original boot, recovery, TWRP & a readme)
(Bug found : battery stuck at 50%)
 
Last edited:
  • Like
Reactions: bragih and greenoid

Vince_02100

Member
Dec 25, 2016
10
12
Thanks dude for your effort , you're the man
Is there a chance to fix the battery bug?

Sent from my D6503 using Tapatalk
Hmmm... Without source code of this device, it's difficult to say if it's a TWRP issue or Kernel issue, or something else (It's possible that I miss something).
About the source code, a mail has been sent to Medion a days ago, but no answer...

In case if I've miss something, if someone can help, or give me a way to solve this ^^
 

diyabolic

Senior Member
Nov 27, 2011
214
36
Cologne
Xiaomi Poco F3
Hmmm... Without source code of this device, it's difficult to say if it's a TWRP issue or Kernel issue, or something else (It's possible that I miss something).
About the source code, a mail has been sent to Medion a days ago, but no answer...

In case if I've miss something, if someone can help, or give me a way to solve this ^^
It's it charging till 50% or only indicating that is charged till 50 but actually is fully charged?

Sent from my D6503 using Tapatalk
 

kamilodiabolo

Member
Apr 19, 2015
5
0
39
I try to root MD60348. I UNLOCK BOOTLOADER. Then stop. I cant do nothing. Device only back to factory setings...
 

Gadgetto

New member
Feb 17, 2017
3
9
I try to root MD60348. I UNLOCK BOOTLOADER. Then stop. I cant do nothing. Device only back to factory setings...

Hi kamilodiabolo, after booting into TWRP you have to flash the UPDATE-SuperSU-v2.79.zip. After flashing the zip your tablet should boot without any problem. Without flashing the SuperSU update my tablet also stuck in bootloader.
 
  • Like
Reactions: kamilodiabolo

kamilodiabolo

Member
Apr 19, 2015
5
0
39
Hi kamilodiabolo, after booting into TWRP you have to flash the UPDATE-SuperSU-v2.79.zip. After flashing the zip your tablet should boot without any problem. Without flashing the SuperSU update my tablet also stuck in bootloader.

O know but i i dont know how to get my oryginal boot.img and stok recovery...
Adb pull
 

diyabolic

Senior Member
Nov 27, 2011
214
36
Cologne
Xiaomi Poco F3
Guys, do you have problem with stuttering videos (yt, vimeo)? Before it was working perfectly, now every video stutters. I would rather not hard reset if I don't have to

Sent from my D6503 using Tapatalk
 

Top Liked Posts

  • There are no posts matching your filters.
  • 2
    Hi everyone,

    Like the title said, I'm searching a way to root this tablet based on MediaTek.

    Aida64 Information :
    CPU : MT8783 (64 Bits ARMv8-A Cortex A53 octa-cores @ 1.3Ghz)
    Platform : MT6753
    Hardware : MT6735
    Manufacturer : Lenovo
    Brand : Medion
    Display : Mali-T720 [email protected], 225 dpi
    RAM : 2GB DDR3
    ROM : 32GB MMC


    After unlocking the bootloader :
    • I have tried some tools like iRoot, KingRoot, Kingo Root, Genius Root, and more that I can find with some search with google, but no one work.
    • I have tried to boot a TWRP/CWM Recovery image based on the same hardware or platform (fastboot boot myrecovery.img), the device reboot in normal mode, or I need to make these recovery for my hadware, but I think it need a rooted device...
    • I have tried to use MTK Droid Tools 2.5.3d, this software couldn't found the rom structure (this software doesn't found my IMEI too), and manualy with adb :
      • cat /proc/mtd
        file is empty
      • cat /proc/emmc
        file doesn't exist
      • cat /proc/partitions
        Code:
        major minor  #blocks  name
        
           7        0       1254 loop0
         254        0     975236 zram0
         179        0   30535680 mmcblk0
         179        1       3072 mmcblk0p1
         179        2       5120 mmcblk0p2
         179        3      10240 mmcblk0p3
         179        4      10240 mmcblk0p4
         179        5        512 mmcblk0p5
         179        6        512 mmcblk0p6
         179        7      16384 mmcblk0p7
         179        8      16384 mmcblk0p8
         179        9       8192 mmcblk0p9
         179       10      10240 mmcblk0p10
         179       11        512 mmcblk0p11
         179       12       2048 mmcblk0p12
         179       13       6144 mmcblk0p13
         179       14       8192 mmcblk0p14
         179       15       5120 mmcblk0p15
         179       16       5120 mmcblk0p16
         179       17       1024 mmcblk0p17
         179       18      32768 mmcblk0p18
         179       19      37888 mmcblk0p19
         179       20    2621440 mmcblk0p20
         179       21     409600 mmcblk0p21
         179       22   27307520 mmcblk0p22
         179       23      16384 mmcblk0p23
         179       96       4096 mmcblk0rpmb
         179       64       4096 mmcblk0boot1
         179       32       4096 mmcblk0boot0
         179      128    7565312 mmcblk1
         179      129    7564288 mmcblk1p1
         253        0    2600764 dm-0
         253        1   27307520 dm-1
      • cat /etc/recovery.fstab
        Code:
        # mount point   fstype          device                  [device2]
        
        /boot           emmc            boot
        /cache          ext4            /dev/block/mmcblk0p4
        /data           ext4            /dev/block/mmcblk0p5
        /misc           emmc            misc
        /recovery       emmc            recovery
        /sdcard         vfat            /dev/block/mmcblk0p6
        /system         ext4            /dev/block/mmcblk0p3
      • ls -l /dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name
        Permission denied

    After some search, it's possible that this device has the same hardware like the Lenovo Phab 2 Plus (correct me if i'm wrong).
    If anyone has some idea to root this device, It's would be great ^^

    Regards

    PS : Sorry if my english is wrong
    2
    Hey guys :eek:

    I have found a way to root this device and worked for me, and work certainly for all other un-rooted device.

    For some curious, I explain below what I have doing to dump recovery partition and boot.
    For other, you can find the ZIP link at the end of this post.

    With the DirtyCow exploit, it's very easy to dump our boot or recovery partition but need a little time without a custom recovery working...
    In a first step, read this : h**ps://github.com/jcadduono/android_external_dirtycow#running
    (a big thank's to jcadduono ! ;))
    Ok, it's need an Android OS Environnement and it's not for our device, but it's not realy a problem.

    A little modification to this file < recowvery-applypatch.c > to dump our recovery or boot partition, like this :
    Code:
    #include <unistd.h>
    #include <stdio.h>
    
    #include <stdint.h>
    #include <time.h>
    
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <time.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    
    #define APP_NAME  "recowvery"
    #define HOST_NAME "applypatch"
    
    #ifdef DEBUG
    #include <android/log.h>
    #define LOGV(...) { __android_log_print(ANDROID_LOG_INFO,  APP_NAME, __VA_ARGS__); printf(__VA_ARGS__); printf("\n"); }
    #define LOGE(...) { __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
    #else
    #define LOGV(...) { printf(__VA_ARGS__); printf("\n"); }
    #define LOGE(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
    #endif
    
    #define SEP LOGV("------------")
    
    #include "bootimg.h"
    
    /* Time delay in microsecond for next loop (1000 = 1ms)
     * 1ms is good for every PC
     * (you can try less than 1ms to speed the process, but you can have an <unexpected EOF>)
     */
    #define DELAY_T			1000
    
    /* For Medion LifeTab X10302 (May work on same hardware MT6735/MT6753)
     * You can define BLOCK_EMMC to other path if needed.
     * Use < adb shell mount > for help.
     */
    #define BLOCK_EMMC		"/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/boot"
    //#define BLOCK_EMMC		"/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/recovery"
    //#define BLOCK_EMMC		"/dev/block/platform/any-folder-point-to-by-name-folder/by-name/boot"
    
    void delay(long t)
    {
    	long timens = t * 1000;
    	nanosleep((const struct timespec[]){{0, timens}}, NULL);
    }
    
    int main(int argc, char **argv)
    {
    	int ret = 0;
    	int i = 0;
    
    	LOGV("Welcome to %s! (%s)", APP_NAME, HOST_NAME);
    	
    	for (i = 30; i > 0; i--)
    	{
    		LOGV("The process start in %is", i);
    		sleep(1);
    	}
    
    	byte rb[32];
    	char *content = malloc(256);
    	FILE *filetest;
    	size_t nread;
    	
    	filetest = fopen(BLOCK_EMMC, "r");
    	if (filetest) {
    		LOGV("*** DUMP START ***");
    		LOGV("* BLOCK_EMMC = %s", BLOCK_EMMC);
    		while ((nread = fread(rb, 1, sizeof rb, filetest)) > 0)
    		{
    			sprintf(content, "HEXDUMP = [");
    			for (i = 0; i < (int)nread; i++)
    			{
    				if (i == 0)
    					sprintf(content, "%s%.2x", content, rb[i]);
    				else
    					sprintf(content, "%s,%.2x", content, rb[i]);
    			}
    			sprintf(content, "%s];", content);
    			LOGV("%s", content);
    			
    			/* sleep to prevent any unexpected EOF with with pipe stream
    			 * ex : adb logcat | my-prg.exe
    			 */
    			delay(DELAY_T);
    		}
        
    		if (ferror(filetest)) {
    			ret = 1;
    			LOGE("*** DUMP ERROR ***");
    			LOGE("Error while reading the file...");
    		}
    		
    		LOGV("*** DUMP END ***");
    		fclose(filetest);
    	}
    	else
    	{
    		LOGV("Can't read the file...");
    		ret = 1;
    		goto oops;
    	}
    	
    	return 0;
    oops:
    	LOGE("*** DUMP ERROR ***");
    	LOGE("Error %d: %s", ret, strerror(ret));
    	LOGE("Exiting...");
    	return ret;
    }
    (Edit : Added a delay in loop, there is some time an <unexpected EOF> during the process)

    What it does ?
    When launched by <recowvery-app_process>, it only open "/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/boot" (in my exemple) in read-only and do like a HexDump, or something else.
    It's human readable, and visible from Windows or any Linux distribution via the command adb logcat -s recowvery. But, we need something to do the revert :silly:

    To solve this issue, I have made a to do this for me :cool:
    C# code version : (not opti)
    Code:
    /*
     * Created by SharpDevelop.
     * User: vince
     * Date: 16/01/2017
     * Time: 17:34
     * 
     * To change this template use Tools | Options | Coding | Edit Standard Headers.
     */
    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Text.RegularExpressions;
    using System.Diagnostics;
    
    namespace HexDumpReader
    {
    	class Program
    	{
    		private static string workingDir = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar;
    		private static string outfile = null;
    		private static List<string> datalist = new List<string>();
    		
    		public static int Main(string[] args)
    		{
    			int val = 0;
    			int ncrash = 0;
    			
    			if (args.Length == 0 || Console.In.Peek() == -1)
    			{
    				DisplayUsage();
    				return 1;
    			}
    			
    			try
    			{
    				// Shorter regex is possible, but I prefer like that.
    				// Used to start the process
    				Regex rs = new Regex("\\*\\*\\* DUMP START \\*\\*\\*");
    				// Used to match all data block, and populate < datalist >
    				Regex rl = new Regex("^\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}\\s{1,2}\\d{3,5}\\s{1,2}\\d{3,5} I recowvery: HEXDUMP = \\[([^\\]].*)\\];$");
    				// Used to break the infinite loop and start parsing all data
    				Regex rf = new Regex("\\*\\*\\* DUMP END \\*\\*\\*");
    				// Used to intercept error from < recowvery-applypatch >
    				Regex re = new Regex("\\*\\*\\* DUMP ERROR \\*\\*\\*");
    				
    				outfile = args[0];
    				bool start = false;
    				bool reboot = false;
    				
    				/* If we want a reboot while finish */
    				if (args.Length > 1)
    					reboot = (args[1] == "-r");
    				
    				while (true)
    				{
    					string line = Console.In.ReadLine();
    					
    					/*
    					 * If an unexpected EOF from recowvery-applypatch...
    					 * We can't receive a null string, close fsout, set start to false and break the loop after 3 crashs.
    					 */
    					if (line == null)
    					{
    						
    						Console.WriteLine("* < null > received !");
    						Console.WriteLine("Try again...");
    						break;
    					}
    					
    					/*
     					 * *** DUMP START ***
     					 * set start = true, and init fsout FileStream
     					 */
    					if (rs.IsMatch(line))
    						start = true;
    					
    					/*
    					 * Add all matched group from HEXDUMP line to datalist.
    					 * Note :
    					 *   It's possible to have matched line before intercept DUMP START,
    					 *   If we convert now, it's a good idea to have a broken output file.
    					 * Important :
    					 *   Never try to parse all data on the fly, you can have a mysterious "unexpected EOF" error.
    					 */
    					if (start && rl.IsMatch(line))
    					{
    						datalist.Add(rl.Replace(line, "$1"));
    						Console.CursorLeft = 0;
    						Console.Write("Block read : " + datalist.Count);
    					}
    					/*
    					 * Display the other lines (for debuging, logging...)
    					 */
    					else if (!rl.IsMatch(line) && (!rf.IsMatch(line) && !start) && line.Length > 1)
    					{
    						Console.WriteLine(line);
    					}
    					
    					/*
    					 * *** DUMP END ***
    					 * Flush and close fsout, inform the user, and break the loop.
    					 */
    					if (start && rf.IsMatch(line))
    						break;
    					
    					/*
    					 * *** DUMP ERROR ***
    					 * An error intercepted from ADB, close fsout, set start to false.
    					 * < applypatch > will restart every 3 min.
    					 * We break the loop after 3 errors.
    					 */
    					if (re.IsMatch(line))
    					{
    						Console.WriteLine("* Error received from ADB *");
    						
    						start = false;
    						if (ncrash == 3)
    						{
    							Console.WriteLine("* Too many tries, please check your < recowvery-applypatch.c > and try again.");
    							break;
    						}
    						Console.WriteLine("* Be patient, recowvery-applypatch will restart in a few minutes.");
    						ncrash++;
    					}
    				}
    				
    				Console.WriteLine();
    				Console.WriteLine("Parsing blocks...");
    				
    				/* recowvery-applypatch read by block of 32 bytes.
    				 * so, we can calculate the final size.
    				 */
    				double finalSize = 32 * datalist.Count;
    				/* used to display the new progression */
    				int lastprogress = 0;
    				
    				FileStream fsout = File.OpenWrite(outfile);
    				fsout.SetLength(0);
    				foreach(string s in datalist)
    				{
    					string[] data = s.Split(',');
    					
    					for (int c = 0; c < data.Length; c++)
    					{
    						try
    						{
    							byte[] b = StringToByteArrayFastest(data[c]);
    							fsout.Write(b, 0, b.Length);
    							
    							/* Calculate progression */
    							int progress = (int)(((double)fsout.Position / finalSize) * 100);
    							/* Display the progression if needed */
    							if (progress != lastprogress)
    							{
    								Console.CursorLeft = 0;
    								Console.Write("Processing... " + progress + "% ");
    								lastprogress = progress;
    							}
    						}
    						catch(Exception ex)
    						{
    							Console.WriteLine();
    							Console.WriteLine("** Exception **");
    							Console.WriteLine(" - When convert : " + data[c]);
    							Console.WriteLine(" - Message      : " + ex.Message);
    							Console.WriteLine(" - StackTrace   : " + ex.StackTrace);
    						}
    					}
    				}
    				fsout.Flush();
    				fsout.Close();
    				
    				Console.WriteLine();
    				Console.WriteLine("Finish !");
    				
    				if (reboot)
    					rebootDevice();
    				else
    					Console.WriteLine("You can reboot your device.");
    			}
    			catch(Exception e)
    			{
    				Console.WriteLine("*** Exception ***");
    				Console.WriteLine(" - Message    : " + e.Message);
    				Console.WriteLine(" - Source     : " + e.Source);
    				Console.WriteLine(" - StackTrace : " + e.StackTrace);
    				val = e.HResult;
    			}
    			
    			return val;
    		}
    		
    		public static void DisplayUsage()
    		{
    			Console.WriteLine("Usage :");
    			Console.WriteLine(" adb logcat -s recowvery | " + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe myImage-output.img [-r]");
    			Console.WriteLine();
    			Console.WriteLine(" -r : Reboot your device when finish.");
    			Console.WriteLine("      (Run \"adb reboot\" for you)");
    		}
    		
    		public static void rebootDevice()
    		{
    			ProcessStartInfo psi;
    			Process p;
    			string strout = "";
    			string strerr = "";
    			
    			psi = new ProcessStartInfo("adb.exe", "reboot");
    			psi.WorkingDirectory = workingDir;
    			psi.RedirectStandardError = true;
    			psi.RedirectStandardOutput = true;
    			psi.UseShellExecute = false;
    			
    			Console.WriteLine("Rebooting your device...");
    			
    			p = new Process();
    			p.StartInfo = psi;
    			p.Start();
    			
    			if (!p.StandardError.EndOfStream)
    				strerr = p.StandardError.ReadToEnd();
    			if (!p.StandardOutput.EndOfStream)
    				strout = p.StandardOutput.ReadToEnd();
    			
    			if (strout.Length > 0)
    				Console.WriteLine(strout);
    			if (strerr.Length > 0)
    			{
    				Console.WriteLine(strerr);
    			}
    			
    			p.WaitForExit();
    		}
    		
    		public static byte[] StringToByteArrayFastest(string hex) {
    		    if (hex.Length % 2 == 1)
    		        throw new Exception("The binary key cannot have an odd number of digits");
    		
    		    byte[] arr = new byte[hex.Length >> 1];
    		
    		    for (int i = 0; i < hex.Length >> 1; ++i)
    		    {
    		        arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
    		    }
    		
    		    return arr;
    		}
    		
    		public static int GetHexVal(char hex) {
    		    int val = (int)hex;
    		    //For uppercase A-F letters:
    		    //return val - (val < 58 ? 48 : 55);
    		    //For lowercase a-f letters:
    		    return val - (val < 58 ? 48 : 87);
    		    //Or the two combined, but a bit slower:
    		    //return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
    		}
    	}
    }

    To compile the C# code, you need :
    • An IDE like SharpDevelop, MonoDevelop, or VisualStudio
    • Create a <New Project> and select <Console Application>
    • copy the code below, and replace all to your main.cs or program.cs.
    • Run it

    C++ code version : (Working good on Ubuntu 16.04, Windows too but not tested)
    Code:
    #include <iostream>
    #include <regex>
    #include <stdio.h>
    
    typedef unsigned char byte;
    
    using namespace std;
    
    void DisplayUsage()
    {
        cout << string("Usage :") << endl;
        cout << string(" adb logcat -s recowvery | ") << string("HexDumpReader") << string(".exe myImage-output.img [-r]") << endl;
        cout << endl;
        cout << string(" -r : Reboot your device when finish.") << endl;
        cout << string("      (Run \"adb reboot\" for you)") << endl;
    }
    
    void split(const string &s, char delim, vector<string> &elems) {
        stringstream ss;
        ss.str(s);
        string item;
        while (getline(ss, item, delim)) {
            elems.push_back(item);
        }
    }
    
    vector<string> split(const string &s, char delim) {
        vector<string> elems;
        split(s, delim, elems);
        return elems;
    }
    
    void string_to_bytearray(std::string str, unsigned char* &array, int& size)
    {
    	int length = str.length();
    	// make sure the input string has an even digit numbers
    	if(length%2 == 1)
    	{
    		str = "0" + str;
    		length++;
    	}
    
    	// allocate memory for the output array
    	array = new unsigned char[length/2];
    	size = length/2;
    
    	std::stringstream sstr(str);
    	for(int i=0; i < size; i++)
    	{
    		char ch1, ch2;
    		sstr >> ch1 >> ch2;
    		int dig1, dig2;
    		if(isdigit(ch1)) dig1 = ch1 - '0';
    		else if(ch1>='A' && ch1<='F') dig1 = ch1 - 'A' + 10;
    		else if(ch1>='a' && ch1<='f') dig1 = ch1 - 'a' + 10;
    		if(isdigit(ch2)) dig2 = ch2 - '0';
    		else if(ch2>='A' && ch2<='F') dig2 = ch2 - 'A' + 10;
    		else if(ch2>='a' && ch2<='f') dig2 = ch2 - 'a' + 10;
    		array[i] = dig1*16 + dig2;
    	}
    }
    
    void rebootDevice()
    {
        system("adb reboot");
    }
    
    int main(int argc, char** argv)
    {
        /* Display help if no argument */
        if (argc == 1)
        {
            DisplayUsage();
            return 1;
        }
    
        cout << string("*** HexDumpReader ***") << endl;
    
        int val = 0;
        vector<string> datalist;
        string outfile = string(argv[1]);
        bool reboot = false;
        int ncrash = 0;
    
        /* Output image file */
        cout << string("* Output file : ") << outfile << endl;
        /* If we want a reboot while finish */
        if (argc > 2)
        {
            reboot = (string(argv[2]) == "-r");
        }
        cout << string("* Reboot device : ") << reboot << endl;
    
        try
        {
            // Shorter regex is possible, but I prefer like that.
            // Used to start the process
            regex rs("^.+I recowvery: (\\*\\*\\* DUMP START \\*\\*\\*)\\s+");
            // Used to match all data block, and populate < datalist >
            regex rl("^.+I recowvery: HEXDUMP = \\[([^\\]]+)\\];\\s+");
            // Used to break the infinite loop and start parsing all data
            regex rf("^.+I recowvery: (\\*\\*\\* DUMP END \\*\\*\\*)\\s+");
            // Used to intercept error from < recowvery-applypatch >
            regex re("^.+I recowvery: (\\*\\*\\* DUMP ERROR \\*\\*\\*)\\s+");
    
            /* write or not to output file */
            bool start = false;
    
            FILE *fsout;
            fsout = fopen(outfile.c_str(), "wb");
            int nBlock = 0;
            long currentSize = 0;
    
            while (true)
            {
                string line;
                getline(cin, line);
    
                /*
                 * If an unexpected EOF from recowvery-applypatch or if no <pipe>...
                 * We can't receive a null string, so break the loop, close fsout, and exit the program.
                 */
                if (line.empty())
                {
                    cout << string("* < null > received !") << endl;
                    cout << string("Try again...") << endl;
                    break;
                }
    
                /*
                  * *** DUMP START ***
                  * set start = true to write parsed data to fsout
                  */
                if (regex_match(line, rs))
                {
                    start = true;
                }
    
                /*
                 * Parse all string received if match
                 * Note :
                 *   It's possible to have matched string before intercept DUMP START,
                 *   If we convert now, it's a good idea to have a broken output file.
                 */
                if (start && regex_match(line, rl))
                {
                    string s = regex_replace(line, rl, "$1");
                    vector<string> data = split(s, ',');
                    for (int c = 0; c < (int)data.size(); c++)
                    {
                        try
                        {
                            byte *b = NULL;
                            int sb;
                            string_to_bytearray(data[c], b, sb);
                            fwrite(b, 1, sb, fsout);
                        }
                        catch (const std::exception &ex)
                        {
                            std::cout << std::endl;
                            std::cout << std::string("** Exception **") << std::endl;
                            std::cout << std::string(" - When convert : ") << data[c] << std::endl;
                            std::cout << std::string(" - Message      : ") << ex.what() << std::endl;
                        }
                    }
                    nBlock++;
                    currentSize = nBlock * 32;
    
                    std::cout << "\r";
                    std::cout << std::string("Block read : ") << nBlock << string(" (Size : ") << currentSize << string(")");
                }
                /*
                 * Display the other lines (for debuging, logging...)
                 */
                else if (!regex_match(line, rl) && (!regex_match(line, rf) && !start) && line.length() > 1)
                {
                    std::cout << line << std::endl;
                }
    
                /*
                 * *** DUMP END ***
                 * Flush and close fsout, inform the user, and break the loop.
                 */
                if (start && regex_match(line, rf))
                {
                    break;
                }
    
                /*
                 * *** DUMP ERROR ***
                 * An error intercepted from ADB, close fsout, set start to false.
                 * < applypatch > will restart every 3 min.
                 * We break the loop after 3 errors.
                 */
                if (regex_match(line, re))
                {
                    cout << std::string("* Error received from ADB *") << std::endl;
    
                    start = false;
                    if (ncrash == 3)
                    {
                        cout << std::string("* Too many tries, please check your < recowvery-applypatch.c > and try again.") << std::endl;
                        break;
                    }
                    cout << std::string("* Be patient, recowvery-applypatch will restart in a few minutes.") << std::endl;
                    ncrash++;
                }
            }
    
            cout << endl;
    
            fclose(fsout);
    
            cout << std::endl;
            cout << std::string("Finish !") << std::endl;
    
            if (reboot)
            {
                rebootDevice();
            }
            else
            {
                std::cout << std::string("You can reboot your device.") << std::endl;
            }
        }
        catch (const std::exception &e)
        {
            std::cout << std::string("*** Exception ***") << std::endl;
            std::cout << std::string(" - Message    : ") << e.what() << std::endl;
        }
    
        return val;
    }
    To build it, you need these CFLAGS : -m32 -std=C++11 -Wall (maybe -g for debug)
    Ex :
    g++ -Wall -fexceptions -g -Wall -std=c++11 -m32 -g -c main.cpp -o main.o
    g++ -o HexDumpReader main.o -m32


    Now, how It work ?
    How can I dump my boot or recovery partition and make my own TWRP ? :crying:
    It's like jcadduono explain here : h**ps://github.com/jcadduono/android_external_dirtycow
    Follow only this steps :
    Code:
    adb push dirtycow /data/local/tmp
    adb push recowvery-applypatch /data/local/tmp
    adb push recowvery-app_process64 /data/local/tmp
    adb push recowvery-run-as /data/local/tmp
    
    adb shell
    
    $ cd /data/local/tmp
    $ chmod 0777 *
    $ ./dirtycow /system/bin/applypatch recowvery-applypatch
    "<wait for completion>"
    $ ./dirtycow /system/bin/app_process64 recowvery-app_process64
    "<wait for completion, your phone will look like it's crashing>"
    $ exit
    
    (It's change here =>)
    adb logcat -s recowvery | HexDumpReader %USERPROFILE%\Documents\my-image-output.img -r

    Wait a moment, you will see that it's finish, and you may see <my-image-output.img> in <%USERPROFILE%\Documents> folder.
    You can try to extract your image from MKTool or any Kitchen tools, it's work, and finally make your TWRP, boot from it, backup your roms (if you have never doing this) and finally root your device.

    I know that some of you can't do all these steps, or need simply the final image, you can download it from this url :
    ZIP File : h**ps://goo.gl/IT7dpl (Contains original boot, recovery, TWRP & a readme)
    (Bug found : battery stuck at 50%)
    1
    I try to root MD60348. I UNLOCK BOOTLOADER. Then stop. I cant do nothing. Device only back to factory setings...

    Hi kamilodiabolo, after booting into TWRP you have to flash the UPDATE-SuperSU-v2.79.zip. After flashing the zip your tablet should boot without any problem. Without flashing the SuperSU update my tablet also stuck in bootloader.
    1
    O know but i i dont know how to get my oryginal boot.img and stok recovery...
    Adb pull

    Depend if you're flashing TWRP or not...
    If not, you can boot your device with these commands : adb reboot-bootloader and fastboot boot TWRP-X10302.img
    It will put your device in fastboot mode, the second to boot to TWRP then you can save your original boot, recovery, system etc. from TWRP without any flashing.

    Anyway...
    I've seen on the medion community forum that they give factory image during this week ;)
    (Drivers, MTK FlashTool and documentation are available from the service support)
    1
    OK, so this is not the recovery kit that people were asking for at the beginning of the thread.
    Anyway, I managed to root the tablet with the help of the TWRP posted by someone on the first page (great job) - or maybe not. Indeed, that was not easy, because after booting on this TWRP, it could saw the partitions but they were 0MB ... So installing the SuperSU failed. Using the adb sideload option of TWRP failed too, for the same reason probably.
    As I didn't installed TWRP but only booted on it, I could still boot on the regular recovery, and I'm almost convince (yes, everything was messed up yesterday night) that I succeed by just installing superSU from the native recovery.
    So in my opinion, a kid could root this tablet : just download the latest SuperSU, boot in recovery and install SuperSU.
    Any feedback appreciated.