Copy Link
Add to Bookmark
Report

SET 032 0x07

  

-[ 0x07 ]--------------------------------------------------------------------
-[ SX1-Primera parte ]-------------------------------------------------------
-[ by FCA00000 ]-----------------------------------------------------SET-32--

Diario de un SX1-ero

Proverbio: "De lo que veas, cree sólo el 50%. De lo que escuches, el 10%. De lo
que oigas, el 2%."


27/08 *********** Sábado ***********
Por una casualidad de esas que da la vida, he conseguido varios Siemens-SX1. No
uno ni 2, sino 7 !
Todos tienen cable USB, batería, y auriculares. Algunos tienen la batería
cargada, y parecen funcionar.
Los he puesto a cargar antes de salir a dar una vuelta.

Cuando vuelvo, 5 horas mas tarde, compruebo que todos funcionan. Sueño
reparador.

28/08 *********** Domingo ***********
Como soy un antiguo forofo de los teléfonos Siemens, he aprendido a modificar
el software que tienen.
Esto me permite hacer cambios (pequeños), pero lo realmente entretenido es
aprender, aunque no tenga utilidad.
Hasta ahora he trabajado con el modelo C35 y S45, que incorporan un procesador
C166. Según creo, el SX1 es distinto.
Pero lo bueno es que tengo 5 tarjetas SIM para usar, y muchas ganas de probar
lo que se puede hacer.

He visto que el SX1 incorpora unos cuantos programas. Los gráficos son bastante
potentes (para ser un móvil, claro)

Sorpresa! Todos llevan una tarjeta de memoria de 128 Mb. Uno de ellos además
contiene canciones. No consigo hacerlas sonar. Al parecer necesito un programa
para ello.

He conseguido conectarlos por infrarrojos. El cable USB veo que funciona porque
aparece un icono en el móvil, pero Windows me pide un driver para el SX1.
Mañana buscaré en Internet desde el trabajo, puesto que en casa no tengo
conexión.

29/08 *********** Lunes ***********
Me he pasado el día surfeando. He conseguido unos 50 programas, la mayoría
juegos.
También he obtenido mucha información:
Al parecer lleva un Sistema Operativo llamado Symbian, al igual que los móviles
Nokia de penúltima generación.
Esto permite que los juegos sirvan para ambos, abriendo un mercado bastante
amplio.
Uno de los modelos de Nokia se llama N-Gage, orientado sobre todo para juegos.
Hoy no tengo tiempo de probar nada porque me voy a cenar fuera.

30/08 *********** Martes ***********
Mas investigación: este cacharrito es más grande de lo que pensaba.
Dentro de un sistema OT433 lleva un microprocesador ARM952 a 120Mhz.
La memoria es RAM de 16Mb, y los programas están en 3 zonas:
-ROM, para el sistema operativo. Ocupa 16 Mb
-flash, para programas y datos "temporales". Usa 4 Mb
-tarjeta extraíble de memoria. En mi caso son de 128 Mb
Además tiene USB, bluetooth, infrarrojos, cámara, sonido estéreo, radio, y una
batería que parece durar poco.
Ah, y las teclas están en unas posiciones muy raras. Por otro lado yo tengo un
S45 con el que estoy muy contento.
El S45 para llamar, y el SX1 para juguetear.

He probado alguno de los juegos. Son aceptablemente rápidos, y ocupan poco
(excepto el Doom)
También he conseguido algunas utilidades imprescindibles:
-FExplorer, para ver todos los archivos. Rápido y efectivo.
Copia/mueve/renombra/borra/crea archivos y directorios.
-TaskSpy, para ver los procesos y matar a aquellos que se quedan colgados.
-HView, un editor hexadecimal.
-Opera, navegador web. No pienso conectarme a Internet desde el móvil, pero me
vendrá bien para leer libros HTML en el autobús.
-Spectrian, emulador del ZX-Spectrum. Realmente impresionante lo bien que está
hecho.
Además de las que vienen incluidas en el sistema operativo:
-Manager, para ver las aplicaciones instaladas, y poder desinstalarlas.
-File Manager, otro navegador de archivos. Permite copiar carpetas completas.
-Notepad, Calculadora, reloj, agenda, ...

31/08 *********** Miércoles ***********
Hoy he bajado de la red otros programas. Entre ellos un driver USB.
Ahora windows está mas contento, pero sigo sin poder acceder al móvil. Yo
pensaba que aparecería como otra unidad de disco, pero nada de nada.
Todo lo que he conseguido es que en el hyperterminal me aparece el puerto COM4
llamado USBSER000, pero no responde a los comandos AT.

Más tarde encontuentro que si arranco la aplicación de FAX y la conecto por
infrarrojos, algunos comandos AT funcionan satisfactoriamente.

Poniendo la configuración a velocidad de 19200 baudios, me aparece basura en el
hyperterminal. Son unos 60 caracteres en 10 ráfagas cada 2 segundos. Podría ser
un protocolo PPP.
~ }#A!}!}!} }4}%}&yi||}"}&} } } } }'}"}(
}"}4~~ }#
A!}!}!} }4}%}&}1cya}"
}&} } } }
}'}"}(}":}9~~ }#À!}%}"} }$Y(~~ }#A!}!}!} }
4}%}&|eR3}"
}&} } } } }'}"}(}"|H~~ }#A
!}!}!} }4}%}&|eR3}"}&} } } } }'}"}(}"|H~~ }#A!}%
}"
} }$Y(~~ }#À!}!}!} }4}%}&ž/ón}
"}&} } } } }'}"}(}"ap~~ }#A!}!}!} }4}%}&|/on
}"
}&} } } } }'}"}(}"ap~~ }#A!}%}"} }
$Y(~~ }#A!}!}!} }4}%}&OA0|}"
}&} } } } }'

También me aparece configurado como módem: Siemens SX1 USB modem a 230400
baudios. Pero aquí no responde nada.
Arranco el Portmon, que es un sniffer del puerto serie.
El tráfico que veo es lo mismo que con el hyperterminal. Además veo que el
puerto de infrarrojos también recibe la misma basura.
Lo bueno es que Windows, con la aplicación irftp, es capaz de transferir
programas desde el PC hacia el móvil.
Eso quiere decir que reconoce el protocolo OFTP para transferencia de ficheros.
Quizas necesite otro programa especial para usar comandos AT-Hayes.

01/09 *********** Jueves ***********
He encontrado un foro en castellano sobre el SX1. Se llama
www.comunidad-siemens.com (en adelante, CS) y la gente sabe bastante.
No he encontrado referencias a programar el móvil, pero he aprendido muchas
cosas:
-es posible actualizar el Sistema Operativo. Yo tengo la versión 10, pero ellos
usan la "15.2 IBERIA". Me la he descargado.
-también se pueden hacer parches para cambiar ciertas cosas.
-los cambios parecen ser en los dibujos, melodías, salvapantallas, ... aunque
espero que también haya parches "funcionales".
-Para actualizar el móvil hay que pulsar el joystick hacia abajo, esperar un
segundo, y a la vez pulsar la tecla de encendido. La actualización se hace por
USB. Ya veremos si me funciona.
-Usar el móvil para transferir datos con el cable USB parece ser problemático.
Necesito el programa MPM (Mobile Phone Manager) desde la web de Siemens,
además de una actualización para el SX1. Ya los tengo.
-He hecho mi primera pregunta en el foro. En 2 horas no ha respondido nadie.
Esperaré a mañana.
-Efectivamente hay muchos juegos. Es más: se puede emular un GameBoy, y otras
consolas más. Como yo no soy muy jugador, me da igual.
-Se pueden hacer programas para Symbian. Hay algunos otros foros dedicados a
ello, por ejemplo www.allaboutsymbian.com
-Hay unos rusos que le han sacado las tripas: www.oslik.ru pero mi nivel de
entender ruso es nulo. Babelfish es mi amigo.

