[Wii Region Free Patch] SourceCode

Hola.


EDITADO: Actualizadas las cadenas del parche


No es el codigo fuente original de SYNDiCATE, me he tomado la libertad/molestia de desensamblar la mini utilidad que parchea las isos NTSC para poder usarlas en consolas PAL y "recostruir" el funcionamiento

Aqui os dejo el codigo fuente por si quereis trastear con el.

Basicamente lo que hace es parchear dos posiciones de la ISO seguramente la que chequea el kernel de la WII para comprobar el formato de la ISO


#include <windows.h>
#include <stdio.h>


struct PARCHE {
   DWORD offset;
   char  valores[17];
   int nbytes;
} parche[]= {
   { 0x04E003, "\x02",0x01},                              // Parche 1
   { 0x04E010, "\x00\x80\x80\x06\x03\x03\x04\x03\x07\x00\x00\x00\x00\x00\x00\x00", 0x10 }, // Parche 2
};


void main(char *argv[],int argc) {

    FILE *fichero;

    system("cls");
    printf("\n\n\t\t --------------------------------\n");
    printf("\t\t|    SYNDICATE Region Patcher    | \n");
    printf("\t\t| dissasembly reconstructed code | \n");
    printf("\t\t --------------------------------\n");

    if ( (fichero = fopen("backup.iso","rb+") ) != NULL) {

        for (int i=0;i<(sizeof(parche) / sizeof(struct PARCHE));i++) {
            fseek(fichero,parche[i].offset,SEEK_SET);
            fwrite(parche[i].valores,parche[i].nbytes, 1,fichero);
        }

        printf("\n\t\t     Us game is now Pal !\n\n\n");
    }

    else printf("\n\t\t     No backup.iso found !\n\n\n");

    system("PAUSE");
}



en la version 1.1 han cambiado un poco las cadenas que sobreescriben.

Aqui os dejo las nuevas cadenas para parchear NTSC JAP a NTSC USA y cualquier NTSC a PAL


/* -------------------------------
    NTSC JAP & NTSC USA  -->  PAL
   ------------------------------- */

struct PARCHE {
   DWORD offset;
   char  valores[17];
   int nbytes;
} parche[]= {
   { 0x04E003, "\x02",0x01},                                                               // Parche 1
   { 0x04E010, "\x80\x80\x80\x06\x07\x07\x06\x07\x00\x80\x80\x80\x80\x80\x80\x80", 0x10 }, // Parche 2
};




/* -------------------------------
        NTSC JAP --> NTSC USA
   ------------------------------- */

struct PARCHE {
   DWORD offset;
   char  valores[17];
   int nbytes;
} parche[]= {
   { 0x04E003, "\x00",0x01},                                                               // Parche 1
   { 0x04E010, "\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80", 0x10 }, // Parche 2
};




Un saludo
gracias, seguro k sera de utilidad a mucha gente =)
wow!! programita sencillo donde los haya, y encima con C yo creo q muchos se van a meter a investigar...
A darle caña a la scene!!!
¿Éste código funciona?, la verdad es que hay algo que me da bastante el cante:


struct PARCHE {
DWORD offset;
char valores[17];
int nbytes;
} parche[]= {
{ 0x04E003, "\x02",0x01}, // Parche 1
{ 0x04E010, "\x00\x80\x80\x06\x03\x03\x04\x03\x07\x00\x00\x00\x00\x00\x00\x00", 0x10 }, // Parche 2
};


, debería dar un error de compilación, ya que se está declarando una array de valores de tamaño 18, y se está inicializando una variable que supera ése tamaño por mucho (donde está el comentario "Parche 2")
hsaoud escribió:¿Éste código funciona?, la verdad es que hay algo que me da bastante el cante:


struct PARCHE {
DWORD offset;
char valores[17];
int nbytes;
} parche[]= {
{ 0x04E003, "\x02",0x01}, // Parche 1
{ 0x04E010, "\x00\x80\x80\x06\x03\x03\x04\x03\x07\x00\x00\x00\x00\x00\x00\x00", 0x10 }, // Parche 2
};


, debería dar un error de compilación, ya que se está declarando una array de valores de tamaño 18, y se está inicializando una variable que supera ése tamaño por mucho (donde está el comentario "Parche 2")


