El primer paso a dar antes
de iniciar la sesión es examinar la cobaya y familiarizarse
con su entorno. Deberemos crear un usuario preferiblemente
con permisos de lectura y escritura (para probar los uploads),
darle acceso a un directorio de nuestra máquina y
posteriormente ejecutar un programa de FTP para conectarnos
(notese que conectamos a nuestra misma máquina ).
Para conectarnos usaremos como dirección IP la 127.0.0.1
(correspondiente a nuestra maquina ya que es local) o el
nombre de nuestro PC, introduciremos el nombre del usuario
y el password que le hubieramos asignado. Ahora probamos
a realizar una transferencia de más de 5 archivos
al directorio de nuestro servidor (que es nuestra misma
máquina). Veremos que se transferirán un máximo
de 5 archivos y luego aparecerá un mensaje en nuestro
programa de FTP que dice algo así:
Unregistered
version limited to 5 uploads...
Ya tenemos algo, una cadena
ahora podriamos intentar
desensamblar el ejecutable del programa (G6FTPSrv.exe) pero
grata es nuestra sorpresa al ver como no hay tabla de importación
ni referencias a cadena. Esto solo puede significar una
cosa: el ejecutable está comprimido. Para corroborar
este hecho tan solo debemos usar alguna aplicación
que identifique los ejecutables (gtw p. ej), pero si conocemos
los nombres de los compresores más habituales podremos
realizar esta comprobación manualmente. Tan solo
necesitamos un editor hexadecimal. Abrimos el ejecutable
con el editor y hechamos un vistazo a la cabezera del EXE,
vemos que es de Windows (debido a la marca 'PE' Portable
Executable) que hay en el offset 100h, si hechamos un vistazo
más abajo veremos la cadena UPX repetida varias veces
(estos nombres correspondes a los nombres de las secciones
del ejecutable), normalmente los ejecutables tienen los
siguientes nombres para sus direferentes
secciones:
.code o .text -> En estas
secciónes se encuentra el código ejecutable
del programa
.idata -> Aquí esta la tabla de importación
.rsrc -> Aquí están los recursos de la
aplicación (iconos bitmaps y demás)
.data -> Aquí están los datos usados por
la aplicación (variables etc.)
.reloc -> Información para la reubicación
del ejecutable (casi siempre en las DLLs)
Podemos ver que el nombre
UPX no es de los que se usan normalmente. Con toda seguridad
podemos afirmar que este archivo esta comprimido con el
compresor UPX (un compresor bastante utilizado ultimamente).
Llegados a este punto se nos
plantea un problema, ¿cómo hacemos para desempaquetar
todo el ejecutable?, pues tenemos varias opciones:
A) Utilizar el ProcDump
(esto es un volcador de procesos)
B) Volcar el ejecutable sección a sección
y recomponerlo.
Yo he elegido la opción
A porque el tipo de parche que voy a crear no necesita que
exista un EXE desempaquetado totalmente funcional. Lo que
voy ha hacer es un injerto de código mediante la
creación de una nueva sección que es la opción
que mejor me ha funcionado en estos casos (digo esto personalmente).
La opción B tiene sentido cuando lo que queremos
es reconstruir el EXE original y modificar grandes porciones
de código, pero esto a veces resulta muy complicado
y normalmente mis experiencias con la opción B producen
ejecutables se cuelgan más que una percha ;) y creo
que es debido a mi limitado conocimiento sobre la estructura
de los PE :(.
Pues primero ejecutamos el
G6 FTP Server y cuando haya arrancado cargamos el Procdump,
nos situamos sobre la ventana donde se encuentran las tareas
(Task) y nos desplazaremos hacia abajo hasta que veamos
al G6 FTP Server (ver Foto 1)

Foto 1
Ahora hacemos click con el
botón derecho del ratón y seleccionamos Dump
Full. Ahora ProcDump nos pedirá donde queremos guardar
el volcado, lo guardaremos en el mismo directorio del G6
FTP Server pero con el nombre G6UPX.exe. Saldremos del G6
FTP server y del ProcDump.Lo que tenemos ahora es una imagen
del ejecutable que se encontraba en memória pero
resulta que esta imagen no es funcional, es decir si probamos
a ejecutar el archivo volcado (G6UPX.exe) Windows nos dirá
que ha ejecutado una operación no válida y
bla.. bla.... La explicación a esto es muy simple:
La imagen es correcta pero no la estructura que la define,
me explico:
La cabezera del ejecutable
volcado pertenece a la cabezera del ejecutable comprimido,
por lo que el punto de entrada de la aplicación (a
partir de donde se empieza a ejecutar código) no
es correcto ya que ahora el código que realizaba
la descompresión continua ejecutandose cuando no
debería. También sucede que la tabla de importación
original haya sido alterada por el compresor UPX y no sea
correcta.
De todas maneras lo único
que necesitamos es el código (death listing) y que
las referencias a cadenas existan. Pues adelante, desensamblamos
el ejecutable (G6UPX.exe) con el W32Dasm y vemos que efectivamente
tenemos el icono de las referencias a cadenas activo, pulsamos
sobre este icono para buscar la cadena 'Unregistered
Version...' y resulta
que por mucho que busquemos no la encontramos, parece que
el programador fue listo y la ocultó bien, pero quizás
la haya encriptado (no es así ya que podemos encontrarla
con un editor hexadecimal) o es probable que no incluyera
esta cadena en la tabla de referencias, desconozco si lo
hizo aposta o por accidente :) . Pues ahora si que nos han
jodido, todo esto para nada. Pero un momento, si miramos
en la lista de referencias a cadenas veremos que hay una
referencia a la cadena suelta 'Unregistered',
está cadena es la que nos aparece al entrar al program
G6 FTP Server y hacer click en el menu Help/About. Si hacemos
doble click sobre esta veremos que el W32Dasm nos lleva
a un código tal que así.
:004CAA29 |
8BC3 |
mov
eax,
ebx |
|
:004CAA2B |
E8489DF6FF |
call
00434778 |
|
:004CAA30 |
A120365000 |
mov
eax,
dword
ptr
[00503620] |
// Carga un valor |
:004CAA35 |
803800 |
cmp
byte
ptr
[eax],
00 |
// Y mira si el valor apuntado en esa dirección
es igual a 0 |
:004CAA38 |
7415 |
je
004CAA4F |
// Si es así salta abajo, no registrado (haz
click en el hipervinculo) |
:004CAA3A |
8B1520385000 |
mov
edx,
dword
ptr
[00503820] |
//
Esta registrado, continua la ejecución |
:004CAA40 |
8B12 |
mov
edx,
dword
ptr
[edx] |
|
:004CAA42 |
8B8320030000 |
mov
eax,
dword
ptr
[ebx+00000320] |
|
:004CAA48 |
E847A5F6FF |
call
00434F94 |
|
:004CAA4D |
EB10 |
jmp
004CAA5F |
|
* Referenced by a (U)nconditional or (C)onditional Jump
at Address: |:004CAA38(C)
|
* Possible StringData Ref from Data Obj ->"Unregistered"
|
:004CAA4F |
BAC4AA4C00 |
mov
edx,
004CAAC4 |
// Aquí se hace referencia a la cadena Unregistered |
:004CAA54 |
8B8320030000 |
mov
eax,
dword
ptr
[ebx+00000320] |
|
:004CAA5A |
E835A5F6FF |
call
00434F94 |
Un
ligero examen de este código nos revela que es posible
que se este utilizando un flag global (TRUE o FALSE ->
1 o 0) si el programa esta registrado, tal y como se puede
apreciar en la línea 4CAA35
donde se compará una dirección de memoria
con 0. En caso de que esto sea cierto tan solo deberiamos
averiguar donde está almacenado este flag y modificarlo
para que sea igual a 1 (registrado). De momento apuntamos
la dirección donde se hace la comparación
(4CAA38), lo que vamos ha hacer
ahora es establecer un breakpoint (punto de ruptura) sobre
está dirección y así averiguar a que
dirección de memória está puntando
EAX (esta es la dirección de nuestro flag), esto
lo haremos usando el ejecutable comprimido (el que funciona).
Para poder hacer esto necesitamos parar la ejecución
del programa (G6 FTP Server) y establecer el breakpoint
cuando estemos ejecutando su código. Un truco consiste
en colocar primero un breakpoint sobre alguna función
(API de Windows) de inicio de las que usan la mayoría
de los programas y luego ir pulsando F12 y G en el SoftIce
hasta que veamos el nombre de la aplicación (g6ftpsrv.exe)
en la ventana de código del SoftIce. Yo he utilizado
un breakpoint en la función GetProcAddress
ya que al estar el ejecutable comprimido, este debe usar
esta función para cargar las direcciones de las funciones
del API necesarias.
Pues
nada, con el SoftIce cargado pulsar Ctrl+D y teclear BC
para borrar los posibles breakpoints que tuvieramos. Ahora
ponemos el breakpoint en GetProcAddress con: BPX GetProcAddress,
pulsar Ctrl+D de nuevo y ejecutar el G6 FTP Server.
Pronto
volveremos a la ventana del SoftIce y tras pulsar F12, G,F12,G
y F12, apareceremos en el código perteneciente al
G6 FTP Server ya que así me lo indica la ventana
de código del SoftIce.
Ahora colocamos el breakpoint en 4CAA35 tecleando: BPX 4CAA35,
desactivamos el breakpoint en GetProcAddress con: BD 0 y
pulsamos G para continuar la ejecución del programa.
Hacemos click en el menu Help y luego en About, y antes
de que aparezca el cuadro de diálogo SoftIce se activará
mostrandonos el código que buscabamos (ver
listado más arriba). Ahora vamos a ver la dirección
donde apunta EAX, para ello teclearemos:
?
EAX
Obtendremos el valor 50339C,
esta es la posición de memória donde se guarda
nuestro supuesto flag, si comprobamos su contenido con
db
*EAX o db 50339C
Fijate
que uso db ya que el flag tiene un solo byte de tamaño
tal y como indica la comparación de la línea
4CAA35. Si observamos la ventana
de datos del SoftIce veremos que el primer byte es 0 (que
teóricamente significa no registrado). Ahora vamos
a relizar la técnica del prueba y a ver que pasa,
vamos a modificar el valor de la posición 50339C
para que sea igual a 1 (teóricamente registrado).
Para hacer esto teclearemos:
e
50339C
Ahora
estamos en la ventana de datos del SoftIce, sobreescribimos
el primer byte con 01 y pulsamos ESC para salir de la ventana.
Ahora el flag está cambiado, pero antes de continuar
con el programa vamos a hacer un seguimiento de los accesos
que se realizan sobre la posición 50339C, esto nos
permitirá determinar si se hace más de una
copia del flag o si este es único. Para ello vamos
a usar un breakpoint de memoria (BPM) estos breakpoints
están limitados a un máximo de 4 ya que utilizan
los registros internos de depuración que se incluyen
en los Pentium. Para crear el breakpoint teclearemos:
BPM
50339C
Ya tenemos
el breakpoint activo, ahora cada vez que se intente leer
o escribir sobre esta posición, SoftIce se activará.
Para continuar la ejecución pulsa G.
Veremos que antes de que aparezca el cuadro de diálogo
el SoftIce volverá a activarse mostrando el siguiente
código:
:004CAA88 |
E8CB9CF6FF |
call
00434758 |
// |
:004CAA8D |
A120365000 |
mov
eax,
dword
ptr
[00503620] |
// |
:004CAA92 |
803800 |
cmp
byte
ptr
[eax],
00 |
// ESTAMOS AQUÍ, comparamos el flag |
:004CAA95 |
7511 |
jne
004CAAA8 |
// si el flag no es 0 salta ya que estamos registrados |
:004CAA97 |
66BAEBFF |
mov
dx,
FFEB |
// no estamos registrados, flag = 0 |
:004CAA9B |
8B8320030000 |
mov
eax,
dword
ptr
[ebx+00000320] |
// |
:004CAAA1 |
E8AEA6F6FF |
call
00435154 |
// |
:004CAAA6 |
EB0D |
jmp
004CAAB5 |
// |
* Referenced by a (U)nconditional or (C)onditional Jump
at Address: |:004CAA95(C) |
:004CAAA8 |
33D2 |
xor
edx,
edx |
// OK estamos registrados |
:004CAAAA |
8B8320030000 |
mov
eax,
dword
ptr
[ebx+00000320] |
// |
:004CAAB0 |
E89FA6F6FF |
call
00435154 |
Como
puedes comprobar se vuelve a comparar el flag de 50339C,
pero esta vez el salto es a la inversa es un JNE en vez
de un JE. Esto nos indica que vamos por el buen camino ya
que el salto se tomará cuando el flag sea <>0
tal y como nosotros lo hemos modificado :) , continuamos
la ejecución del programa sin tocar nada pulsando
G. Nos aparecerá el
cuadro de dialogo y veremos que pone registered to: y no
saldrá ningún nombre. Pulsamos el botón
OK y salimos del cuadro de diálogo. Ahora vamos a
probar a hacer una transferencia de más de 5 archivos,
para comprobar si el flag con el que estamos jugando se
utiliza antes de transferir los archivos, es de lógica
suponer que si, ya que si estamos registrados no deberá
comprobar el número de archivos que estamos transfiriendo
y si no estamos registrados si deberá comprobar el
número de archivos a transferir. Pues probamos, conectamos
con el programa de FTP y veremos que aparecerá de
nuevo SoftIce mostrandonos lo siguiente:
:004BE18A |
A120365000 |
mov
eax,
dword
ptr
[00503620] |
// Carga puntero el flag (50339C) |
:004BE18F |
803800 |
cmp byte
ptr
[eax], 00 |
// Comprueba el valor del flag |
:004BE192 |
754B |
jne
004BE1DF |
// Si es <> 0, salta el usuario está registrado |
:004BE194 |
68C8F04B00 |
push
004BF0C8 |
//
Lo siguiente muestra un mensaje por el og del G6 FTP |
:004BE199 |
A1183A5000 |
mov
eax,
dword
ptr
[00503A18] |
//
indicandonos que no estamos registrados. |
:004BE19E |
FFB0C4000000 |
push
dword
ptr
[eax+000000C4] |
|
:004BE1A4 |
68D8F04B00 |
push
004BF0D8 |
|
:004BE1A9 |
FF35F8305000 |
push
dword
ptr
[005030F8] |
|
:004BE1AF |
8D85C0FEFFFF |
lea
eax,
dword
ptr
[ebp+FFFFFEC0] |
|
:004BE1B5 |
BA04000000 |
mov
edx,
00000004 |
|
:004BE1BA |
E8A95EF4FF |
call
00404068 |
|
:004BE1BF |
8B8DC0FEFFFF |
mov
ecx,
dword
ptr
[ebp+FFFFFEC0] |
|
:004BE1C5 |
A158365000 |
mov
eax,
dword
ptr
[00503658] |
|
:004BE1CA |
8B00 |
mov
eax,
dword
ptr
[eax] |
|
:004BE1CC |
8B80D0020000 |
mov
eax,
dword
ptr
[eax+000002D0] |
|
:004BE1D2 |
8B55FC |
mov
edx,
dword
ptr
[ebp-04] |
|
:004BE1D5 |
E8BAC8FCFF |
call
0048AA94 |
|
:004BE1DA |
E97F070000 |
jmp
004BE95E |
// Salto incondicional que nos aleja |
:004BE1DF |
807DCC00 |
cmp
byte
ptr
[ebp-34],
00 |
|
:004BE1E3 |
747E |
je
004BE263 |
Como
vemos se está realizando un test al efectuar la conexión
al servidor, esta comprobación la realiza para mostrarnos
un mensaje en el log del G6 FTP Server que nos recuerda
que la versión no registrada esta limitada a 5 uploads
y 5 downloads. Ahora podemos estar más seguros de
que andamos por el buen camino. Vamos a continuar la ejecución
del programa pulsando G .
Ahora vamos a hacer un upload de 6 o 7 archivos al FTP.
Veremos que antes de iniciarse la transferencia SoftIce
vuelve a activarse de nuevo mostrandonos lo siguiente.
:004E5D2D |
8BB7D8050000 |
mov
esi,
dword
ptr
[edi+000005D8] |
// |
:004E5D33 |
803D9C33500000 |
cmp
byte
ptr
[0050339C],
00 |
// compara el flag directamente |
:004E5D3A |
754F |
jne
004E5D8B |
// salta abajo si estamos registrados flag <>0 |
:004E5D3C |
83BEEC00000000 |
cmp
dword
ptr
[esi+000000EC],
00000000 |
:004E5D43 |
750B |
jne
004E5D50 |
:004E5D45 |
83BEE800000005 |
cmp
dword
ptr
[esi+000000E8],
00000005 |
// Comprueba el número de fichero transferidos |
:004E5D4C |
723D |
jb
004E5D8B |
// si es menos que cinco SALTA y continua la transferencia
|
:004E5D4E |
EB02 |
jmp
004E5D52 |
// salto incondicional para terminar la transferencia |
* Referenced by a (U)nconditional or (C)onditional Jump
at Address: |:004E5D43(C) |
:004E5D50 |
7C39 |
jl
004E5D8B |
|
* Referenced by a (U)nconditional or (C)onditional Jump
at Address: |:004E5D4E(U) |
:004E5D52 |
C60300 |
mov
byte
ptr
[ebx],
00 |
// pone un flag a 0 si hemos terminado |
:004E5D55 |
8D858CFEFFFF |
lea
eax,
dword
ptr
[ebp+FFFFFE8C] |
El análisis
de este código nos revela que efectivamente el flag
que hemos estado espiando es la clave del asunto, siempre
que la conexión continue se termina saltando a la
dirección 4E5D8B y cuando termina siempre se pasa
por 4E5D52. Apartir de aquí el camino está
claro, hacer que el valor en 50339C siempre sea <>0
(en mi ejemplo 1). Si continuamos la ejecución del
programa veremos que se transferiran todos y cada uno de
los archivos que hubieramos seleccionado ya que antes habiamos
cambiado el flag a 1.
La cuestión
ahora es cómo conseguir que el valor en 50339C sea
siempre igual a 1. Pues como bien he dicho antes, mediante
un injerto de código en el ejecutable original. Teóricamente
no podemos alterar el código para invertir los saltos
ya que el código no existe hasta que se descomprime,
pero la solución es más sencilla. Todo ejecutable
comprimido debe de descomprimirse, y en algún punto
cuando la descompresión finaliza se debe de saltar
al punto de entrada original del programa. La solución
es buscar este punto (donde se salta al punto de entrada
original), sustituir el salto allí presente por un
salto a la dirección donde coloquemos nuestro código,
que debería ser algo así::
mov
byte ptr [50339C], 01
y después
realizar el salto al punto de entrada original con algo
así:
jmp
dirección_punto_entrada_original
El problema
es que para realizar esto deberemos de disponer de espacio
adicional en la sección donde se encuentre el codigo
de descompresión, o en su defecto deberemos crear
una sección donde colocar nuestro código.
Pero antes de continuar vamos a buscar el punto de entrada
del ejecutable original, para ello deberemos desensamblar
el EXE comprimido (G6FTPSrv.EXE) con el W32Dasm e ir a su
punto de entrada haciendo click en el menu Goto/Program
EntryPoint. Veremos algo así:
:00586A70 |
60 |
pushad |
//
guarda los registros en la pila |
:00586A71 |
BE00305200 |
mov
esi,
00523000 |
// |
:00586A76 |
8DBE00E0EDFF |
lea
edi,
dword
ptr
[esi+FFEDE000] |
// |
:00586A7C |
57 |
push
edi |
// |
:00586A7D |
83CDFF |
or
ebp,
FFFFFFFF |
// |
:00586A80 |
EB10 |
jmp
00586A92 |
// salta |
:00586A82 |
90 |
nop |
:00586A83 |
90 |
nop |
:00586A84 |
90 |
nop |
:00586A85 |
90 |
nop |
:00586A86 |
90 |
nop |
:00586A87 |
90 |
nop |
La primera
instrucción que nos encontramos es muy típica
en los compresores de ejecutables ya que estos normalmente
guardan el estado del programa al iniciarse y luego lo restauran
antes de pasar el control al programa descomprimido. Esto
quiere decir que seguramente la rutina de descompresión
del UPX usará la instrucción inversa a pushad
(popad) para volver a obtener los valores originales de
los registros. Por lo tanto vamos a buscar esta instrucción
en el código que nos muestra el W32DAsm, iremos bajando
poco a poco hasta llegar a:
:00586BCC |
FF96947B1800 |
call
dword
ptr
[esi+00187B94] |
// |
* Referenced by a (U)nconditional or (C)onditional Jump
at Address: |:00586B94(C) |
:00586BD2 |
61 |
popad |
// Sacamos los registros de la pila |
:00586BD3 |
E9E8A5F7FF |
jmp
005011C0 |
// y saltamos al punto de entrada original |
:00586BD8 |
F06B5800 |
DWORD
00586BF0 |
// Esto son bytes sobrantes de la sección |
:00586BDC |
006C5800 |
DWORD
00586C00 |
// |
:00586BE0 |
D444 |
aam
(base68) |
// e intrucciones que nunca se ejecutarán |
:00586BE2 |
50 |
push
eax |
Como
podemos observar la teória a sido correcta en este
caso. lo cual no quiere decir que lo vaya a ser siempre,
ya que se hubieran podido sacar los registros de manera
manual, pero esta es la manera más fácil (así
es como piensan los programadores), por lo tanto tenemos
que el punto de entrada original esta en 5011C0, vemos que
nos sobran unos cuantos bytes para poder hacer nuestras
modificaciones. Si nos fijamos en la barra de estado del
W32Dasm veremos que el desplazamiento (offset) dentro del
archivo para la instrucción jmp 5011C0 está
la posición 63FD3. Vamos
a ver que sección comienza a partir de de esta posición.
Esto puede comprobarse mediante el ProcDump. Abrimos el
ProcDump, click en PE Editor, seleccionamos el EXE comprimido
y hacemos click en sections. Vemos tres secciones UPX0,
UPX1 y .rsrc lo que estamos buscando es el inicio de cada
sección dentro del archivo y esto ProcDump lo llama
"Raw Offset", vemos que las dos secciones UPX
comienzan en el mismo offset y que la .rsrc comienza en
el offset 64000. Por lo tanto sabemos que despues del salto
habra un espacio equivalente a 64000-63FD3 = 2D -> 45
bytes no utilizados, suficiente para añadir nuestro
injerto. Pero resulta que este espacio es utilizado por
el UPX y si lo utilizasemos el ejecutable no funcionaría
(lo he probado y me daba un error de memoría insuficiente).
La cosa se complica bastante ya que ahora necesitamos un
espacio adicional que no tenemos y para poder conseguirlo
la única solución es crear una nueva sección
en el ejecutable. La cosa sería bastante complicada
de hacer a mano por lo que yo he utilizado el programa Topo
v1.1 (gracias a Mr. Crimson de WKT) para crear una nueva
sección de 16 bytes de longitud, suficiente para
nuestros propósitos. Después de crear la nueva
sección con el Topo, este nos dirá la dirección
Virtual de inicio (en mi caso 589000) y el offset dentro
del ejecutable (en mi caso 65E00). La cosa ahora es un poco
más complicada ya que primero deberemos cambiar el
salto en 568BD3 (JMP 5011C0) por
JMP 589000 que es donde empieza
nuestra nueva sección, a partir de esta dirección
ensamblaremos las siguientes instrucciones.
mov
byte ptr [50339C], 01 // pone flag de registro a TRUE
jmp 5011C0 // Salta al punto de entrada original
Tal
y como se puede apreciar primero se establece el flag de
registro y luego se salta al punto de entrada original.
Ahora
tenemos que averiguar que opcodes corresponden a estas instrucciones.
Nada más sencillo que utilizar el SoftIce para realizar
las modificaciones y desde allí copiar los opcodes
generados. Para realizar esto necesitamos parar de nuevo
la ejecución del programa tal y como hicimos anteriormente
unsando un BPX en GetProcAddress. Repetimos el proceso y
cuando estemos en la ventana de SoftIce colocamos un breakpoint
sobre la dirección donde se encuentra el salto al
punto de entrada original, con:
BPX
586BD3
Antes
de continuar si nos fijamos veremos que al volver de la
función GetProcAddress, el código en el cual
nos hayamos está cerca de la dirección 586BD3
e incluso podremos ver el salto en la ventana de código
del SoftIce, esto es debido, a que como dije anteriormente
el UPX carga las direcciones de todas las funciones del
API que usa el programa una vez ha descomprimido las secciones,
concretamente estamos en el bucle que se encarga de esto.Pues
nada, desactivamos el breakpoint que teniamos sobre GetProcAddres
con BC 0 y continuamos la ejecución
con pulsando G. SoftIce volverá
activarse y estaremos sobre la línea de código
586BD3, el salto que buscabamos. Ahora vamos a modificar
el código para añadir nuestro injerto. Tecleamos:
A
586BD3
Esto
entrará en el ensamblador en línea del SoftIce
y nos permitira introducir nuestro código sobre la
dirección 586BD3. Ahora teclearemos cada una de las
instrucciones seguidas de un intro y al finalizar pulsaremos
ESC.
jmp
589000 + Intro
Ya tenemos
el código modificado, ahora vamos a ver cuales son
los opcodes correspondientes, pare ello volcaremos el código
como si de datos se tratara con:
d
586BD3
Ahora
veremos que en la ventana de datos nos aparecen los opcodes
que deben ser tal que así:
E9
28 24 00 00
Sabemos
que son 5 ya que es la resta entre la dirección 586BD3
(donde empieza nuestro código) y la dirección
donde empieza la instrucción siguiente al salto jmp
(586BD8). Pues vale, los copiamos para posteriormente modificar
el ejecutable.Ahora podemos tomar el salto pulsando F8 una
vez, ahora estaremos sobre la direcciíon 589000 y
veremos que donde debería haber códigos de
operación solo hay 'INVALID', esto es debido a que
hemos saltado a una sección diferente y al SoftIce
no le ha dado tiempo de procesar los opcodes, pulsaremos
F8 de nuevo y veremos que se ejecutará un NOP (esto
es debido a que el Topo rellena la sección con este
código de operación por defecto), ahora comenzaremos
a ensamblar las instrucciones.
A
589000
Esto
entrará en el ensamblador en línea del SoftIce
y nos permitira introducir nuestro código sobre la
dirección 586BD3. Ahora teclearemos cada una de las
instrucciones seguidas de un intro y al finalizar pulsaremos
ESC.
mov
byte ptr [50339c],1 + Intro
jmp 5011c0
+ Intro + ESC
Ya tenemos
el código modificado, ahora vamos a ver cuales son
los opcodes correspondientes, pare ello volcaremos el código
como si de datos se tratara con:
d
589000
Ahora
veremos que en la ventana de datos nos aparecen los opcodes
que deben ser tal que así:
90
C6 05 9C 33 50 00 01 E9 B3 81 F7 FF
Podemos
comprobar que el NOP (90) inicial está incluido,
por lo que ya nos va bien. Ahora podemos continuar con la
ejecución y veremos que ya no tenemos limitación
de upload y downloads.
Resumiendo
ya tenemos los datos necesarios para modificar el ejecutable.
En el
offset 65E00 (obtenido con el Topo) deberemos escribir con
el editor hexadecimal:
90
C6 05 9C 33 50 00 01 E9 B3 81 F7 FF -> Que corresponde
al NOP y al MOV BYTE PTR [50339C],1
En el
offset 63FD3 (obtenido con
el W32Dasm ) deberemos escribir con el editor hexadecimal:
E9
28 24 00 00 -> Que corresponde al jmp 589000
y podremos
comprobar que ya no tenemos limitación ninguna de
uploads ni de downloads. Ya tenemos el offset donde aplicar
el parche y los datos a cambiar, por último solo
queda hacer el parche para que la modificación sobre
el ejecutable sea definitiva. Para ello recomiendo utilizar
el WinPatch ya que el archivo parcheado es más grande
que el original. También existe otra solución
más sencilla que es utilizar un parcheador de procesos,
yo recomiendo el R!SC Process Patcher, de esta manera no
necesitariamos crear ningún parche que modifique
el archivo original.
|