Aunque tengo ganas de probar los programas que me he bajado, hoy hace muy buen
tiempo, y hemos decidido salir de terrazas para tomar unas tapas.

02/09 *********** Viernes ***********
Como he desperdiciado bastante tiempo en los últimos dias, hoy tengo un poco de
trabajo atrasado. Música de Strauss para aislarme del mundo y poder acabar la
documentación que necesita el equipo de Weblogic. Hay reunión el próximo Lunes.

03/09 *********** Sábado ***********
Cargo en el ordenador el programa FW15.2[CS].exe de actualización del móvil,
que tiene la batería llena, por supuesto.
Con gran excitación pulso el joystick y la tecla de encendido, y en la pantalla
me dice algo así como "Listo para actualización de software".
El programa empieza a hacer su trabajo y observo satisfecho que la barra de
progreso se mueve, indicando que el firmware se está actualizando.
Al cabo de 15 minutos termina, y el móvil se apaga.
Lo enciendo de nuevo, y ahora usa unos gráficos diferentes. Parece que lo he
hecho bien.
Pulsando *#06# me dice el IMEI, y el botón "Info" arranca la aplicación
CC-Monitor que me indica que la versión es 15.2

No voy a actualizar todos los móviles. Sólo 2 de ellos tendrán la versión 15.2
y otros 2 tendran la 14. El resto, para pruebas.

Esto es una ventaja de Siemens sobre Nokia: permiten que el usuario actualice
desde casa su móvil usando un cable estándar, que viene incluído cuando compras
el teléfono.

El programa que sirve para actualizar la memoria flash resulta ser un
ejecutable de 25 Mg. Espero buscar los mensajes que muestran las aplicaciones
del móvil, para hacer mi propia versión, pero no encuentro las cadenas de texto.
Es posible que el actualizador este comprimido o cifrado.

Activo el puerto infrarrojos del móvil y del ordenador, y veo que pueden
comunicarse. El programa irftp incluido en Windows permite transferir en ambas
direcciones, así que meto unos cuantos de los juegos que he bajado de la red.
A mí siempre me ha gustado más la programación, pero una partida de vez en
cuando no está mal.

Mirando en los foros descubro que es posible emular juegos de la N-Gage de
Nokia, pues ambos tienen el mismo sistema operativo Symbian.
Para eso hay que instalar un parche que también tengo. Lo que no sé es cómo se
aplica el parche, que es del tipo
replace:0032040504350410:00B240A205402A0

Esto me resulta de lo mas extraño. En los otros modelos de Siemens los parches
son simpre un cambio en una dirección fija de memoria, del tipo
0xC12346: 045A 032A
pero al parecer en el SX1 los parches se limitan a buscar una cadena, y
reemplazarla por otra.
Deduzco que esto es así porque hay varias versiones de firmware, y la misma
cadena puede estar en distintas posiciones de memoria dependiendo de la versión.
?Pero que pasa si mi versión no tiene esa secuencia de caracteres?
Ademas, esa cadena no aparece en el fichero FW15.2[CS].exe por lo que no puedo
aplicar el parche. Me quedo sin poder jugar a la N-Gage .

Más descubrimientos: existen unidades de disco:
Z: es donde está el sistema operativo. La única manera de escribirlo es
actualizando el firmware.
E: es la tarjeta MMC - MultiMedia Card. Aquí es donde se suelen instalar los
programas, canciones, vídeos, ...
D: es un disco RAM. Los datos se pierden cuando se resetea el móvil. Se usa
como almacenamiento temporal.
C: es otro disco en el que se pueden guardar programas. En particular los SMS
se guardan aquí, y también los programas transferidos por infrarrojos,
aunque luego se pueden instalar en E: o en C:
A: es de sólo lectura. Aquí están los programas que la operadora de red le pide
a Siemens o a Symbian. Hay algunos juegos, un reproductor mp3, la radio, y
el RealPlayer para ver vídeos. En la versión 14 fabricada a medida para la
empresa O2, también hay un navegador hecho a medida.

La manera más cómoda de instalar programas es usar un escritor de tarjetas MMC
y luego meter la tarjeta en el móvil.
Pero como yo no tengo un lector (ya sé que sólo cuestan 10 euros) los tengo que
transferir por infrarrojos. El programa para usar el puerto USB no consigo que
me funcione.

COn ésto se me han pasado algunas horas. Momento de cine y unas copichuelas.

04/09 *********** Domingo ***********
Día de descanso. Hoy no enchufo el ordenador. Pero he notado que la batería
dura menos de 48 horas, por lo que me tendré que acostumbrar a dejarlo cargando
todas las noches.


05/09 *********** Lunes ***********
Entre unas cosas y otras no he podido surfear, pero me ha dado tiempo para ver
la respuesta en el foro CS. Básicamente sólo hay parches para cambiar los
iconos, músicas, tipos de letras, pantalla de inicialización, y otros que hacen
que alguna aplicación lea los ficheros de E: en vez de Z: , para poder meter
mis propios iconos.
Pero no hay parches funcionales. Quizás es muy complicado. Pero de verdad me
gustaría cambiar algunas cosas. Por ejemplo, para instalar una aplicación hay
que aceptar algunas verificaciones, en total 5 mensajes !
Si fuera posible eliminar algunas de estas preguntas, la instalación sería más
cómoda.

Con la aplicación FExplorer he podido ver que cada aplicación tiene un
identificador único, para que no se instale 2 veces. No sólo eso, sino que la
misma aplicación no puede ejecutarse a la vez 2 veces, lo cual tiene bastante
sentido para un juego, pero no para el Notepad.


06/09 *********** Martes ***********
Hoy me he bajado el OggPlay para escuchar música. Tiene algunas cosas mejores
que el reproductor mp3 que viene incluído, pero el formato de las canciones es
diferente. Tendré que convertirlas a formato OGG. Para eso uso el programa
"ACE-HIGH Converter".
Malas noticias: si escucho canciones durante más de tres horas, la batería se
agota. No dura casi nada, en parte debido a que no hay posibilidad de cambiar
la intensidad de la iluminación. ?Para qué necesito que ilumine durante el día?
Esto es un fallo grave de diseño.

Más investigaciones: las aplicaciones de la unidad Z: ocupan una media de 20 Kb,
y también hay un monton de librerías en Z:\System\Libs . En total hay unos
1.500 ficheros.

Transfiero alguno de ellos al PC, y lo único que veo en claro son algunas
cadenas de caracteres, en formato Unicode, esto es, que cada car'cter ocupa 2
bytes.
Por ejemplo, el fichero z:\system\libs\MenuEng.dll contiene la cadena
Z:\system\data\op_folder.mbm
ocupando 28*2 bytes

Un parche típico es cambiar la primera Z por E para que el fichero se lea desde
E: , donde es posible alterarlo.
Pero sigo sin saber cómo meter un parche, ni tampoco sé qué es un fichero de
tipo mbm .


07/09 *********** Miércoles ***********
Desde la web de oslik he encontrado muchas utilidades:
-RSCTool, para cambiar archivos de recursos, de extensión .rsc
-MBMTool, para archivos de imágenes MBM: Multi-Bit-Map
-UnMakeSIS, para ver los ficheros dentro de un archivo SIS, que es un
instalador de aplicaciones
-SISTool, para lo mismo
-AIFTool, para leer archivos AIF: Application Information File , con los iconos
y nombre del programa
-WSFFXBI, para extraer un XBI desde un WinSwup (tal como FW15.2[CS].exe ) y
viceversa
-Xbi_Extract, para romper un XBI en pedazos, uno para cada unidad A: , Z: ,
bootcore, ...
-WSMP para meter parches en un XBI

