-[ 0x0E ]--------------------------------------------------------------------
-[ Lista negra ]-------------------------------------------------------------
-[ by FCA00000 ]-----------------------------------------------------SET-31--

Listas negras en mviles. Y algo ms.
*************************************

Otro artculo ms sobre mviles para aadir a la coleccin.
Ya s que escribo mucho sobre telefona, pero cada uno escribe sobre lo que
le gusta y conoce.
Y despus de muchas horas aprendiendo sobre mi Siemens, es hora de sacarle
partido, ?no crees?

Lo importante de este texto es que intentar explicar todo lo que hago, para
que otros puedan usar estos conocimientos y adaptarlos a otros modelos Siemens
o quizs incluso a otras marcas de mviles.

Hace tiempo alguien public una nota en el tabln de SET diciendo que quera
hackear un mvil porque reciba mensajes molestos enviados por alguien que
le odiaba.
Est claro que la gente cree que la web de SET es un chat dinmico en la que
los usuarios estn constantemente conectados, y que pueden enviar respuestas
inmediatas.
No es as, por lo que supongo que dicha persona jams leer este artculo.
Por otro lado, no me qued claro si conoca el nmero desde el que le
mandaban mensajes, o si el "atacante" los enviaba annimamente.
Porque esto es muy fcil de hacer: busca en tu mvil alguna opcin
llamada "Esconder ID" o algo similar.
Tambin es posible mandar annimamente slo 1 mensaje. Para eso hay que
poner el caracter "i" antes del nmero de telfono.
Estas dos formas de esconder tu identidad slo funcionan si el proveedor
de servicios lo permite. Pero todos los que yo he visto lo hacen.
Como ya conoces (o deberas conocer) los comandos AT, te dir que esto se
consigue tambin con el comando AT+CLIR=1 que selecciona el
modo "incgnito" para el CLIR (Call Line Identification Restriction).

Como en el caso que me ocupa, a veces se reciben mensajes o llamadas de
gente con la que no quiero comunicarme.
Esto sin contar con que cada vez ms y ms frecuentemente estn
apareciendo compaas que mandan publicidad mediante SMS.
Para combatir esta nueva modalidad de spam voy a desarrollar una
aplicacin que desecha automticamente los SMS de personas indeseables.
Tambin es posible anular las llamadas que me hagan.

Lo primero es conseguir un telfono Siemens. ?Cmorr? ?Despus de todos
los artculos que he escrito contando las bondades de esta marca todava
no tienes uno?
Yo trabajo con el S45i-v04. Adems de las mltiples herramientas que he
explicado en textos anteriores, es imprescindible la ayuda de los cientos
de entusiastas esparcidos por Internet.
Sin su ayuda y apoyo mi tarea sera mucho ms difcil, por no decir imposible.

Tambin es necesario otro telfono, que ser con el que har las llamadas.
Para esto yo uso un telfono fijo, que es ms barato. El nmero es 987-65-43-21

Doy de alta este telfono en mi libreta de direcciones con el nombre XXXX.
Lo meto en la libreta del mvil, no la del SIM.
Preparo un programa en el mvil que me permitir buscar en la memoria
cualquier secuencia de bytes.
Para esto hace falta acceso de lectura y escritura a la memoria del mvil.
Aunque ya lo he explicado, lo contar una vez ms: se necesita un cable
especial (10 euros) para conectar el mvil y el ordenador.
Entonces hay mltiples programas que permiten modificar la ROM del
mvil: yo uso V_klay, SiemensDebugger, y ATCGSN

El programa de bsqueda es algo as:
   mov r4, 0200 ; direccin para escribir las posiciones encontradas
   mov r8, #00h ; empieza por el segmento 0
otro_r8:
   mov r6, #0h ; empieza por el offset 0
   mov r5, #0h
otro_r5:

   extp r8, #1h
   mov r3, [r5+] ; saca el dato de la memoria
   cmp r3, #5858h ; lo compara con "XX"
   jmpr cc_Z, encontrado

   add r6, #02h ; si no lo encuentra, va al siguiente dato
   cmp r6, #04000h ; hasta que termino con este segmento
   jmpr cc_NZ, otro_r5

   add r8, #01h ; entonces salto al siguiente segmento
   cmp r8, #0400h ; recorre 400h segmentos = 16 Mg.
   jmpr cc_NZ, otro_r8

encontrado
   extp #40h,#2h
   mov [r4+], r5
   mov [r4+], r6

y escribir la(s) posicin(es) encontrada(s) en 0040:0200

Inicio la llamada desde XXXX, y cuando empieza a sonar el mvil, arranco el
programa de bsqueda de la palabra 'XXXX'
Aparece en 5 posiciones.
Una de ellas es la propia de la libreta de direcciones, claro.
Esta direccin es  B5C500=02D7:0500 
Tambin aparece en B71300=02DC:1300 pero esto es porque el microprocesador C166
del Siemens mantiene copias de la memoria en varias direcciones.
Si cambio un dato, el otro tambin cambia.

