P-Code Tutorial –1 : El Cuentapasos: Se abrió la LAPIDA

 

Tools: WKTVBDebugger,ExDec

Target at: http://www.cuentapasos.com

 

Bien pues aquí quiero saldar una vieja cuenta pendiente que tenia con un programita en P-Code que de seguro a mas de uno de vosotros también os llevo de cabeza en sus tiempos... EL ARCHIFAMOSO CUENTAPASOS en su versión 3.85, y de paso dar una rápida introducción al WKTDEVB.DLL

 

Quién iba a decir que en tan solo 30 minutos podemos dejar este programa en el más absoluto KO, y cambiando simplemente un par de instrucciones J .

 

Eso si con la ayuda de otro programita creado especialmente para desensamblar el Pcode, si exacto hablo de ExDec el desensamblador de Josephco.

 

Lo único que nos queda por saber es el funcionamiento de cada Nmonico P-code, que por cierto el juego completo de instrucciones es de unas 1000. Pero bueno para eso somos reverses...

 

Sin mas cogemos el CP y como sabrás este programa esta comprimido, así que en estos momentos no se puede calificar como P-code, para que sea tal primero hay que descomprimirlo, supongo que sabrás como hacerlo si no visita el ECD que hay tutos que lo explican... Bueno una vez descomprimido, vamos a ejecutarlo a ver que tal va y.....

Sorpresa comienza a decir tonterías, si te dice cosas así como que los ficheros del sistema esta corrompidos que instales de nuevo, es simplemente porque no encuentra los ficheros de datos que necesita, para que los encuentre simplemente renombra el fichero descomprimido y ponle el nombre del fichero original (cpasos32.exe), vuelve a ejecutar y...  juer ahora dice que no hay tarifas, y por mucho que le demos a aceptar pasa de todo...

Eso solo puede significar una cosa CHECKSUM o Verificación de la integridad del fichero, usease que a ver lo que nuestro pequeño debugger puede hacer por nosotros...

 

Cogemos la dll del debugger la copiamos en el directorio del programa , así con todos los archivos necesarios del debugger (bdasm.dll, wktvbde.dll, ploader.exe y una copia de la VM) , ejecutamos el loader y elegimos el exe (cpasos32.exe) le damos a ejecutar y ...

Comienza la carga del debugger, nos dará unos mensajes avisándonos que hay secciones que no corresponden a las típicas de un fichero p-code, pulsamos aceptar en todas y el debugger aparece ante nuestros ojos.

 

Buff la de cosas que dice la ventanita verde ¡¡¡hee¡¡¡, no os cortéis comenzar a trazar para intentar comprender un poco el funcionamiento del p-code.

Pero antes de nada acudamos a nuestro amigo ZEN, veamos si el programa detecta que esta descomprimido eso debe de ser  o bien por que mira el tamaño del fichero o bien porque realiza un checksum, yo voto por la primera opción, así que me pongo a trazar como un loco hasta que vea una referencia al nombre del ejecutable.

 

Fale para el carro antes de nada habría que explicar un poco algunas instrucciones pcode, porque si no podemos estar trazando toda la vida... 

Veamos algunos mnemonicos P-code importantes para nuestro objetivo:

 

ThisvCallHresult

ImpAdCallFPR4

ImpAdCallI2

 

Estos nmonicos se encargan de llamar a un procedimiento distinto del actual

Retornando a la siguiente instrucción después de la llamada (call/ret)

 

Branch   à   Salto Incondicional (JMP)

BranchF  à   Salto condicional si es False/Falso (jnz)

BranchT  à   Salto condicional si es True/Verdadero (jz)

 

Y como habrás deducido estos son los encargados de saltos condicionales e incondicionales.

 

Bien sabiendo esto nos ponemos  a trazar el programa con F8 (step trace)  y cuando veamos cualquiera de los opcodes que llaman a otros procedimientos (ImpAdCallFPR4, ThisvCallHresult ImpAdCallI2) pulsaremos F10 (Trace Over) , la razón de que hagamos esto es porque queremos ver como se desarrolla el flujo del programa desde el procedimiento PRINCIPAL .

 

Ten en cuenta que no podemos trazar el programa entero con F10 (step Over) ya que si topáramos con un salto condicional/incondicional, el punto de ruptura se establecería en la siguiente instrucción, y como vamos a realizar un salto seguramente no regresaremos nunca a esa instrucción...

 

El primer ImpAdCallFPR4 lo podemos ver en 4bb0fd:

 

 

 

004BB0E3: 28 LitVarI2 3Ch , 60

004BB0E8: FC Lead1/FStVar

004BB0EC: 00 LargeBos

004BB0EE: F5 LitI4: -> 1Eh 30

004BB0F3: 7B ImpAdStR4

004BB0F6: 00 LargeBos

004BB0F8: F4 LitI2_Byte: -> 0h 0

004BB0FA: 2B PopTmpLdAd2 0012FCD2 -> 00h 0

004BB0FD: 0A ImpAdCallFPR4 Principal!0049E3DCh ß Llamada al procedimiento

004BB102: 00 LargeBos

004BB104: 1B LitStr: 'ContPaso.HLP'

004BB107: 04 FLdRfVar 0012FCD4h

