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.
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
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)
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
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
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 (.)
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