Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - [L]ord [R]NA

#1
 Aqui les traigo una clase para colocar mecanismos contra Debuggers en nuestros codigos de una forma rapida y sencilla. Los metodos estan claros y simplemente se deben utilizar depende el metodo que deseemos utilizar para detectar los Debuggers. Estan integrados los metodos de deteccion a traves del PEB, del NTGlobal, utilizando los nombres comunes de los procesos de OllyDBG, IDA Pro y Win32DASM. En el metodo TimeStamp deben verificar antes de dar un valor el tiempo que dura la funcion que toma como segundo parametro. Tenemos otro metodo que es el metodo Protect, el cual toma una funcion y verifica con los tres primeros metodos de deteccion para verificar que no estan siendo Debuggeados, de caso contrario ejecutara una funcion que toma como parametro.

Como lo prometido es deuda aqui van los codigos:

Código (cpp) [Seleccionar]
#ifndef __ClsAntiDebug__
#define __ClsAntiDebug__
#include <windows.h>
#include <tlhelp32.h>

class ClsAntiDebug
{
private:
bool Debugged;
public:
ClsAntiDebug();
void __declspec() PEBDebug();
void __declspec() NTGlobalDebug();
void __declspec() DebuggerActive();
void __declspec() TimeStamp(int time, void *func);
void Protect(void *func);
bool IsDebugged();
};
#endif


Aqui debajo estan las declaraciones de los metodos en la clase:

Código (cpp) [Seleccionar]
#include "AntiDebug.h"

ClsAntiDebug::ClsAntiDebug()
{
this->Debugged=false;
}

bool ClsAntiDebug::IsDebugged()
{
return this->Debugged;
}

void __declspec() ClsAntiDebug::PEBDebug()
{
__asm
{
_PEBLoop:
push 500
call dword ptr ds:[Sleep]
xor edx, edx
mov dl,0x30
mov esi, fs:[edx]
movzx eax, byte ptr[esi+2]
dec eax
jne _PEBLoop
inc eax
}
this->Debugged = true;
}

void __declspec() ClsAntiDebug::NTGlobalDebug()
{
__asm
{
_NTLoop:
push 500
call dword ptr ds:[Sleep]
xor edx, edx
mov dl,0x30
mov esi, fs:[edx]
movzx eax, byte ptr[esi+0x68]
and eax,eax
je _NTLoop
xor eax,eax
inc eax
}
this->Debugged = true;
}

void __declspec() ClsAntiDebug::DebuggerActive()
{
HANDLE hProcSnap;
PROCESSENTRY32 pProcess;
LPTSTR Exename;
int strlength;
int deb[3]={18416231/*IDA Pro*/,997340682/*W32DASM*/,1853255255/*OllyDbg*/};
int i;
do
{
hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pProcess.dwSize = sizeof(PROCESSENTRY32);
Process32First(hProcSnap,&pProcess);
do
{
strlength = strlen(pProcess.szExeFile);
__asm
{
lea eax,[pProcess.szExeFile]
mov ecx,dword ptr[strlength]
xor edx,edx
xor edi, edi
push edi
gethash:
pop edi
xor dl, byte ptr[eax+edi]
rol edx,8
inc edi
push edi
xor edi,ecx
jne gethash
mov [strlength],edx/*We don't need strlength, so we recycle to get
     The Hash on Int Variable*/
pop edi
}
for(i=0;i<3;i++)if (strlength==deb[i])
{
this->Debugged = true;
__asm{jmp ___end}
}
}while(Process32Next(hProcSnap,&pProcess));
Sleep(500);
}while(1);
__asm
{___end:}
}
void __declspec() ClsAntiDebug::Protect(void *func)
{

do
{
switch(GetTickCount()%4)
{
case 0:this->PEBDebug();break;
case 1:this->NTGlobalDebug();break;
case 2:this->DebuggerActive();break;
};
if (this->Debugged)
{
__asm
{
call [func]
}
}
Sleep(500);
}while(1);
}

void __declspec() ClsAntiDebug::TimeStamp(int time,void *func)
{
__asm
{
rdtsc
mov ebx,eax
call [func]
rdtsc
sub eax, ebx
cmp eax, [time]
jna ___rtend
}
this->Debugged = true;
__asm{___rtend: }
}


Aqui tenemos una muestra de como utilizar la clase:

Código (cpp) [Seleccionar]
#pragma comment(linker,"/ENTRY:main")

#include "AntiDebug.h"
void CALLBACK HolaMundo()
{
int i;
i++;
i++;
}

int __declspec() main()
{

ClsAntiDebug *Debugger=new(ClsAntiDebug);
Debugger->TimeStamp(200,HolaMundo);
if (Debugger->IsDebugged())MessageBox(0,"Hola","Mundo",0);
Debugger->Protect(HolaMundo);
return 0;
}
#2
.NET (C#, VB.NET, ASP) / [SRC/VB.Net]Ec2Solver
18 Marzo 2011, 03:53 AM
Soluciona Ecuaciones de 2do Grado... contiene un modulo el cual cree especialmente para esta ocasion.

Modulo Ec2Solver
Código (vbnet) [Seleccionar]
Module Ec2Solver
    '*----------------------------------------------------------------------------------------------*
    '| Author: [L]ord [R]NA                                                                         |
    '| Country: Dominican Republic                                                                  |
    '*----------------------------------------------------------------------------------------------*
    ' Description: A Module to solve 2nd Degree Equations. The Module Ec2Solver has a Function that |
    ' Get the First 3 constant value of the equation And 2 Double Variables are public in the module|
    ' to get the possible values of X. If everything is Ok the Function return True and if it's     |
    ' something wrong Return False.                                                                 |
    '*----------------------------------------------------------------------------------------------*
    '|Website: http://lordrna.co.cc/ http://foro.h-sec.org/                                         |
    '|Mail: lordrna@h-sec.org                                                                       |
    '*----------------------------------------------------------------------------------------------*
    Public X1 As Double, X2 As Double
    Dim A1 As Double, B1 As Double, C1 As Double

    Public Function Ec2Solver(ByVal A As String, ByVal B As String, ByVal C As String) As Boolean
        If Double.TryParse(A, A1) And Double.TryParse(B, B1) And Double.TryParse(C, C1) Then
            Ec2Solver = Ec2Solver(A1, B1, C1)
        Else
            Ec2Solver = False
        End If
    End Function

    Public Function Ec2Solver(ByVal A As Double, ByVal B As Double, ByVal C As Double) As Boolean

        Dim temp As Double
        X1 = 0
        X2 = 0
        If A = 0 Then Ec2Solver = False
        If B = 0 And A <> 0 Then
            If C / A > 0 Then
                Ec2Solver = False
            Else
                If C = 0 Then
                    Ec2Solver = True
                Else
                    X1 = -System.Math.Sqrt(System.Math.Abs(C / A))
                    X2 = System.Math.Sqrt(System.Math.Abs(C / A))
                    Ec2Solver = True
                End If
            End If
        ElseIf C = 0 Then
            X1 = B / A
            Ec2Solver = True
        Else
            temp = (System.Math.Pow(B, 2)) - 4 * A * C
            If temp < 0 Then
                Ec2Solver = False
            Else
                temp = System.Math.Sqrt(temp) / (2 * A)
                X1 = -B + temp
                X2 = -B - temp
                Ec2Solver = True
            End If
        End If

    End Function
End Module


Source
Código (vbnet) [Seleccionar]
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        A.Clear()
        B.Clear()
        C.Clear()
        X1.Clear()
        X2.Clear()
    End Sub

    Private Sub A_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles A.Click
        A.Text = ""
    End Sub

    Private Sub B_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles B.Click
        B.Text = ""
    End Sub

    Private Sub C_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles C.Click
        C.Text = ""
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        If Len(A.Text) = 0 Or A.Text = "0" Then A.Text = "1"
        If Len(B.Text) = 0 Then B.Text = "0"
        If Len(C.Text) = 0 Then C.Text = "0"

        If Ec2Solver.Ec2Solver(A.Text, B.Text, C.Text) = True Then
            X1.Text = Str(Ec2Solver.X1)
            X2.Text = Str(Ec2Solver.X2)
        Else
            X1.Text = "Sin Solucion"
            X2.Text = "Real"
        End If
    End Sub
End Class
#3
Foro Libre / Saludos desde el Hades
26 Febrero 2011, 02:25 AM
Tengo mucho tiempo que no pasaba por aqui, se podria decir meses, pero aun no los he abandonado... aun me queda mucho por trollear. Espero que no mueran pronto...

[L]ord [R]NA ::)
#4
Programación C/C++ / [SRC] ByteCounter
17 Enero 2011, 18:14 PM
::) Pequeño codigo en C++ que cuenta la cantidad de bytes de un archivo pasado como parametro.

Código (cpp) [Seleccionar]

#include <cstdio>
#include <iostream>

void main(int argc, char *argv[])
{
FILE *pFile;
long size;
if(argc==2)
{
pFile = fopen(argv[1],"r");
if(pFile!=NULL)
{
if(!fseek(pFile,0,SEEK_END))
{
size=ftell(pFile);
fclose(pFile);
std::cout<<"El tamaño total del archivo es ";
std::cout<<size<<" Bytes."<<std::endl;
}
else std::cout<<"Sucedio un problema mientras se trataba de obtener la cantidad de bytes."<<std::endl;
}
else std::cout<<"Problemas con el archivo, verifique que el archivo exista."<<std::endl;
}

else std::cout<<"Uso: "<<argv[0]<<" <ruta de archivo>"<<std::endl;
}