Otra de ellas es dinmica y cambia si hago distintas llamadas. Seguramente
hay algn puntero que la referencia, pero no voy a perder tiempo con esto.
La direcin ms interesante empieza a partir de F2900.
El dato en F2905 es justamente el nmero de telefono 987-65-43-21 .
Para ahorrar memoria se guarda agrupado por bytes: 0x98 0x76 0x54 0x32 0x10
El tamao (nmero de cifras) del telfono est en F2904. Vale 9, claro.
El nombre de la persona, tal como yo lo he definido en mi listin, empieza
en la direccion F2978. Este es justamente el dato "XXXX" que estaba buscando.

Repito el experimento con otro telfono y otra entrada en el listn, y llego
a la evidencia de que siempre F2978 contiene el nombre de la persona que llama.
Si el nmero no est en mi agenda, este dato es 0x00.

Ahora se trata de saber cual ha sido la rutina que ha obtenido ese dato de la
agenda y la ha puesto en dicha direccin.

La posicin de memoria 0F2904 se escribe en formato C166 como 003C:2904 por
lo que miro cuales trozos de programa hace uso de esa direccin.
No encuentro ninguna, as que amplio mi radio de bsqueda a cualquiera que
use el segmento 003C.
Lamentablemente salen ms de 1000 referencias; demasiadas para investigar.

En otro artculo he comentado que he hecho un mini-emulador para el mvil.
Pero no es en tiempo real, as que no puedo tracear todas las rutinas.
Otra tcnica que podra resultar es mirar muy frecuentemente la memoria F2904.
En cuanto valga "XXXX" averiguo las rutinas que se han ejecutado ltimamente.

Esta lista se obtiene de la pila.
Cuando se llama a una rutina, la direccin llamante se guarda en la
pila, pues es necesario recordarlo a la hora de retornar.
Si pudiera recibir una notificacin cada vez que se entra o se sale de una
rutina, podra tracear las llamadas.

Esta idea la he sacado del debugger NTSD:
-lee el programa desde el disco
-sustituye cada llamada CALL con otra instruccin CALL mi_rutina_entrar
-sustituye cada retorno RET con otra instruccin CALL mi_rutina_salir
-inicia el programa traceado
-en   mi_rutina_entrar   averigua qu rutina la ha
 llamado, pues est en la pila
-guarda el dato en un buffer interno, para permitir breakpoints, traceado, ...
-obtiene desde el disco la direccin destino original
-crea dinmicamente una instruccin JMP direccion_original
-sigue el programa en esta instruccin recin creada
-cuando se llame a   mi_rutina_salir   vuelve a guardarlo, para tener
 una lista del flujo del programa
-saca el dato de la pila
-crea dinmicamente una instruccin RET
-salta a esta instruccin

Esto se puede hacer porque los programas en un ordenador se leen siempre
desde el disco antes de iniciar su ejeccin.

Pero en el mvil los programas se ejecutan directamente desde la ROM, por
lo que esta tcnica no sirve.
Aunque me ha dado una idea: en el C166 la pila es muy limitada, 4096 bytes, y
existen 2 registros STKOV y STKUN que indican el tope mximo y mnimo.
Cuando se llena la pila (o se vacian ms datos de los que existen) entonces
se produce una interrupcin.
Si pusiera  STKOV=0 y STKUN=0 , cualquier llamada intentara guardar en la
pila la direccn de retorno, y fallar porque no hay hueco.
Entonces se dispara mi interrupcin. Yo debo guardar ese dato en otra
direccin de memoria (mi propia pila) y salir de la interrupcin como
si nada malo hubiera pasado.
Aunque se produce un desbordamiento, el dato en realidad se ha guardado.
Esto tiene el inconveniente de que cualquier instruccin PUSH tambin me
provocar un desbordamiento, a pesar de que no es una instruccin CALLS.
El mayor problema, y es precisamente el que complica esta tcnica, es que
la propia interrupcin se trata internamente como una llamada a la rutina
de manejo de interrupcin, es decir, que tambin pone datos en la pila.

Estos datos son los tpicos de cualquier interupcn, es decir: PSW (flags),
CSP (Context Segment Pointer), e IP (Instruction Pointer)
O sea, que para que el sistema pueda llamar a la interrucin es necesario
que la pila est en buenas condiciones. Si no, es imposible saber de dnde
vengo, y por lo tanto es imposible retornar.
En otras palabras, el dato SP (Stack Pointer) debe apuntar a una zona
no usada dentro de la RAM . Si apuntara a la ROM o a una direccin fuera
de la memoria o a una zona usada por otro programa, no se podra escribir.