Si no me equivoco, cada \xNN representa 1 byte.
hsaoud escribió:¿Éste código funciona?, la verdad es que hay algo que me da bastante el cante:


struct PARCHE {
DWORD offset;
char valores[17];
int nbytes;
} parche[]= {
{ 0x04E003, "\x02",0x01}, // Parche 1
{ 0x04E010, "\x00\x80\x80\x06\x03\x03\x04\x03\x07\x00\x00\x00\x00\x00\x00\x00", 0x10 }, // Parche 2
};


, debería dar un error de compilación, ya que se está declarando una array de valores de tamaño 18, y se está inicializando una variable que supera ése tamaño por mucho (donde está el comentario "Parche 2")


No se de donde sacas tu el 18, porque yo cuento 16, ten en cuenta que parche representa a un STRUCT que contiene un DWORD, un array de tamaño 17 de caracteres y un entero.

Es decir, no es que se superen los 17 caracteres de valores[], es que se quedan cortos, cosa que si funciona y para eso supongo que sera el nbytes del final.
No se de donde sacas tu el 18, porque yo cuento 16



efectivamente, el código está bien.
kriogeN escribió:
No se de donde sacas tu el 18, porque yo cuento 16, ten en cuenta que parche representa a un STRUCT que contiene un DWORD, un array de tamaño 17 de caracteres y un entero.

Es decir, no es que se superen los 17 caracteres de valores[], es que se quedan cortos, cosa que si funciona y para eso supongo que sera el nbytes del final.


Hijo mío, un array de x posiciones en C/C++ tiene un tamaño de x+1, ya que los arrays empiezan en la posición 0, y no la 1.

Así que char valores[17] tiene 18 posiciones, desde valores[0] hasta valores[17].


Por otro lado, no sabía que \xNN representara 1 byte, todos los días se aprende algo ;D.
hsaoud escribió:
Hijo mío, un array de x posiciones en C/C++ tiene un tamaño de x+1, ya que los arrays empiezan en la posición 0, y no la 1.

Así que char valores[17] tiene 18 posiciones, desde valores[0] hasta valores[17].


Por otro lado, no sabía que \xNN representara 1 byte, todos los días se aprende algo ;D.


no, estas equivocado

un array valores[17] tiene 17 posiciones, que van de la 0 a la 16
Dredok escribió:
no, estas equivocado

un array valores[17] tiene 17 posiciones, que van de la 0 a la 16


Exactamente, así es.
Dredok escribió:
no, estas equivocado

un array valores[17] tiene 17 posiciones, que van de la 0 a la 16


Cierto, estaba equivocado, suele pasar por abrir la boca antes de pensar :P
hsaoud escribió:
Hijo mío, un array de x posiciones en C/C++ tiene un tamaño de x+1, ya que los arrays empiezan en la posición 0, y no la 1.

Así que char valores[17] tiene 18 posiciones, desde valores[0] hasta valores[17].


Por otro lado, no sabía que \xNN representara 1 byte, todos los días se aprende algo ;D.


Bueno, ya te has corregido tu mismo, pero es lo que ya se ha dicho, defines 17 que van de 0 a 16.