Ejemplos:

lordrna@AAO150:~/Proyectos/C++/ByteCounter$ ls
bc  bc.cpp

lordrna@AAO150:~/Proyectos/C++/ByteCounter$ ./bc bc.cpp
El tamaño total del archivo es 627 Bytes.

lordrna@AAO150:~/Proyectos/C++/ByteCounter$ ./bc cdc
Problemas con el archivo, verifique que el archivo exista.
#5
Scripting / [SRC] ByteCounter
17 Enero 2011, 18:11 PM
Cuenta los bytes totales de un archivo.
Código (python) [Seleccionar]
#!/usr/bin/env python
#coding: utf-8

import sys,os

if len(sys.argv)==2:
    try:
        file=open(sys.argv[1],'r')
    except:
        print "Problemas con el archivo, verifique el que archivo existe."
        sys.exit(0)
    file.seek(0,os.SEEK_END)
    print "El Tamaño total del archivo es",file.tell(),"Bytes."
   
else:
     print "uso:",sys.argv[0],"<Ruta Del Archivo>"

#6
Felicitaciones a Azielito... Hoy llega a sus Bastardos 26
;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-)
#7
Bases de Datos / Cifrar una Base de Datos.
17 Noviembre 2010, 09:09 AM
Bueno, el caso es que tengo una aplicacion en la cual querria cifrar toda la Base de Datos o protegerla con contraseña... Alguna idea de como es posible realizar esto sin tener que cifrar directamente el archivo?, Estoy trabajando desde el FrameWork Qt con C++.
#8
Foro Libre / .NET Sucks
10 Noviembre 2010, 14:03 PM
 ;-) ;-) Felicitaciones a D4N93R... El bastardo esta de cumpleaño hoy, a menos que el facebook se equivoque  :silbar:

Vive solo 1 año mas y deja de programar en C#  :xD :xD :xD
#9
Programación C/C++ / [Capitulo III]Threads.
28 Octubre 2010, 09:12 AM
Threads

Los Threads como los procesos son mecanismos que permiten a un programa realizar mas de una accion a la vez. Como sucede con los procesos, los Threads al igual que los procesos parecen correr al mismo tiempo; El kernel de Linux los organiza de forma asincronica, interrumpiendo cada Thread durante un tiempo hasta otro tiempo, dando asi a los demas la oportunidad de ejecutarse.

Los Threads existen en conjunto con los procesos, son pequeñas porciones de ejecucion del proceso. Cuando ejecutamos un programa este crea un proceso y en ese proceso se crea un Thread simple que ejecuta el programa de forma secuencial. Ese Thread puede crear threads adicionales y dichos threads ejecutan el mismo programa en el mismo proceso. pero cada thread puede estar ejecutando una parte diferente de programa en cualquier momento dado.

Hay que tomar en cuenta algunas cosas en los Threads:


  • Existen con el proceso y utilizan los recursos del proceso.
  • Tienen su propio flujo independiente de control durante el tiempo que el proceso dueño del thread exista.
  • Duplica solamente los recursos esenciales necesarios para ser independientemente planificable.
  • Puede compartir recursos del proceso con otros Threads que tambien actuan de manera independiente o dependiente.
  • El thread es terminado si el proceso dueño del Thread muere.
  • Es ligero debido a que la mayoria del consumo se ha conseguido mediantre la creacion de su proceso.

Los Threads con el mismo proceso comparten recursos debido a las siguientes caracteristicas:


  • Los cambios realizados por un Thread a un recurso compartido pueden ser visto por todos los demas threads.
  • Dos punteros como el mismo valor apuntan a los mismos datos.
  • La lectura y escritura hacia la misma direccion de memoria es posible y se necesita de forma explicita que el programador realice la sincronizacion.

Creacion de Threads.

Inicialmente el main() comprende un unico thread por defecto, los demas threads deberan ser creados por el programador. Cada threads es identificado por un thread ID, cuando nos referimos a threads ID en C o C++ utilizaremos el tipo ppthread_t.

A su creacion cada Thread debera ejecutar una funcion Thread. Esta es una funcion ordinaria y contiene el codigo que el Thread deberia ejecutar. Cuando la funcion retorne el thread terminara. En GNU/Linux las funciones threads toman un simple parametro de tipo void*, y se tiene un valor de retorno de tipo void*.

La funcion encargada de crear un nuevo thread es la funcion pthread_create

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

donde:

pthread_t *thread es un unico identificador para el nuevo thread devuelto por la subrutina
const pthread_attr_t *attr es un puntero a un objeto de atributos para threads. Este objeto controlara detalles sobre como el thread interactuara con el resto del programa. Si se pasa NULL como atributo para el thread, el thread sera creado con los atributos por defectos.

void*(*start_routine)(void*) es un puntero a la funcion del thread, la cual es un puntero a una funcion del tipo void* (*) void(*).

void *arg es un argumento para el thread del tipo void*, lo que sea que pases sera pasado como argumento a la funcion del thread cuando el thread empiece a ejecutarse.

Una llamada a pthread_create retorna el control al thread principal inmediatamente para que este continue su ejecucion, mientras tanto el nuevo thread inicia su ejecucion. Linux planifica ambos threads de forma asincronica por lo tanto no se tiene un control de cual thread ira avanzando mas rapido que el otro por lo tanto para trabajar se necesitara una sincronizacion que veremos mas adelante.

Veamos un pequeño ejemplo pero primero debemos tomar algo en cuenta; Se  debe enlazar la libreria pthread al programa cada vez que se utilizen threads, esto lo realizaremos añadiendo '-lpthread' al momento de enlazar.

#include <pthread.h>
#include <stdio.h>

void* MundoThread(void *ptr)
{
  int j=0;
  for(j;j<10;j++)printf("Mundo\n");
}

int main()
{
  int i=0;
  pthread_t thread_id; //Con esto crearemos una variable para obtener el thread_id
  pthread_create(&thread_id,NULL,&MundoThread,NULL);//Creamos el Thread
  for(i;i<10;i++)printf("Hola ");
  return 0;
}


Pasando Datos al Thread.

Pasar datos a traves del argumento nos da una manera sencilla de proveer al thread de los datos que necesita para realizar una correcta ejecucion. Como se pudieron dar cuenta la variable que recibe los argumentos es de tipo void* por lo cual no se podria pasar una gran cantidad de datos directamente a traves del argumento, por lo tanto utilizaremos el argumento del thread para pasar un puntero a una estructura o a una cadena de caracteres. Es recomendable y comunmente utilizado el crear una estructura para cada thread que se quiera ejecutar la cual contenga los datos que dicho thread necesitara.

#include <pthread.h>
#include <stdio.h>

struct thread_arg
{
  int ini;
  int fin;
  int par;
};

void* Count(void* argument)
{
   struct thread_arg* arg = (struct thread_arg*) argument;
   for(arg->ini;arg->ini<=arg->fin;arg->ini++)
   {
     if(arg->par==1)
     {
       if(arg->ini%2==0)printf("%d \n",arg->ini);
     }
     else
     {
       if(arg->ini%2==1)printf("%d \n",arg->ini);
     }
   }
}

int main()
{
  pthread_t thread_id1, thread_id2;
  struct thread_arg thread1;
  struct thread_arg thread2;
  int junk;
  thread1.ini=0;
  thread1.fin=10000;
  thread1.par=1;
 
  thread2=thread1;
  thread2.par=0;
 
  pthread_create(&thread_id1,NULL, &Count,&thread1);
  pthread_create(&thread_id2,NULL, &Count,&thread2);
  return 0;
}


Si se fijan este codigo deberia de funcionar, pero no muestra nada en pantalla. Esto se debe a que cuando el proceso termina los threads terminan sin importar si completaron o no su funcion. Para este caso pasaremos al proximo tema.

Esperando Threads

En el codigo anterior vimos que aunque deberia de funcionar no muestra nada en pantalla debido a que el proceso termina antes de que estos lleguen a ejecutarse. Una solucion a esto es forzar el Thread principal (main()) a esperar a que los demas Threads terminen. Para estos casos tenemos la funcion pthread_join()

int pthread_join(pthread_t thread, void **value_ptr);

pthread_t thread es el thread por el cual esperaremos.

void **value_ptr es un puntero a una variable tipo void* que recibira el valor de retorno del thread. En caso de que no se quiera saber el valor de retorno del thread se puede pasar el valor NULL al segundo parametro.

Ahora veremos el ejemplo pasado de una forma que mostrara la salida de los threads por pantalla y luego terminara el proceso.


#include <pthread.h>
#include <stdio.h>

struct thread_arg
{
  int ini;
  int fin;
  int par;
};

void* Count(void* argument)
{
   struct thread_arg* arg = (struct thread_arg*) argument;
   for(arg->ini;arg->ini<=arg->fin;arg->ini++)
   {
     if(arg->par==1)
     {
       if(arg->ini%2==0)printf("%d \n",arg->ini);
     }
     else
     {
       if(arg->ini%2==1)printf("%d \n",arg->ini);
     }
   }
}