La interrupcin de stack overflow se llama STOTRAP y saltar a 000010h.
All pondr yo un salto a mi rutina que ser:

miPush:
mov [-r0], r2
mov [-r0], r3
mov [-r0], r4
mov [-r0], r5
mov [-r0], r6
pop r2 ; saca IP
pop r3 ; saca CSP
pop r4 ; saca PSW
pop r5 ; saca el dato que se pretenda escribir
push r4 ; vuelve a meter PSW , para poder retornar
push r3 ; vuelve a meter CSP , para poder retornar
push r2 ; vuelve a meter IP , para poder retornar
; ahora toca guardar en un sitio seguro el dato que no se ha podido meter
extp #0013h, #1 ; el segmento 0013:0000 no se usa y est a 0x00
mov r6, 0004h ; en 0013:0004 digo cuantos datos llevo metidos en mi pseudo-pila
extp #0013h, #1
mov [r6+], r5 ; guardo el dato en mi pseudo-pila
extp #0013h, #1 ; y de paso incremento el contador
mov 0004h, r6 ; que ahora vuelvo a guardar
; con lo anterior simplemente emulo una pila
; una rutina similar sacar los datos en el stack underflow STUTRAP
; pero decrementar 0013:0004 
; ahora me toca archivar estos datos
; para eso uso el segmento 0018:0000 que tampoco se usa.
extp #0018h, #1
mov r6, 0004h ; miro cuantos llevo metidos. Este contador siempre se incrementa
extp #0018h, #1
mov [r6+], r5
extp #0018h, #1
mov 0004h, r6

mov r6, [r0+]
mov r5, [r0+]
mov r4, [r0+]
mov r3, [r0+]
mov r2, [r0+]


Esto es una manera ms o menos eficiente de tracear las llamadas que se hagan.

Para activar ese traceo tengo que hacer que la interrupcin apunte ah:
mov r6, #offset(miPush)
extp #000h, #1
mov 0010h, r6
mov r6, #pagina(miPush)
extp #000h, #1
mov 0012h, r6

Lo mismo para miPop , en la direccin STUTRAP , es decir, 0018h

Esto es muy bueno para saber quin llama a quin, pero al final siempre
acabo analizando un montn de rutinas.

Voy con otra solucin. Existen unas 130.000 rutinas en la memoria del mvil.
Una de ellas, que se usa muy frecuentemente, es el equivalente a strcmp.
Compara bytes desde una direccin hasta que son dferentes o el dato del
origen vale 0x00.

Esta rutina est en la ROM y puedo modificarla para que me diga en cuales
situaciones el dato es "XXXX".
La rutina original es:
010486: movb    rl5, [r13+] ; saca el dato apuntado por   r13
010488: cmpb    rl5, [r3+]  ; lo compara con el dato en   r3
01048A: jmpr    cc_NZ, loc_010490 ; si no son iguales, ya puedo salir. 
01048C: cmp     r3, r14           ; si no es el finalizador de cadena...
01048E: jmpr    cc_NZ, loc_010486 ; sigue comparando
010490: rets
O sea:
Lo que tengo que hacer es cambiar
01048E
para que guarde la pila (4 rutinas mas o menos) en caso de que el dato sea "X"

 sub r13, #2h
 movb    rl5, [r13]
 cmpb    rl5, #'X'
 jmpr    cc_Z, siX
noX:
 add r13, #2h
 rets
siX:
mov r15, SP
mov mi_memoria+0, [r15+]
mov mi_memoria+2, [r15+]
mov mi_memoria+4, [r15+]
mov mi_memoria+6, [r15+]

Faltan algunos detalles, como verificar que es la primera vez que escribo
el dato, guardar los registros, ... pero lo bsico est aqu.

Inicio de nuevo la llamada, y veo que me ha llamado la rutina C4BAFC
Un par de comprobaciones ms, y estoy completamente seguro de que este es
una buena rutina para saber el nombre correspondiente al nmero de telfono
que me est intentado llamar.

Ahora llega la segunda parte: abortar la llamada.
La primera idea es que se puede interrumpir pulsando la tecla de 'colgar'
Para eso necesito averiguar cual es la rutina que procesa el teclado.
Supongo que es algo as como:
c=leeTecla();
if(c=='Colgar')
	llama rutina_tecla_colgar
