tuts_gba
Thread Id: 11144
Thread Name: Otros | Otros | [Creación de herramientas] Modificar ROM en python
#0
cosarara97 12296
Hola!!!
Tienes una idea? Quieres hacer una herramienta pero no sabes como? Si? Pues que raro, no es que sea muy frecuente, lol

Ok, ya he acabado mi chiste malo, ahora viene la intro del tutorial.
Bueno, en este tutorial vamos a aprender a leer y modificar un ROM usando python, lo que nos permite crear herramientas en un lenguaje fácil de aprender como es python.




En este tutorial no aprenderemos python. Este tutorial está orientado a gente que ya sabe un poco de python, pero no sabe como escribir bytes en un rom.

Dificultad: Baja (Voy a poner ejemplos), si sabes python. Si conoces otros lenguajes de programación como C, java, o similares (HTML NO es un lenguaje de programación xD), sería media-baja, si nunca has programado pero eres inteligente, deberías poder entenderlo, y si no eres tan listo, pues ejem, piensa, luego busca en google y finalmente pregunta, ok?


Ok, empezamos:

Leer y modificar un rom con python

NOTA: Todas las lineas que empiecen con import, solo hay que ponerlas una vez en todo el programa. Recomiendo escribirlos todos al principio.

Leer el rom:

Primero vamos a definir una variable que contendrá la ruta hasta el ROM:
filename = ""
El nombre del rom, o la ruta completa hasta el rom
ejemplo1: filename = "mirom.gba"
ejemplo2 (linux): filename = "/home/mi_usuario/asdf/mirom.gba"
ejemplo3 (windows): filename = "C:\Users\usuario\asdf\mirom.gba"

Luego abrimos el rom
f = open(filename, "rb")
f es el nombre de la variable que almacenará el la función open(), open es la función que abre el rom, filename es la variable que hemos definido antes y "rb" es la opción de leer bytes (r,read, y b,bytes).

Luego almacenamos lo que el contenido del rom en una variable.
fcontents = f.read()
fcontents es la variable donde almacenamos todos los bytes del rom. (Va a ser de tipo string)



Si estás abriendo un ROM real y haces un "print fcontents" vas a morir (o tu PC va a morir), porque se escribirá todo el contenido del rom en tu terminal :P

Si en lugar de un ROM de GBA estas usando un binario creado por ti en un editor HEX, puedes imprimirlo en pantalla de dos maneras diferentes:

1:
print fcontents
Si tu binario contiene 0011223344, va a escribir:
'\x00\x11"3D'




2:
import binascii
print binascii.hexlify(fcontents)
Si tu binario contiene 0011223344, va a escribir:
0011223344



NOTA: A partir de ahora, para decir "imprimir en pantalla" usaré el verbo inexistente "printar", que es mas corto :D


Ok, ahora vamos a printar el byte que hay en un offset (decimal) en concreto:
offsetdec = "123456"




import binascii
print binascii.hexlify(fcontents[offsetdec])








Ahora lo mismo usando un offset HEX:
offsethex = "123456"




import binascii
print binascii.hexlify(fcontents[int(offsethex, 16)])




Y ahora vamos a printar de un offset (HEX) a otro
offsethex1 = "800000"
offsethex2 = "800100"



NOTA: El primero tiene que ser un numero mas
pequeño que el segundo (lógico, no?)

import binascii
print binascii.hexlify(fcontents[int(offsethex1, 16):int(offsethex2, 16)])




Modificar el rom (escribir):

Necesitamos el texto que hay en el ROM, así que si no lo hemos hecho:
filename = "Ruby.gba"




f = open(filename, "rb")
fcontents = f.read()




Escribir un solo byte (algo así como el WBTO pero para el ROM xD):
fwb = open(filename, "wb")


newbyte = "2C"



hexoffset = "800500"



import binascii
fwb.write(fcontents[:int(hexoffset, 16)] + binascii.a2b_hex(newbyte) \
+ fcontents[int(hexoffset, 16) + 1:])





Y en realidad la variable no se llama ROM, sino dcontents, así que lo cambiamos:
fwb.write(fcontents[:offset] + bytes + fcontents[offset + 1:])
Ahora codificamos los offsets y el byte.
fwb.write(fcontents[:int(hexoffset, 16)] + binascii.a2b_hex(newbyte) \
+ fcontents[int(hexoffset, 16) + 1:])
Y bueno, este es el resultado final:
fwb.write(fcontents[:int(hexoffset, 16)] + binascii.a2b_hex(newbyte) \
+ fcontents[int(hexoffset, 16) + 1:])

Pero para hacerlo mas fácil también se podría escribir así:

offset = int(hexoffset, 16)
inicio_del_rom = fcontents[:offset]
final_del_rom = fcontents[offset + 1:]
byte_codificado = binascii.a2b_hex(newbyte)
newcontent = inicio_del_rom + byte_codificado + final_del_rom
fwb.write(newcontent)

[/spoiler]
[/spoiler]



Escribir tantos bytes como queramos
fwb = open(filename, "wb")
newbytes = "3322446655AA00FFDD"



hexoffset = "800000"



import binascii
fwb.write(fcontents[:int(hexoffset, 16)] + binascii.a2b_hex(newbytes) \
+ fcontents[int(hexoffset, 16) + len(binascii.a2b_hex(newbytes)):])



Ya hemos acabado, pero si has llegado hasta aquí leyéndolo todo, te agradecería que me dejaras un mensaje en el perfil con tu opinión y, si las tienes, dudas.


Espero que ayude a la gente a crear sus herramientas :)

Bye!





EDIT 7: He añadido muchos ejemplos y explicaciones :D

EDIT 8: He añadido MÁS ejemplos y explicaciones.
#1
cosarara97 12296
Bueno, he re-formateado todo el tutorial para que se entienda mejor, y he puesto un programa como ejemplo (adjunto).
Si alguien quiere que ponga un ejemplo más especifico, que amplíe el que hay, hacer una pregunta (no entiendo nada no me sirve) o ponga mas comentarios, que me deje un comentario en el perfil o enviadme un MP, y estaré encantado de ayudarle :D
#2
THIAGOKAPO 18818
muchas gracias a linuxeros como a mi nos sirve mucho, pero hay herramientas como en nse para linux?
bueno me despido
grax por el tuto:D
#3
RogellParadox~ 13353
Sin duda, es de muy gran ayuda, sin hablar que es muy fácil hacerlo..
Como ya te dije, programé en Python un par de días y fue una buena experiencia.

Espero que hagas más, y que va siempre actualizando.
#4
VGS 12616
es una gran ayuda, lo entendi bien:) espero q sigas haciendo mas y mas.......