int main()
{
  pthread_t thread_id1, thread_id2;
  struct thread_arg thread1;
  struct thread_arg thread2;
  int junk;
  thread1.ini=0;
  thread1.fin=10000;
  thread1.par=1;
 
  thread2=thread1;
  thread2.par=0;
 
  pthread_create(&thread_id1,NULL, &Count,&thread1);
  pthread_create(&thread_id2,NULL, &Count,&thread2);
  pthread_join(thread_id1,NULL);
  pthread_join(thread_id2,NULL);
 
  return 0;
}


Valor de Retorno en un Thread

En caso de que el segundo argumento no sea NULL estamos requiriendo que nos sean devuelto los valores de retorno. Este valor de retorno sera colocado en la direccion pasada como argumento. Hay que tomar en cuenta que el valor de retorno es como el argumento en pthread_create(), es de tipo void*.

#include <pthread.h>
#include <stdio.h>

void* Euler(void *ptr)
{
  int j=0;
  int a=0;
  int b=*((int*)ptr);
  for(j;j<=b;j++)a+=j;
  return (void*)a;
}

int main()
{
  int i=0, num;
  pthread_t thread_id;
  scanf("%i",&num);
  pthread_create(&thread_id,NULL,&Euler,&num);
  pthread_join(thread_id,(void*)&i);
  printf("El numero %d de la escalera es: %d\n",num,i);
  return 0;
}


Atributos en Threads

Los Atributos en los Threads nos dan la posibilidad de optimizar el funcionamiento de un thread en especifico. La funcion pthread_create acepta  como segundo parametro un puntero a un objeto de atributos de thread. En caso de que se pase NULL el thread se iniciara con los atributos por defecto. Para modificar los atributos de un thread simplemente hay que realizar algunos pasos.

1) Creamos una variable del tipo pthread_attr_t.
2) Llamamos la funcion pthread_attr_init() pasando como parametro la direccion de memoria de la variable del tipo. pthread_attr_t.
3) Modificamos el objeto que contiene los atributos para contener los atributos decididos.
4) Pasamos a pthread_create() la direccion de memoria del objeto con los atributos en el segundo parametro.
5) Llamamos pthread_attr_destroy() para liberar el objeto de los atributos.

Para modificar los objetos existen unas funciones especificas pthread_attr_ las cuales los invitare a que lean sobre el tema debido a que posiblemente a muchos no les   sirva de mucho darle importancia sobre los atributos a los threads

http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setaffinity_np.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setdetachstate.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setguardsize.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setinheritsched.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setschedparam.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setschedpolicy.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setscope.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setstack.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setstackaddr.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_attr_setstacksize.3.html

Sincronizacion  y Zonas Criticas.

Cuando programamos utilizando threads debemos tener un especial cuidado debido a que no sabemos como el S.O. ha planificado la ejecucion, por lo tanto un thread puede detenerse para dar paso a otro inmediatamente inicie su ejecucion como puede durar una gran cantidad de tiempo.

La causa mas probable de fallo cuando se trabaja con threads es que varios threads quieran utilizar el mismo recurso a la vez. Por ejemplo pensemos en un programa que tiene dos Threads realizando una lista de tareas hasta que la terminen todas. Llega el caso de que ambos procesos terminen sus respectivas tareas y quede solo una; El primer thread llega y toma la tarea, pero antes de marcarla como que la tomo debido a la planificacion del S.O. dicho thread se pausa y entra en funcionamiento el segundo thread. Aqui hay un problema debido a que tendremos varios threads realizando una tarea que se supone que deberia realizarse una sola vez. Para estos casos surgieron los Mutex, esto daba la posibilidad de que solo un thread a la vez pudiese acceder a la lista y mientras ese thread estuviese utilizandola el otro thread no tendria acceso hasta que el thread que accedio primero al recurso tome lo que necesite.

Mutex

El Sistema Operativo nos da la posibilidad de utilizar Mutex como una forma de sincronizacion para evitar el tipo de problema explicado en el caso anterior. como su nombre lo expresa, un Mutex (Mutual Exclusion Locks) como su nombre lo indica son cerraduras especiales las cuales un thread a la vez puede cerrar. Cuando un thread bloquea un mutex y luego otro thread trata de bloquearlo, el segundo thread se queda en espera o es bloqueado, con esto el Sistema Operativo evita que ocurra que dos threads a la vez bloqueen el mismo Mutex y accedan a los mismos recursos.

Para crear un mutex crearemos una variable del tipo pthread_mutex_t y pasaremos un puntero a la funcion pthread_mutex_init() como primer parametro, el segundo parametro sera un puntero a un objeto de atributos de un mutex el cual especificara los aatributos del mutex. Si el segundo parametro es NULL el mutex iniciara con los atributos por defecto. Una variable para un mutex puede ser inicializada una y solo una vez. por cierto existe una forma mas facil de inicializar un mutex y es asignandole el valor especial PTHREAD_MUTEX_INITIALIZER.

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

mas info: http://opengroup.org/onlinepubs/007908775/xsh/pthread_mutex_init.html

Un thread puede tratar de bloquear un Mutex llamando la funcion pthread_mutex_lock() en el. En caso de que el Mutex este desbloqueado la funcion bloqueara el Mutex y retornara inmediatamente, pero si esta bloqueado paralizara la ejecucion y retornara cuando el Mutex sea liberado por el otro thread. En caso de que varios threads traten de bloquear un thread ya bloqueado, la ejecucion de todos cesara y cuando el thread que bloqueo el Mutex libere otro Thread lo bloqueara sin un orden predecible especifico. La funcion pthread_mutex_unlock() desbloquea el Mutex y deberia ser llamada por el thread que bloqueo el Mutex.

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);


mas info:http://opengroup.org/onlinepubs/007908775/xsh/pthread_mutex_lock.html

#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex[4];
int var[4]={0,0,0,0};
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;

void *Mult(void *arg)
{
int k = *((int*)arg);
pthread_mutex_lock(&mutex[k]);
k++;
k*=250;
int j = k-249;
pthread_mutex_unlock(&lock);
for(j;j<=k;j++)
{
if(j%3==0||j%5==0)var[(k/250)-1]+=j;
}
pthread_mutex_unlock(&mutex[(k/250)-1]);
}

int main()
{
int i;
pthread_t threadid[4];
for(i=0;i<4;i++)
{
pthread_mutex_init(&mutex[i],NULL);
pthread_mutex_lock(&lock);
pthread_create(&threadid[i],NULL,&Mult,&i);
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
}
for(i=0;i<4;i++)pthread_mutex_lock(&mutex[i]);
printf("resultado: %i\n",var[0]+var[1]+var[2]+var[3]);
return 0;
}


Semaphores

Los Semaphores al igual que los Mutex son mecanismos para la sincronizacion de threads. Un semaphore es un contador que puede ser utilizado para sincronizar multiples threads, para que multiples threads puedan acceder al mismo recurso (dependiendo de la cantidad de threads admitidos para trabajar a la vez con un recurso).

Un Semaphore es representado por una variable del tipo sem_t y antes de utilizarlos deben de ser inicializados de forma semejante a los mutex, con la funcion sem_init() cuyo primer parametro es un puntero a una variable del tipoo sem_t, el segundo parametro deberia ser cero y el tercer parametro sera el valor inicial del semaphore. Si en algun momento necesitamos saber cual es el valor del Semafore podemos conseguirlos utilizando la funcion sem_getvalue() la cual recibe como primer parametro un puntero a una variable del tipo sem_t inicializada y como segundo parametro un puntero a una variable tipo int para obtener el valor de retorno. En caso de que no se necesite un semaphore es bueno destruirlo con sem_destroy() el cual recibe un puntero a un semaphore.

int sem_init(sem_t *sem, int pshared, unsigned int value);
mas info:[urlhttp://opengroup.org/onlinepubs/007908799/xsh/sem_init.html[/url]

int sem_getvalue(sem_t *sem, int *sval);
mas info:http://opengroup.org/onlinepubs/007908799/xsh/sem_getvalue.html

int sem_destroy(sem_t *sem);
mas info: http://opengroup.org/onlinepubs/007908799/xsh/sem_destroy.html


Cada Semaphore es un contador de enteros positivos y soportan basicamente dos operaciones.

wait: Disminuye el valor del Semaphore en 1, Si el valor del semaphore a la hora de realizar la operacion wait es cero, la funcion queda bloqueada hasta que el valor del semaphore sea positivo. La funcion especifica para realizar un wait en un semaphore es sem_wait() para un wait bloqueante y sem_trywait() para un wait no bloqueante. Ambas funciones reciben como parametro un puntero a una variable del tipo sem_t

post: Incrementa el valor del Semaphore en 1, Si el Semaphore previamente estaba en cero y otro thread estaba bloqueado esperando para realizar un wait en el semaphore, este al realizarse el post se desbloqueara y ejecutara el wait sobre el semaphore. La funcion para realizar un post es sem_post() y al igual que sem_wait() y sem_trywait() recibe un puntero a una variable del tipo sem_t.

int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);

mas info:http://opengroup.org/onlinepubs/007908799/xsh/sem_wait.html

int sem_post(sem_t *sem);
mas info:http://opengroup.org/onlinepubs/007908799/xsh/sem_post.html

En el ejemplo supongamos que tenemos una piramide de numeros y quisieramos obtener obtener la mayor posible suma de la piramide siguiendo un camino. La piramide esta organizada de la siguiente forma:
1
8 3
5 6 8