Ademas, desde la web de CS he encontrado manuales para la mayoría de estos
programas.
Brevemente:
-el WinSwup se convierte en XBI usando WSFFXBI
-el XBI se parchea con WSMP
-el XBI se convierte en WinSwup con WSFFXBI
-el WinSwup se ejecuta, que instala la nueva versión.

El fichero XBI extraído de esa manera contiene una copia de todos los ficheros
en Z:

Manos a la obra. Elijo uno de los parches para leer menu_folders.mbm desde E: ,
sigo los pasos anteriores, y cuando inicio el móvil, se resetea. ?Qué he hecho
mal? Obviamente, me he olvidado de copiar menu_folders.mbm en E:
Menos mal que tengo otro móvil. Cambio la tarjeta MMC, copio el archivo usando
FExplorer, y ahora funciona en el móvil parcheado !
Los iconos son los mismos que antes, pero con el MBMTool descomprimo
menu_folders.mbm y cambio uno de los dibujos, lo transfiero al móvil, lo copio
en E: , y tras resetear el móvil, el nuevo icono aparece.
Bueno, todo un acontecimiento.


08/09 *********** Jueves ***********
Hoy ha surgido el típico marrón del jueves, así que no me quedan tiempo ni
ganas de enredar con el móvil. Quería hacer algo porque el fin de semana tengo
otro asunto planeado, pero no va a poder ser.


09/09 *********** Viernes ***********
Uso el programa FileMan para transferir todos los archivos de Z: hasta E: y
después los meto en el PC. Hago un programa que busca una cadena de caracteres
dentro de cada uno de los ficheros, para ver cuales archivos son usados por
otros programas, y hacer una especie de árbol relacional.
Los archivos avkon.mbm, EidPic.mbm y Muiu.mbm se usan muy frecuentemente por
otras aplicaciones. En particular avkon.mbm contiene 250 iconos usados a lo
largo de todo el sistema operativo. No hay parches para usarlo desde E: , pero
hay parches para cambiarlo en Z: .
El motivo de no meterlo en E: es que la unidad E: está en la MMC, y es muy
lenta de acceder. La unidad Z: está siempre en memoria, así que los iconos se
pueden acceder sin demoras.
Pero yo no pretendo cambiar los dibujos. Hay muchos artistas por ahí, y yo lo
máximo que sé hacer es la letra O, ayudado por un canuto.
Bueno, no me da tiempo para más antes de que salgamos de viaje.

10/09 *********** Sabado ***********
Londres esta cada día mas caro. 35 libras por chicken-tikka-massala y
KingFisher para dos !

11/09 *********** Domingo ***********
Me encanta el flea market. Sobre todo las tiendas de discos de alrededor.

12/09 *********** Lunes ***********
Como no he dormido mucho el fin de semana, estoy cansado y hoy tampoco toco el
ordenador.

13/09 *********** Martes ***********
He abierto la aplicación Notepad.app con un editor hexadecimal y he averiguado
que los primeros bytes es una cabecera diseñada siguiendo un estándar:
-los primeros 4 bytes son 79000010 que escritos en little-indian significan
0x10000079. Todas las aplicaciones de tipo *.app empiezan por estos bytes.
-los segundos 4 bytes son 0x100039CE , y también sucede con muchas aplicaciones
*.app . Este número mágico se llama KAppUidValue16 , y significa que la
aplicación es Unicode, es decir, que puede contener mensajes con caracteres no
ASCII.
-los terceros 4 bytes son 0x10005907. Al ejecutar la aplicación y mirar con
TaskSpy, éste es el número identificador. Así que cada programa tiene un
número único.
-el cuarto grupo vale 0x3EB18517, y es otro identificador, aunque no
necesariamente único.
-cada uno de estos números se llama UID: Unique IDentifier
-el siguiente grupo vale 0x506D53D5 e indica el punto de inicio del programa.
Para aplicaciones en Z: ésta es exactamente la dirección en la que están
ubicados.

Lo explicaré mejor: la memoria en Symbian es un bloque de 16 Mb que se carga a
partir de la dirección 0x50000000. Cada fichero, por el hecho de estar en este
gran bloque, va a parar a una dirección de memoria. Pues bien, esta dirección
también está escrita en el propio fichero.

Los programas que residen en A: , C: o E: son cargados dinámicamente, por lo
que su dirección no es siempre la misma. Pero Symbian tiene un mecanismo de
memoria paginada que hace que todos los programas aparezcan como cargados en
la dirección 0x00400000, aunque obviamente el gestor de tareas se encarga de
alternar entre uno y otro, lo que se conoce como actualización de entorno.
Esto existe en prácticamente todos los sistemas operativos multitarea de disco.

-El siguiente dato es 0x506D53D4 (uno menos que el anterior) e indica la
dirección donde empieza el código.
-Luego viene 0x00000000 que es la dirección de los datos. Al ser 0 quiere
decir que no hay datos pre-inicializados, y la propia aplicación se encargará
de solicitar la memoria necesaria cuando llegue el momento.
-Sigue el dato 0x00000AE0 que indica el tamaño del código. Este programa ocupa
0x0AE0 = 2784 bytes.
-Después va 0x00000ADC que es el tamaño total. Es el dato anterior, menos 4.
-A continuación 0x00000000 que es el tamaño de los datos.
-Otra vez 0x00000000 para indicar el tamaño del BSS, es decir, la pila.
-El siguiente es 0x00100000 = tamaño máximo de la pila.
-Sigue 0x00001000 = tamaño mínimo de la pila.
-Después, 0x00002000 = tamaño del stack para las rutinas.
-y 0x50F17610 indica las referencias a DLL. Esto dice cuáles rutinas son usadas
desde otras librerías.
-El dato 0x00000001 dice que sólo hay 1 función exportada.
-0x50F1760C indica la lista de funciones exportadas, precisamente la de
inicialización del programa, correspondiente a la función main.

Esto me va a servir para saber cuáles programas llaman a las librerías, y por
tanto las funciones exportadas. Lo que no sé es el significado de cada rutina.


14/09 *********** Miércoles ***********
He estado paseándome por la web de Symbian y he bajado el SDK que sirve para
hacer programas.
El lenguaje es C/C++ pero un poco anticuado. Cuando los desarrolladores de
Psion (predecesor de Symbian) inventaron su sistema operativo, C++ todavía no
tenía un mecanismo de excepciones maduro.
Esto hace que las aplicaciones Symbian tengan que encargarse ellas mismas de
liberar la memoria que soliciten. A la porra toda la funcionalidad del
recolector de basura, auto-destrucción, y además complica el polimorfismo.
Esto parece ser una grave inconveniencia para hacer programas de usuario, según
he estado leyendo.

Por lo menos he visto que existen 2 sitios web dedicados a la programación en
Symbian:
www.newlc.com
allaboutsymbian.com , que frecuentemente está sobrecargado.

Desde la web de Siemens me he bajado el SDK específico para el SX1. Ocupa 200
Mg comprimido, y 600 Mg instalado completamente.
Lo he instalado y veo que incluye un emulador. Pero apenas cubre el 30% de la
funcionalidad real del teléfono.
Para empezar, la aplicación principal es el menú, desde el que se pueden
iniciar otras aplicaciones.
En el móvil real esto no es así, sino que la aplicación es llamada Phone.app ,
con posibilidad de iniciar llamadas, acceso rápido a aplicaciones (manteniendo
pulsada una tecla durante 2 segundos), gestión del manos libres, ...
Por ejemplo: cuando el móvil no hace nada, pasa a la aplicación Phone.app . Si
se pulsa el joystick hacia abajo, se inicia la aplicación de la agenda. Esto
no se puede hacer desde el emulador, y precisamente yo estaba interesado en
esto.

