j’essaie de modifier le binaire du kernel, mon but est de modifier le logo de boot actuel,
je possède le patch des sources,
j'ai appliqué le patch, lancé la compilation, ça ma généré depuis le ppm un fichier C
depuis le fichier C j'ai pécho les tailles des deux tableaux, que j'ai présumé le raw 8bit de l'image et la palette,
j'ai pécho assez d'octet au début comme signature,
ai extrait le gz du kernel compressé de uImage, l'ai decompacté
(dans un second temps j'ai trouvé ce script qui me sort aussi un footer de 60 octets et c'est plus simple qu'à la main avec dd)
j'ai trouvé les offset de l'image et la palette dans le binaire du kernel avec binwalk .. avec dd j'ai extrait deux fichiers brut correspondant aux deux tableaux
j'ai fait un programme chargeant un png quelconque, comptant les couleurs, me générant un 8bit + palette avec verif des couleurs max et nombre de px suivant l'image originale,
il charge le binaire du kernel, l'image originale, la palette originale, trouve les offset et écrase avec la nouvelle image/palette
source
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <cstring>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <errno.h>
#include <signal.h>
#include <png.h>
using namespace std;
#define u8 u_int8_t
#define u16 u_int16_t
#define u32 u_int32_t
#define ARGS_MAX_LENGTH 8
#define MAX_ARGS 2
#define wait(ms) usleep(ms*1000)
u8 * png2img(const char* file, int*width , int*height){
png_byte color_type;
png_byte bit_depth;
png_structp png_ptr;
png_infop info_ptr;
png_bytep * row_pointers;
char header[8];
/* open file and test for it being a png */
FILE *fp = fopen(file, "rb");
if (!fp) return 0;
fread(header, 1, 8, fp);
if(png_sig_cmp((const unsigned char*)header, 0, 8)) return 0;
/* initialize stuff */
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr) return 0;
info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr) return 0;
if(setjmp(png_jmpbuf(png_ptr))) return 0;
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
*width = png_get_image_width(png_ptr, info_ptr);
*height = png_get_image_height(png_ptr, info_ptr);
color_type = png_get_color_type(png_ptr, info_ptr);
bit_depth = png_get_bit_depth(png_ptr, info_ptr);
if(bit_depth == 16)
png_set_strip_16(png_ptr);
if(color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr);
// PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png_ptr);
if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png_ptr);
// These color_type don't have an alpha channel then fill it with 0xff.
if(color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_PALETTE)
png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);
if(color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
png_read_update_info(png_ptr, info_ptr);
row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * *height);
if( !row_pointers ) return 0;
for (int y=0; y<*height; y++){
row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
if( !row_pointers[y] ) return 0;
}
png_read_image(png_ptr, row_pointers);
fclose(fp);
u8 * bf = (u8*)malloc( *width * *height + 225*4 );
if( !bf ) return 0;
u8 *img = &bf[225*4], *i = img;
u32 *nbColor = (u32*)bf, *colors = nbColor + 1, *start = colors, *end = start+1;
int x, y, px=0;
for( y = 0 ; y < *height ; y++){
png_byte* row = row_pointers[y];
u32 * c = (u32*)row, n;
for( x = 0; x < *width; x++){
px++;
*c &= 0xffffff;
u32 * p = start;
while( p < end && *c != *p ) p++;
if( p != end ){ // found
//printf("use color %u\n", p - start);
*i++ = p - start;
} else { // new color
if( *nbColor == /*224*/ 224 ){
printf("too much colors, stop at %u, on px %u\n",*nbColor,px);
free(bf);
return 0;
}
*i++ = *nbColor;
*nbColor = *nbColor + 1;
*end++ = *c;
//printf("new color %u 0x%x\n", *nbColor, *c);
}
c++; // next pixel
}
free(row);
}
free(row_pointers);
return bf;
}
u32 getSize(FILE *f)
{ int last, size ;
last = ftell(f) ; fseek(f,0,SEEK_END) ;
size = ftell(f) ;
fseek(f,last,SEEK_SET) ; return size ;
}
u8 * loadFile(const char *path, u32*size)
{ FILE *f ; int sz ; u8 * fl ;
f = fopen(path,"r") ;
if(!f) return 0;
else { sz = getSize(f) ; if(size) *size=sz; }
fl = (u8*)malloc(sz) ;
if( !fl ) return 0;
fread(fl,sz,1,f) ; fclose(f) ;
return fl ;
}
u32 writeFile(const char *path, void*buffer, u32 size)
{ FILE *f = fopen(path,"w") ;
if(!f) return 0 ;
fwrite(buffer,size,1,f);fclose(f);
return 1;
}
int main(int argc, char const *argv[]) {
int width, height, nbpx;
// load png into a 8b raw buffer
u8 * bf = png2img( argv[1], &width, &height );
if( !bf ){
printf("cannot load picture\n");
return EXIT_FAILURE;
}
nbpx = width * height;
u32 *nbColor = (u32*)bf, *pal = nbColor + 1;
u8 *img = (u8*)&bf[225];
printf( "%u colors found\n", *nbColor );
/*for( int n=0; n < *nbColor ; n++ ){
printf("%u - 0x%x\n", n, pal[n]);
}*/
u32 kernelLength = 0, pictureLength = 0, palLength = 0;
u8 * kernel = loadFile("./kernel", &kernelLength);
if( !kernel ) return EXIT_FAILURE;
u8 * picture = loadFile("./picture", &pictureLength);
if( !picture ) return EXIT_FAILURE;
u8 * kpal = loadFile("./pal", &palLength);
if( !kpal ) return EXIT_FAILURE;
if( kernelLength < pictureLength || nbpx > pictureLength ){
printf("impossible\n");
free( kernel );
free( picture );
free( bf );
return EXIT_FAILURE;
}
u8 *k = kernel, *kend = k + kernelLength - pictureLength;
while( k <= kend && memcmp( k, picture, pictureLength ) ) k++;
if( k == kend ){ // not found
printf("picture not found in kernel\n");
free( kernel );
free( picture );
free( kpal );
free( bf );
return EXIT_FAILURE;
}
// found
printf("picture found in kernel at offset %u\n", k - kernel);
printf("replace original picture..\n");
memcpy( k, img, nbpx );
memset( k+nbpx, 0, pictureLength-nbpx );
k = kernel;
kend = k + kernelLength - palLength;
while( k <= kend && memcmp( k, kpal, palLength ) ) k++;
if( k == kend ){ // not found
printf("palette not found in kernel\n");
free( kernel );
free( picture );
free( kpal );
free( bf );
return EXIT_FAILURE;
}
// found
printf("palette found in kernel at offset %u\n", k - kernel);
printf("replace original palette..\n");
memset( k, 0, palLength );
u8 * p = (u8*)pal;
for( int n=0;n < *nbColor; n++ ){
*k++ = *p++;
*k++ = *p++;
*k++ = *p++;
p++;
}
//memcpy( k, pal, ( *nbColor ) * 4 );
/*
> 56*12
672
> 672/4
168
> 672/3
224
>
*/
writeFile("./kernel.patched",kernel,kernelLength);
free( kernel );
free( picture );
free( kpal );
free( bf );
return EXIT_SUCCESS;
}
ensuite je refait le gz via un gzip --no-name puis cat header kernel.gz footer > uImage
mais ca bloque au splash screen de uboot :- /
je ne peux debuguer via le port série, impossible de ne recevoir autre chose que de la merde malgré les deux adaptateurs différents et les milliard d'essais à différents baudrate et changement de config sur différents kernel fonctionels via stty
je n'ai plus d'idées ... si vous en auriez une ^^