#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>

int piramid[3][3]={{1,0,0},{8,3,0},{5,6,8}};
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
sem_t sem1, sem21, sem22, sem31, sem32, sem33, semmaster;

void* Sum(void* argument)
{
int var=0;
sem_wait(&sem1);
pthread_mutex_unlock(&mutex);
var+=piramid[0][0];
if(sem_trywait(&sem21)!=-1)
{
var+=piramid[1][0];
if(sem_trywait(&sem31)!=-1)
{
var+=piramid[2][0];
sem_post(&semmaster);
return (void*)var;
}
else if(sem_trywait(&sem32)!=-1)
{
var+=piramid[2][1];
sem_post(&semmaster);
return (void*)var;
}
}
else if(sem_trywait(&sem22)!=-1)
{
var+=piramid[1][1];
if(sem_trywait(&sem32)!=-1)
{
var+=piramid[2][1];
sem_post(&semmaster);
return (void*)var;
}
else if(sem_trywait(&sem33)!=-1)
{
var+=piramid[2][2];
sem_post(&semmaster);
return (void*)var;
}
}

}

int main()
{
  pthread_t thread_id[4];
  int i,res=0,sem=0;
  sem_init(&sem1,0,4);
  sem_init(&sem21,0,2);
  sem_init(&sem22,0,2);
  sem_init(&sem32,0,2);
  sem_init(&sem31,0,1);//Este trabajaria como si fuera un Mutex
  sem_init(&sem33,0,1);//Al igual que este
  sem_init(&semmaster,0,0);
   
  for(i=0;i<4;i++)
  {
  pthread_mutex_lock(&mutex);
  pthread_create(&thread_id[i],NULL, &Sum,NULL);
  }
  while(sem!=4)sem_getvalue(&semmaster,&sem);
  for(i=0;i<4;i++)
  {
  pthread_join(thread_id[i],(void*)&sem);
  if(sem>res)res=sem;
  }
  printf("La mayor suma de la piramide es %i\n",res);
  return 0;
}
#10
Programación C/C++ / [Capitulo II] Procesos
6 Octubre 2010, 08:19 AM
Procesos

   Un programa en ejecucion recibe el nombre de proceso. Estos estan gestionados por el sistema operativo. Un proceso esta conformado por las instrucciones que van a ser ejecutadas por el microprocesador, el estado de ejecucion en un momento especifico, la memoria de trabajo para el proceso y otra informacion que requiera el sistema operativo.

   En los sistemas operativos basados en Linux cada proceso es identificado por un unico ID llamado Process ID(pid). Los Process IDs son numeros de 32bits asignados secuencialmente por Linux cada vez que un nuevo proceso es creado. Aparte de todo esto, cada proceso tiene un proceso padre, exceptuando el proceso 'init', cuando nos refiramos desde un proceso hijo hacia un proceso padre nos referiremos con la abreviatura ppid(Parent Process ID).

   Para referirnos al ID de un proceso utilizaremos el tipo 'pid_t' el cual esta definido en el archivo cabecera '<sys/types.h>'. Una pequeña aclaracion, el tipo de dato pid_t es simplemente un tipo 'signed int', utilizar el tipo 'pid_t' o 'signed int' no hara ningun cambio pero para facilidad de lectura de tu codigo por otras personas es preferible utilizar 'pid_t' cuando te refieras a un Process ID.

Obteniendo nuestro Process ID


   En algunos casos necesitaremos obtener nuestro Process ID, para verificarlo en una lista, para pasarlo a otro proceso, etc. Para obtener dicho Process ID se nos ha dotado de dos funciones getpid(),para obtener nuestro propio Process ID, y getppid(),para obtener el Process ID del proceso padre, dichas funciones se encuentran en el archivo cabecera 'unistd.h' el cual es el archivo que nos da acceso a las API del Sistema Operativo POSIX (Portable Operative System Interface for uniX).
   
   Ninguna de las funciones vistas anteriormente reciben un parametro y como valor de retorno devuelven un pid_t, el cual dependera de la funcion que ha sido llamada.

pid_t getpid (void)
pid_t getppid (void)



   Veamos un pequeño ejemplo del uso de estas funciones:


#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
pid_t currentpid, parentpid;
currentpid = getpid();
parentpid = getppid();
printf("El proceso %i es padre del proceso %i \n",parentpid,currentpid);
return 0;
}


Como vemos si ejecutamos varias veces el mismo programa en la misma consola, el valor del Process ID del proceso padre no varia debido a que la consola es el proceso padre.

Creando un Proceso.

Existen dos tecnicas comunes para crear un proceso, la primera es utilizando 'system()', es sencilla de utilizar pero esta se debe de utilizar con cierta precaucion debido a que es ineficiente y es considerada como un riesgo de seguridad.La segunda es utilizando fork() o exec(), esta es mas compleja pero nos otorga flexibilidad, velocidad y seguridad.

Utilizando system():


int system (const char *string)

Hay que tomar en consideracion 2 valores de retorno, devolvera '127' si la ejecucion en la consola falla, en caso de otro error el valor de retorno sera -1. Aparte de estos valores, system() mostrara en pantalla en caso de ser posible el proceso o comando ejecutado.

#include <stdio.h>

int main()
{
printf("%i \n",system("dir"));
return 0;
}


para mas informacion:
man 3 system

Utilizando fork() y exec():


pid_t fork(void)

La funcion fork() crea un proceso hijo identico al proceso padre, la unica diferencia entre ellos es el PID y la direccion de memoria fisica en la RAM. En los actuales Sistemas Operativos las direcciones de las variables en memoria no corresponden a la verdadera memoria fisica en hardware. Las direcciones estan administradas por direcciones virtuales en el Sistema Operativo por esta razon en el proceso padre y el proceso hijo incluso cuando tienen la misma direccion virtual de memoria, la direccion fisica es diferente.

La funcion fork() devuelve en el proceso padre el pid del proceso hijo, mientras que en el proceso hijo devuelve 0.


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
pid_t proc;
int status,value=0;

if(proc=fork())
{
printf("Process: %i %x\n",getpid(),&value);
waitpid(proc,&status,0);
printf("%i \n",value);
return 0;
}

else
{
printf("Process: %i %i %x\n",getpid(),getppid(),&value);
value = 2000;
return 0;
}
}


para mas informacion:
man 2 fork

La familia exec()



int execl(const char *path, const char *arg, ...)
int execlp(const char *file, const char *arg, ...)
int execle(const char *path, const char *arg, ..., char * const envp[])
int execv(const char *path, char *const argv[])
int execvp(const char *file, char *const argv[])


Las funciones exec() remplazan el programa en ejecucion por otro programa dentro de un proceso. Inmediatamente se hace una llamada exec() el proceso en ejecucion se detiene y el nuevo programa inicia la ejecucion asumiendo que la llamada no tenga un error. Debido a que exec() remplaza el programa actual en ejecucion, este no retornara el control a menos que suceda un error o nuevo programa en ejecucion termine.

Veamos un pequeño ejemplo para utilizar fork() y exec() en el mismo programa:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
pid_t proc;
int status,value=0;

if(proc=fork())
{
waitpid(proc,&status,0);
printf("Clear Used \n");
return 0;
}

else
{
execvp("clear",argv);
return 0;
}
}


Terminando un proceso


   Normalmente un proceso termina de dos formas. o llamando una funcion de salida, o por el valor de retorno. Cada proceso tiene un valor de salida. Cada proceso tiene un codigo de salida y ese codigo es devuelto a su proceso padre, entiendase por codigo el valor de retorno.

   En algunos casos necesitaremos cerrar un proceso, debido a que ya no lo necesitemos, para estos casos existe la funcion kill(). La funcion kill recibe 2 parametros. El primer parametro es el PID de un proceso o de un grupo de procesos. El segundo parametro es la señal, la cual es un valor constante.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>

int main(int argc, char *argv[])
{
pid_t proc;
int status,value=0;

if(proc=fork())
{
kill(proc,SIGTERM);
if(status==0)printf("El proceso %i se ha cerrado \n",proc);
return 0;
}

else
{
while(1)printf("KILL ME. \n");
}
}


para mas informacion sobre kill():
man 2 kill

para mas informacion sobre el valor constante de las señales:
/usr/include/bits/signum.h

Esperando la terminacion de un proceso


   Debido a que el S.O. Linux es un sistema operativo multitareas cuando trabajamos con varios procesos, por ejemplo con una llamada a fork, no existe la certeza de cual proceso terminara primero. En algunas ocasiones necesitaremos esperar el valor de retorno de un proceso hijo o de multiples procesos hijos que habran realizado diferentes instrucciones y para estos casos existe la funcion wait().

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
pid_t proc;
int status,value=0;

if(proc=fork())
{
waitpid(proc,&status,0);
if(status==0)printf("El proceso %i ha terminado con exito \n",proc);
return 0;
}

else
{
return 0;
}
}


para mas informacion:man 2 wait
#11
[Taller] Programacion Avanzada en C/C++ (Linux)





EN CONSTRUCCION