Y el \xNN representa un Byte en Hexadecimal, es decir, en el NN podrias poner un valor entre 00 y FF, o lo que es lo mismo, entre 0 y 255.
No me compila en linux :(

¿Alguien puede arreglarlo / portarlo?

$ gcc -o wiiregion wiiregion.c
wiiregion.c:1:21: error: windows.h: No existe el fichero o el directorio
wiiregion.c:6: error: expected specifier-qualifier-list before 'DWORD'
wiiregion.c:10: warning: excess elements in struct initializer
wiiregion.c:10: warning: (near initialization for 'parche[0]')
wiiregion.c:10: warning: excess elements in struct initializer
wiiregion.c:10: warning: (near initialization for 'parche[0]')
wiiregion.c:10: warning: excess elements in struct initializer
wiiregion.c:10: warning: (near initialization for 'parche[0]')
wiiregion.c:11: warning: excess elements in struct initializer
wiiregion.c:11: warning: (near initialization for 'parche[1]')
wiiregion.c:11: warning: excess elements in struct initializer
wiiregion.c:11: warning: (near initialization for 'parche[1]')
wiiregion.c:11: warning: excess elements in struct initializer
wiiregion.c:11: warning: (near initialization for 'parche[1]')
wiiregion.c: In function 'main':
wiiregion.c:27: error: 'for' loop initial declaration used outside C99 mode
wiiregion.c:27: warning: division by zero
wiiregion.c:28: error: 'struct PARCHE' has no member named 'offset'
wiiregion.c:29: error: 'struct PARCHE' has no member named 'valores'
wiiregion.c:29: error: 'struct PARCHE' has no member named 'nbytes'
wiiregion.c:15: warning: return type of 'main' is not 'int'
Toz escribió:No me compila en linux :(

¿Alguien puede arreglarlo / portarlo?

$ gcc -o wiiregion wiiregion.c
wiiregion.c:1:21: error: windows.h: No existe el fichero o el directorio
.
.
.



Normal que no te compile, esta programado en windows usando las libreras de windows (windows.h)

Si hoy tengo un momento lo porto a linux, si alguien se aburre y lo hace antes pues mejor.

(Porque antes de poneros a criticar de que algo no funciona lo probais ? y luego si veis que no va pues "protestatis" porque vamos, que manera de tener 10 posts de: No va. Si va. No va porque tal: Si va... En fin)

Un saludo.
El script es simple como el mecanismo de un chupete: Busca una posicion en un fichero binario y sustituye unas cadenas. Que bonito es comprobar que las cosas simples funcionan tan bien ;)

wiiregion.c:1:21: error: windows.h: No existe el fichero o el directorio


¿Ese error no te dice nada? Esta preparado para compilar en Windows, por lo que si no tienes ese fichero de header no va a funcionar.
El código anterior funcionaba con visual studio 6 o borland C++ builder.
Si lo quereis compilar conj Gcc, os dejo aqui el codigo modificado

#include
#ifndef DWORD
#define DWORD unsigned long
#define CLS "clear"
#else
#define CLS "cls"
#endif
struct PARCHE {
DWORD offset;
char valores[17];
int nbytes;
} parche[]= {
{ 0x04E003, "\x02",0x01}, // Parche 1
{ 0x04E010,
"\x00\x80\x80\x06\x03\x03\x04\x03\x07\x00\x00\x00\x00\x00\x00\x00", 0x10
}, // Parche 2
};


int main(int argc, char *argv[]) {

FILE *fichero;
int i;
char path[256]="backup.iso";

system(CLS);
printf("\n\n\t\t --------------------------------\n");
printf("\t\t| SYNDICATE Region Patcher | \n");
printf("\t\t| dissasembly reconstructed code | \n");
printf("\t\t --------------------------------\n");
if (argc==2) strcpy(path,argv[1]);
printf("args: %i\n",argc);
if ( (fichero = fopen(path,"rb+") ) != NULL) {

for ( i=0;i<(sizeof(parche) / sizeof(struct PARCHE));i++) {
fseek(fichero,parche[i].offset,SEEK_SET);
fwrite(parche[i].valores,parche[i].nbytes, 1,fichero);
}

printf("\n\t\t Us game is now Pal !\n\n\n");
}

else printf("\n\t\t No %s found !\n\n\n",path);
getchar();
return(1);
}
Este es el codigo adaptado para que funcione en Linux. Para compilarlo:

gcc -o parche parche.c


#include


struct PARCHE {
unsigned long offset;
char valores[17];
int nbytes;
} parche[]= {{0x04E003,"\x02",0x01},{0x04E010,"\x00\x80\x80\x06\x03\x03\x04\x03\x07\x00\x00\x00\x00\x00\x00\x00",0x10},};

int main(char *argv[],int argc) {

FILE *fichero;
int i=0;

printf("\n\n\t\t --------------------------------\n");
printf("\t\t| SYNDICATE Region Patcher | \n");
printf("\t\t| dissasembly reconstructed code | \n");
printf("\t\t --------------------------------\n");

if ( (fichero = fopen("backup.iso","rb+") ) != NULL) {
for (i=0;i<(sizeof(parche) / sizeof(struct PARCHE));i++) {
fseek(fichero,parche[i].offset,SEEK_SET);
fwrite(parche[i].valores,parche[i].nbytes, 1,fichero);
}
printf("\n\t\t Us game is now Pal !\n\n\n");
return (0);
}
else printf("\n\t\t No backup.iso found !\n\n\n");
return (1);
}
Glicer escribió:Normal que no te compile, esta programado en windows usando las libreras de windows (windows.h)


Ya lo sé, aunque no se programar, eso lo he entendido perfectamente, si no, no hubiera dicho 'portar'.

SKyo escribió:¿Ese error no te dice nada? Esta preparado para compilar en Windows, por lo que si no tienes ese fichero de header no va a funcionar.


Idem.

--

Gracias por portarlo, enseguida lo pruebo, está bien que, ya que se hace el código, se pueda usar en cualquier sistema, si no, con el exe del release ya valdría ¿no?
desde luego esto va mejorando dia a dia,y ademas decis que es algo sencillo.uffffff,aunque veo mas dificil que se pueda cargar un juego sin chip,parcheando una posicion.
Lo que me sorprende es: Las variable del source original eran en castellano? O el usuario que lo destripo las modifico?
gonx escribió:Lo que me sorprende es: Las variable del source original eran en castellano? O el usuario que lo destripo las modifico?


si es una variable que mas da como lo llames...
Como me aburria hice una version nueva del codigo, muy chorra para que se coja el nombre de la imagen por linea de comandos, que es mas comodo, ademas de cambiar la llamada al sistema de limpieza de la consola.

#include <stdio.h>


struct PARCHE {
   unsigned long offset;
   char  valores[17];
   int nbytes;
} parche[]= {
   { 0x04E003, "\x02",0x01},                              // Parche 1
   { 0x04E010, "\x00\x80\x80\x06\x03\x03\x04\x03\x07\x00\x00\x00\x00\x00\x00\x00", 0x10 }, // Parche 2
};


int main(int argc,char *argv[]) {
    FILE *fichero;
    int i;
    system("clear");
    printf("\n\n\t\t --------------------------------\n");
    printf("\t\t|    SYNDICATE Region Patcher    | \n");
    printf("\t\t| dissasembly reconstructed code | \n");
    printf("\t\t --------------------------------\n");
    if (argc!=2) {
   printf("\n\t\t   USAGE: %s image.iso\n\n",argv[0]);
   return 1;
    }
    if ( (fichero = fopen(argv[1],"rb+") ) != NULL) {

        for (i=0;i<(sizeof(parche) / sizeof(struct PARCHE));i++) {
            fseek(fichero,parche[i].offset,SEEK_SET);
            fwrite(parche[i].valores,parche[i].nbytes, 1,fichero);
        }

        printf("\n\t\t     Us game is now Pal !\n\n\n");
   return 0;
    }

    else printf("\n\t\t     No %s found !\n\n\n",argv[1]);
   return 1;
}

Compilar:
gcc archivo.c -o wiiregionpatcher

Uso:
./wiiregionpatcher imagendejuegowii.iso


PD: Esta hecho para Linux, no se si funcionara en Windows, en todo caso habria que cambiar algo. Al menos me entretuve un rato ;)
gonx escribió:Lo que me sorprende es: Las variable del source original eran en castellano? O el usuario que lo destripo las modifico?