Si el emulador no es perfecto, la documentación es todavía peor. Es cierto que
explica muchas cosas, pero como un manual de referencia; no cuenta en detalle
cómo usar esas librerías.
Al menos hay muchos ejemplos que tendré que investigar. Necesito el compilador
Microsoft VC 6.0 porque no funciona con versiones superiores ! Lo único que
usa es el nmake , pues el compilador es el GCC, incluido en el SDK.

Intento compilar el ejemplo HelloWorld, pero se queja de que no tengo instalado
el Perl. Mañana me lo bajaré.


15/09 *********** Jueves ***********
Por fin tengo todas las herramientas, incluido el Cygwin para usar un automake
y un shell decente.
Me cuesta un poco compilar la primera aplicación, pero al final consigo
HelloWorld.app
El método es el siguiente:
-poner bien la variable EPOCROOT, en mi caso \Symbian\6.1\Siemens\SX1\bin\
-pasar al directorio ....\group\
-bldmake bldfiles para que construya el proyecto
-abld makefile para defini cuáles archivos son necesarios: fuentes, cabeceras,
dibujos, ioconos, sonidos, ...
-si se quiere hacer la aplicación para el emulador: abld build wins urel
-si se hace para el móvil real: abld build armi urel

Parece que empiezo bien. La aplicación HelloWorld.app funciona en el emulador.
Meto en el móvil la versión compilada para armi , pero se resiste a arrancar.

Tras leer mucha documentación, parece ser que no vale con copiar la aplicación
en el móvil; es necesario instalarla adecuadamente con HelloWorld.sis
Para esto hay que hacer
-makesis HelloWorld.pkg

Ahora se deja instalar adecuadamente, pero cuando la inicio, da un error y sale.

Tras muchas pruebas y perder el tiempo, lo intento con otra aplicación simple
llamada Language y ésta funciona !
No es una maravilla de aplicación, pero al menos tengo algo que funciona.

Lo que estaba haciendo era correcto. Simplemente que la aplicación HelloWorld
parece no funcionar en el móvil.


16/09 *********** Viernes ***********
La conexión a Internet del trabajo está que echa humo. Hace 2 días me descargue
el SDK, ayer el Perl y el Cygwin. Hoy me he bajado todos los ejemplos de
programación que he encontrado. Un montón de documentación desde la web de
Nokia, y algunos juegos que he encontrado por el camino.
A ver si tengo tiempo para organizarlo todo. Leerlo me llevará mucho más
tiempo, por supuesto.

Me sorprende que Nokia parece darle mucho más apoyo al sistema operativo
symbian que la propia compañía Symbian.
Sus foros están llenos de preguntas sobre programación. Lamentablemene no hay
muchas respuestas.
La mayoría de los temas parecen centrarse en "cómo hacer una llamada automática" y "cómo hacer un programa que mande SMS".
Lamentablemente en las webs de CS, oslik, y www.siemens-mobile.org (en
adelante, SMO) los foros de programación están bastante vacíos.

Pero por ahora estoy bastante contento. Han pasado 3 semanas desde que tengo
los móviles, y ya me hago una idea de lo que es capaz de hacer el SX1. Esto se
merece una mini-celebración. Comida mongola para dos, que a mi chica también le
apetece ir a un sitio exótico.

17/09 *********** Sábado ***********
Como ya he comentado, al pulsar el joystick hacia abajo se inicia la aplicación
de contactos, llamada Phonebook.
Tiene un UID con valor 0x101F4CCE
Lo que pretendo hacer es cambiarlo para que inicie otra aplicación distinta.

Al pulsar el joystick hacia arriba se inicia la aplicación de últimas llamadas
recibidas y enviadas, que se llama Logs y tiene UID=0x101F4CD5

Supongo que la aplicación que gestiona el joystick usa ambos valores en rutinas
similares; simplemente inicia Phonebook.app o Logs.app

Para buscar esos bytes, recordar que hay que cambiar el formato a little-indian,
por lo que 0x101F4CCE hay que buscarlo como CE.4C.1F.10

Mirando en el archivo XBI generado a partir del FW15.2[CS].exe lo encuentro en
11 sitios.
Obviamente uno de ellos corresponde al UID del propio fichero Phonebook.app
pero éste no lo puedo cambiar.
Otros sitios son en Phonebook.aif, que es el fichero con la configuración del
propio Phonebook.
Otro de los sitios es en la aplicación Phone.app que si recuerdas es la que
está ejecutándose cuando estás en el menú principal, precisamente cuando puedes
pulsar el joystick para que arranque otras aplicaciones.
No sólo éso, sino que encuentro la cadena de bytes:
CE4C1F10 D54C1F10
es decir, los UIDs de las dos aplicaciones que se pueden ejecutar con el
joystick.
Modifico estos datos en el XBI para que apunten a la calculadora
(UID=0x10005902) usando los bytes
02590010 en vez de CE4C1F10
y tras instalar el firmware modificado observo con regocijo que ahora abre la
calculadora !

Primer parche funcional en mi carrera del SX1.

Lo meto en un fichero de texto, le pongo unos cuantos comentarios, y lo preparo
para publicarlo en CS. A ver qué les parece.

Este parche no tiene nada de programación, pero los siguientes seguro que sí.

Para intentar entender cómo funcionan los programas, necesito desensamblarlos.
Para el modelo S45 usaba el IDA dissasembler, que es un gran programa, aunque
un poco caro. Pero lo he usado tanto que me parece justo pagar por él.
Además incluye soporte para ARM. Cargo el IDA, le digo que destripe el
Notepad.app, y lo identifica como un fichero EPOC, es decir, de la antigua
versión Symbian. Pero luego se hace un lío con las cabeceras. Lo mejor es
decirle que es un fichero binario puro, por supuesto para el procesador ARM,
en concreto ARM710a .

Entonces hay que decirle cuál es la dirección en la que tiene que cargarlo.
La cabecera tiene el dato 0x506D53D4 que dice que el código empieza
precisamente ahí.
Pero como he cargado el fichero entero, tengo que excluir el tamaño de la
cabecera, es decir, restarle 0x64 bytes para obtener 0x506D5370.
Esa es la direccion de inicio, y ademas genero una sección de ROM con
exactamente la misma dirección.

Cuando lo carga, no desensambla nada. Todavía me faltan un par de pasos.

El procesador ARM tiene 2 modos de funcionamiento.
Uno llamado ARMI, en el que las instrucciones de código ocupan 4 bytes. Es más
rápido, más potente, pero consume más batería y ocupa mas espacio.
El otro modo se llama THUMB, y las instrucciones ocupan 2 bytes. El código es
más compacto, pero más limitado. Algunas operaciones sólo se pueden ejecutar
en ARMI. A cambio, consume menos.
En particular, el kernel y los drivers están compilados en ARMI, y los
programas de usuario en THUMB.

Como IDA está configurado por defecto para desensamblar en modo ARMI, no
empieza el desensamblado automático.
El programa Notepad.app está compilado en THUMB. Para que IDA lo pueda
desensamblar hay que que cambiar el registro T con valor 1, usando la tecla
Alt-G
Ahora ya lo puedo desensamblar. Selecciono todo el trozo de programa desde la
dirección 0x506D53D4 y le digo que lo analize.
Al cabo de un par de minutos me ha generado un listado de 150 rutinas, de unas
2000 líneas en total.
Pero no sé lo que significan las rutinas. Espero encontrar un listado de ellas
en algun sitio del SDK. Pero eso será otro día.