Nota: No postear en este tema, lo tomare para organizar un poco el taller debido a que sera un trabajo un poquito extenso para un solo post. En caso de querer comentar, hacerlo en el post de dicho capitulo.
#12
Compilando con GCC

   Un compilador transforma desde un codigo fuente legible por los humanos en un objeto legible para una maquina. En los sistemas operativos basados en Linux los compiladores por excelencia forman parte del GNU Compiler Collection, usualmente conocidos como GCC. GCC incluye compiladores para C, C++, Java y Fortran.

   Supongamos que tenemos un codigo simple, por ejemplo verificar si un numero es o no perfecto, en el cual tenemos un codigo fuente en C++ llamado "perfect.cpp", un archivo de cabecera C++ llamado "perfect.hpp" un codigo fuente en C llamado "main.c", supongamos que ambos archivos seran compilados, luego seran enlazados para crear un programa llamado "perfect" el cual nos dira si un numero es o no un numero perfecto.

main.c:
#include <stdio.h>
#include <stdlib.h>
#include "perfect.hpp"

int main(int argc,char *argv[])
{
int a;
if(argc>1)
{
a = atoi(argv[1]);
if(perfect(a))printf("El numero %i es perfecto\n",a);
else printf("El numero %i no es perfecto\n",a);
}
return 0;
}


perfect.cpp:
Código (cpp) [Seleccionar]
#include "perfect.hpp"

int perfect(int a)
{
int b=0;
for(int i=1;i<a;i++)if(a%i==0)b+=i;
if(a==b)return 1;
else return 0;
}


perfect.hpp:
Código (cpp) [Seleccionar]
#ifndef _Perfect
#define _Perfect
#ifdef __cplusplus
extern "C" {
#endif

extern int perfect(int);

#ifdef __cplusplus
}
#endif
#endif



El nombre del compilador de C es gcc y para compilar un archivo se utiliza la opcion -c. El compilador de C++ es g++ y al igual que el compilador de C se utiliza la opcion -c. Compilando los codigo fuente antes vistos tendriamos:


lordrna@personal-laptop:~$ gcc -c main.c
lordrna@personal-laptop:~$ g++ -c perfect.cpp


En caso de que no suceda ningun error se crearan los archivos "main.o" y "perfect.o".

Para mas informacion del compilador:


lordrna@personal-laptop:~$ info gcc


Enlazar archivos compilados

Cuando obtengamos los archivos compilados que ya necesitemos enlazarlos, deberemos utilizar siempre g++ en caso de que alguno de los compilados a enlazar contenga codigo en C++, incluso si es simplemente un solo archivo compilado contiene codigo fuente en C++. Para esto utilizaremos:

lordrna@personal-laptop:~$ g++ -o Perfecto main.o perfect.o

Entre las principales ventajas que nos brinda compilar y luego enlazar  es que en caso de que uno de los archivos fuente tenga un error simplemente tendriamos que reparar el error, compilar el codigo fuente modificado y enlazar con los demas.


Utilizando el Debugger de GNU (GDB)

   Para agregar informacion extra para poder buscar posibles errores con el debugger de GNU añadiremos la opcion '-g', esto agrega informacion extra para poder tracear el programa. La forma de compilar y enlazar quedaria de la siguiente forma:


lordrna@personal-laptop:~$ gcc -g -c main.c
lordrna@personal-laptop:~$ g++ -g -c perfect.cpp
lordrna@personal-laptop:~$ g++ -g -o Perfecto main.o perfect.o


Cuando compilamos y enlazamos de esta forma el debugger obtiene informacion de que direccion de memoria corresponde a cada linea del codigo fuente, como mostrar variables locales entre otras cosas.

Para ejecutar el GNU Debbuger escribimos en consola:

lordrna@personal-laptop:~$ gdb perfecto


Para mas informacion 'man gdb'

En caso de que el programa perfecto exista en consola aparecera:

(gdb)

para ejecutar el programa escribimos 'run' y seguido los parametros, en caso de ser necesarios:

(gdb) run 6

En caso de que exista un error con 'where' nos mostrara la porcion del codigo donde el debugger tuvo problemas para ejecutar y asi podremos en el codigo fuente modificar la parte defectuosa:

(gdb) where

Podremos tambien colocar breakpoints dando el nombre de la funcion donde queremos colocarlo:

(gdb) break main

Para ver el valor de una variable utilizamos 'print' seguido del nombre de la variable.

(gdb) print argv[1]

Si quieres avanzar un paso, pero recibiendo los valores de retorno de las funciones se utiliza 'next'.

(gdb) next

Si quieres adentrarte en las funciones mientras avanzas se utiliza 'step'.

(gdb) step
#13
Scripting / [Python] WhoPingMe by LordRNA.
19 Septiembre 2010, 06:46 AM
Disculpen los comentarios en ingles... escribi el script para publicarlo en otro lugar pero soy fiel a mi origen, :xD eso fue una excusa... Los puse en ingles y me da peresa traducir. :silbar: :silbar:

Cualquier pregunta o duda, no duden en postearla.

PsData: Fue probado en Linux, se necesitan privilegios para ejecutar.

Código (python) [Seleccionar]
#! /usr/bin/env python
########################################################################
#Script     : WhoPingMe.py                                             #
#Description: Detect if you receive a Ping and make a list with Date.  #
#By         : LordRNA                                                  #
#Date`      : Sept 19th-2010                                           #
#Comments   : Tested on Python 2.6.5                                   #
########################################################################

import socket, datetime

def whopingme(date):
   source = '' #To put the IP Source.
   header = ["%i"%ord(x) for x in data]
#I made a list of int values for each byte in data variable.
   if int(header[20])==8:#If Type(ICMP) is 8, i received a Echo Request.
       for x in range(4):#To make a string with the IP Source.
           source += str(header[12+x])
           if x<3:source +='.'
       date = str(datetime.datetime.today())
       print date[:len(date)-7]+" ---> "+ str(source)
#I deleted the Miliseconds with [:len(date)-7]

sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
#ICMP Protocol on RAW Socket

while 1:
   data = sock.recv(21)#I Just want these bytes, IPHeader Lenght + Type(ICMPHeader)
   whopingme(data)#Sending data to whopingme() function.


Muestra de la Salida del programa:

rna@rna-laptop:~$ sudo python ./whopingme.py
2010-09-19 00:47:57 ---> 192.168.10.230
2010-09-19 00:47:58 ---> 192.168.10.230
2010-09-19 00:47:59 ---> 192.168.10.230


Edito: Segun me ha dicho Karcrack, LittleHorse y ctlon deberia funcionar en windows con privilegios de administrador.
#14
Scripting / [Python] Capturar Paquetes TCP
10 Septiembre 2010, 17:52 PM
Código (python) [Seleccionar]
########################################################################
#Programa: Sniffer de paquetes TCP                                     #
#Autor   : LordRNA                                                     #
#Fecha   : 09-Sept-2010                                                #
########################################################################
#Se necesitan privilegios de root para trabajar con sockets raw.
#Probado en Ubuntu10.04 con Python2.7
import socket

translate =''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])

def dump(src, length=16):
   result=''
   while src:
      s,src = src[:length],src[length:]
      hex = ' '.join(["%02X"%ord(x) for x in s])
      s = s.translate(translate)
      result += "%-*s %s\n" % (length*3,hex,s)
   return result

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
L=0
while 1:
L+=1
raw = s.recv(16000)
       print "========================================================================"
print "Paquete: "+str(L)
print "========================================================================"
print dump(raw)
#15
Scripting / [Python] Coeficiente Binomial.
6 Septiembre 2010, 16:37 PM
Coeficiente Binomial o Combinaciones Maximas de un conjunto de N elementos tomando M elementos cualesquiera.
Código (python) [Seleccionar]
#Coeficiente Binomial by LordRNA
#Realizado en Python2.7

def factorial(a):
if a<2:return 1
a*=factorial(a-1)
return a

try:
n=int(raw_input("Intruduzca la cantidad total de elementos: "))
m=int(raw_input("Introduzca la cantidad de elementos a combinar: "))

if m>n:
print "Error: La cantidad total de elementos debe ser mayor que la cantidad de elementos a combinar."
else:
num = factorial(n)
den = factorial(m) * factorial((n-m))
res = num/den
print res

except ValueError:
print "Introdujo un tipo de datos no valido."
except RuntimeError:
print "El numero de combinaciones es demasiado grande."

#16
Scripting / [Python] IRCBot
5 Septiembre 2010, 18:39 PM
Bueno, aqui un ejemplo de un IRCBot en Python... es el codigo que he creado de prueba para el que actualmente estoy realizando, por lo tanto esta un tanto chapucero en lo que se refiere a la seleccion de nick ya que este es fijo y se pueden realizar algunas mejoras mas :¬¬ :¬¬.

Nota: No des criticas constructivas o inconstructivas.

Código (python) [Seleccionar]
import socket, time, string

Version = ':RNA PyBot  V1.0Beta\r\n'
while True:
try:MainSock = socket.socket()
except: continue

try:
MainSock.connect(("irc.elhacker.net",6667))
except socket.gaierror:
print "Sin Conexion"
time.sleep(5)
MainSock.close()
continue
time.sleep(10)
MainSock.send("USER RNABOT PYTHON PoC BOT\n")
MainSock.send('Nick RNA_PyBot\n')
MainSock.send("JOIN #elhacker.net\n")

while True:
MainSock.setblocking(0)
try: s = MainSock.recv(1024)
except:
time.sleep(0.1)
MainSock.setblocking(1)
continue