A ver, no es el codigo fuente original del ejecutable publicado por SYNDiCATE

Sino que he desensamblado el exe de ellos con el IDA, he visto lo que hace y he programado algo que hace lo mismo

Por eso hay variables en castellano, simplemente por eso

Gracias a wiirules por el port a linux


Un saludo
Como me aburria hice una version nueva del codigo, muy chorra para que se coja el nombre de la imagen por linea de comandos, que es mas comodo


Si miras en la página anterior verás que ya está XD
Toz escribió:
Ya lo sé, aunque no se programar, eso lo he entendido perfectamente, si no, no hubiera dicho 'portar'.



Idem.

--

Gracias por portarlo, enseguida lo pruebo, está bien que, ya que se hace el código, se pueda usar en cualquier sistema, si no, con el exe del release ya valdría ¿no?



joder ... pero es que era muy simple el cambio. Asi que menos quejarse xD

de todas formas si es cierto que podrian haber hecho un par de includes condicionales a plataforma y tal ...


pero vaya tela tu pregunta. Un consejo es que, usando linux, te iria bien algunas nociones basicas de programacion. Por otra parte me alegro de que Linux haya evolucionado tango como para que gente que no tiene ni idea de programar pueda utilizarlo.
wiirules escribió:

Si miras en la página anterior verás que ya está XD