Ahora, al cine y a darnos ir garbeo.

18/09 *********** Domingo ***********
Tal como sospechaba, las cabeceras del SDK (*.h) contienen los nombres de
muchas de las funciones exportadas.
Por ejemplo, la documentación dice que hay una función llamada FileExists()
que está declarada en coeutils.h e implementada en cone.lib
Efectivamente, coeutils.h contiene la línea

public:
IMPORT_C static TBool FileExists(const TDesC& aFileName);

Y el fichero cone.lib contiene la palabra FileExists , más concretamente
"FileExists__9ConeUtilsRC7TDesC16".
Esto es la notación que usan las librerías en Windows, y significa que es una
función que:
-toma como argumento un objeto de tipo TDesC16
-devuelve un objeto de tipo 9 , es decir, un TInt (o un TBool, que es lo mismo)

Para saber cual es el número dentro de esta librería, uso el programa ar
(Archive) :
ar -tv cone.lib
que resulta tener 319 funciones. El fichero ds00063.o contiene la palabra
"FileExists", así que ya sé que la función 63 de ConeUtils es FileExists.
Esta función está implementada en la librería Cone.dll del móvil, pero no sé
cual es el punto de entrada a la rutina.

Así que cargo el fichero ds00063.o en IDA, que lo identifica como ARM COFF
(little endian)
Pero el desensamblado no me da ninguna pista. Lo único que contiene es una
referencia al número 0x3F = 63 , pero esto ya lo sabía yo.

Así que cojo el programa Language que conseguí compilar el otro día, y hago
que use la función FileExists .
No me molesto en hacerlo funcionar. Lo único que quiero es saber cómo hace
para referenciar a la función 0x3F.
Y en realidad es bastante sencillo:
el compilador crea una función sub_10009A88 que servirá como punto único de
entrada:
sub_10009A88
LDR R3, off_10009A90
LDR R3, [R3]
BX R3

el registro R3 apunta a una dirección de memoria:
off_10009A90 DCD 0x1000BD60

en esta dirección se invoca a la función de la librería externa:
; Imports from CONE.DLL
1000BD60 IMPORT FileExists__9ConeUtilsRC7TDesC16

Este último dato será rellenado por el ejecutor de tareas en el móvil: carga
la aplicación en memoria, rellena la tabla de referencias, y salta a la
dirección de inicio de la aplicación.
Esto es algo típico de los sistema operativos que usan librerias dinámicas.

Lo que no me gusta tanto es que hay una referencia a una referencia a una
referencia. Así va a ser difícil seguir el flujo de los programas.
Y tampoco me gusta que las rutinas tengan nombres como
FileExists__9ConeUtilsRC7TDesC16. Preferiría algo mas legible.

Empiezo a darle vueltas a la cabeza para hacer un programa que saque los
nombres en claro, a partir de los nombres incluidos en las librerías y los
ficheros de cabecera. Primero necesito meditarlo, y luego programarlo.

19/09 *********** Lunes ***********
He publicado el parche en CS, y parece que ha tenido cierta aceptación. No
porque sea terriblemente útil, sino porque
es de los primeros parches funcionales. Recibo muchos ánimos de la comunidad.

Por otro lado, busco algun programa que me ayude a sacar los nombres de las
librerías.
El truco está en usar el programa dumpbin.exe incluido con el VisualC++ :

dumpbin /ALL cone.lib
..........
Version : 0
Machine : 14C (i386)
TimeDateStamp: 3FAA5B88 Thu Nov 06 14:32:40 2003
SizeOfData : 00000032
DLL name : CONE.DLL
Symbol name : ?FileExists@ConeUtils@@SAHABVTDesC16@@@Z
(public: static int __cdecl ConeUtils::FileExists(class TDesC16 const &))
Type : code
Name type : ordinal
Ordinal : 76
................

Unas cuantas de líneas de Perl , y ya tengo sacadas todas las definiciones de
las librerías.

Vamos a ver si me sirve de algo:
Hay un programa llamado torch que lo único que hace es mantener encendida la
constantemente pantalla del móvil, por si necesitas una linterna. Bastante
inútil, pero es simple.

Tengo el torch.sis que vale para instalarlo.
Con el programa SISTool veo que consiste en 4 archivos:
-Torch.app, con la aplicación
-Torch.rsc, con los recursos, es decir, los textos de los diálogos y los menús
-Torch_caption.rsc con el nombre de la aplicación
-Torch.aif con el icono de la aplicación y el UID

El que me interesa es el primero. Lo extraigo, y lo paso por el IDA.

Veo que usa:
10000FCC IMPORT Start__9CPeriodicG27TTimeIntervalMicroSeconds32T1G9TCallBack

la cual es referenciada en:
off_100003EC DCD Start__9CPeriodicG27TTimeIntervalMicroSeconds32T1G9TCallBack

que es llamada desde:
sub_100003E0
PUSH {R6}
LDR R6, =Start__9CPeriodicG27TTimeIntervalMicroSeconds32T1G9TCallBack
LDR R6, [R6]
MOV R12, R6
POP {R6}
BX R12