m = string.split(s,":",2)

if m[0]=="PING ":
s = string.replace(s,"I","O")
MainSock.send(s)
continue
else:
nick = string.split(m[1],"!",1)
canal= string.split(s)
print "Canal:"+canal[2]+" "+nick[0]+": "+m[len(m)-1]

if m[len(m)-1] == ".ver\r\n":
if canal[2]=="RNA_PyBot":MainSock.send("PRIVMSG "+ nick[0]+" "+Version )
else: MainSock.send("PRIVMSG "+ canal[2]+" "+Version )
#Aqui se continuaran colocando las funciones... con elif
else: continue

MainSock.close()
#17
No se si es bien pero desearria que realizaran un torneo de Ajedrez oficial en el foro... muchos usuarios frecuentes lo practican por lo tanto tendria aceptacion y personas para tal fin.
#18
Ejercicios / Retos C/C++
19 Agosto 2010, 03:18 AM
Bueno, esta zona esta un poco muerta por lo tanto no cuesta nada tratar de revivirla.

Tomando las mismas reglas que la del pasado post de retos de Python que se hizo en esta zona haremos uno en C/C++.

Reglas:

1) Se empezara con un ejercicio, quien lo resuelva propone otro ejercicio y asi seguimos.
2) Los ejercicios tendran un tiempo de vida de 3 dias, si en exactamente 3 dias alguien no publica una solucion alguien podra proponer otro ejercicio.
3) No publicar para decir cosas que no tengan que ver con la solucion al reto o para postear un nuevo reto.
4) Numerar los retos (Ej. Reto#1)


Bueno ya que yo postee, seria de mala educacion dejar que otro ponga el reto.



Reto#1: Realizar un programa que reciba un numero como argumento y diga si es primo o no.

PData: No estoy estudiando C/C++ actualmente en la universidad... (Para los que diran que es una tarea.)
#19
Una madre denuncia a Walt Disney porque un empleado vestido de 'Donald' le metió mano

Se llama April Mologon, tiene 27 años y cuando acudió al Epoc Center de Florida con sus dos hijos, lo último que esperaba era que sus senos fueran manoseados por el Pato Donald. Pero eso es precisamente lo que denuncia esta estadounidense, que ahora pide una indemnización de 50.000 dólares (39.000 euros) a la compañía Walt Disney.

Según la mujer, el empleado disfrazado como el conocido personaje de animación infantil le tocó un pecho y, cuando intentó retirarse, siguió manoseándola. Y eso que llevaba en brazos a uno de sus hijos, según recoge el Daily Mail en su edición de este jueves.

El incidente, que se produjo hace dos años, ha quedado en el recuerdo de April provocándole un traúma, según ella, además de "severos daños psicológicos", "cefaleas", "ansiedad aguda", "sudores fríos", "insomnio", "pesadillas" y "problemas digestivos".

Un portavoz de Disney, Bryan Malenius, ha declarado que responderán a las acusaciones "en el juzgado", pero que todavía no habían tenido acceso a la denuncia de Mologon, archivada en un juzgado del estado de Pennsylvania.

No es la primera vez que Disney debe afrontar un caso similar. En el año 2004, un trabajador llamado Michael Chartrand, vestido como el personaje Tigger de la serie 'Winnie The Pooh', fue acusando de tocar lascivamente a una niña de 13 años y a su madre.

Pero Chartrand se libró de la condena cuando su abogado, poniéndose el disfraz, convenció al jurado de lo difícil que es ver algo desde dentro y la imposibilidad de sentir nada con los guantes puestos...

Fuente: http://noticias.terra.es/2010/mundo/0812/actualidad/madre-denuncia-walt-disney-empleado-pato-donald-metio-mano-pecho.aspx

#20
El titulo lo explica, es un generador de passwords. Genera passwords de entre 8 y 32 caracteres agregando numeros, letras y simbolos. Compila perfectamente en Qt4.6.

main.cpp:

Código (cpp) [Seleccionar]
#include <QtGui/QApplication>
#include "qtpass.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QtPass w;
    w.show();
    return a.exec();
}


qtpass.h:
Código (cpp) [Seleccionar]
#ifndef QTPASS_H
#define QTPASS_H

#include <QtGui>

class QLineEdit;
class QPushButton;
class QLabel;
class QSpinBox;
class QString;

class QtPass : public QWidget {
    Q_OBJECT

public:
    QtPass(QWidget *parent = 0);

private slots:
    void GenerarPass();
    void About();

private:
    QString *pass;
    QLineEdit *LinePass;
    QPushButton *ButtonGen, *ButtonAbout, *ButtonSalir;
    QLabel *LabelPass;
    QSpinBox *SpinChar;
    QHBoxLayout *TopLayout;
    QHBoxLayout *BottomLayout;
    QVBoxLayout * MainLayout;


};

#endif // QTPASS_H


qtpass.cpp:
Código (cpp) [Seleccionar]
#include "qtpass.h"

QtPass::QtPass(QWidget *parent) :
    QWidget(parent)
   {
//Creamos los Widgets que vamos a necesitar
    this->LinePass = new QLineEdit;
    this->SpinChar = new QSpinBox;
    this->ButtonGen = new QPushButton("&Generar");
    this->ButtonAbout = new QPushButton("&About");
    this->ButtonSalir = new QPushButton("&Salir");
    this->LabelPass = new QLabel("Password: ");

//Configuramos algunos Widgets
    this->ButtonGen->setDefault(true);
    this->LinePass->setReadOnly(true);
    this->SpinChar->setMaximum(32);
    this->SpinChar->setMinimum(8);

//Preparamos los Layouts que necesitaremos para organizar.
    this->TopLayout = new QHBoxLayout;
    this->BottomLayout = new QHBoxLayout;
    this->MainLayout = new QVBoxLayout;

//Empezamos la organizacion de los Widgets
    this->TopLayout->addWidget(this->LabelPass);
    this->TopLayout->addWidget(this->LinePass);
    this->TopLayout->addWidget(this->SpinChar);
    this->BottomLayout->addWidget(this->ButtonGen);
    this->BottomLayout->addWidget(this->ButtonAbout);
    this->BottomLayout->addWidget(this->ButtonSalir);
    this->MainLayout->addLayout(this->TopLayout);
    this->MainLayout->addLayout(this->BottomLayout);

//Añadimos titulo y el Layout principal a la ventana.
    this->setWindowTitle("QtPassGen by Lord R.N.A.");
    this->setLayout(this->MainLayout);
    this->setFixedSize(420,80);

//Realizamos las conexiones que necesitaremos.
    connect(this->ButtonSalir,SIGNAL(clicked()),this,SLOT(close()));
    connect(this->ButtonGen,SIGNAL(clicked()),this,SLOT(GenerarPass()));
    connect(this->ButtonAbout,SIGNAL(clicked()),this,SLOT(About()));
    }

//La funcion encargada de generar el password.
void QtPass::GenerarPass()
{
this->pass = new QString;
QTime *seed = new QTime;
seed->start(); //Para inicializar el puntero seed con la hora actual.
qsrand(seed->msec()); //La semilla para qrand();
for(int i=0;this->SpinChar->value()>i;i++)
{
    this->pass->insert(i,QChar(qrand()%95 +33));//Inserta en la posicion i, el char devuelto por QChar();
    if(this->pass->at(i)==QChar(96))i--;

}
this->LinePass->setText(*this->pass);
delete this->pass;
delete seed;
}

//El MessageBox para el About.
void QtPass::About()
{
    QMessageBox::about(this,"About","<b>QtPassGen v1.0 by Lord R.N.A.</b> <br><br>"
                       "Aplicacion Generadora de Passwords <br>Qt 4.6"
                       "<br><br><b>R.N.A. Labs.</b>");
}
#21
Foro Libre / Alguien Juega al CounterStrike
1 Agosto 2010, 06:09 AM
Bueno el titulo lo dice todo... algunas veces estoy un tanto aburrido pero no encuentro muchas personas con las cuales pasar un rato de diversion y quisiera saber cuales miembros de la comunidad aun lo juegan.

#22
Vaya demostracion que he encontrado en mis dias bellos en facebook...

#23
Los Signals y Slots son los mecanismos de comunicación utilizados para comunicar objetos que heredan de Q_OBJECT. Q_OBJECT es la base de todos los objetos de Qt.

Los Slot son simplemente funciones, que se quiere decir con esto, que pueden ser llamadas por el objeto según el estandar de C++ precediendo el nombre del metodo del nombre de la funcion seguida de un punto(.) o precediendola de una  flecha(->).

Las señales podrian interpretarse como los valores de retorno que se enviaran al metodo que esta conectado a esta señal. Se declaran como si fueran metodos pero sin procedimientos. Se envian colocando primero la macro "emit" posteriormente la señal rellenando sus argumentos con los valores que se desean emitir.

Los Signals y Slots se conectan utilizando la API de Qt llamada connect(), la cual lleva la siguiente forma: connect(const Qobject* sender, const char* signal, const Qobject* reciever, const char*  slot);