LOL

En cuanto vi la peticion de Toz, me puse con el tema xD y eso que normalmente suelo leerme todo el hilo, pa una vez que no lo hago... [qmparto] tb es mala pata....

En cualquier caso pase 5 mins entretenido...;)
Para los expertos en el C, ¿lo que hace el código es recorrer toda la iso y cambiar una cadena por otra no? (corregidme si me equivoco)

¿Podría se que esos juegos que no funcionan el problema sea que cambia la cadena en dos sitios, uno donde debería de cambiarla y otro donde no debería de cambiarla?

Espero haberme explicado

PD: No seáis muy crueles conmigo gurus del C
No, lo que hace es que en la posicion que se le dice en offset escribe lo que tiene en valores.

En el post tecnico se comentaba que cambiando un par de bytes (Parche 1) se conseguia compatibilidad solo con un par de juegos. En este programa se realiza un segundo parcheo y han conseguido un 70%. Puede que modificando algo mas se consiga el 100%, o puede que hasta que no se descubra como descifrar/cifrar el disco o acceder al firmware no se pueda avanzar mas, ya se vera.
Para los que querais compilarlo en linux, eso compila pero no va bien, al menos con isos mas grandes de 2Gb :P

Hay que meter justo al principio del codigo fuente (antes del #include ) la linea:

#define _FILE_OFFSET_BITS 64

para que soporte ficheros grandes el programita ;)

En cuanto llegue a casa pruebo a ver si la primera iso que he pasado va bien :)
Hola de nuevo

En la version 1.1 con GUI hace exactamente lo mismo pero han cambiado las cadenas de bytes que escriben.

Se cambia en el fuente y listo




/* -------------------------------
    NTSC JAP & NTSC USA  -->  PAL
   ------------------------------- */

struct PARCHE {
   DWORD offset;
   char  valores[17];
   int nbytes;
} parche[]= {
   { 0x04E003, "\x02",0x01},                                                               // Parche 1
   { 0x04E010, "\x80\x80\x80\x06\x07\x07\x06\x07\x00\x80\x80\x80\x80\x80\x80\x80", 0x10 }, // Parche 2
};




/* -------------------------------
        NTSC JAP --> NTSC USA
   ------------------------------- */

struct PARCHE {
   DWORD offset;
   char  valores[17];
   int nbytes;
} parche[]= {
   { 0x04E003, "\x00",0x01},                                                               // Parche 1
   { 0x04E010, "\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80", 0x10 }, // Parche 2
};





Un saludo.
Edito: Podeis bajaros el codigo fuente y el ejecutable para Linux x86 de http://rapidshare.com/files/18386790/frii-regionx-0.1.tar.bz2

Mi codigo ^^

#define _FILE_OFFSET_BITS 64

#define APP_VERSION "0.1"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* patch structure */
struct patch
{
   unsigned long offset; /* Offset */
   char values[17]; /* Values to patch */
   int nbytes; /* Bytes to patch */
};

/* NTSC to PAL patch */
struct patch ntsc2pal[]= {
                           { 0x04E003, "\x02", 0x01}, /* Patch #1 */
                           { 0x04E010, "\x00\x80\x80\x06\x03\x03\x04\x03\x07\x00\x00\x00\x00\x00\x00\x00", 0x10} /* Patch #2 */
                         };

/* NTSC-J to NTSC-U patch */
struct patch ntscj2ntscu[] = {
                               { 0x04E003, "\x00",0x01}, /* Patch #1 */
                               { 0x04E010, "\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80", 0x10 } /* Patch #2 */
                             };

/* Functions prototypes */
void pause(void);
int patchIso(char *, struct patch *);

