HTML Injection
La inyección de HTML es una de las técnicas de Defacing, consiste en inyectar, mediante un formulario, código html con el fin de que se ejecute y se produsca un efecto "anormal" en la página.
Debe quedar claro que cualquier técnica de Defacing es una falta de ética, ningún webmaster merece que su sitio web sea modificado; además de que en varios países se considera un acto ilegal.
Existen un par de formas para lograr inyectar código html en una página, la que mejor manejo y conosco consiste en insertar un texto, en un campo de formulario, que modifique el código fuente de la página.
Para ello, el texto que se inserta en el campo (como puede ser un text) debe mostrarse tal cual en cualquier parte de la página. Esto ocurre en comentarios de blogs, tagboards, libros de visitas y demás, sitios en donde el texto que introduces se guarda en una Base de Datos y de ésta se extrae y muestra en la página para todos los usuarios que visiten el sitio.
Los programadores Web suelen desactivar el html en sus formularios, poner filtros, limpiar el código y cualquier cosa para evitar que sean defaceados; aún así se puede comprobar si la página es vulnerable; un método es introducir esto <> en todos los campos y se envían, en un caso normal estos símbolos no se visualizarán en pantalla pero si buscamos en el código fuente los campos que introducimos tendríamos que ver los "<>" en los valores vulnerables.
Un método más infalible es la simple práctica, enviar la inyección y ver si funciona o no.
Les pondré un ejemplo de un blog que, para el ejemplo, se hiso vulnerable. A mi me gusta usar el navegador Chrome por que permite inspeccionar el código HTML de cada objeto de la página. Podemos observar que el blog tiene un sistema de registro (simple) de usuarios y que el nick del usuario logeado se muestra normalmente:
En la imagen en nick "legender" se encuentra entre las etiquetas <font>y</font>. Entonces para hacer una inyección efectiva se realiza cerrando las etiquetas en las cuales se encuentra este valor.
Como los nicks se guardan en la Base de Datos, necesitamos registrar un nick tal que cierre la etiqueta e introdusca el código html que queramos, por ejemplo:
Aquí nuestro "nick" sería "fuckencio" y cerramos la etiqueta </font>, después hacemos una simple inyección de <h1>Hacked</h1> que insertará un titular cuando nos logeemos con éste nick.
Entonces registramos en nuevo usuario:
El usuario se registró ya en la B.D. Si notamos, el formulario nos arroja un warning debido a la sintaxis, ésto no obligatoriamente ocurre solo en ciertos casos.
Nos logeamos con el nuevo usuario, utilizando obviamente el nick completo con el código a insertar, recordemos que todo éste código llegó tal cual a la BD por lo que ese es nuestro nick completo:
Y como ven la página nos muestra como si nuestro nick fuera "fuckencio", pero debido a la inyección html nos muestra el titular "Hacked", lo cual no provoca realmente nada dañino pero muestra la efectividad de la inyección.
Ahora, poniéndonos en el lado del Webmaster, se debe saber el método para evitar éstas inyecciones; los métodos son muy sencillos debido a que existen ya funciones para éste tema. La primera es strip_tags("código a filtrar") ; lo que hace la función es eliminar las etiquetas html introducidas, o sea que si se introduce "<h1>hola</h1>" al pasar por esa función resultaría "hola".
La segunda función es htmlentities("código a filtrar") que lo que hace es mostrar el html como texto plano y el navegador no lo ejecutará; o sea que si se introduce "<h1>hola</h1>" se mostraría tal cual en el navegador "<h1>hola</h1>".
Esto es todo.
Me despido y recuerden: Ante todo la ¡ÉTICA!
domingo, 8 de enero de 2012
jueves, 24 de noviembre de 2011
[Hacking] Obtención de contraseñas
Por qué no puse robo? pues simplemente para disfrazar la intención, pero tómese en cuenta que es no solo ilegal, también una falta de ética el obtener la contraseña de un tercero (y usarla) sin su consentimiento; pero de igual manera pueden surgir eventos en los cuales se llegue a tal caso, no estoy yo aquí para juzgar los principios éticos de cada quien. Aun que prefiero que usen esta información con carácter informativo para seguridad propia.
Primeramente pienso que ésta es la segunda pregunta más hecha a google, justo después de la pregunta "¿Cómo hackear Messenger/facebook", claro está de que, a parte de que google no responde preguntas, no se encuentra JAMÁS una receta de cocina para obtener contraseñas y tampoco les daré una.
Es muy difícil realmente la garantía de robo de contraseñas, por que desde siempre la mayor parte la debe de poner el usuario victima (aun que no lo crean), y los métodos para que el usuario "caiga" depende de si se conoce a la víctima o no, todo esto ya tiene cabida en otro ámbito en el hacking: ingeniería social.
Les hablaré de 2 métodos usuales.
El primero, siendo el más sencillo, hacer que el usuario te envíe la contraseña directamente; claro que no así como suena, lo común es inducir al usuario a escribir sus datos en un formulario (que piensa que es seguro) que se conecta a tu servidor, al enviar los datos realmente te los envía a tí y no a donde el usuario cree que se envían. Un método muy a los MASTER es el defacing que consiste en alterar un formulario (de logeo principalmente) de una página legítima para que también te envíe a tí los datos que pasan por ella, la inyección SQL es muy habitual pero existen algunos métodos más.
Una segunda opción más viable son los fake's, éstos son imitaciones de páginas auténticas que pueden engañar al "usuario promedio" que inocentemente introduces sus datos para identificarse; por ejemplo, chequen ésta página: fake de facebook, como pueden notar es casi idéntica a la págin principal del facebook salvo unos detalles y que la barra de navegación es "http://gadel.webcindario.com/face/index.htm", ésta es inofensiva y que solo la hice como muestra pero puedo hacer una conexión a una Base de datos que introduzca los datos metidos en los campos y obtendré libremente las contraseñas de las pobres víctimas. Incluso si se dan cuenta, al hacer clic en "entrar" te envía a la página del Face como si te hubieras equivocado de contraseña o algo, un buen detalle para desorientar más.
Una segunda opción más común es el robo de contraseñas mediante la computadora víctima, ésto es más arriesgado pero más eficaz; consiste en instalar un programa en la computadora víctima que capture todo lo tecleado y lo envíe a un servidor en internet. Éstos programas son llamados "keylogger", su función es muy sencilla pero envían información detallada de todo lo escrito, cuándo y en qué aplicaciones/páginas se escribió tal cosa; obviamente son considerados como virus por el sistema y los antivirus, lo que dificulta la instalación de los mismos pero es más que conocido que éstas protecciones son fácilmente burlables: encriptando el programa, tumbando el antivirus antes de instalarlo, en fin...
Ya conocen 2 de los métodos más "funcionales" usados actualmente, como pueden ver es el usuario victima el último en ceder ante el atacante, es verdad que la seguridad total es inexistente ya que vulnerabilidades siempre van a existir, por ellos es bueno conocer las formas en que podemos ser atacados y evaluar nuestra propia seguridad ante tal situación.
Espero que ésto les pueda servir, cualquier pregunta pueden hacerla.
Primeramente pienso que ésta es la segunda pregunta más hecha a google, justo después de la pregunta "¿Cómo hackear Messenger/facebook", claro está de que, a parte de que google no responde preguntas, no se encuentra JAMÁS una receta de cocina para obtener contraseñas y tampoco les daré una.
Es muy difícil realmente la garantía de robo de contraseñas, por que desde siempre la mayor parte la debe de poner el usuario victima (aun que no lo crean), y los métodos para que el usuario "caiga" depende de si se conoce a la víctima o no, todo esto ya tiene cabida en otro ámbito en el hacking: ingeniería social.
Les hablaré de 2 métodos usuales.
El primero, siendo el más sencillo, hacer que el usuario te envíe la contraseña directamente; claro que no así como suena, lo común es inducir al usuario a escribir sus datos en un formulario (que piensa que es seguro) que se conecta a tu servidor, al enviar los datos realmente te los envía a tí y no a donde el usuario cree que se envían. Un método muy a los MASTER es el defacing que consiste en alterar un formulario (de logeo principalmente) de una página legítima para que también te envíe a tí los datos que pasan por ella, la inyección SQL es muy habitual pero existen algunos métodos más.
Una segunda opción más viable son los fake's, éstos son imitaciones de páginas auténticas que pueden engañar al "usuario promedio" que inocentemente introduces sus datos para identificarse; por ejemplo, chequen ésta página: fake de facebook, como pueden notar es casi idéntica a la págin principal del facebook salvo unos detalles y que la barra de navegación es "http://gadel.webcindario.com/face/index.htm", ésta es inofensiva y que solo la hice como muestra pero puedo hacer una conexión a una Base de datos que introduzca los datos metidos en los campos y obtendré libremente las contraseñas de las pobres víctimas. Incluso si se dan cuenta, al hacer clic en "entrar" te envía a la página del Face como si te hubieras equivocado de contraseña o algo, un buen detalle para desorientar más.
Una segunda opción más común es el robo de contraseñas mediante la computadora víctima, ésto es más arriesgado pero más eficaz; consiste en instalar un programa en la computadora víctima que capture todo lo tecleado y lo envíe a un servidor en internet. Éstos programas son llamados "keylogger", su función es muy sencilla pero envían información detallada de todo lo escrito, cuándo y en qué aplicaciones/páginas se escribió tal cosa; obviamente son considerados como virus por el sistema y los antivirus, lo que dificulta la instalación de los mismos pero es más que conocido que éstas protecciones son fácilmente burlables: encriptando el programa, tumbando el antivirus antes de instalarlo, en fin...
Ya conocen 2 de los métodos más "funcionales" usados actualmente, como pueden ver es el usuario victima el último en ceder ante el atacante, es verdad que la seguridad total es inexistente ya que vulnerabilidades siempre van a existir, por ellos es bueno conocer las formas en que podemos ser atacados y evaluar nuestra propia seguridad ante tal situación.
Espero que ésto les pueda servir, cualquier pregunta pueden hacerla.
martes, 1 de noviembre de 2011
Eliminar los accesos directos de la USB creados por virus
Es muy sencillo encontrarse en los Cybers con el molesto virus que te esconde tus carpetas reales y te crea accesos directos de éstas.
La manera de eliminar esos archivitos y volver a mostrar los tuyos es mediante un sencillo escript echo en batch; lo creas, lo guardas en tu USB y cuando tengas éstos virus lo ejecutas.
Lo primero es abrir el bloc de notas.
Luego escribimos los siguientes comandos:
del *.ink
attrib -s -h -r /d /s
Luego lo guardamos como un archivo pero con extensión .bat; o sea que si le queremos poner "mata_virus_chafas" lo guardamos como "mata_virus_chafas.bat".
Se creará un archivo del sistema y lo copiamos a nuestra memoria.
Y así, cada vez que tengamos éste problema, le damos doble clic al archivito y solo pondrá tu memoria tal cual estaba. En ocasiones llega a tardar algunos segundos, todo depende de lo llena que se encuentre.
Esto será todo ;)
La manera de eliminar esos archivitos y volver a mostrar los tuyos es mediante un sencillo escript echo en batch; lo creas, lo guardas en tu USB y cuando tengas éstos virus lo ejecutas.
Lo primero es abrir el bloc de notas.
Luego escribimos los siguientes comandos:
del *.ink
attrib -s -h -r /d /s
Luego lo guardamos como un archivo pero con extensión .bat; o sea que si le queremos poner "mata_virus_chafas" lo guardamos como "mata_virus_chafas.bat".
Se creará un archivo del sistema y lo copiamos a nuestra memoria.
Y así, cada vez que tengamos éste problema, le damos doble clic al archivito y solo pondrá tu memoria tal cual estaba. En ocasiones llega a tardar algunos segundos, todo depende de lo llena que se encuentre.
Esto será todo ;)
[Computación-Windows]Agregar un programa al iniciar windows
Puede ser que, por varias razones, uno quiera lanzar un programa, aplicación o archivo al iniciar windows (logearnos).
Para ello hay varias formas, una de ellas es conseguirse programas que lo hagan por nosotros; yo no tengo ni conosco alguno, pero se que existen. Pero hay formas manuales y más sencillas de hacerlo, sin necesidad de instalar nada.
Primero tenemos la forma sencilla, consiste en poner un acceso directo del programa en la carpeta de inicio de windows. Para ello ve a esta ruta en tu explorador:
C:\Documents and Settings\%Username%\Menú Inicio\Programas\Inicio
Si tal ruta no existe o no la encuentras usaremos el método 2: manipularemos el registro de windows para que se ejecute directamente el programa :)
Se puede hacer de manera gráfica o mediante comandos, de manera gráfica será mediante el editor del registro.
Presionamos control + windows (ctrl + windows).
Escribiremos "regedit" en el ejecutar.
Nos aparecerá el editor de registro de windows:
El panel de la izquierda muestra las direcciones (claves) del registro. Entonces buscaremos la siguiente dirección:
HKEY_LOCAL-MACHINE -> SOFTWARE -> MICROSOFT -> WINDOWS -> CurrentVersion -> Run
Damos clic derecho en el panel de la derecha (ese espacio enorme) y seleccionamos muevo-> "valor de cadena".
Nos aparecerá un nuevo valor, lo nombramos a nuestro antojo y le damos enter. Luego doble clic y nos aparecerá una barra con las propiedades del valor.
En la barra que dice "información del valor" le escribimos la ruta del archivos que queremos se ejecute al iniciar windows y le damos aceptar.
Lísto!!! ya se ejecutará el archivo/programa o lo que sea al iniciar windows.
Ahora lo haremos de ma forma PRO:
presionamos control + windows (ctrl + windows)
en ejecutar le escribimos "CMD" y enter.
Nos aparecerá la consola de windows:
Ahora solo es cuestión de escribir el siguiente comando:
add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v "nombre_del_valor" /d "dirección_del_archivo"
En nombre del valor solo le ponen un nombre para que identifiquen qué clave están agregando.
dirección el archivo es precisamente la dirección del archivo que quieren ejecutar.
Le dan a Enter, les pedirá confirmación, escriban 's' y enter otra vez.
Listo, en menos pasos y más efectivo :P
Para ello hay varias formas, una de ellas es conseguirse programas que lo hagan por nosotros; yo no tengo ni conosco alguno, pero se que existen. Pero hay formas manuales y más sencillas de hacerlo, sin necesidad de instalar nada.
Primero tenemos la forma sencilla, consiste en poner un acceso directo del programa en la carpeta de inicio de windows. Para ello ve a esta ruta en tu explorador:
C:\Documents and Settings\%Username%\Menú Inicio\Programas\Inicio
Si tal ruta no existe o no la encuentras usaremos el método 2: manipularemos el registro de windows para que se ejecute directamente el programa :)
Se puede hacer de manera gráfica o mediante comandos, de manera gráfica será mediante el editor del registro.
Presionamos control + windows (ctrl + windows).
Escribiremos "regedit" en el ejecutar.
Nos aparecerá el editor de registro de windows:
El panel de la izquierda muestra las direcciones (claves) del registro. Entonces buscaremos la siguiente dirección:
HKEY_LOCAL-MACHINE -> SOFTWARE -> MICROSOFT -> WINDOWS -> CurrentVersion -> Run
Damos clic derecho en el panel de la derecha (ese espacio enorme) y seleccionamos muevo-> "valor de cadena".
Nos aparecerá un nuevo valor, lo nombramos a nuestro antojo y le damos enter. Luego doble clic y nos aparecerá una barra con las propiedades del valor.
En la barra que dice "información del valor" le escribimos la ruta del archivos que queremos se ejecute al iniciar windows y le damos aceptar.
Lísto!!! ya se ejecutará el archivo/programa o lo que sea al iniciar windows.
Ahora lo haremos de ma forma PRO:
presionamos control + windows (ctrl + windows)
en ejecutar le escribimos "CMD" y enter.
Nos aparecerá la consola de windows:
Ahora solo es cuestión de escribir el siguiente comando:
add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v "nombre_del_valor" /d "dirección_del_archivo"
En nombre del valor solo le ponen un nombre para que identifiquen qué clave están agregando.
dirección el archivo es precisamente la dirección del archivo que quieren ejecutar.
Le dan a Enter, les pedirá confirmación, escriban 's' y enter otra vez.
Listo, en menos pasos y más efectivo :P
lunes, 31 de octubre de 2011
[Programación] Simulador de gestor de memoria
Vale programadores, aquí hay una guía de cómo pueden simular un gestor de memoria.
Primero que nada ya deberían tener programada al menos una de las políticas para el gestor de procesos, en el cual deben tener una estructura (array, cola, pila, arbol, etc) en dónde guardan los procesos en pausa (ya se inició su tiempo de ejecución pero no están precisamente en ejecución).
Si ya tienen una política así sáltense casi hasta el final, si no es así les echaré una mano ;)
Ya está la base para la política FCFS (Primero en entrar, primer en ser servido) justo AQUÍ; parece que todo está explicado más o menos decente (Comprendan que lo escribí hace como 1 mes y en 1 hora...) pero como se ve, en esta política no contemplé que existiera una estructura para especificar qué procesos están en la memoria (en espera de ser ejecutados) y cuales no; tendremos que crear una y lo ideal es una cola... espero por su bien que recuerden cómo es una cola, si no es así pues a googlear. Vale yo encontré estos 2 sitios que les pueden servir:
Crear clase cola en java
Colas en java
Les puse en java por que supongo que allí lo harán... y por que no les voy a poner en C#, verdad?
Ahora, en ésta cola iremos metiendo los procesos que hayan tanto llegado su tiempo de ejecución como los que quepan en la memoria (o sea que deben cumplir las dos condiciones). Así, cada vez que un proceso se ejecuta, metemos a ésta cola el (los) procesos que cumplen estas condiciones y ya será de ésta cola que sacaremos los procesos a ejecución, vale?
Primero hay que modificar la clase proceso para que tengan un valor para el espacio en memoria (por ejemplo int espacio;)
La memoria puede ser un simple arreglo de x espacios (que será el espacio de la memoria), y si un proceso ocupa 5 de espacio, entonces ocupará 5 espacios o cuadritos del arreglo memoria. ¿Cómo indicar que un espacio del arreglo está ocupado por una parte de un proceso? Pues hay muchas alternativas, una de ellas es que el arreglo memorial sea del tipo Proceso y que apunte al proceso que le ocupa, así si un espacio está libre tendrá un valor null, sino es así tendrá un puntero al proceso (o sea no será null); otro es que sea del tipo string y que guarde el nombre del proceso... en fin ustedes sabrán como darle originalidad al programa.
Ahora explicaré algo, los procesos que están en la cola serán los mismos que están en la memoria, la cuestión es que en la memoria se debe representar la ubicación y el espacio ocupado por cada proceso (tanto en gestión segmentada y paginada).
Bueno, ya teniendo la memoria (el arreglo memoria) hecho, necesitamos controlar los procesos que entran y salen de ella; para ello crearemos funciones.
Primero las funciones para ver si un proceso puede caber en la memoria (mmm... me refiero a checar si cabe en la cola, si no cabe en la memoria pues no entrará en la cola).
Para al segmentada es muy sencillo, solo checamos los espacios de la memoria libres y si son iguales o más que el tamaño del proceso entonces va para adentro, sino, pues no :P
public boolean cabe(int tamañoDelProceso)
{
int espacios=0;
for(int i=0;i<memoria.lenght;i++)
{
if(memoria[i]==null) //Suponiendo el caso de que aputámos al proceso que ocupa la memoria
{
espacios++;
}
}
if(espacios>=tamañoDelProceso)
{
return true;
}
else
{
return false;
}
}
Para la paginada es muy parecido, sólo que en este caso es necesario determinar de cuántos espacios será la paginación (debe ser un divisor entero del tamaño de la memoria, esto es si la memoria es de 30 espacios la paginación puede ser de 3,5 o 6); de allí (suponiendo que la paginación es de 6) sólo buscamos los espacios de 6 en 6 y ver si están libres, si lo están es obvio que los otros 5 espacios adyacentes estarán libres; sacamos otra vez el total de espacios libres y hacemos el mismo procedimiento.
public boolean cabePaginada(int tamañoDelProceso)
{
int espacios=0;
for(int i=0;i<memoria.lenght;i+=6)
{
if(memoria[i]==null) //Suponiendo el caso de que aputámos al proceso que ocupa la memoria
{
espacios++;
}
}
if(espacios*6>=tamañoDelProceso)
{
return true;
}
else
{
return false;
}
}
fácil, no?
Ahora a meterlos. Para la segmentada (como siempre) será sencillo, sólo hay que meter el proceso en tantos huecos espacios libres como espacio ocupe éste proceso. O sea que si el proceso ocupa 5 espacios entonces lo meteremos en 5 espacios libres.
public void meter(Proceso proceso)
{
int espacios=0;
for(int i=0;i<memoria.length;i++)
{
if(memoria[i]==null & espacios<proceso.espacio)
{
memoria[i]=proceso;
espacios++;
}
}
}
Para la paginada necesitamos avanzar de tantos espacios como la paginación de nuestra memoria (en este caso de 6 en 6), buscar si ése espacio está libre y meter allí y en los 5 espacios siguientes el proceso, claro que hay que cuidar no ocupar espacios de más.
public void meterPaginada(Proceso proceso)
{
int espacios=0;
for(int i=0;i<memoria.length;i++)
{
if(memoria[i]==null & espacios<proceso.espacio)
{
for(j=0;j<6;j++)
{
if(espacios<proceso.espacio)
{
memoria[i+j]=proceso;
espacios++;
}
}
}
}
}
Y para sacar los procesos de la memoria, o sea cuando se terminaron de ejecutar ése proceso, es lo mismo para ambos métodos, sólo buscamos por toda la memoria el proceso que vamos a sacar, y cuando lo encontremos (en todos los espacios que ocupa) ponemos es espacio como null.
public void sacar(Proceso proceso)
{
for(int i=0;i<memoria.lenght;i++)
{
if(memoria[i]==proceso)
{
memoria[i]=null;
}
}
}
Hasta aquí sería todo lo necesario para construir el programa, ¿Cuándo usar las funciones? pues cuando chequen que procesos se van meter a la cola usen primero el que checa si cabe o no; si cabe usen el de meter en la memoria y también lo meten en la cola. Y cando un proceso pase a ejecución y termine (solo hasta que termine) usan el de sacar y también lo sacan de la cola. Recuerden que deben hacer su método para que les imprima el estado de la memoria.
Vale, espero y lo entiendan ya que me lo chuté en 23 minutos de la media noche.
Nota, yo no usé el de FCFS para éste ejercicio, usé el RR pero es más complejo de explicar y ya tenía éste escrito, si en algo me salté (espero que no) para que funcione ya chéquenle ustedes...
SALUDOS
Primero que nada ya deberían tener programada al menos una de las políticas para el gestor de procesos, en el cual deben tener una estructura (array, cola, pila, arbol, etc) en dónde guardan los procesos en pausa (ya se inició su tiempo de ejecución pero no están precisamente en ejecución).
Si ya tienen una política así sáltense casi hasta el final, si no es así les echaré una mano ;)
Ya está la base para la política FCFS (Primero en entrar, primer en ser servido) justo AQUÍ; parece que todo está explicado más o menos decente (Comprendan que lo escribí hace como 1 mes y en 1 hora...) pero como se ve, en esta política no contemplé que existiera una estructura para especificar qué procesos están en la memoria (en espera de ser ejecutados) y cuales no; tendremos que crear una y lo ideal es una cola... espero por su bien que recuerden cómo es una cola, si no es así pues a googlear. Vale yo encontré estos 2 sitios que les pueden servir:
Crear clase cola en java
Colas en java
Les puse en java por que supongo que allí lo harán... y por que no les voy a poner en C#, verdad?
Ahora, en ésta cola iremos metiendo los procesos que hayan tanto llegado su tiempo de ejecución como los que quepan en la memoria (o sea que deben cumplir las dos condiciones). Así, cada vez que un proceso se ejecuta, metemos a ésta cola el (los) procesos que cumplen estas condiciones y ya será de ésta cola que sacaremos los procesos a ejecución, vale?
Primero hay que modificar la clase proceso para que tengan un valor para el espacio en memoria (por ejemplo int espacio;)
La memoria puede ser un simple arreglo de x espacios (que será el espacio de la memoria), y si un proceso ocupa 5 de espacio, entonces ocupará 5 espacios o cuadritos del arreglo memoria. ¿Cómo indicar que un espacio del arreglo está ocupado por una parte de un proceso? Pues hay muchas alternativas, una de ellas es que el arreglo memorial sea del tipo Proceso y que apunte al proceso que le ocupa, así si un espacio está libre tendrá un valor null, sino es así tendrá un puntero al proceso (o sea no será null); otro es que sea del tipo string y que guarde el nombre del proceso... en fin ustedes sabrán como darle originalidad al programa.
Ahora explicaré algo, los procesos que están en la cola serán los mismos que están en la memoria, la cuestión es que en la memoria se debe representar la ubicación y el espacio ocupado por cada proceso (tanto en gestión segmentada y paginada).
Bueno, ya teniendo la memoria (el arreglo memoria) hecho, necesitamos controlar los procesos que entran y salen de ella; para ello crearemos funciones.
Primero las funciones para ver si un proceso puede caber en la memoria (mmm... me refiero a checar si cabe en la cola, si no cabe en la memoria pues no entrará en la cola).
Para al segmentada es muy sencillo, solo checamos los espacios de la memoria libres y si son iguales o más que el tamaño del proceso entonces va para adentro, sino, pues no :P
public boolean cabe(int tamañoDelProceso)
{
int espacios=0;
for(int i=0;i<memoria.lenght;i++)
{
if(memoria[i]==null) //Suponiendo el caso de que aputámos al proceso que ocupa la memoria
{
espacios++;
}
}
if(espacios>=tamañoDelProceso)
{
return true;
}
else
{
return false;
}
}
Para la paginada es muy parecido, sólo que en este caso es necesario determinar de cuántos espacios será la paginación (debe ser un divisor entero del tamaño de la memoria, esto es si la memoria es de 30 espacios la paginación puede ser de 3,5 o 6); de allí (suponiendo que la paginación es de 6) sólo buscamos los espacios de 6 en 6 y ver si están libres, si lo están es obvio que los otros 5 espacios adyacentes estarán libres; sacamos otra vez el total de espacios libres y hacemos el mismo procedimiento.
public boolean cabePaginada(int tamañoDelProceso)
{
int espacios=0;
for(int i=0;i<memoria.lenght;i+=6)
{
if(memoria[i]==null) //Suponiendo el caso de que aputámos al proceso que ocupa la memoria
{
espacios++;
}
}
if(espacios*6>=tamañoDelProceso)
{
return true;
}
else
{
return false;
}
}
fácil, no?
Ahora a meterlos. Para la segmentada (como siempre) será sencillo, sólo hay que meter el proceso en tantos huecos espacios libres como espacio ocupe éste proceso. O sea que si el proceso ocupa 5 espacios entonces lo meteremos en 5 espacios libres.
public void meter(Proceso proceso)
{
int espacios=0;
for(int i=0;i<memoria.length;i++)
{
if(memoria[i]==null & espacios<proceso.espacio)
{
memoria[i]=proceso;
espacios++;
}
}
}
Para la paginada necesitamos avanzar de tantos espacios como la paginación de nuestra memoria (en este caso de 6 en 6), buscar si ése espacio está libre y meter allí y en los 5 espacios siguientes el proceso, claro que hay que cuidar no ocupar espacios de más.
public void meterPaginada(Proceso proceso)
{
int espacios=0;
for(int i=0;i<memoria.length;i++)
{
if(memoria[i]==null & espacios<proceso.espacio)
{
for(j=0;j<6;j++)
{
if(espacios<proceso.espacio)
{
memoria[i+j]=proceso;
espacios++;
}
}
}
}
}
Y para sacar los procesos de la memoria, o sea cuando se terminaron de ejecutar ése proceso, es lo mismo para ambos métodos, sólo buscamos por toda la memoria el proceso que vamos a sacar, y cuando lo encontremos (en todos los espacios que ocupa) ponemos es espacio como null.
public void sacar(Proceso proceso)
{
for(int i=0;i<memoria.lenght;i++)
{
if(memoria[i]==proceso)
{
memoria[i]=null;
}
}
}
Hasta aquí sería todo lo necesario para construir el programa, ¿Cuándo usar las funciones? pues cuando chequen que procesos se van meter a la cola usen primero el que checa si cabe o no; si cabe usen el de meter en la memoria y también lo meten en la cola. Y cando un proceso pase a ejecución y termine (solo hasta que termine) usan el de sacar y también lo sacan de la cola. Recuerden que deben hacer su método para que les imprima el estado de la memoria.
Vale, espero y lo entiendan ya que me lo chuté en 23 minutos de la media noche.
Nota, yo no usé el de FCFS para éste ejercicio, usé el RR pero es más complejo de explicar y ya tenía éste escrito, si en algo me salté (espero que no) para que funcione ya chéquenle ustedes...
SALUDOS
lunes, 26 de septiembre de 2011
[Programación] Pseudo Ordenamiento de colas
EN un trabajo de la escuela tuve la "maravillosa" idea de usar una cola para el manejo de objetos. En su primera implementación tuvo éxito, pero después tuve la necesidad de usar la misma cola pero con los elementos ordenados de menor a mayor en base a cierto atributo... ¿Cómo hago eso sin alterar el funcionamiento de la cola? Bueno, pensé que si implementaba un método de ordenamiento de la cola y lo mandaba a llamar solo cuando necesitaba que la cola esté ordenada; justo de aquí surgió el verdadero problema: ¿Cómo ordenar una cola? Ya que el inicio de la cola no es forzosamente la posición 0 ni la posición final es la posición [tamaño_del_arreglo - 1]; puede empezar en cualquier posición y terminar en otra posición cualquiera y éstas posiciones varían durante toda la ejecución del programa. Entonces?
Es muy probable que se inventen millones de métodos para resolver este problema (dije probable); pero justo se me vino a la idea de que si necesito sacar los elementos en un orden, no es rotundamente necesario tener ordenada la cola, solo asegurarme que el objeto que voy a sacar es el más bajo (o más alto, según las necesidades) de la cola, ésto me simplifica muchas operaciones.
Bueno, comúnmente nosotros tenemos el método de sacar un objeto de la cola de la siguiente manera:
public Objeto sacarCola()
{
Objeto a;
if(delante<array.length-1)
{
delante++;
}
else
{
delante =0;
}
a=array[delante]; return a;
}
Vale, es sencillo y práctico, pero con unas cuantas correcciones se puede obtener una ilusión de ordenamiento de la cola para asegurarse de siempre sacar el objeto menor de la cola en cada vez.
Mi lógica es asegurarme en que el objeto en la posición delante sea el menor, de no ser así buscar el objeto que le sea menor y al final, que esté seguro de obtener el menor objeto, solo intercambio las posiciones del objeto menor con el del objeto en la posición delante.
Para lo anterior solo necesito hacer un recorrido desde el inicio del arreglo hasta el final y buscar cuál objeto es el menor de la cola.
Ahora, también es necesario no tomar en cuenta a los objetos que se suponen ya no deben estar en la cola (ésto por que es muy recurrido a no eliminarlos realmente de las cola, solo se excluyen). Ésto se arregla con que al sacar un objeto, lo ponga como NULL en la cola.
Mi algoritmo termina siendo el siguiente en un segundo método de sacar:
public Objeto sacarColaOrdenada()
{
int referencia = delante;
for(int i =0;i<array.length;i++)
{
if(array[i]!=NULL)
{
if(array[i]<array[referencia]
{
referencia = i;
}
}
}
Objeto intercambio;
intercambio = array[delante];
array[delante] = array[referencia]
array[referencia] = intercambio;
Objeto a;
a=array[delante];
array[delante]=null;
Es muy probable que se inventen millones de métodos para resolver este problema (dije probable); pero justo se me vino a la idea de que si necesito sacar los elementos en un orden, no es rotundamente necesario tener ordenada la cola, solo asegurarme que el objeto que voy a sacar es el más bajo (o más alto, según las necesidades) de la cola, ésto me simplifica muchas operaciones.
Bueno, comúnmente nosotros tenemos el método de sacar un objeto de la cola de la siguiente manera:
public Objeto sacarCola()
{
Objeto a;
if(delante<array.length-1)
{
delante++;
}
else
{
delante =0;
}
a=array[delante]; return a;
}
Vale, es sencillo y práctico, pero con unas cuantas correcciones se puede obtener una ilusión de ordenamiento de la cola para asegurarse de siempre sacar el objeto menor de la cola en cada vez.
Mi lógica es asegurarme en que el objeto en la posición delante sea el menor, de no ser así buscar el objeto que le sea menor y al final, que esté seguro de obtener el menor objeto, solo intercambio las posiciones del objeto menor con el del objeto en la posición delante.
Para lo anterior solo necesito hacer un recorrido desde el inicio del arreglo hasta el final y buscar cuál objeto es el menor de la cola.
Ahora, también es necesario no tomar en cuenta a los objetos que se suponen ya no deben estar en la cola (ésto por que es muy recurrido a no eliminarlos realmente de las cola, solo se excluyen). Ésto se arregla con que al sacar un objeto, lo ponga como NULL en la cola.
Mi algoritmo termina siendo el siguiente en un segundo método de sacar:
public Objeto sacarColaOrdenada()
{
int referencia = delante;
for(int i =0;i<array.length;i++)
{
if(array[i]!=NULL)
{
if(array[i]<array[referencia]
{
referencia = i;
}
}
}
Objeto intercambio;
intercambio = array[delante];
array[delante] = array[referencia]
array[referencia] = intercambio;
Objeto a;
a=array[delante];
array[delante]=null;
if(delante<array.length-1)
{
delante++;
}
else
{
delante =0;
}
return a;
}
Parece complicado? Explico:
Lo que hago en el primer bloque (el for) es posicionar un indice de referencia (que servirá para indicar el supuesto objeto más bajo de valor) inicialmente en la posición delante. Luego con la variable i voy checando cada posición no nula (no nula por que más adelante, a la hora de sacar el objeto, lo elimino del array) si ésta posición es menor a la referencia, de ser así cambio la posición de referencia por la del índice y así me sigo hasta que termine el array.
En el segundo bloque solo hago el intercambio de objetos, el objeto en la posición delante se va a la posición que apunta referencia y viceversa.
La tercera parte es casi igual al método anterior de sacarCola salvo el detalle de que pongo como NULL la posición del objeto que voy a sacar para después no tomarlo en cuenta en próximas llamadas a la función.
Bueno, éste es mi método de Pseudo ordenamiento de colas, resulta económico para el procesador y versátil en cuestiones en donde no es realmente necesario tener la cola ordenada en todo momento.
{
delante++;
}
else
{
delante =0;
}
return a;
}
Parece complicado? Explico:
Lo que hago en el primer bloque (el for) es posicionar un indice de referencia (que servirá para indicar el supuesto objeto más bajo de valor) inicialmente en la posición delante. Luego con la variable i voy checando cada posición no nula (no nula por que más adelante, a la hora de sacar el objeto, lo elimino del array) si ésta posición es menor a la referencia, de ser así cambio la posición de referencia por la del índice y así me sigo hasta que termine el array.
En el segundo bloque solo hago el intercambio de objetos, el objeto en la posición delante se va a la posición que apunta referencia y viceversa.
La tercera parte es casi igual al método anterior de sacarCola salvo el detalle de que pongo como NULL la posición del objeto que voy a sacar para después no tomarlo en cuenta en próximas llamadas a la función.
Bueno, éste es mi método de Pseudo ordenamiento de colas, resulta económico para el procesador y versátil en cuestiones en donde no es realmente necesario tener la cola ordenada en todo momento.
jueves, 22 de septiembre de 2011
Política FCFS [Primero en entrar, primero en ser servido]
Esta política resulta ser la más sencilla, ya que consiste de 3 pasos:
1.- Ordenar los procesos por orden de llegada
2.- Resolver los instantes de finalización de los procesos
3.- Obtener los valores T,E,I con las fórmulas de esta política.
Ahora, debo aclarar que yo tengo mi clase de Procesos de esta manera:
class Proceso
{
public double instanteEntrada, tiempoEjecucion, t, e, i,instanteFinalizacion,tiempoEjecutado;
int prioridad;
public char[] nombre = new char[5];
public Boolean dormido = true;
public Proceso(char[] nombre, double instanteEntrada, double tiempoEjecucion,int prioridad)
{
this.nombre = nombre;
this.instanteEntrada = instanteEntrada;
this.tiempoEjecucion = tiempoEjecucion;
this.t = 0;
this.e = 0;
this.i = 0;
this.instanteFinalizacion=0;
this.prioridad = prioridad;
}
}
Como ven, al crear un proceso recibe los valores: nombre, instanteEntrada, tiempoEjecucion y prioridad.
Ahora, tomando en cuenta que el instante de entrada es un número, resulta sencillo meter los procesos a un array y ordenarlos de menor a mayor de acuerdo a su instante de Entrada.
Proceso[] procesos = new Proceso(numero_de_procesos);
y voy agregando los procesos al arreglo:
procesos[0]= proceso;
procesos[1]= proceso2;
procesos[2]= proceso3;
..... //indefinidamente;
Luego se hace un ordenamiento con el método burbuja:
for(int i=0;i<procesos.Length-1;i++) //procesos.Lenght es la longitud del array en donde estan los procesos
{
for(int j=i+1;j<procesos.Length;j++)
{
Proceso procesoTemp; //creo un objeto para guardar temporalmente los procesos
if(procesos[j].instanteEntrada<procesos[i].instanteEntrada)
{
procesoTemp = procesos[j];
procesos[j]=procesos[i];
procesos[i]=procesoTemp;
}
}
}
Así tenemos en la posición 0 el primer proceso en entrar, y en la ultima posicion el ultimo proceso en entrar.
Falta calcular el instante de finalización:
Para la posición 0: instanteFinalizacion= instanteEntrada + tiempoEjecucion.
Para las siguientes posiciones
Si el instante de finalización del proceso anterior es igual o superior al instante de inicialización del proceso actual:
instanteFinalizacion = (instanteFinalización_procesoAnterior) + tiempoEjecución
Si no es así (si el proceso anterior acabó antes de que iniciara el actual)
instanteFinalización = (instanteEntrada + tiempoEjecución)
El resto de los valores (T,E,I) se calculan a partir de estos tres valores obtenidos.
Siento no ser más específico pero estoy con el tiempo encima
1.- Ordenar los procesos por orden de llegada
2.- Resolver los instantes de finalización de los procesos
3.- Obtener los valores T,E,I con las fórmulas de esta política.
Ahora, debo aclarar que yo tengo mi clase de Procesos de esta manera:
class Proceso
{
public double instanteEntrada, tiempoEjecucion, t, e, i,instanteFinalizacion,tiempoEjecutado;
int prioridad;
public char[] nombre = new char[5];
public Boolean dormido = true;
public Proceso(char[] nombre, double instanteEntrada, double tiempoEjecucion,int prioridad)
{
this.nombre = nombre;
this.instanteEntrada = instanteEntrada;
this.tiempoEjecucion = tiempoEjecucion;
this.t = 0;
this.e = 0;
this.i = 0;
this.instanteFinalizacion=0;
this.prioridad = prioridad;
}
}
Como ven, al crear un proceso recibe los valores: nombre, instanteEntrada, tiempoEjecucion y prioridad.
Ahora, tomando en cuenta que el instante de entrada es un número, resulta sencillo meter los procesos a un array y ordenarlos de menor a mayor de acuerdo a su instante de Entrada.
Proceso[] procesos = new Proceso(numero_de_procesos);
y voy agregando los procesos al arreglo:
procesos[0]= proceso;
procesos[1]= proceso2;
procesos[2]= proceso3;
..... //indefinidamente;
Luego se hace un ordenamiento con el método burbuja:
for(int i=0;i<procesos.Length-1;i++) //procesos.Lenght es la longitud del array en donde estan los procesos
{
for(int j=i+1;j<procesos.Length;j++)
{
Proceso procesoTemp; //creo un objeto para guardar temporalmente los procesos
if(procesos[j].instanteEntrada<procesos[i].instanteEntrada)
{
procesoTemp = procesos[j];
procesos[j]=procesos[i];
procesos[i]=procesoTemp;
}
}
}
Así tenemos en la posición 0 el primer proceso en entrar, y en la ultima posicion el ultimo proceso en entrar.
Falta calcular el instante de finalización:
Para la posición 0: instanteFinalizacion= instanteEntrada + tiempoEjecucion.
Para las siguientes posiciones
Si el instante de finalización del proceso anterior es igual o superior al instante de inicialización del proceso actual:
instanteFinalizacion = (instanteFinalización_procesoAnterior) + tiempoEjecución
Si no es así (si el proceso anterior acabó antes de que iniciara el actual)
instanteFinalización = (instanteEntrada + tiempoEjecución)
El resto de los valores (T,E,I) se calculan a partir de estos tres valores obtenidos.
Siento no ser más específico pero estoy con el tiempo encima
Suscribirse a:
Entradas (Atom)