pero a su vez, la rutina_tecla_colgar puede ser:
if(llamada_en_activo)
	{
	colgar_llamada;
	mostrar_mensaje('Llamada finalizad);
	}
Gracias a los conocimientos del artculo anterior sobre 'modificacin de
la Rom' aprendo que la rutina del teclado est en CCB510.
Voy siguiendo el flujo del programa y aterrizo en C49D94. Parece ser que
esta rutina provoca que se corte la llamada cuando r12=1 y r13=-1.
Lo pruebo un par de veces: hago un parche que, cuando pulso la tecla '3' , 
salte a C49D94.
Inicio la llamada, y en el mvil receptor pulso el '3'. Efectivamente la
llamada se corta.

Otra manera de cortar la llamada es usando comando AT. El comando ATH sirve
para cancelar la llamada en curso.
Ahora bien, ?Cmo hago para que el mvil se auto-mande un comando AT?
Existe un parche llamado ATCGSN que yo uso constantemente. Conectando un
emulador de terminal, permite leer la memoria del mvil, y tambin
escribir (slo la RAM) e incluso ejecutar programas.

Desensamblo el parche, y veo que lo que hace es
04422C: B2D5ED00 BEC58700

La ROM a partir de 04422C parece ser una tabla que empieza en 04422C.
Digo que es una tabla porque al desensamblarlo no tiene coherencia y los
datos parecen estar organizados de 4 en 4.
Unos 400 bytes detrs en 044530 hay otra tabla con lo que parecen ser
comandos AT+Cyyyy .Por ejemplo, estn
AT+CACM para saber el nmero de minutos que he hablado
AT+CALM para poner el sonido para la alarma
AT+CAOC para saber la carga
AT+CBC para saber el nivel de la batera
y muchos ms. Incluso hay algunos comandos AT+Cyyyy que no estn documentados.
Por ejemplo AT+CXXPIN que parece servir para saber si el mvil necesita PIN o
ya est operativo.
Como iba diciendo, la tabla 044530 contiene los cdigos AT+Cyyyy que se pueden
usar, y la tabla 04422C dice las rutinas encargadas de procesarlos.

El parche ATCGSN lo que hace es 
4422C: B2D5ED00 BEC58700

o sea, sustituir la llamada original a la
rutina 00EDD5B2 por otra a 0087C5BE, donde instala una rutina diferente.

O sea, que AT+CGSN ya no llama a EDD5B2 sino a 87C5BE.
Meto un breakpoint en mi traceador y cuando llega a 87C5BE miro de dnde vengo.
Tirando del ovillo veo que todos los comandos AT pasan por la rutina E0B07A
No hay ms que poner en 100200 el comando a procesar (ATH en mi caso) y llamar
a E0B07A para que lo ejecute.
Dicho y hecho: en C4BAFC miro si el dato en 0F2904 vale 'X'. Si es as,
meto "ATH" en 100200 y siguientes, y llamo a E0B07A.

org 0C4BAFCh
extp #003Ch, #1
movb rl4, 02904h
cmpb rl4, #'X'
jmpr cc_NZ, noX

movb rl4, #'A'
extp #0040h, #1
movb 0200h, rl4

movb rl4, #'T'
extp #0040h, #1
movb 0201h, rl4

movb rl4, #'H'
extp #0040h, #1
movb 0202h, rl4

movb rl4, #0
extp #0040h, #1
movb 0203h, rl4

calls 0E0B07Ah

noX:
rets


Con esto, si quiero evitar las llamadas de alguien, slo tengo que poner
una 'X' al principo de su nombre, y el mvil le colgar automticamente.

Profundizando en el tema encontr otra rutina en C49E2A que permite
rechazar la llamada haciendo parecer que el mvil est ocupado (busy)
en otra llamada. Pero esto no lo he usado.


En otro orden d cosas, el mvil mantiene una lista de las llamadas efectuadas
y recibidas, tanto si he respondido como si he colgado. Tambin guarda las
llamadas que no se han completado por haber otra llamada en activo.
Esto me sirve para saber quien me ha llamado, aunque est en mi lista negra.

Es posible activar una opcin para que vayan al buzn de voz todas las
llamadas no completadas por estar ocupado. Esto se llama "Divert" y me
permite que los indeseables me dejen un mensaje en el buzn.
No slo se gastan el dinero, sino que, en caso de que la llamada sea ofensiva,
tengo una grabacin para presentar a la polica, que era lo que pretenda
esta persona que lanz la cuestin a tabln de SET.

Esto mismo tambin es vlido para los SMS. Cuando el emisor tiene un nombre
que comienza por "X" entonces no me llega el aviso dque tengo un nuevo mensaje.
Sin embargo el SMS s que aparece en la lista de SMS recibidos.

Para borrarlo uso un truco similar, con los comandos AT+CMGyyyy

El comando AT+CPMS selecciona la memoria desde la que quiero leer mensajes.
En mi caso es "MS"=mvil.
El comando AT+CMGL lista todos los SMS recibidos.
El comando AT+CMGD borra un mensaje.

Tambin necesito el comando AT^SPBG=? que sirve para mostrar todos los
detalles de una entrada en la agenda. Para no hacerlo demasiado complicado,
explicar que es posible usar este comando para averiguar el nombre, a partir
de un nmero de telfono.
En teora, lo que tengo que hacer es ejecutar estos comandos uno tras otro.
El problema es que la respuesta no es sncrona.
Me explico: el sistema operativo del mvil es multiproceso. Cuando uno
quiere ejecutar una tarea que tarda bastante tiempo (ms de 100 milisegundos)
no es posible hacerlo todo seguido, ya que otras tareas se detendran, tales
como el teclado, el sonido, o, lo que sera peor: la conexin con la red.
Para solucionarlo, existe un gestor interno de tareas.
En el registro r13 se pone el segmento de la rutina a ejecutar. En r12 se
pone el offset.
En r14 y r15 se ponen los argumentos que quiero mandar a mi rutina.
Entonces debo llamar a la rutina CC79AE para que ponga mi peticin en la cola.
Cuando el sistema operativo no tiene nada mejor que hacer, mira si hay
peticiones pendientes y las procesa segn van llegando en una tpica cola FIFO.

Ten en cuenta que los comandos AT tardan bastante tiempo en ejecutarse, en
cierto modo debido a que la respusta hay que mandarla por el puerto serie,
incluso aunque no haya nadie para recibir los datos.

Ms o menos el esquema de mi programa, en forma de mquina de estados, es:
empieza en FEF000
 averigua la hora y minutos. Esto est en F3D4E+0 y F3D4E+2
 Compara con el tiempo que se ejecuto la ultima vez.
 Si no ha pasado 1 minuto, ve al final
 En caso contrario:
  Almacena la nueva hora y minutos
  si flag==NADA_PENDIENTE entonces:
    flag=SELECCIONA_MEMORIA_MOVIL
    manda AT+CPMS="MS"
    ve al final
  si flag==SELECCIONA_MEMORIA_MOVIL entonces:
    flag=LISTA_SMS_RECIBIDOS
    mensajes_procesados=0
    manda AT+CMGL=0 para listar los mensajes recibidos pero no ledos
    ve al final
  si flag==LISTA_SMS_RECIBIDOS entonces:
    el retorno del comando AT+CMGL=0 va a 00B98E ; una lnea por cada mensaje
    desde 00B98E hasta 00B98E+2000h :
      buscar la respuesta +CMGL: x,z,t   y el final de carro 0x0D 0x0A
      Si ha llegado al final de la lista:
         flag=NADA_PENDIENTE
         mensajes_procesados=-1
         ve al final
      Si no ha llegado al final de la lista:
         a partir de la posicin averiguada anteriormente, el nmero que mand
          el SMS est en la posicin+4
         leer cada byte ; primero la posicin impar, y luego la par, hasta el
          nmero de datos indicado en posicin+1
         por ejemplo, para el telfono +34-987-65-43-21 debera
          ser: 0B xx 43 89 67 45 23 1y
         flag=BUSCA_EMISOR_SMS
         busca el nombre para ese nmero ; por ejemplo AT^SPBG="987654321"
         ve al final
  si flag==BUSCA_EMISOR_SMS entonces:
    lee el nombre desde 0F2904
    Si la inicial es "X" entonces:
      flag=BORRA_SMS_RECIBIDO
      manda AT+CMGD=mensajes_procesados    para borrar el mensaje
      mensajes_procesados++
      ve al final
    Si la inicial no es "X" entonces:
      mensajes_procesados++
      flag=LISTA_SMS_RECIBIDOS
      ve al final
  si flag==BORRA_SMS_RECIBIDO entonces:
    flag=LISTA_SMS_RECIBIDOS
    ve al final
final:
 r13_r12 = FEF000
 llama CC79AE para meterlo de nuevo en la cola de proceso

La inicializacin de mi programa se produce en FEF100, el cual es llamado
desde una rutina que se ejecuta cuando se enciende el mvil.
Este inicio pone flag=NADA_PENDIENTE y salta a FEF000

En realidad es simple, una vez que se tiene clara la secuencia de instrucciones.
Bueno, si te parece complicado te recomiendo que lo leas un par de veces y
hagas un diagrama de flujo en un papel.

Lo podra haber hecho todava ms sencillo si no usara comandos AT^SPBG para
sacar datos de la agenda; podra acceder directamente a la memoria, pero no
est siempre en la misma posicin, sino que se guarda en los bloques EEPROM y
tambin en el SIM.
Otra opcin es leer el resultado de los comandos AT directamente en la rutina
que los maneja, en vez de acceder a la memoria.
Para esto s que todas las respuestas a AT pasan por EDD5B2. Pero tampoco
gano mucho, pues tendra que parchear las rutinas AT+CMGL, AT+CMGD, y AT+CPMS

Seguramente esto es mucho ms de lo que esperaba la persona que pregunt en
el foro de SET, pero espero que t hayas aprovechado estas enseanzas.


SACANDO PROVECHO
****************
Para dejar de jugar voy a intentar aplicar estos conocimientos a algo que me
suponga un beneficio.
Cuando quiero recargar una tarjeta de prepago, una de las opciones es ir a la
tienda y pagar una tarjeta de recarga. Esto consiste en un cartoncillo con
un nmero escrito.
Si le pido al propietario de la tienda que escriba l mismo el numero, tambin
se encargar de hacer que funcione bien.
El mtodo de recargar la tarjeta es llamar a un cierto nmero de telfono, y 
uando la voz lo dice, marcar los nmeros del cartoncillo, acabando con '#'.
Entonces una voz grabada confirma que el saldo se ha ampliado.

En esta ocasin mi tcnica es que el telfono se vuelva mudo tras la tecla '#'.
El encargado de la tienda no recibir la confirmacin, as que lo intentar
varias veces, quizs con distintos nmeros y diferentes cartoncillos.

En todo caso, hay que pagarle con dinero -no con tarjeta de credito- pero slo
despus de que haya efectuado la recarga, lo cual nunca suceder.
Hay que hacer un poco de ingeniera social para que sea l quien recargue
la tarjeta, pero no creo que esto suponga mayores problemas.
Estuve tentado de mandar a mi abuelo a que fuera l a la tienda a recargarlo,
pero no quera ponerle en un aprieto. De todas maneras creo que es una buena
idea: ?quien va a creerse que un ancianito es un estafador de telefona mvil?

Est claro que la entrada a mi procedimiento ser la rutina CCB510 de proceso
de teclado. Ahora tengo que ver cmo hago para enmudecer el mvil.

Para no gastar ni una perra, meto una tarjeta sin saldo, y llamo al 'mailbox',
que es gratis. Lo bueno es que el mailbox habla sin detenerse, as puedo
saber si de verdad he desconectado el altavoz. Lo malo es que a los 2 minutos
se corta la llamada.
Mientras tengo la llamada activa pulso la tecla de subir/bajar el volmen.
Empiezo a analizar rutina tras rutina y averiguo que la rutina que procesa
el cambio de nivel de volmen est en DEFFA8.
El mismo resultado obtengo si uso el comando AT^SNFV=x para poner el volmen.
El dato se verifica que est entre 0 y 4 . El volmen 0 es bajito pero
perfectamente audible. Sin embargo puedo pasarle el valor FFFF a dicha
rutina, y observo que el altavoz queda totalmente mudo ! Ahora no se oye
el mensaje grabado que indica que el saldo se ha incrementado.

Otra manera es hacindole creer al mvil que tiene conectado el manos libres.
Entonces el sonido no sale por el altavoz interno sino por los audfonos
tericamente conectados al adaptador.
Para ello estudio la rutina que se ejecuta cuando conecto el manos-libres.
Pongo en marcha mi debugger de trampas, conecto el manos-libres, y vuelco
la informacin al PC.
La funcin que maneja la conexin de cualquier cacharro (cable de datos,
carga de batera, auricular, manos libres) resulta estar en E1EE48.
El cacharro que est conectado se guarda en 10E1DE.

Pongo el valor 0x05 (auriculares) en 10E1DE (0043:21DE) y llamo a E1EE48 para
que el mvil se lo crea.
Inmediatamente el mvil se vuelve mudo. Voy por la buena pista.

El valor 0x03 significa que no hay nada conectado, y el mvil vuelve a hablar.
De este modo puedo volver a habilitarlo cuando se pulsa otra tecla, por
ejemplo la de "colgar"

El parche completo es:
org 0CCB510h
calls miTecla

org FEF100
miTecla:
mov r5, r12 ; tecla pulsada
cmp r5, #001Dh ; mira si es la tecla '#'
jmpr cc_NZ, no_ponManosLibres

ponManosLibres:
mov r5, #05h ; simula conexin del cacharro de manos libres
extr #0043h, #1h
mov 21DEh, r5
calls 0E1EE48h ; haz que el mvil se entere
jmpr cc_UC, sal

no_ponManosLibres:
cmp r5, #000Dh ; mira si es la tecla 'colgar'
jmpr cc_NZ, sal
mov r5, #03h ; simula que no hay nada conectado
mov 21DEh, r5
calls 0E1EE48h ; haz que el mvil se entere
jmpr cc_UC, sal

sal:
rets

El atnito vendedor se sorprender cuando ninguno de los nmeros
realiza la carga con xito.

Por supuesto que yo no he llevado a cabo el experimento; ni nunca lo har.
No me voy a arriesgar por una msera recarga de 20 euros.
Al margen de que es totalmente ilegal, condenable, y deshonesto. Y te
recomiendo que tampoco lo hagas t.


Otra manera similar de alterar la recepcin de la confimacin es mostrar
unos dgitos en la pantalla, pero mandar otros distintos a la red.
El vendedor creer que ha mandado el cdigo correcto pero la red no lo
aceptar.

As que necesito saber cmo hace el mvil para marcar un nmero mientras la
llamada est activa.
Gracias a la intercepcin que tengo en la rutina de proceso del teclado, voy
siguendo el flujo del programa.
Lamentablemente recorro ms de 100 rutinas y me pierdo fcilmente.
Seguir un programa en ensamblador no es tarea fcil.

Pero se me ocurre que la nica manera en que los cdigos tecleados se
comuniquen por la red es a travs de tonos multifrecuencia DTMF.
Efectivamente cuando llamo al nmero de telfono de recarga y empiezo a
pulsar teclas oigo un pitido de distinta frecuencia para cada tecla.
Notar que esto es slo una indicacin para que el usuario sepa que
efectivamente ha pulsado la tecla ; los tonos DTMF se mandan a la red en
forma de paquetes de datos, no de sonido.

Por cierto, que el comando AT+VTS=x permite mandar un tono DTMF sin usar
el teclado . ?Hay algo que no se puede hacer con comandos AT ?

En la documentacin dice que se pueden mandar los caracteres 0123456789#*ABCD
Para el mvil SL45i (que es distinto al mo) ya alguien averigu que
la rutina C300EC se encarga de mandar tonos DTMF.
Hace algo asi como:

2300EC: mov     [-r0], r9
2300EE: mov     [-r0], r8
2300F0: mov     r9, r12
2300F2: mov     r8, #0
2300F4: calls   0A4h, loc_A4A476
2300F8: cmp     r4, #0
2300FA: jmpr    cc_Z, loc_230102
2300FC: mov     r8, #4
2300FE: jmpa    cc_UC, loc_230170
;------------------------------------------------
230102:loc_230102:
230102: calls   0A4h, loc_A4A484
230106: cmp     r4, #0
230108: jmpa    cc_Z, loc_230170
23010C: sub     r9, #23h
230110: cmp     r9, #16h

Busco la equivalente en mi mvil:
-la direccin de la rutina no ser 2300EC , dado que para una versin
 diferente, las rutinas estn en distintas posiciones.
-no saltar a loc_A4A476 ni loc_A4A484, por la misma razn
-las instrucciones    mov [-r0], r9    y     mov [-r0], r8   son
 demasiado comunes como para buscarlas unvocamente
-los registros r9, r8, r4 usados en esta versin pueden ser distintos
 de la ma, dependiendo cmo se haya compilado la rutina
-el dato #23h en 23010C es el carcter "#". Esto es un buen indicio
-el dato #16h en 230110 sirve para 23h-16h = 0Dh , que tambin coincide
 con el rango de datos permitidos

Por eso no me cuesta mucho encontrar la rutina en CDDD26.
Como supongo que ya ests preparado para algo ms avanzado, aqu va el
desensamblado del cdigo original, con mis comentarios:
org CDDD26
 mov     [-r0], r9
 mov     [-r0], r8
 mov     r9, r12
 mov     r8, #0
 calls   0CCh, loc_CC662A ; S45i_AcquireGbsLock , para garantizar que nadie
		; modifica la memoria mientras yo la estoy leyendo
 calls   0F7h, loc_F7D2C0 ; Mira que no estoy ejecutando algo relacionado
 cmp     r4, #0		; Si puedo proseguir...
 jmpr    cc_Z, loc_CDDD40 ; contina.
 mov     r8, #4		; Si no puedo proseguir...
 jmpa    cc_UC, loc_CDDDAE ; sal.
loc_CDDD40:
calls   0F7h, loc_F7D2F8 ; Mira que no estoy ejecutando ya un DTMF
 cmp     r4, #0		; Si no puedo proseguir...
 jmpa    cc_Z, loc_CDDDAE ; sal.
 sub     r9, #23h	; Resta el cdigo correspondiente a  "#"
 cmp     r9, #16h	; Lo compara con 0x16
 jmpr    cc_UGT, loc_CDDDAA ; Si es mayor, sal.
 shl     r9, #1		; Si no, lo multiplica por 2
 add     r9, #2F88h	; Y le aade un offset
 extp    #203h, #1	; Y lo obtiene de la tabla 0203:02F88+X*2
 mov     r9, [r9]	; Saca el dato de la tabla...
jmpi    cc_UC, [r9]	; y salta . Eso es como llamar a function_teclaX
			; o lo que es lo mismo loc_(CDDD62+X*4)
loc_CDDD62:             ; para la tecla '0'
 mov     r8, #18h	; Mete el dato 0x18 ...
 jmpr    cc_UC, loc_CDDDAE ; y sigue
loc_CDDD68:             ; para la tecla '1'
 mov     r8, #19h
 jmpr    cc_UC, loc_CDDDAE
loc_CDDD68:             ; para la tecla '2'
 mov     r8, #1Ah
 jmpr    cc_UC, loc_CDDDAE
loc_CDDD6E:             ; para la tecla '3'
 mov     r8, #1Bh
 jmpr    cc_UC, loc_CDDDAE
loc_CDDD74:
.......as un total de 0x16 rutinas.....
loc_CDDDAA:
  mov     r8, #22h      ; Dato por defecto
loc_CDDDAE:		; Ahora encola la nueva rutina
 mov     r12, #3ACEh
 mov     r13, #41h	; que es 0041:3ACE
 mov     r14, #6	; con indicador 0x06 (que no s lo que signfica)
 mov     r15, #35h
 calls   0CCh, loc_CC79AE ; Manda en mensaje a la cola
........
CDDDD6:
 mov     r12, r8
 calls   0CDh, loc_CDDB3E ; esto es S45i_PlayTone y hace que
                          ; suene el tono indicado en r12

Para hacer que mande un tono DTMF distinto al que debera mandarse, slo
tengo que modificar loc_CDDD62+X*4 y meter un valor distinto en r8.
O tambin puedo hacer que loc_CDDDAE incremente r8 , y luego
contine haciendo    mov r12, #3ACEh   y el resto como antes.

Si sigo los pasos hacia atrs para ver cmo he llegado hasta aqu, veo que
todo se cuece en FB9AD2 y tambin aqu se verifican los datos.
En fin, hay muchas posibles rutinas para alterar el dato enviado.



*******************************
Hay otro metodo similar para recargar la tarjeta , pero sin hacer una
llamada de voz.
Se compra una tarjeta de rascar, se escribe un nmero de telefono, seguido por
la tecla '*' y a continuacin el cdigo del cartoncillo y la tecla "MARCAR".
Si todo ha ido bien se recibe un mensaje instantneo indicando el nuevo saldo.

Mi tctica ser hacer que el mvil muestre el saldo antiguo en el mensaje
de confirmacin, con lo que el vendedor lo intentar de nuevo, quizs con
varios cartoncillos. Cada vez que lo intente con un nmero diferente, parece
que no lo ha cargado, pero en realidad s que lo ha hecho, aumentando cada
vez ms mi saldo.
Tambin se podra eliminar el mensaje de confirmacin antes que el mvil lo
muestre, o mil procedimientos ms.
Lo que tengo que averiguar es cmo hacer para modificar el SMS del nuevo
saldo antes de que se muestre en la pantalla.
La tcnica es fcil: me mando un SMS desde otro mvil.
Como esperaba, la primera vez que identifico que ha llegado mensaje lo
encuentro en formato PDU empaquetado, es decir, que 8 caracteres se meten
en 7 bytes, y resulta complicado de localizar y modificar.

Pero en otro momento posterior, el SMS se desempaqueta y se muestra.
Esto pasa a travs de la rutina S45i_strcpy en FF40A0. As que uso algo
parecido a lo anterior: si encuentro la palabra "saldo" entonces
cambio "es ahora xxx euros" por "es ahora  3.00 euros" .

En vez de escribirlo en ensamblador, decido escribirlo en lenguage C y usar el
compilador KeilC que me permite generar cdigo ensamblador para C166.
org FF40A0
calls miCopy
mov r4, #0h

/*
Los datos de entrada son:
r15:r14=puntero al fuente
r13:r12=puntero al destino
miCopy()
{
int i;
far char *pFuente;
pFuente=r15*0x4000+r14;
if(strstr(pFuente,"saldo")>0)
 {
 pEuros=strstr(pFuente,"euros");
 if(pEuros>0)
  {
  *(pEuros-7)=' ';
  *(pEuros-6)=' ';
  *(pEuros-5)='3';
  *(pEuros-4)='.';
  *(pEuros-3)='0';
  *(pEuros-2)='0';
  }
 calls original_FF40A0;
}

Con cuidado de que la funcin strstr (en FF417A, tambin conocida
como S45i_FindSubstring) no se le ocurra llamar a FF40A0.
Esta informacin la he obtenido a partir del listado que he hecho
desensamblando con el programa IDA toda la ROM del mvil.


Podra decirte cul es la funcin que llama a esta copia de strings, pero
posiblemente ya lo puedes hacer por tu cuenta, ?o no?

Bueno, y esto es todo por ahora. No creo haber descubierto nada nuevo que
no supiera antes, a saber:
-Siemens hace unos telfonos realmente potentes
-Hay mucha informacin en Internet
-La paciencia es la madre de la ciencia
-El que nada tiene que hacer, con el culo caza moscas.

*EOF*