004BB10A: 05 ImpAdLdRf

004BB10D: 24 NewIfNullPr

004BB110: 0D VCallHresult

004BB115: 08 FLdPr

004BB118: 0D VCallHresult

004BB11D: 1A FFree1Ad

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Si llegados a esta línea pulsamos F10 el procedimiento será ejecutado y retornaremos a 4BB102 (eso siempre que el procedimiento regrese), en este caso se mostrara la pantalla de presentación del cuentapasos.

Bien pues seguimos aplicando esta técnica hasta encontrar un procedimiento que no regrese o que nos muestre un mensaje de error.

Como recordaras si ejecutamos en Cpasos32.exe descomprimido nos dice que no tenemos ninguna tarifa, así pues nuestro objetivo de momento será encontrar el procedimiento o parte del código que nos muestra este mensaje... 

Trazamos aprovechando las funciones de F8 y F10 caeremos en: 4BB147

 

 

 

004BB13F: F4 LitI2_Byte: -> 2h 2

004BB141: CB NeI2

004BB142: 7A ImpAdStI2

004BB145: 00 LargeBos

004BB147: 0B ImpAdCallI2 Opciones!004C5428h

004BB14C: C3 NotI4

004BB14D: 0B ImpAdCallI2 Versiones!00488918h

004BB152: C3 NotI4

004BB153: C5 OrI4

004BB154: 1C BranchF 004BB178 »

004BB157: 00 LargeBos

004BB159: 05 ImpAdLdRf

004BB15C: 56 NewIfNullAd

004BB15F: FD Lead2/FStAdNoPop

004BB163: 05 ImpAdLdRf

004BB166: 24 NewIfNullPr

004BB169: 0D VCallHresult

004BB16E: 1A FFree1Ad

004BB171: 00 LargeBos

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Principal! 4bb147

 

Si pulsas F10 sobre esta llamada veras como aparece el dialogo diciéndonos que no tenemos las tarifas , pos bien ya tenemos al culpable de ese cartel , cerramos el prog , lo volvemos a cargar y ponemos un Breack Point en esa dirección , para hacer esto simplemente pulsamos en el debugger el botón con el nombre On Execution , veremos como nos aparece un pequeño dialogo a la derecha , este dialogo nos mostrara los puntos de ruptura que tenemos puestos y al lado aparecerá un simbolito en verde diciéndonos que el bpx esta activo o amarillo lo cual quiere decir que esta deshabilitado.

En estos momentos no debería aparecer ningún BP en el dialogo, así que vamos a poner el nuestro, escribimos el numero de línea donde nos queremos detener (4bb147) y pulsamos el botón ADD, ya esta veréis como aparece en el dialogo la dirección del BP y a su Izquierda un símbolo en verde, podemos alterar el estado del BP pulsando con el ratón 2 veces encima de el. O seleccionarlo y pulsar cualquiera de los botones de este dialogo (remove, disable... creo que es muy intuitivo).También podemos poner BP pulsando 2 veces encima de  la línea de desensamblado que deseemos que se detenga, claro esta que para esto tendremos que tener la dirección a la vista.

 

Sigamos, con nuestro BP activado pulsamos F5(go) para que el programa se ejecute y pare en el BP. Una vez en 4bb147 pulsamos F8 y entramos en este procedimiento.

Si te fijas en la parte de debajo dela ventana de desensamblado veras algo como esto: Opciones!4c5428, lo cual nos indica que estamos en el procedimiento correspondiente a  opciones. Si te fijaste el procedimiento del que veníamos antes de entrar aquí se llamaba Principal.

 

Dentro de este nuevo procedimiento seguimos como antes trazando con la ayuda de F8 y F10 y llegaremos a este lugar: 4C57BC

 

 

 

004C579B: 2A ConcatStr

004C579C: 23 FStStrNoPop

004C579F: 1B LitStr: '.INI'

004C57A2: 2A ConcatStr

004C57A3: FD Lead2/FMemStStr

004C57A9: 32 FFreeStr

004C57B2: 1A FFree1Ad

004C57B5: 00 LargeBos

004C57B7: 0B ImpAdCallI2 Archivos!0047B140h

004C57BC: 23 FStStrNoPop 'C:\CuentaPasos 3\cpasos32.exe' 0012FB74h

004C57BF: 5E ImpAdCallI4 rtcFileLen on address 0F036192h

004C57C4: 99 FMemStI4

004C57C9: 2F FFree1Str

004C57CC: 00 LargeBos

004C57CE: 94 FMemLdR4

004C57D3: 4A FnLenStr

004C57D4: F5 LitI4: -> 0h 0

004C57D9: C7 EqI4

004C57DA: 1C BranchF 004C5816 »

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Como podéis ver aparece el nombre y el directorio del exe que hemos ejecutado y si miramos la siguiente línea 4c56bf vemos una llamada a rtcFileLen , ¿se os ocurre que esta haciendo? Jeje exacto esta obteniendo el tamaño del exe del programa ejecutado.

Vamos a ver dale a F8 para situarnos en rtcfilelen, pulsa otra vez F8 y fíjate en la Pila, (ponla en modo DWORD) en la cima de esta veras 00FC68C que es igual a 1033868, que si te fijas en el tamaño de Cpasos32.exe, ahora deberías ver algo como esto:

 

 

 