invocada desde:
.text:100001E4 LDR R2, =0x989680
.text:100001E6 LDR R0, =(loc_10000298+1)
.text:100001E8 STR R0, [SP,#0x14+arg_0]
.text:100001EA STR R4, [SP,#0x14+arg_4]
.text:100001EC LDR R0, [R4,#0x30]
.text:100001EE ADD R1, R2, #0
.text:100001F0 LDR R3, [SP,#0x14+arg_0]
.text:100001F2 LDR R4, [SP,#0x14+arg_4]
.text:100001F4 STR R4, [SP,#0x14+var_14]
.text:100001F6 BL sub_100003E0
.text:100001FA ADD SP, SP, #0x1C


Vamos a ver si lo entiendo (desde abajo hacia arriba):
100001F6 llama a sub_100003E0
en 0x100001F4 mete en la pila el valor de R4
que en 0x100001F2 lo ha sacado desde la pila
También R3 lo ha sacado en 100001F0 desde la pila
En 0x100001EE ha hecho R1=R2+0
Me salto las otras instrucciones hasta 0x100001E4 , en donde hace
R2=0x989680
este valor es 10.000.000 en decimal y se le pasará como segundo argumento a la
rutina sub_100003E0 , o sea,
void Start(TTimeIntervalMicroSeconds32 aDelay,TTimeIntervalMicroSeconds32
anInterval,TCallBack aCallBack);

Obviamente quiere decir que cada 10 segundos llamará a una función que
re-encenderá la pantalla.
Pero mi pantalla no se apaga automáticamente a no ser que no pulse ninguna
tecla durante 20 segundos. Podría cambiar el valor 10.000.000 por 20.000.000 ,
y me ahorro algo de proceso.

Vale, no es el cambio que va a arreglar el mundo, pero yo sólo pretendo
aprender.

Ahora es cuando tengo que admitir que he hecho trampa. El programa Torch es de
código abierto, y tengo el código fuente original, por lo que podría haberlo
cambiado, recompilar, y a correr.

20/09 *********** Martes ***********
Los programas que puedo instalar en el móvil siempre tienen una tabla de
funciones importadas, para que el iniciador de tareas los pueda unir con las
librerías dinámicas. Esto hace sencillo averiguar los nombres de las funciones
usadas, con lo que es fácil hacerse una idea de lo que hacen los programas, a
no ser que usen trucos complicados, o el programa sea demasiado grande para
analizarlo.

Pero los programas que vienen incluidos en el móvil no son dinámicos. Ellos
_saben_ exactamente dónde están las librerías, pues forman parte del mismo
sistema.
Por poner un símil, imagina que tienes que usar un teclado de un ordenador en
otro idioma. Las teclas pueden estar en una posición distinta, por lo que tú
tienes que mirar el teclado constantemente.
Pero los nativos del país ya saben dónde están las teclas, y pueden escribir
más rápido.
Esta ventaja también existe en los programas nativos: se cargan más rápidos
porque no es necesario resolver las dependencias de enlace; ya fueron resueltas
en tiempo de compilación.

A cambio dificultan la tarea de aquellos que, como yo, pretenden modificar los
programas nativos.
Primero tengo que averiguar cuales son las rutinas llamadas, suponiendo que
estén documentadas.

Empiezo por atacar al Notepad.app . No es una gran aplicación, pero voy a ver
que saco.

Lo primero que encuentro es que hay un trozo con las instrucciones:
BX R1
NOP
NOP
BX R2
NOP
NOP
BX R3
NOP
NOP
....
BX R13
NOP
NOP

(la instruccion BX indica "saltar a")

Estas son rutinas de acceso indirecto o indexado.
Supongamos que tengo una rutina que quiero que haga
if(x=100) salta a rut100;
if(x=101) salta a rut101;
if(x=102) salta a rut102;
if(x=103) salta a rut103;

esto es más eficiente si hago
lista_ruts={rut100, rut101, rut102, rut103};
lista_vals={100, 101, 102, 103};
for(i=0;i<sizeof(lista_vals);i++)
if(x==lista_vals[i])
{
R1=lista_ruts[i];
salta a R1;
}

En otras palabras: este troz ode código actúa simplemente como un trampolín
para saltar a otra rutina.
Aunque la pregunta es clara: si tengo
BX R1
?para que necesito BX R2 ?
Bueno, la respuesta es que a veces necesitas mandar un parámetro, y el primer
parámetro que admite una rutina siempre es R1.
Ya, ya, entonces te preguntas si de verdad hay funciones con 14 parámetros.
La respuesta es no. Pero al parecer el compilador siempre incluye todas las
intrucciones
BX R_??

Más cosas: casi todas las rutinas empiezan guardando los registros que van a
corromper.
En ARM existe una instrucción que puede meter varios registros en la pila, por
ejemplo
PUSH {R4-R6,LR}
meterá los registros R4, R5, R6 y LR
obviamente al final de la rutina se hace
POP {R4-R6}
y después
POP R1
BX R1
que es equivalente a
RET
Esto me ayuda a saber dónde termina una rutina y empieza la otra.

Otra curiosidad más: existe una intrucción para cargar valores sencillos en un
registro:
MOV R0, #0x1C
pero sólo se pueden cargar valores de 8 bits.
Para cargar un valor más grande (de 32 bits) hay que hacerlo con una referencia:
LDR R4, val(dato_grande)
.....
dato_grande DCD 0x12345678

Notar que se usa el comando LDR en vez de MOV . Hace lo mismo, pero sirve para
cuando usas referencias.

A menudo se usa un truco consistente en multiplicar el valor por otro.
Por ejemplo, no se puede hacer
MOV R1, #0x124

pero se puede hacer
MOV R1, #0x49
LSL R1, R1, #2

que desplaza R1 hacia la izquierda 2 veces, es decir, lo multiplica por 4, y
#0x49*4 = #0x124

Al principio me cuesta un poco entender el ensamblador del ARM, pero en
realidad es más sencillo de lo que parece.
A decir verdad, no he aprendido mucho del funcionamiento real del Notepad,
pero creo que ha sido útil.

21/09 *********** Miércoles ***********
Me he bajado de la red unos manuales de ARM, porque hay algunas instrucciones
que no consigo entender: MCR, MSR, registro CFSR, P15, ...
Por lo que averiguo, sólo se usan para tiempo real y para gestionar la caché de
memoria y otras cosas más complicadas.
Me las he encontrado en el Notepad.app porque en realidad estaba desensamblando
una parte de datos, no de código, con lo que IDA se ha liado y me ha confundido
también a mí.

En el foro de CS he visto que alguien quería eliminar un mensaje que aparece
cuando cambias la tarjeta MMC sin antes notificárselo al móvil. Lo explicaré
mejor: el SX1 puede leer tarjetas de memoria. Las que yo tengo son de 128 Mg,
con lo cual caben muchos programas y canciones.
La tarjeta está ubicada en un lateral, y no es necesario apagar el móvil para
cambiarla.
Cuando quieres meter otra tarjeta, hay que ir a un menú, que se encarga de
cerrar los archivos abiertos, y finaliza las aplicaciones que se están
ejecutando desde la memoria MMC.
Pero también es posible sacar la tarjeta sin usar el menú. Eso sí, te arriesgas
a perder datos.
Cuando lo haces así, el móvil muestra un mensaje advirtiendo que no es
recomendable sacar la tarjeta de esta manera violenta.
Este usuario del foro quería que no saliera este mensaje.

Lo primero que he hecho es buscar este mensaje "Puede perder datos si extrae
su tarjeta MMC"
por todos los ficheros. No lo he encontrado, lo cual me
sorprende bastante. Quizás está comprimido.

Lo siguiente que he hecho es averiguar cual es la aplicación que muestra el
mensaje.
Hago un programa que muestre un mensaje simple, y veo que el compilador incluye
una referencia a CAknGlobalNote::ShowNoteL

Por el nombre, y un poco de suerte, descubro que ésta función está definida en
AknNotify.dll

veo que tras un par de comparaciones, llama a una función sub_503EB9B4 que a
su vez llama a
RNotifier::StartNotifierAndGetResponse(TRequestStatus &, TUid, TDesC8 const &,
TDes8 &)

Así que decido parchear esta rutina para que no haga nada.
Modifico el firmware, lo meto en el móvil, y ahora no muestra ese mensaje. Ni
ese, ni ningún otro !
Creo que la rutina ésta es llamada desde muchos otros sitios.

Deshago el cambio, y ahora parcheo sub_503EB9B4 . Lo mismo. No sale ningún
mensaje.

Así que miro cuales rutinas llaman a
CAknGlobalNote::ShowNoteL
y descubro que hay un total de 50 aplicaciones que importan una referencia a
esta rutina.

Tengo que encontrar cual es la aplicación exacta. Si hubiera encontrado el
texto del mensaje "Puede perder datos si extrae su tarjeta MMC" entonces sería
más sencillo.
La solución en este caso es tediosa: anulo 25 de las llamadas. Si sigue
apareciendo el mensaje, es que está en una de las llamadas no anuladas.
Repitiendo este proceso de nuevo, me quedan 13 llamadas. Luego 7, despues 4,
más tarde 2, y por fin averiguo que la aplicación es SysApp.app
La desensamblo, y descubro que llama a CAknGlobalNote::ShowNoteL desde 20
sitios distintos. Recordar que sólo hay una referencia, pero puede ser invocada
desde distintas rutinas dentro de la misma aplicación.
Como no me apetece buscarlo otra vez, anulo la llamada en esta aplicación, aun
sabiendo que no sólo se elimina ese mensaje, sino otros 19 también.

El proceso de meter el firmware en el móvil lleva unos 10 minutos, sin contar
el tiempo que necesito para analizar las rutinas. Se me hacen las 2 de la
mañana cuando tengo algo parecido a un parche.
Lo preparo para publicarlo en CS, a ver qué opinan. Incluyo una advertencia de
que es posible que elimine otros mensajes.

22/09 *********** Jueves ***********
No he podido publicar el parche porque la web no funcionaba. Mejor, así puedo
depurarlo más.
Pero no hoy, que tengo que ir de compras, y a mí me cuesta un montón decidirme
por una camisa.

23/09 *********** Viernes ***********
Como todavía no he podido mejorar el parche, no lo publico. Así tengo el fin de
semana entero para mejorarlo.
Lo que veo es que necesito un sistema para seguir en vivo cuáles son las
rutinas que se llaman. Hice algo parecido para el S45, pero para el Symbian
necesito aprender mucho todavía.

Lo que he averiguado es que la memoria flash del firmware se mapea en la
dirección 0x50000000 ; por eso todos los programas incluídos de serie se
cargan a partir de ahí.
Pero no sé cómo leer datos de esa dirección. Intento un programa con:
TChar *p, c;
p=0x50000000;
c= *p ;

pero la aplicación da un error y es terminada.

Aprendo que es posible hacer las mismas barbaridades que en C, en particular
referenciar a memoria que no está inicializada, reservar memoria con alloc y
luego no liberarla, y usar char * como un puntero a cualquier cosa.

También veo que hay 2 zonas de memoria: heap y stack.
El stack es para los parámetros en las llamadas a funciones, y para guardar
datos, por ejemplo con PUSH y sacarlos con POP.
En cambio el heap es memoria interna al programa, usada por los objetos
inicializados. Se reserva con malloc.
La programación en Symbian se hace en C++ orientado a objetos. Esto obliga a
usar:
-New en lugar de alloc
-no se pueden usar variables globales estáticas
-no hay señales entre procesos. Pero hay semáforos globales
-Unicode. Brevemente, esto quiere decir que cada letra de un String ocupa
2 bytes.
-se usa el stack para guardar objetos persistentes. Luego hay que eliminarlos
con CleanupStack

Esto último es uno de los conceptos más raros que me he encontrado.
Supongamos que hay una función que puede fallar.
Antes de llamarla hay que meter en la pila los objetos que queremos que se
borren automáticamente si la función llamada falla.
Pero si no falla, es mi obligación limpiarlos. O sea, que tengo que saber
cuantos objetos he metido, y esto en cada uno de los posibles flujos del
programa.

En C++ moderno, esto es mucho más simple: cuando un objeto deja de estar
referenciado, el recolector de basura lo elimina, y todos tan contentos.

En fin, he visto que ésto es uno de los mayores quebraderos de cabeza de los
programadores que intentan hacer algo para teléfonos Symbian, y a menudo la
aplicación funciona bien, pero falla cuando menos lo esperas. Y por supuesto,
es casi imposible saber cuál es el objeto que te has olvidado de destruir.

Por la parte buena, he encontrado que se puede reservar una zona de memoria, y
no se libera aunque el programa termine. Luego se puede reiniciar el programa,
y encadenarse de nuevo a la memoria anterior.
Esto se llama Chunk.
Eso me va a permitir crear una memoria para tracear el estado de los programas,
tanto míos como ajenos.

Pero esto es adelantar acontecimientos.

24/09 *********** Sabado ***********
Hoy he encontrado que es posible incluir código ensamblador dentro de un
programa en C. Por supuesto que esto es lógico, pero no es tan intuitivo como lo que yo estoy acostumbrado.
Un caso simple:
asm volatile ("MOV r6, r4" : : : "r6" );

Hace que el registro R6 reciba el valor del registro R4

El ensamblador del ARM es bastante sencillo. Hay 16 registros R0-R15 pero:
-R13 se usa como SP, es decir, el puntero a la pila.
-R14 se usa para guardar la dirección de retorno, antes de saltar a una
subrutina.
-R15 es el registro PC, que indica dónde estamos.
-R0 se suele usar como puntero al objeto. Esto lo explicaré más tarde.
-R1, R2 y R3 se usan como parámetros a las funciones. Si la función recibe más
de 3 parámetros, se usa la pila para los restantes.
-R9, R10 y R11 apenas se usan. Sólo hay unas 20 rutinas que los modifican.
-los otros son usados como almacenamiento temporal, de propósito general.

Luego tiene unas cuantas peculiaridades, que algunos podrían considerarlos
inconvenientes:
-Es posible asignar un valor a una variable, por supuesto, pero sólo si cabe
en 1 byte (thumb) o 3 bytes (ARM)
Por ejemplo, en modo thumb es válido hacer
mov r1, #0x1
pero no
mov r1, #0x12345678
El truco es usar una referencia:
mov r1, off_0x12345678
off_0x101: DB 0x12345678
Lo cuento porque esto fastidia a la hora de parchear programas.

Esto es más evidente desde un programa en C :
int valor;
valor=0x12345678;
asm volatile ("MOV r6, %0" : : "r"(valor) : "r6" );

se convierte en
LDR R12, =0x12345678 ; equivalente a int valor=*(off_0x12345678);
MOV R6, R12
...más codigo...
off_0x12345678: DCD 0x12345678
que ocupa 2+2+4 bytes.

Otra instrucción importante es la que se usa para saltar a otra dirección de
memoria.
Hay saltos cortos (no más de 256*2 bytes) y saltos largos.
Los saltos cortos pueden incluir una condición dependiente de la última
operacion: si es igual, si es distinto, si es mayor, ...
Por ejemplo
CMP R1, R0
BEQ loc_xxx
que saltara a loc_xxx sólo en el caso de que R1 sea igual que R0

Los saltos largos ocupan 4 bytes y pueden saltar a cualquier dirección, hasta
16 Mg.
Dado que los programas de Symbian se ubican a partir de 0x50000000, ésto obliga
a que el programa más grande no puede saltar más allá de 16 Mg. En otras
palabras, todo el sistema operativo debe estar en menos de 16 Mb.

Por último, las instrucciones PUSH y POP meten datos en la pila.
Sin embargo, en modo ARM se usa STMFD y LDMFD, por ejemplo
STMFD SP!, {R4}
...
LDMFD SP!, {R4}

desde un programa en C puedo hacer:
asm volatile ("STMFD SP!, {R7}" : : : "r7" );
...
asm volatile ("LDMFD SP!, {R7}" : : : "r7" );

Incluso es posible meter varios valores con una única instrucción:
STMFD SP!, {R4,R5}
...
LDMFD SP!, {R4,R5}

Una cosa buena que descubro es que el código ensamblador generado por el
compilador GCC está optimizado, pero no demasiado. Es relativamente sencillo
mapear un programa C con su equivalente en ensamblador, suponiendo que tienes
acceso a ambos.
Como siempre, el código ensamblador tiene extensión .s

Tras un buen rato compilando programas y estudiando su resultado en
ensamblador, me hago una idea de cómo funciona. Espero que esto me ayude a
entender código ensamblador, y traducir (más o menos) a su equivalente en C.

25/09 *********** Domingo ***********
Hoy voy a cambiar de enfoque. La verdad es que hasta ahora no tengo un
objetivo definido; simplemente aprender tanto como pueda. Pero al usar el
móvil me doy cuenta de que hay ciertas cosas que no me gustan.
Una de ellas es que no es posible activar permanentemente el sistema de
infrarrojos. Si no lo uso durante 1 minuto, se desactiva automáticamente.

Voy a ver si soy capaz de cambiarlo, dado que 1 minuto me parece poco.

El primer intento es buscar algun código que use el valor 60, pues sospecho
que en algún sitio se define que 1 minuto son 60 segundos.
Lamentablemente el byte 0x3C (60, en decimal) aparece más de 10.000 veces.

Voy con otro método: en un programa Symbian es posible llamar a una función
para definir una tarea que se ejecute al cabo de un cierto tiempo. Este tiempo
está dado en millonésimas de segundo, aunque lo llama MicroSeconds.
Por tanto, 60 segundos se definirán como 60.000.000, que en hexadecimal se
escriben como 0x03938700.
Convertido a little-indian (invertir los bytes de 2 en 2 desde el final),
resulta 00879303
Busco esta cadena, y aparece 45 veces, en 24 ficheros.
De ellos, uno se llama IRLISTENSRV.dll y otro Iru.dll . Observar que incluyen
la palabra "IR" en su nombre.

Desensamblo IRLISTENSRV.dll con IDA, y veo que hace
LDR R0, =0x3938700
STR R0, [R5,#0x6C]

y en otro sitio hace
LDR R1, [R5,#0x6C]
BL CIrListenActive::SetInactiveTimeout(TTimeIntervalMicroSeconds32)

Está claro: primero hace que una variable global valga 60.000.000, y después
lee la variable, y pone un timeout. Cuando llegue el timeout, el sistema de
infrarrojos se apagará. Supongo que cuando hay una transmisión por el puerto,
el timeout se pondrá de nuevo a 60.000.000
Así que para aumentar este valor, sólo tengo que cambiar
LDR R0, =0x3938700
por
LDR R0, =0x11E1A300
para que el tiempo sea 300000000 = 5*60*1.000.000 es decir 5 minutos

Dicho y hecho. Parcheo la flash con el programa WSMP, la meto en el móvil, y
ahora el puerto infrarrojos se apaga si no hay datos tras 5 minutos, no tras 1
minuto.

Totalmente orgulloso de mí mismo, hago un fichero de texto con el parche, le
pongo una cabecera explicando cómo funciona, y lo preparo para publicarlo
mañana.
Tiempo total consumido: hora y media.

26/09 *********** Lunes ***********
Publico el parche de eliminar los mensajes innecesarios, y la respuesta es muy
satisfactoria.
Creo que esperaré un poco antes de seguir haciendo más parches. La razón es
que, mal que me pese, el SX1 es un modelo de más de 3 años, bastante caro, y no
sé si hay mucha gente que lo use. Y es posible que simplemente haya pasado de
moda. Visto de otro modo: ?quién hace actualmente programas para OS/2 ?

He conseguido extraer de los ficheros de cabecera .h todas las funciones
exportadas, y las librerías en las que se encuentran.
Con esta lista hago un mega-programa que las invoca a todas, y averiguo en qué
posicion de la flash se encuentran.
Esto es equivalente a esos listados que circulan por ahí con las funciones
exportadas en windows.dll
Lo bueno es que ahora puedo saber más o menos las rutinas llamadas por otros
programas, con lo que adquieren mayor sentido los desensamblados producidos por
IDA.

En total, unas 2.000 rutinas que me serán muy útiles.

27/09 *********** Martes ***********
Pues los parches tienen cierto éxito. Sobre todo entre los usuarios que más
activos están en el foro. Eso me anima a hacer más.
Otra cosa que me fastidia es que, cuando quieres instalar una nueva aplicación,
el móvil pregunta demasiadas cosas:
1) Aviso de seguridad de instalación: Imposible verificar proveedor. Continuar?
2) Instalar myApplication?
3) Opciones: Instalar/Ver certificado/Ver detalles
4) Sustituir x.yz por x.yz? (en caso de que ya esté instalada)
5) Seleccione memoria: Mem. tel. / Tarj. m.
6) Instalación completa

Esto es bastante engorroso, sobre todo cuando yo instalo mis propios programas.
El proceso incluye
A) editar mi programa
B) compilar
C) activar infrarrojos
D) transferirlo
E) instalarlo, respondiendo las preguntas 1-6 anteriores
F) probarlo