Hay ciertas caracteristicas con las que cuenta la comunicación entre los signals y los slots, entre estas estan:


  • Son type-safe, esto quiere decir que la signal debe encajar con el slot.
  • Los objetos emiten señales, pero no se preocupan de que estos sean recibidos por un slot.
  • Se pueden conectar multiples signals a un solo slot.
  • Se pueden conectar un signal a multiples slots.
  • Se puede conectar un signal con otro signal.
  • Para conectarse un signal con un slot estos deben tener el mismo numero de parametros y el mismo tipo de parametros en el orden correcto.
  • Existe una simple excepcion, si un signal contiene mas parametros que un slot y ambos se conectan, se obviaran los parametros sobrantes en el signal.


No existe mejor forma para hechar un vistazo que viendo un codigo de ejemplo que demuestre lo antes explicado.

Código (cpp) [Seleccionar]

//Ejemplo.h
#ifndef EJEMPLO_H
#define EJEMPLO_H

#include <QtGui>

class QSpinBox;
class QSlider;
class QLabel;
class QVBoxLayout;
class QHBoxLayout;

class Ejemplo : public QWidget
{
   Q_OBJECT

signals:
   void setRGB(int,int,int);

private slots:
   void getRGB(int,int,int);
   void setRed(int);
   void setGreen(int);
   void setBlue(int);
   void setAlpha(int);

private:
   short int red, green, blue, alpha;
   QSpinBox *SpinRed, *SpinGreen, *SpinBlue;
   QSlider *SliderRed, *SliderGreen, *SliderBlue;
   QLabel *LabelRed, *LabelBlue, *LabelGreen;
   QVBoxLayout *LeftVertical, *MiddleRightVertical, *MiddleLeftVertical;
   QHBoxLayout *MainHorizontal;


public:
   Ejemplo(QWidget *parent = 0);


};

#endif // EJEMPLO_H



Código (cpp) [Seleccionar]

//Ejemplo.cpp
#include "ejemplo.h"

Ejemplo::Ejemplo(QWidget *parent)
   : QWidget(parent)
{

   //Construimos los Slider que utilizaremos.
   this->SliderBlue = new QSlider(Qt::Vertical,0);
   this->SliderBlue->setMinimum(0);
   this->SliderBlue->setMaximum(255);
   this->SliderRed = new QSlider(Qt::Vertical,0);
   this->SliderRed->setMinimum(0);
   this->SliderRed->setMaximum(255);
   this->SliderGreen = new QSlider(Qt::Vertical,0);
   this->SliderGreen->setMinimum(0);
   this->SliderGreen->setMaximum(255);

   //Construimos los SpinBox que utilizaremos.

   this->SpinRed = new QSpinBox;
   this->SpinRed->setMinimum(0);
   this->SpinRed->setMaximum(255);
   this->SpinBlue = new QSpinBox;
   this->SpinBlue->setMinimum(0);
   this->SpinBlue->setMaximum(255);
   this->SpinGreen = new QSpinBox;
   this->SpinGreen->setMinimum(0);
   this->SpinGreen->setMaximum(255);

   //Construimos los Labels.
   this->LabelBlue = new QLabel("Azul");
   this->LabelGreen = new QLabel("Verde");
   this->LabelRed = new QLabel("Rojo");

   //Construimos los Layout para Organizar.
   this->LeftVertical = new QVBoxLayout;
   this->MiddleLeftVertical = new QVBoxLayout;
   this->MiddleRightVertical = new QVBoxLayout;
   this->MainHorizontal = new QHBoxLayout;

   //Vamos agregando los Objetos a los Layout.
   this->LeftVertical->addWidget(this->LabelRed);
   this->LeftVertical->addWidget(this->SpinRed);
   this->LeftVertical->addWidget(this->SliderRed);
   this->MiddleLeftVertical->addWidget(this->LabelGreen);
   this->MiddleLeftVertical->addWidget(this->SpinGreen);
   this->MiddleLeftVertical->addWidget(this->SliderGreen);
   this->MiddleRightVertical->addWidget(this->LabelBlue);
   this->MiddleRightVertical->addWidget(this->SpinBlue);
   this->MiddleRightVertical->addWidget(this->SliderBlue);
   this->MainHorizontal->addLayout(this->LeftVertical);
   this->MainHorizontal->addLayout(this->MiddleLeftVertical);
   this->MainHorizontal->addLayout(this->MiddleRightVertical);
   this->setLayout(this->MainHorizontal);
   this->setWindowTitle("Cambia el Fondo(Codigo de Ejemplo)");

   this->MainHorizontal->addStretch();
   this->setFixedHeight(this->sizeHint().height());

   this->red = 0;
   this->blue = 0;
   this->green = 0;
   this->alpha = 0;

   //Realizamos las conexiones que necesitaremos.
   connect(this->SpinRed,SIGNAL(valueChanged(int)),this->SliderRed,SLOT(setValue(int)));
   connect(this->SpinGreen,SIGNAL(valueChanged(int)),this->SliderGreen,SLOT(setValue(int)));
   connect(this->SpinBlue,SIGNAL(valueChanged(int)),this->SliderBlue,SLOT(setValue(int)));
   connect(this->SliderRed,SIGNAL(valueChanged(int)),this->SpinRed,SLOT(setValue(int)));
   connect(this->SliderGreen,SIGNAL(valueChanged(int)),this->SpinGreen,SLOT(setValue(int)));
   connect(this->SliderBlue,SIGNAL(valueChanged(int)),this->SpinBlue,SLOT(setValue(int)));
   connect(this->SliderRed,SIGNAL(valueChanged(int)),this,SLOT(setRed(int)));
   connect(this->SliderGreen,SIGNAL(valueChanged(int)),this,SLOT(setGreen(int)));
   connect(this->SliderBlue,SIGNAL(valueChanged(int)),this,SLOT(setBlue(int)));
   connect(this,SIGNAL(setRGB(int,int,int)),this,SLOT(getRGB(int,int,int)));



   emit setRGB(this->red,this->green,this->blue); //Enviamos una señal para cambiar el color.

   }

void Ejemplo::setAlpha(int change)
{
   this->alpha = change;
   emit setRGB(this->red,this->green,this->blue); //Enviamos una señal para cambiar el color.

   }

void Ejemplo::setRed(int change)
{
   this->red = change;
   emit setRGB(this->red,this->green,this->blue); //Enviamos una señal para cambiar el color.

   }

void Ejemplo::setGreen(int change)
{
   this->green = change;
   emit setRGB(this->red,this->green,this->blue); //Enviamos una señal para cambiar el color.

   }

void Ejemplo::setBlue(int change)

{
   this->blue = change;
   emit setRGB(this->red,this->green,this->blue); //Enviamos una señal para cambiar el color.
   }

void Ejemplo::getRGB(int red, int green, int blue)
{
QColor *Background = new QColor(red,green,blue,255);
QPalette *Paleta = new QPalette;
Paleta->setColor(QPalette::Background,Background->convertTo(QColor::Rgb));
this->setPalette(*Paleta);
}



Código (cpp) [Seleccionar]

//main.cpp
#include <QtGui/QApplication>
#include "ejemplo.h"

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   Ejemplo w;
   w.show();
   return a.exec();
}
#24
Buenas Noches, disculpen pero he visto que en estas semanas en el foro varios usuarios van posteando siempre el mismo mensaje... me parece que son cuentas creadas por el mismo usuario para hacer spam. Aqui les dejo el link refiriendome al ultimo caso.

http://foro.elhacker.net/desafios_wargames/tienes_cosas_por_hacer_en_internet_y_necesitas_dinero_en_paypalalertpay-t297493.0.html
#25
Foro Libre / IRC de elhacker.net
19 Mayo 2010, 14:57 PM
Tanto tiempo un grupo de usuarios solicitando un chat... dan el chat y ahora nadie entra, que sucede? :xD parece como si fueran las fantasias de algunos que al obtenerlas ya pierden interes. Siempre somos los mismos.

ESPERAMOS A LOS USUARIOS QUE SOLICITABAN EL CHAT OFICIAL.
#26
Foro Libre / Piropea a Bianc4
15 Mayo 2010, 00:03 AM
Bianc4, la nueva integrante de la comunidad... moderadora de nuestro Chat en IRC te queremos dedicar los mejores piropos...

Dejen Sus Piropos a Bianc4:

bianc4 quisiera hacerte un BufferOverflow para meterte mi exploit.
#27
[Taller] Introduccion al Diseño de Rutinas de Encriptacion


Contenido

1.   Introducción
1.1 Concepto de Encriptacion

2.   Tipos de Encriptacion.
2.1 Encriptacion Por Sustitucion.
2.2 Encriptacion por Llaves Corredizas
2.3 Encriptacion por Llaves Largas
2.4 Encriptacion por Transposicion

3.   Despedida


1. Introduccion


En este taller sobre diseño de rutinas de encriptacion bajo Assembler debido a su simplicidad para ser añadidos a proyectos en C/C++ y Delphi. Para seguir el taller no se necesitara mas que conocimientos basicos sobre Assembler.

Tambien es recomendado el conocimiento basico del formato PE, especificamente los flag de la sección, debido a que seran necesario para la desencriptacion en memoria del codigo del programa.

De cada Tipo de encriptacion dare 2 ejemplos (a menos que crea que no es necesario), uno sencillo  para que se familiaricen con el metodo y otro metodo un poco mas complejo para que capten una idea del uso que se podria dar.


1.1 Concepto de Encriptacion

La encriptacion no es mas que el metodo utilizado para volver ilegible una sección de codigo que consideremos importante. La encriptacion debe de ser lo mas robusta posible complicando asi el analisis de dicha rutina.