004C579F: 1B LitStr: '.INI'

004C57A2: 2A ConcatStr

004C57A3: FD Lead2/FMemStStr

004C57A9: 32 FFreeStr

004C57B2: 1A FFree1Ad

004C57B5: 00 LargeBos

004C57B7: 0B ImpAdCallI2 Archivos!0047B140h

004C57BC: 23 FStStrNoPop

004C57BF: 5E ImpAdCallI4 rtcFileLen on address 0F036192h

004C57C4: 99 FMemStI4 004C8590 -> 000FC68Ch , 1033868

004C57C9: 2F FFree1Str

004C57CC: 00 LargeBos

004C57CE: 94 FMemLdR4

004C57D3: 4A FnLenStr

004C57D4: F5 LitI4: -> 0h 0

004C57D9: C7 EqI4

004C57DA: 1C BranchF 004C5816 »

004C57DD: 00 LargeBos

004C57DF: 04 FLdRfVar 0012FB74h

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Como verás el mnemonico FmemStI4 nos muestra unos números en su propia sintaxis estos números corresponden a: 4c8590= lugar de la memoria donde guardara el valor de la cima de la pila, FC68Ch= valor de la cima de la pila y 1033868 = el valor de la cima de la pila en Decimal.

así pues podemos deducir que este opcode lo que hace es guardar en 4c8590 el tamaño del exe del programa (fc68c) , si te fijas en el nombre de este opcode es algo así como “Memory Store Integer 4” y como ves su objetivo es guardar en la zona de memoria indicada el valor de la cima de la pila , para comprobarlo simplemente  Pulsa el botón Memory Dump del debugger , se te abrirá una ventana .

Esta ventana te permite Ver y Buscar datos por la memoria, e incluso te muestra un desensamblado en código máquina x86, de momento vamos a inspeccionar la zona de memoria que comentábamos, donde pone Adress To Dump escribe 4c8590, si te fijas justo debajo te mostrara el volcado de la zona especificada, veras que esta a 00 00 00 00 bien ahora pulsa F8, veras como esa dirección cambia a 8c c6 0f 00, que es el tamaño del ejecutable.

Muy bien ahora nuestro objetivo es ver cuando esta zona de memoria es recuperada y comparada, para evitar que detecte que el programa ha sido descomprimido.

Como vimos el opcode 99 FmemStI4 es el encargado de guardar el valor en la memoria así pues debe de haber otro encargado de cargar este valor.

Pulsa en el botón Opcodes del debugger, se mostrara una ventana con el conjunto Juego completo de Nmonicos Pcode, busquemos el 99, los nmonicos anteriores y posteriores a este parecen estar relacionados veamos:

 

0F0FE145h 93h         FMemLdI2            5             

0F0FE16Ch 94h         FMemLdR4            5             

0F1056F8h 95h         FMemLdCy            5             

0F10571Ch 96h         FMemLdFPR4          5             

0F10573Dh 97h         FMemLdFPR8          5             

0F0FE1B5h 98h         FMemStI2            5             

0F0FE1DCh 99h         FMemStI4            5             

0F105789h 9Ah         FMemStR8            5             

0F1057ADh 9Bh         FMemStFPR4          5             

0F1057D8h 9Ch         FMemStFPR8          5           

  

Estos serán todos los que veamos que empiecen por Fmem y todos ellos son encargados de guardar o restaurar un valor de la memoria a la pila y el mas parecido que restaure un valor de la memoria a la pila parece que sea el 94 fmemldr4, daros cuenta que se usa St=Store y Ld=Load con lo que nos decantamos por este FMemLdR4 así pues en la misma ventana de opcodes pulsamos 2 veces sobre el 94, con lo cual estamos estableciendo un BP en es este nmonico, con lo que cada vez que la VM lo ejecute pararemos para inspeccionar que esta leyendo.

 

Ahora nos liamos a pulsar F5(go) hasta que paremos en una instrucción parecida a esta

FMemLdR4   4C8590 à xxxxx , xxxxxx

 

Apareceremos aquí:

 

 

 

004C5FCA: 00 LargeBos

004C5FCC: F5 LitI4: -> FB4h 4020

004C5FD1: 99 FMemStI4

004C5FD6: 00 LargeBos

004C5FD8: 94 FMemLdR4

004C5FDD: F5 LitI4: -> CE4h 3300

004C5FE2: D1 LtI4

004C5FE3: 1C BranchF 004C5FF2 »

004C5FE6: 00 LargeBos

004C5FE8: F5 LitI4: -> CE4h 3300

004C5FED: 99 FMemStI4

004C5FF2: 00 LargeBos

004C5FF4: 94 FMemLdR4 004C8590 -> 000FC68Ch , 1033868

004C5FF9: F5 LitI4: -> 493E0h 300000

004C5FFE: D1 LtI4

004C5FFF: 94 FMemLdR4

004C6004: F5 LitI4: -> AAE60h 700000

004C6009: DB GtI4 AAE60h,FC68Ch ?

004C600A: C5 OrI4

004C600B: 1C BranchF 004C6018 »

004C600E: 00 LargeBos

004C6010: 1B LitStr: ''