El paso C) más o menos lo tengo apañado. El paso B) y D) los tengo
automatizados con pulsaciones de teclas en el PC.
Pero si redujera el paso E), sería más rapido de instalar.

La pregunta 1) se hace porque mi aplicación no está firmada. He mirado en la
web, y parece que un programador normal no puede firmar sus aplicaciones. Hace
falta un certificado proporcionado por Symbian o Nokia, el cual no voy a
solicitar.

Lo primero es averiguar cual es el programa que manda el mensaje. Empiezo la
instalación, y con ayuda del TaskSpy descubro que es InstEng.dll
Este programa tiene unas 300 subrutinas.
una de ellas llama a
CAknMessageQueryDialog::NewL
La cual se usa para mostrar un mensaje.
La primera idea que se me ocurre es no llamar a esta rutina. Grave error.
Cuando lo pruebo, no aparece ningún mensaje en absoluto. Así que no es posible
responder "Sí, quiero instalar esta aplicación". Por eso la rutina que espera
la respuesta nunca se llama, por lo que se queda esperando una respuesta que
nunca será capaz de recibir.

Veo que esta rutina es llamada a su vez por otras 5. Una de ellas debe de ser
la que hay que eliminar.

Estudiando un poco aprendo que una aplicación firmada incluye un flag en la
cabecera del instalador.
Lo explicaré mejor: un programa consiste siempre en un fichero de tipo *.app ,
ademas de otros ficheros extras, tales como otro con todos los dibujos (*.mbm),
otro para diferentes idiomas (*.r0x, *.rsc), uno con los iconos para el menú
(*.aif), los sonidos (*.wav), ...
Todos estos se empaquetan en un instalador *.sis , que se puede firmar con un
certificado.
El instalador mira si el .sis está firmado, y luego si el certificado es
válido.
Una de las características del certificado es que el quinto byte es 0x04
Esto aparece unas 20 veces en el programa que instala aplicaciones. Sólo 3 de
ellas están relacionadas con las rutinas encontradas antes, por lo que decido
sustituir las 3 veces
MOV R0, #4
CMP R1, R0
BEQ loc_xxx