2. Tipos de Encriptacion

Se podria decir que existen miles de rutinas de encriptacion pero la gran mayoria se basa en la combinacion de 2 o mas de los principales tipos de encriptacion. por ejemplo la mezcla una encriptacion simple con una encriptacion de transposicion podria ser robusta. Todo depende de las ganas de creacion del programador y el empeño que este quiera añadir a la rutina diseñada.

Los tipos de encriptacion que voy a tratar en este taller son:



  • Encriptacion por Sustitucion (Substitution Encryption).
  • Encriptacion por Llaves Corredizas (Sliding Key Encryption).
  • Encriptacion por llaves largas (Long Key Encryption).
  • Encriptacion por Transposicion (Transposition Encryption).



2.1-Encriptacion por Sustitucion.


Se podria decir que es uno de los metodos mas utilizados para encriptacion, A cada byte se agregar, reducir, rotar, etc. para la creacion de un nuevo caracter que sera el sustituto del caracter anterior. Para descifrar dicha encriptacion tan solo es necesario la realizacion de las operaciones de encriptacion pero con el orden inverso, por ejemplo si rotaste a la derecha un X numero de bits para descifrar debes rotar a la izquierda igual numero de bits.

La operacion mas utilizada para este tipo de encriptacion es el metodo XOR, debido a que la misma rutina de encriptacion funciona para la desencriptacion.

Codigo Ejemplo1:
Código (asm) [Seleccionar]

mov ecx,(fin_codigovir - ini_codigovir)/2 ; Tomamos el numero de words de longitud del codigo a cifrar
mov esi,ini_codigovir ; Pasamos a ESI el principio del codigo a cifrar
mov edi,esi ; Copiamos en EDI el valor de ESI (principio de codigo a cifrar)
mov bx,0F432h ; Pasamos la llave a bx

encrypt_routine:         ; Inicio de la rutina de encriptacion
lodsw ; Movemos a AX el vamor de [ESI] y sumamos 2 a ESI
xor ax,bx         ; XOR a AX con respecto a BX
stosw ; Movemos a [EDI] el valor de AX y sumamos 2 a EDI
loop encrypt_routine


En este ejemplo pasado al ser utilizado el Metodo XOR puede ser utilizado tanto para encriptacion como para desencriptacion.Esto que parece una ventaja para el programador es una desventaja para la encriptacion que este esta realizando en su codigo.

Codigo Ejemplo2(Encriptacion): Quedara de parte del usuario que lee el taller deducir que hace el codigo (Tomenlo como ejercicio mental xD)


Código (asm) [Seleccionar]
mov ecx,(fin_codigovir - ini_codigovir)/2
mov esi,ini_codigovir
mov edi,esi
mov bx,0F432h

encrypt_routine:
lodsw
rol al,bh
add al,bl
ror ah,bl
add ah,bh
xor ax,bx
stosw
loop encrypt_routine

Codigo Ejemplo2(Desencriptacion):Lo mismo de la rutina de  encriptacion (Ejercicio Mental xD)

Código (asm) [Seleccionar]
mov ecx,(fin_codigovir - ini_codigovir)/2
mov esi,ini_codigovir
mov edi,esi
mov bx,0F432h

decrypt_routine:
lodsw
ror al,bh
sub al,bl
rol ah,bl
sub ah,bh
xor ax,bx
stosw
loop encrypt_routine



2.2 Encriptacion por Llaves Corredizas

En el tipo de encriptacion de llave corrediza, en la encriptacion de cada byte la llave experimenta un cambio en su valor. Es una especie de encriptacion simple que dentro de su rutina realiza cambios a la llave de encriptacion.

Codigo Ejemplo1:

Código (asm) [Seleccionar]
mov ecx,(fin_codigovir - ini_codigovir)/2 ; Tomamos el numero de words de longitud del codigo a cifrar
mov esi,ini_codigovir ; Pasamos a ESI el principio del codigo a cifrar
mov edi,esi ; Copiamos en EDI el valor de ESI (principio de codigo a cifrar)
mov bx,0F432h ; Pasamos la llave a bx

encrypt_routine: ; Inicio de la rutina de encriptacion
lodsw ; Movemos a AX el vamor de [ESI] y sumamos 2 a ESI
xor ax,bx ; XOR a AX con respecto a BX
stosw ; Movemos a [EDI] el valor de AX y sumamos 2 a EDI
dec bx ; Modificamos el valor de la llave almacenada en bx
loop encrypt_routine

Al igual que en el ejemplo pasado al ser utilizado el Metodo XOR puede ser utilizado tanto para encriptacion como para desencriptacion.

Codigo Ejemplo2(Encriptacion):Otra vez lo mismo (Ejercicio Mental xD)


Código (asm) [Seleccionar]
mov ecx,(fin_codigovir - ini_codigovir)/2
mov esi,ini_codigovir
mov edi,esi
mov bx,0F432h

encrypt_routine:
lodsw
rol al,bh
add al,bl
ror ah,bl
add ah,bh
xor ax,bx
rol bx,bl
dec bx
not bx
stosw
loop encrypt_routine

Codigo Ejemplo2(Desencriptacion):Me canse de Escribir... a partir de ahora solo pondre (Ejercicio Mental xD)
Código (asm) [Seleccionar]

mov ecx,(fin_codigovir - ini_codigovir)/2
mov esi,ini_codigovir
mov edi,esi
mov bx,0F432h

decrypt_routine:
lodsw
ror al,bh
sub al,bl
rol ah,bl
sub ah,bh
xor ax,bx
rol bx,bl
dec bx
not bx
stosw
loop encrypt_routine


2.3-Encriptacion por Llaves Largas

En este metodo se toma una sección de datos o codigo mayor al tamaño de un registro para realizar una llave, dicho tamaño estara definido por el programador, por lo tanto la llave puede medir desde 4 bytes hasta donde crea necesario el programador de la rutina de encriptacion.

Codigo Ejemplo1:
Código (asm) [Seleccionar]

mov ecx,(fin_codigovir - ini_codigovir)/2 ; Tomamos el numero de words de longitud del codigo a cifrar
mov esi,ini_codigovir ; Pasamos a ESI el principio del codigo a cifrar
mov edi,esi ; Copiamos en EDI el valor de ESI (principio de codigo a cifrar)
mov ebx,offset ini_llave ; Movemos a ebx la direccion del inicio de la llave
mov dx,fin_llave-ini_llave ; Movemos a dx el tamaño de la llave

encrypt_routine: ; Inicio de la rutina de encriptacion
lodsw ; Movemos a AX el vamor de [ESI] y sumamos 2 a ESI
xor ax,bx ; XOR a AX con respecto a BX
add bx,2 ; Nos movemos 1 word dentro de la llave (2bytes)
cmp bx,dx ; Comparamos si bx y dx son iguales
jne cont: ; Si no son iguales continuamos la rutina
mov ebx,offset ini_llave; Si son iguales llegamos al final de la llave, por lo tanto debemos volver al inicio
cont:
stosw ; Movemos a [EDI] el valor de AX y sumamos 2 a EDI
loop encrypt_routine

Este tipo de encriptacion no necesita la explicacion de un codigo con un cierto mayor grado de complejidad debido a que simplemente el registro va tomando valores de una llave de gran longitud y la rutina de encriptacion solo esta realizando una encriptacion simple con diferentes valores como llave.

2.4-Encriptacion por Transposicion

Este metodo invierte cada par de Word en la sección de codigo que queremos cifrar, es un metodo muy debil, se podria decir que el mas debil de todos pero combinado con otro de los metodos es un serio dolor de cabeza para quien trate de desencriptarlo manualmente.

Codigo Ejemplo1:
Código (asm) [Seleccionar]

mov ecx,(fin_codigovir - ini_codigovir)/2 -;Tomamos el numero de words de longitud del codigo a cifrar
mov esi,ini_codigovir ; Pasamos a ESI el principio del codigo a cifrar
mov edi,esi ; Copiamos en EDI el valor de ESI (principio de codigo a cifrar)

encrypt_routine:
lodsw ; Movemos a AX el valor de [ESI] y sumamos 2 a ESI
mov bx,ax ; Guardamos en BX el valor de AX
lodsw ; Movemos a AX el valor de [ESI] y sumamos 2 a ESI
stosw ; Movemos a [EDI] el valor de AX y sumamos 2 a EDI
mov ax,bx ; Recuperamos el valor que guardamos previamente en BX y lo retornamos a AX
stosw ; Movemos a [EDI] el valor de AX y sumamos 2 a EDI
loop encrypt_routine

Como ven no es una rutina de otro mundo y muy debil trabajando sola, debido a que no hace una sustitucion de bytes y con solo alterar el orden de los bytes de word en word ya esta descifrado. Al igual que en el metodo XOR esta rutina puede cifrar o descifrar sin necesidad de modificacion alguna.

3. Despedida

Bueno eso es todo, cualquier toda en lo que concierne al tema pueden dejar sus preguntas en el foro o contactarme via MSN/E-mail que con gusto le respondere las preguntas que tengan. Todo tipo de criticas son aceptadas (Contructivas, Destructivas, Exageradas, Ignorantes, etc.).

Espero que esto sirva de ayuda para aquellos que se motiven en hacer o diseñar sus propias rutinas de encriptacion.