004C6013: 54 FMemStStrCopy

004C6018: 00 LargeBos

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Jeje que os parece el amigo esta cargando nuestro numero mágico desde la memoria a la pila, ahora simplemente nos ceñiremos a buscar un salto condicional, el cual me juego la vida a que es el culpable de ese molesto mensaje que no nos deja continuar. Así pues examinemos el código que hay un poco mas adelante, si te fijas en 4c6009 aparece el opcode DB GtI4 es cual es encargado de comparara los 2 valores en la cima de la pila, así pues el salto que estábamos buscando lo encontramos en 4c600b, branchf, salta si es falso, para comprobar si es así vamos a cambiar el BranchF por un Branch, para eso trazamos hasta situarnos en esa línea y después pulsamos el botón EDIT que tenemos debajo de la ventana de desensamblado, esto hará que se abra el memory dump pero apuntando a la dirección donde se encuentra el cursor, ahora donde podemos ver los bytes en la memoria pulsamos 2 veces con lo cual se abrirá una pequeña ventana la cual nos permitirá alterar el contenido de la memoria, como veréis el valor de la primera casilla es 1C el cual corresponde a BranchF , por lo que lo vamos a cambiar por 1E que corresponde a Branch , una vez hecho esto pulsamos Patch Now , y veremos como en la ventana de desensamblado el BranchF ha cambiado a Branch , ahora elimina todos los BP tanto de código como de mnemonicos y pulsa F5 , ¡¡¡¡ Sorpresa ya no sale la temida pantalla ¡¡¡¡¡ , jeje ya tenemos nuestro primer parche , address 4c600b 1c x 1e , ueno realmente hemos aplicado el parche en memoria no en el fichero en si para ese proposito el amigo silver , ha puesto una cajita llamada File Offs : la cual aparece delante del boton EDIT , ¿imaginais a que corresponde el valor que muestra ? Premio para el chico con los dientes pa arriba ... Si eso mismo esa direccion es la que tendremos que buscar con cualquier Hex Editor y parchear. Asi pues se acabaron las busquedas de cadenas hex para el parcheo .J

 

Sin embargo al ejecutar nos sale la FEA NAG recordándonos los días que nos quedan para que el programa expire, así que FASE 2 a por la nag......

 

Bien iniciemos de nuevo el debugger carguemos el CP y lo primero que vamos a hacer es parchear el salto que comprueba el tamaño del file , para eso abre el memory dump escribe la dirección 4c6009 dale 2 clicks encima y cambia el 1C por 1D ahora ponemos un BP de ejecución justo después del procedimiento que comprobaba el tamaño del file 4bb14c , pulsa F5(go) y espera a que pare , cuando pare en el BP seguiremos trazando como hicimos antes hasta que veamos que aparece la NAG :

 

 

 

 

 

004BB5D4: A9 AddI2

004BB5D5: 7A ImpAdStI2

004BB5D8: 00 LargeBos

004BB5DA: 27 LitVar_Missing 0012FC84h

004BB5DD: 25 PopAdLdVar

004BB5DE: FE Lead3/LitVarI4

004BB5E6: 25 PopAdLdVar

004BB5E7: 05 ImpAdLdRf

004BB5EA: 24 NewIfNullPr

004BB5ED: 0D VCallHresult 001C2528     ß llamada que muestra la nag

004BB5F2: 00 LargeBos

004BB5F4: 75 ImpAdLdI2

004BB5F7: F4 LitI2_Byte: -> 1h 1

004BB5F9: AD SubI2

004BB5FA: 7A ImpAdStI2

004BB5FD: 00 LargeBos

004BB5FF: 04 FLdRfVar 0012FCD2h

004BB602: 05 ImpAdLdRf

004BB605: 24 NewIfNullPr

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

Veremos como si trazamos 4BB5ED aparece la nag , puede que esta posición varíe ya que he podido apreciar que el programador se ha preocupado de tomar decisiones de salto a rutinas gemelas , es decir hay varias rutina iguales destinadas a mostrar la nag , pero si lo hacéis por vosotros mismo rápidamente llegareis a un VcallHresult que mostrara la nag , una vez llegado a el usaremos la técnica conocida como Flash Back (salto atrás) es decir que tendremos que mirar las instrucciones anteriores a esta para ver donde se produce un salto condicional , para esta tarea podemos usa ExDec aunque no es necesario , nos ahorrara algo de tiempo , ExDec es una herramienta desarrollada por JosephCo la cual muestra un desensamblado de programas Pcode con lo cual podemos usarlo como IDA o Win32Dasm para localizar instrucciones importantes en un listado de código muerto, en la ultima versión del debugger se incluye un analizador de saltos, por lo que tambien es posible utilizarlo para no tener que abrir Exdec en busca del salto.

 

Bien cargamos el programa en ExDec y le damos a buscar y buscamos la dirección donde nos ha salido la nag en mi caso 4bb5ed, retrocedo en el listado buscando un salto que sobrepase esta dirección, y lo encuentro en 4bb4e6 como veis e optado por usar exDec ya que el listado muerto siempre ayuda. Al final de este doc os dejaré un fragmento del código desensamblado por exDec para esta rutina. Procediendo como anteriormente lo parcheamos ejecutamos y TACHAN no nos ha salido la nag, pero la cosa no termina aquí si pulsamos en el menú about veremos como ya no pone que es SHAREWARE y nos dice que estamos en el Día 0 de 30 jeje.

 

 

4BB4D6: 04 FLdRfVar                local_00F0

4BB4D9: 0a ImpAdCallFPR4:          4a33a0

4BB4DE: 04 FLdRfVar                local_00F0

4BB4E1: Lead4/1b CBoolVarNull    

4BB4E3: 35 FFree1Var               local_00F0

4BB4E6: 1c BranchF:                4BB61A

 

Como ya he dicho antes esta dirección pude variar, ya que el amigo Tobarra se a preocupado por esto y en el siguiente código extraído de ExDec podréis ver a lo que me refiero, aunque esto no es ningún problema, ya que con el debugger y procediendo como he señalado anteriormente rápidamente daremos con la dirección correcta.

 

Despedida y cierre

 

Como podéis ver este debugger nos aclara mucho el tema del P-code, eso si aun tenemos mucho Nuevos mnemonicos que Aprender y eso ya es cosa de todos. Así que después de este tutorial, solo nos queda esperar a que vosotros mismos vayáis escribiendo tutoriales, mientras y si la cosa funciona hiremos documentando los opcodes que faltan, y así entre todos podremos mejorar este Fantástico Debugger que nuestro GENIAL Mr.Silver ha desarrollado el solito o casi...

 

Y bueno ni que decir tiene que como todo genio puede haberse equivocado, así que sugerencias, bugs, e información sobre el tema siempre será aceptada de buen gusto.

 

Soy consciente de que me he dejado muchas cosas en el tintero pero daros cuenta que también es la primera vez que yo uso el debugger, y no quisiera confundir, así que no tardare mucho en escribir otro tutorial mucho mas elaborado explicando los mnemonicos P-code mas usados, que por cierto son los que están implementados ya que no hemos tenido tiempo de analizar el juego completo el cual cubre sobre los 1000 aunque muchos se repiten o son iguales.

 

Pero como he dicho antes esperamos vuestra colaboración para que esto sea solo el principio...

 

Saludos .

 

Mr.Snow [WKT!] 2001

 

 

( Fragmento de código desensamblado por ExDec, corresponde a la rutina que muestra la nag y lo he diferenciado por colores para que veáis a lo que me refería con rutinas gemelas)

 

4BB25C: 0a ImpAdCallFPR4:          _rtcRandomNext

4BB261: 73 FStFPR4                

4BB264: f4 LitI2_Byte:             0xf  15  (.)

4BB266: eb CR8I2                 

4BB267: 6e FLdFPR4               

4BB26A: b3 MulR8                 

4BB26B: f4 LitI2_Byte:             0x3  3  (.)

4BB26D: eb CR8I2                 

4BB26E: ab AddR8                 

4BB26F: Lead0/e6 FnIntR8         

4BB271: e5 CI2R8                 

4BB272: 7a ImpAdStI2               local_param_0024

4BB275: 35 FFree1Var               local_00F0

4BB278: 00 LargeBos              

4BB27A: 04 FLdRfVar                local_00F0

4BB27D: 0a ImpAdCallFPR4:          4a3fc0

4BB282: 04 FLdRfVar                local_00F0

4BB285: Lead4/1b CBoolVarNull    

4BB287: 35 FFree1Var               local_00F0

 

4BB28A: 1c BranchF:                4BB3E4

 

4BB28D: 00 LargeBos               

4BB28F: 04 FLdRfVar                local_00F0

4BB292: 0a ImpAdCallFPR4:          475120

4BB297: 04 FLdRfVar                local_00F0

4BB29A: Lead4/1b CBoolVarNull    

4BB29C: 35 FFree1Var               local_00F0

 

4BB29F: 1c BranchF:                4BB2B2

 

4BB2A2: 00 LargeBos              

4BB2A4: 04 FLdRfVar                local_00F0

4BB2A7: 0a ImpAdCallFPR4:          47d8e8

4BB2AC: 35 FFree1Var               local_00     F0

4BB2AF: 1e Branch:                 4bb2c1

 

4BB2B2: 00 LargeBos               

4BB2B4: 00 LargeBos              

4BB2B6: 04 FLdRfVar                local_00F0

4BB2B9: 0a ImpAdCallFPR4:          47ed14

4BB2BE: 35 FFree1Var               local_00F0

4BB2C1: 00 LargeBos              

4BB2C3: 00 LargeBos              

4BB2C5: 0a ImpAdCallFPR4:          4914a4

4BB2CA: 00 LargeBos              

4BB2CC: 6b FLdI2                   local_00BC

4BB2CF: 1c BranchF:                4BB2D9

 

4BB2D2: 00 LargeBos              

4BB2D4: 0a ImpAdCallFPR4:          47e690

4BB2D9: 00 LargeBos              

4BB2DB: 00 LargeBos              

4BB2DD: f4 LitI2_Byte:             0xff  -1  (.)

4BB2DF: 98 FMemStI2              

4BB2E4: 00 LargeBos              

4BB2E6: f4 LitI2_Byte:             0xff  -1  (.)

4BB2E8: 2b PopTmpLdAd2           

4BB2EB: 0a ImpAdCallFPR4:          49e6a4

4BB2F0: 00 LargeBos              

4BB2F2: 05 ImpAdLdRf:              4c89b8

4BB2F5: 24 NewIfNullPr             408a9c (frmSplash)

4BB2F8: 0d VCallHresult            O»408a9c0|__.°__

4BB2FD: 00 LargeBos              

4BB2FF: 0a ImpAdCallFPR4:          _rtcDoEvents

4BB304: 00 LargeBos              

4BB306: 04 FLdRfVar                local_00C8

4BB309: f3 LitI2:                  0x1389   5001  (..)

4BB30C: 05 ImpAdLdRf:              4cc518

4BB30F: 24 NewIfNullPr             42c4f8

4BB312: 0d VCallHresult            CVBApplication::LoadResString

4BB317: 3e FLdZeroAd               local_00C8

4BB31A: Lead2/b7 ImpAdStStr      

4BB31E: 00 LargeBos              

4BB320: 04 FLdRfVar                local_00C8

4BB323: f3 LitI2:                  0x1389   5001  (..)

4BB326: 05 ImpAdLdRf:              4cc518

4BB329: 24 NewIfNullPr             42c4f8

4BB32C: 0d VCallHresult            CVBApplication::LoadResString

4BB331: 3e FLdZeroAd               local_00C8

4BB334: Lead2/b7 ImpAdStStr      

4BB338: 00 LargeBos              

4BB33A: 04 FLdRfVar                local_00C0

4BB33D: 05 ImpAdLdRf:              4cc518

4BB340: 24 NewIfNullPr             42c4f8

4BB343: 0d VCallHresult            CVBApplication::get_Screen

4BB348: 3e FLdZeroAd               local_00C0

4BB34B: Lead2/6f CVarAd          

4BB34F: 05 ImpAdLdRf:              4c8d5c

4BB352: 56 NewIfNullAd             40fea4 (frmRegistro)

4BB355: Lead1/f8 FStAd           

4BB359: 04 FLdRfVar                local_0148

4BB35C: 4d CVarRef:                ( local_00E0 ) 4009

4BB361: 0a ImpAdCallFPR4:          49a0d0

4BB366: 6c ILdRf                   local_0148

4BB369: 3d CastAd                

4BB36C: Lead2/bf ImpAdStAdFunc   

4BB370: 1a FFree1Ad                local_0148

4BB373: 35 FFree1Var               local_00F0

4BB376: 00 LargeBos              

4BB378: f5 LitI4:                  0x0  0  (....)

4BB37D: e4 CI2I4                 

4BB37E: 04 FLdRfVar                local_00C0

4BB381: 05 ImpAdLdRf:              4cc518

4BB384: 24 NewIfNullPr             42c4f8

4BB387: 0d VCallHresult            CVBApplication::get_Screen

4BB38C: 08 FLdPr                   local_00C0

4BB38F: 0d VCallHresult            _CSCRN_vtbl::put__ipropMOUSEPOINTERSCRN

4BB394: 1a FFree1Ad                local_00C0

4BB397: 00 LargeBos              

4BB399: 75 ImpAdLdI2             

4BB39C: f4 LitI2_Byte:             0x1  1  (.)

4BB39E: a9 AddI2                 

4BB39F: 7a ImpAdStI2               local_param_0032

4BB3A2: 00 LargeBos               

4BB3A4: 27 LitVar_Missing        

4BB3A7: 25 PopAdLdVar            

4BB3A8: Lead3/c1 LitVarI4:         ( local_param_1FF20 ) 0x1  (1)

4BB3B0: 25 PopAdLdVar            

4BB3B1: 05 ImpAdLdRf:              4c8d5c

4BB3B4: 24 NewIfNullPr             40fea4 (frmRegistro)

4BB3B7: 0d VCallHresult            meth__imethSHOW

4BB3BC: 00 LargeBos              

4BB3BE: 75 ImpAdLdI2             

4BB3C1: f4 LitI2_Byte:             0x1  1  (.)

4BB3C3: ad SubI2                 

4BB3C4: 7a ImpAdStI2               local_param_0032

4BB3C7: 00 LargeBos              

4BB3C9: 04 FLdRfVar                local_00C2

4BB3CC: 05 ImpAdLdRf:              4c8d5c

4BB3CF: 24 NewIfNullPr             40fea4 (frmRegistro)

4BB3D2: 0d VCallHresult            O»40fea40|__.°__

4BB3D7: 6b FLdI2                   local_00C2

4BB3DA: 44 CVarI2                  local_00E0

4BB3DD: Lead1/f6 FStVar            local_00B4

4BB3E1: 1e Branch:                 4bb427

 

4BB3E4: 00 LargeBos              

4BB3E6: 00 LargeBos              

4BB3E8: 93 FMemLdI2              

4BB3ED: 1c BranchF:                4BB3FD

4BB3F0: 00 LargeBos              

4BB3F2: 05 ImpAdLdRf:              4c89b8

4BB3F5: 24 NewIfNullPr             408a9c (frmSplash)

4BB3F8: 0d VCallHresult            O»408a9c0|__.°__

4BB3FD: 00 LargeBos              

4BB3FF: f5 LitI4:                  0x0  0  (....)

4BB404: Lead2/c1 ImpAdStStrCopy  

4BB408: 00 LargeBos              

4BB40A: 04 FLdRfVar                local_00F0

4BB40D: 0a ImpAdCallFPR4:          _rtcGetPresentDate

4BB412: 04 FLdRfVar                local_00F0

4BB415: 04 FLdRfVar                local_0100

4BB418: 0a ImpAdCallFPR4:          _rtcGetMonthOfYear

4BB41D: 04 FLdRfVar                local_0100

4BB420: Lead1/f6 FStVar            local_00B4

4BB424: 35 FFree1Var               local_00F0

 

4BB427: 00 LargeBos              

4BB429: 00 LargeBos              

4BB42B: 1e Branch:                 4bb65f

 

 

4BB42E: 00 LargeBos              

4BB430: 0a ImpAdCallFPR4:          46a918

4BB435: 00 LargeBos               

4BB437: 0b ImpAdCallI2             4726a8

 

4BB43C: 1c BranchF:                4BB4D2

 

4BB43F: 00 LargeBos              

4BB441: f4 LitI2_Byte:             0xff  -1  (.)

4BB443: 7a ImpAdStI2               local_param_001D

4BB446: 00 LargeBos               

4BB448: 04 FLdRfVar                local_00C8

4BB44B: f3 LitI2:                  0x13ac   5036  (..)

4BB44E: 05 ImpAdLdRf:              4cc518

4BB451: 24 NewIfNullPr             42c4f8

4BB454: 0d VCallHresult            CVBApplication::LoadResString

4BB459: 27 LitVar_Missing        

4BB45C: 27 LitVar_Missing        

4BB45F: 27 LitVar_Missing        

4BB462: f5 LitI4:                  0x24  36  (...$)

4BB467: 3e FLdZeroAd               local_00C8

4BB46A: 46 CVarStr                 local_00F0

4BB46D: 0b ImpAdCallI2             _rtcMsgBox

4BB472: 71 FStR4                   local_014C

4BB475: 36 FFreeVar         local_00F0 local_0100 local_0120 local_0140

4BB480: 00 LargeBos              

4BB482: 6c ILdRf                   local_014C

4BB485: f5 LitI4:                  0x6  6  (....)

4BB48A: c7 EqI4                  

 

4BB48B: 1c BranchF:                4BB4AF

 

4BB48E: 00 LargeBos              

4BB490: 0a ImpAdCallFPR4:          478630

4BB495: 00 LargeBos              

4BB497: 63 LitVar_TRUE           

4BB49A: 0b ImpAdCallI2             484ab8

4BB49F: 35 FFree1Var               local_00F0

 

4BB4A2: 1c BranchF:                4BB4AC

 

4BB4A5: 00 LargeBos              

4BB4A7: f4 LitI2_Byte:             0xff  -1  (.)

4BB4A9: 70 FStI2                   local_00BC

4BB4AC: 1e Branch:                 4bb4c9

4BB4AF: 00 LargeBos              

4BB4B1: 6c ILdRf                   local_014C

4BB4B4: f5 LitI4:                  0x7  7  (....)

4BB4B9: c7 EqI4                  

 

4BB4BA: 1d BranchT:                4BB4C9

 

4BB4BD: 6c ILdRf                   local_014C

4BB4C0: f5 LitI4:                  0x2  2  (....)

4BB4C5: c7 EqI4                  

 

4BB4C6: 1c BranchF:                4BB4C9

 

4BB4C9: 00 LargeBos              

4BB4CB: 00 LargeBos              

4BB4CD: f4 LitI2_Byte:             0x0  0  (.)

4BB4CF: 7a ImpAdStI2               local_param_001D

4BB4D2: 00 LargeBos              

4BB4D4: 00 LargeBos              

4BB4D6: 04 FLdRfVar                local_00F0

4BB4D9: 0a ImpAdCallFPR4:          4a33a0

4BB4DE: 04 FLdRfVar                local_00F0

4BB4E1: Lead4/1b CBoolVarNull    

4BB4E3: 35 FFree1Var               local_00F0

 

4BB4E6: 1c BranchF:                4BB61A :Salida

 

4BB4E9: 00 LargeBos              

4BB4EB: f4 LitI2_Byte:             0xff  -1  (.)

4BB4ED: 98 FMemStI2              

4BB4F2: 00 LargeBos              

4BB4F4: f4 LitI2_Byte:             0xff  -1  (.)

4BB4F6: 2b PopTmpLdAd2           

4BB4F9: 0a ImpAdCallFPR4:          49e6a4

4BB4FE: 00 LargeBos              

4BB500: 05 ImpAdLdRf:              4c89b8

4BB503: 24 NewIfNullPr             408a9c (frmSplash)

4BB506: 0d VCallHresult            O»408a9c0|__.°__

4BB50B: 00 LargeBos              

4BB50D: 0a ImpAdCallFPR4:          _rtcDoEvents

4BB512: 00 LargeBos              

4BB514: 04 FLdRfVar                local_00C8

4BB517: f3 LitI2:                  0x1389   5001  (..)

4BB51A: 05 ImpAdLdRf:              4cc518

4BB51D: 24 NewIfNullPr             42c4f8

4BB520: 0d VCallHresult            CVBApplication::LoadResString

4BB525: 3e FLdZeroAd               local_00C8

4BB528: Lead2/b7 ImpAdStStr      

4BB52C: 00 LargeBos              

4BB52E: 04 FLdRfVar                local_00C8

4BB531: 28 LitVarI2:               ( local_00E0 ) 0x1389  (5001)

4BB536: 04 FLdRfVar                local_00F0

4BB539: 0a ImpAdCallFPR4:          4a0760

4BB53E: 04 FLdRfVar                local_00F0

4BB541: 04 FLdRfVar                local_0100

4BB544: 0a ImpAdCallFPR4:          4a0760

4BB549: 04 FLdRfVar                local_0100

4BB54C: Lead0/bc DivVar          

4BB550: Lead0/bc DivVar          

4BB554: 55 CI2Var                

4BB555: 05 ImpAdLdRf:              4cc518

4BB558: 24 NewIfNullPr             42c4f8

4BB55B: 0d VCallHresult            CVBApplication::LoadResString

4BB560: 3e FLdZeroAd               local_00C8

4BB563: Lead2/b7 ImpAdStStr      

4BB567: 36 FFreeVar         local_00F0 local_0100

4BB56E: 00 LargeBos              

4BB570: 04 FLdRfVar                local_00C0

4BB573: 05 ImpAdLdRf:              4cc518

4BB576: 24 NewIfNullPr             42c4f8

4BB579: 0d VCallHresult            CVBApplication::get_Screen

4BB57E: 3e FLdZeroAd               local_00C0

4BB581: Lead2/6f CVarAd          

4BB585: 05 ImpAdLdRf:              4c8d5c

4BB588: 56 NewIfNullAd             40fea4 (frmRegistro)

4BB58B: Lead1/f8 FStAd           

4BB58F: 04 FLdRfVar                local_0148

4BB592: 4d CVarRef:                ( local_00E0 ) 4009

4BB597: 0a ImpAdCallFPR4:          49a0d0

4BB59C: 6c ILdRf                   local_0148

4BB59F: 3d CastAd                

4BB5A2: Lead2/bf ImpAdStAdFunc   

4BB5A6: 1a FFree1Ad                local_0148

4BB5A9: 35 FFree1Var               local_00F0

4BB5AC: 00 LargeBos              

4BB5AE: f5 LitI4:                  0x0  0  (....)

4BB5B3: e4 CI2I4                  

4BB5B4: 04 FLdRfVar                local_00C0

4BB5B7: 05 ImpAdLdRf:              4cc518

4BB5BA: 24 NewIfNullPr             42c4f8

4BB5BD: 0d VCallHresult            CVBApplication::get_Screen

4BB5C2: 08 FLdPr                   local_00C0

4BB5C5: 0d VCallHresult            _CSCRN_vtbl::put__ipropMOUSEPOINTERSCRN

4BB5CA: 1a FFree1Ad                local_00C0

4BB5CD: 00 LargeBos              

4BB5CF: 75 ImpAdLdI2             

4BB5D2: f4 LitI2_Byte:             0x1  1  (.)

4BB5D4: a9 AddI2                  

4BB5D5: 7a ImpAdStI2               local_param_0032

4BB5D8: 00 LargeBos              

4BB5DA: 27 LitVar_Missing        

4BB5DD: 25 PopAdLdVar            

4BB5DE: Lead3/c1 LitVarI4:         ( local_param_1FF20 ) 0x1  (1)

4BB5E6: 25 PopAdLdVar            

4BB5E7: 05 ImpAdLdRf:              4c8d5c

4BB5EA: 24 NewIfNullPr             40fea4 (frmRegistro)

4BB5ED: 0d VCallHresult            meth__imethSHOW

4BB5F2: 00 LargeBos              

4BB5F4: 75 ImpAdLdI2             

4BB5F7: f4 LitI2_Byte:             0x1  1  (.)

4BB5F9: ad SubI2                 

4BB5FA: 7a ImpAdStI2               local_param_0032

4BB5FD: 00 LargeBos              

4BB5FF: 04 FLdRfVar                local_00C2

4BB602: 05 ImpAdLdRf:              4c8d5c

4BB605: 24 NewIfNullPr             40fea4 (frmRegistro)

4BB608: 0d VCallHresult            O»40fea40|__.°__

4BB60D: 6b FLdI2                   local_00C2

4BB610: 44 CVarI2                  local_00E0

4BB613: Lead1/f6 FStVar            local_00B4

 

4BB617: 1e Branch:                 4bb65d

 

Salida1:

 

4BB61A: 00 LargeBos              

4BB61C: 00 LargeBos              

4BB61E: 93 FMemLdI2              

4BB623: 1c BranchF:                4BB633

4BB626: 00 LargeBos              

4BB628: 05 ImpAdLdRf:              4c89b8

4BB62B: 24 NewIfNullPr             408a9c (frmSplash)

4BB62E: 0d VCallHresult            O»408a9c0|__.°__

4BB633: 00 LargeBos              

4BB635: f5 LitI4:                  0x0  0  (....)

4BB63A: Lead2/c1 ImpAdStStrCopy  

4BB63E: 00 LargeBos