int main(int argc, char *argv[])
{
   char *filename;
   int option;

   printf("----------------------------------\n");
   printf("+    SYNDICATE Region Patcher    +\n");
   printf("+ dissasembly reconstructed code +\n");
   printf("----------------------------------\n");

   printf("----------------------------------\n");
   printf("+        Frii-RegionX %3s        +\n", APP_VERSION);
   printf("+     Developed by Waninkoko     +\n");
   printf("+      Based on Glicer code      +\n");
   printf("----------------------------------\n");

   /* If at least one argument has been passed, use it as filename */
   if(argc > 1)
      filename = argv[1];
   else
   {
      filename = (char *)malloc(128); /* Allocate memory */

      do
      {
         printf("\n:: ISO file to patch: ");
         scanf("%s", filename);
      } while(filename == "");
   }

   /* Show options */
   printf("\n1. NTSC-J/NTSC-U to PAL patch.");
   printf("\n2. NTSC-J to NTSC-U patch.");
   printf("\n3. Quit application.\n\n");

   do
   {
      /* Get option */
      printf(":: Select an option: ");
      scanf("%d[^\n]", &option);

      fflush(stdin); /* Flush standard input */
   } while( (option < 1) || (option > 3) );

   printf("\n");

   switch(option)
   {
      /* NTSC-J/NTSC-U to PAL patch */
      case 1:
         if( patchIso(filename, ntsc2pal) == 0 )
            printf("\n:: [NTSC-J/NTSC-U -> PAL] patch applied succesfully!!\n\n");
         else
            printf("\n:: [NTSC-J/NTSC-U -> PAL] patch failed!!\n\n");

         break;

      /* NTSC-J to NTSC-U patch */
      case 2:
         if( patchIso(filename, ntscj2ntscu) == 0 )
            printf("\n:: [NTSC-J -> NTSC-U] patch applied succesfully!!\n\n");
         else
            printf("\n:: [NTSC-J -> NTSC-U] patch failed!!\n\n");

         break;

      /* Exit */
      case 3:
         return 0;
   }

   /* Pause */
   pause();

   return 0;
}

void pause(void)
{
   fflush(stdin); /* Flush standard input */
   getchar(); /* Wait until user press a key */
}

int patchIso(char *isofile, struct patch *ppatch)
{
   FILE *fp;
   int i;

   printf(":: Patching ISO... ");

   /* Open ISO file */
   fp = fopen(isofile, "rb+");
   if(fp)
   {
      /* Patch file */
      for(i = 0; i < ( sizeof(ppatch) / sizeof(struct patch) ); i++)
      {
         fseek(fp, ppatch[i].offset, SEEK_SET);

         /* Check that patch is being written */
         if( fwrite(ppatch[i].values, ppatch[i].nbytes, 1, fp) < 1 )
         {
            /* Print an error message */
            printf("ERROR!! Cannot patch "%s". Please, check file write permissions.", isofile);

            fclose(fp);
            return 1;
         }
      }

      /* Close file */
      fclose(fp);
   }
   else
   {
      /* Print an error message */
      printf("ERROR!! "%s" not found!!", isofile);
      return 1;
   }

   printf("OK!!\n");

   /* Return success */
   return 0;
}
Joder, al final haréis un montón de versiones XD si lo se me callo [+risas]

Bueno, la cuestión es que podamos usar todos el programa, sin saber o sabiendo programar, usando linux o windows, o mac, o lo que sea :P

Gracias a todos.
Nueva version del Region-Friix. Ahora SI parchea (XD) y he añadido una opcion para pasar de PAL a NTSC-U pero vete a saber si funciona xD

Version Windows: http://rapidshare.com/files/18415157/region-friix.exe

Adjuntos

relacionado con esto pongo otro hilo sobre los valores de region de los juegos:


http://www.elotrolado.net/showthread.php?s=&threadid=715262
Alguien tiene los fuentes del 1.21
Me interesaría mucho para así poderlo usar en mi Ubuntu, y no tener que entrar en mi *#+!¡ de window$.
Muchas gracias por darnos la posibilidad de usarlo en Linux..., no podemos decir lo mismo de los programas para ripear los juegos o otros como el wiibrick... :(:(:(
34 respuestas