por
....
B loc_xxx

para que salte en todos los casos, aunque la validación no sea cierta.
Ahora parece funcionar, y siempre aparece como firmado. Luego pruebo una por
una, y encuentro la rutina que es correcta.

Ya sé que no lo he explicado con mucho detalle, pero es que éste es el
típico-tedioso proceso de encontrar la rutina adecuada. Es lo mismo que se
hace para crackear programas de PC, de ZX-Spectrum, o de XBox.

Prosigo. La pregunta 4) aparece cuando quieres instalar la misma aplicación
que ya está instalada. Cuando yo hago mis propios programas, la versión es
siempre la misma, por lo que la pregunta es correcta, aunque es inútil en mi
caso, y me gustaría eliminarla.

Cada programa tiene una versión consistente en 3 datos:
-Número mayor de versión, desde 0 hasta 127
-Número menor, desde 0 hasta 99
-Número de construcción, desde 0 hasta 32767
Es posible saber la versión de un programa. A partir del UID, se carga; después
se crea un objeto TVersion, y se usan los miembros iMajor, iMinor, iBuild

Esto se hace en InstEng.dll en las rutinas
505bd88c = MajorVersion()
505bd898 = MinorVersion()
la versión de construcción (build) no se compara. Aunque sea superior, aparece
como si fuera la misma.
Por lo tanto el parche es fácil. Hago que MajorVersion() siempre devuelva
127+1, así el instalador siempre se creerá que está instalando una versión
superior y nunca preguntará.
Lo bueno es que, cuando está instalado, aparece como la versión correcta.
Sólo engaño al instalador en la comprobación que se hace durante el proceso de
instalación.

Una solución más limpia sería simplemente eliminar el mensaje que informa de
que las versiones son distintas, pero por ahora funciona.

Tras algunas pruebas más, compruebo que funciona adecuadamente, y lo meto en un
fichero con una explicación, listo para ser publicado.

*EOF*

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT