Algo heavy en C++

Iniciado por Kaxperday, 12 Julio 2015, 20:58 PM

0 Miembros y 1 Visitante están viendo este tema.

Kaxperday

Hola miren, quiero realizar un MITM a la red, para ello me estoy sirviendo de wpcap.

Tengo la lista de usuarios en la red con su ip y mac asociada.

Ahora bien ya se como mandar mensajes ARP response para engañarlos y que me manden los datos a mí, el problema viene ahora.

Los mensajes ARP respose se los mando a los usuarios de una lista donde tengo las ips y sus macs de los usuarios de la red.

Lo que quiero es pasar el vector donde tengo las ips y macs a una funcion para que mande ARP responses a los hosts, pero a la vez quiero estar monitoreando el tráfico y añadiendo nuevos miembros a esa lista, y en caso de que uno falle o no responda ni un paquete en X tiempo quitarlo, si el numero de hosts es menor a X también se detendría, no sé si sería buena idea hacer 2 asyncs o threads.

Uno para mandar ARP responses y envenenar la red y otro que mientras me actualice la lista de hosts con sus ip y mac, la duda es:

¿Si tengo 2 asyncs que comparten una variable en este caso una clase que contiene un vector con la lista de usuarios, y una me está añadiendo y eliminando elementos mientras otra está trabajando con ellos, ¿fallaría el programa o no?

Ya os digo usar 2 asyncs o threads, uno escanea y actualiza la red y otro hace el spoofing.

Nada más, sino también se me ocurre meterlo todo en una función pero no sería igual de elegante y quedaría un poco gorda.

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Como dije, tienes que usar un método de que solo un hilo entre a los fragmentos de código que modifican campos de la clase.
Mutex es la mejor opción en C++.

Kaxperday

Pero.. ¿con mutex lo que hago no es detener un proceso (async o thread) para centrarme en otro? Es decir, cuando haga el lock el otro proceso se detendría y podría añadir los hosts pero en ese tiempo el otro proceso estaría muerto, no me parece tampoco muy buena solución.

De todas formas seguiré leyendo acerca de ello a ver si lo acabo entendiendo.

Básicamente lo que sé es que es un método de pasarse la pelota entre procesos, y no sería lo más eficiente, quizás podríamos saltarlo y que funcionara. O utilizar otro método como variables volatiles globales, ¿podría funcionar?

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Estará muerto durante unos milisegundos, tal vez menos. Solo durante el tiempo que accedes a los puntos importantes donde se modifican campos del código.

Si no quieres definitivamente detener el hilo, también tienes mutex::try_lock, que entra y bloquea el mutex en caso de que pueda. Si no puede porque ya hay un hilo dentro, retorna false.

Citarno sería lo más eficiente

¿Qué sería más eficiente? ¿Usar variables globales entre hilos para saber cual entra y cual no? Es lo mismo que usar mutex.

De todos modos, por qué quieres usar variables volatiles. Las variables volatiles evitan que el compilador optimize fragmentos de código donde las variables no se usen aparentemente.

Kaxperday

#4
CitarEstará muerto durante unos milisegundos, tal vez menos.

Mmm es verdad, deberia ser solo para añadir un host a la lista con ip y mac (un vector), luego lo desbloquearía, entonces.. si el otro proceso estaba recorriendo el vector, cuando yo he añadido o eliminado un elemento para ese vector usando mutex, ¿cómo se debería de comportar el otro proceso que estaría recorriendo en ese momento los elementos del vector?

Supongo que podría fallar, puesto que si en ese momento estaba haciendo algo como:

for(int i=0;i<lista.usuarios.size();i++

Y en ese caso, lista.usuarios.size() valía 5, y estaba por el elemento i=4 (último y quinto elemento), al añadir un nuevo elemento por ejemplo ¿ya lo estaría teniendo en cuenta e iría hasta el sexto no? (i=5). Y si elimino uno, me saldría del bucle.... vamos esos problemas vendrían de una mala colocación del lock.

Bueno trataré de implementarlo se me hace algo raro, ya lo iré poniendo por aquí a ver que tal va, gracias socio.

Saludos.

Edito: Me vendría bien un poco de ayuda con la implementación pues soy nuevo en esto y se me puede alargar un poco, a ver que os parece esto:

Código (cpp) [Seleccionar]

mutex mtx;
int main()
{
auto a = async(arp_spoofing, ..);
auto b = async(actualiza_usuarios, ..);
}
void arp_spoofing(lista_usuario lista)
{
for (int i; i < lista.usuarios.size(); i++)
{
spoof(ip, mac);
               //cuando acaba una ronda espera X tiempo...
                //quizás aqui podria desbloquear el mutex para que modifiquen la lista
                //pero como?
}
}

void actualiza_usuarios(lista_usuarios lista)
{
//analizo paquetes que entran
//cada x tiempo reactualizo los host de la red.
//ejemplo añadiria 1 y eliminaria 2.
mtx.lock();
lista.añadir(ip1, mac1);
lista.eliminar_host(ip2, mac2);
lista.eliminar_host(ip3, mac3);
mtx.unlock();

}


¿Donde debería de meter el mutex en arp_spoofing?
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

¿cómo se debería de comportar el otro proceso que estaría recorriendo en ese momento los elementos del vector?

Cualquier operación de vector, incluyendo recorrerlo, ha de ser envuelta por el mutex.

Código (cpp) [Seleccionar]
#ifndef MUTEX_TYPE
#define MUTEX_TYPE

#include <mutex>

template<class T>
class MutexType{
    T _value;
    std::mutex _m;

public:
    MutexType(){}
    MutexType(T newValue):_value(newValue){}
    MutexType(const MutexType&)=delete;

    T& lock(){
        _m.lock();
        return _value;
    }

    void unlock(){
        _m.unlock();
    }
};

#endif // MUTEX_TYPE


Esta clase para envolver cualquier tipo en mutex, te puede ayudar. Claro que esta implementación basa su fiabilidad en el programador que la utilice, pues puedes hacer lock() y luego unlock() y seguir usando el objeto.

También puedes hacer funciones para trabajar con un objeto privado:

Código (cpp) [Seleccionar]
template<class T>
class Mutexvector{
    std::mutex _m;
    std::vector<T> _v;

public:
    void push_back(T value){
        _m.lock();
        _v.push_back(value);
        _m.unlock();
    }
    /* ... */

};


Uses mutex, uses variables, uses lo que quieras usar, simplemente tienes que entender que acceder a contenido dinámico y modificarlo desde varios hilos (o ya incluso contenido estático), puede dar muchos problemas.

Kaxperday

#6
No entiendo como me podría ayudar ese code a solventar mi problema mm.

Código (cpp) [Seleccionar]
mutex mtx;
int main()
{
auto a = async(arp_spoofing, ..);
auto b = async(actualiza_usuarios, ..);
}
void arp_spoofing(lista_usuario lista)
{
        mtx.lock();
for (int i; i < lista.usuarios.size(); i++)
{
spoof(ip, mac);
                //cuando acaba una ronda espera X tiempo...
                //quizás aqui podria desbloquear el mutex para que modifiquen la lista
                //pero como?
                if(ha acabado una ronda)
                      mutex.unlock(); Sleep(2000);
                mutex.lock();
}
}

void actualiza_usuarios(lista_usuarios lista)
{
//analizo paquetes que entran
//cada x tiempo reactualizo los host de la red.
//ejemplo añadiria 1 y eliminaria 2.
mtx.lock();
lista.añadir(ip1, mac1);
lista.eliminar_host(ip2, mac2);
lista.eliminar_host(ip3, mac3);
mtx.unlock();

}


Vamos no veo necesario para hacer esto usar una clase, la idea del mutex aplicada aquí,  la implementaría haciendo que cuando arp_spoofing acabe una ronda de arps, desbloquee el mutex, y entonces actualiza_usuarios proceda a modificar el vector.

Pero debería de pillar a actualiza_usuarios ya preparada para hacerlo y esperando ese unlock(), se juntan varias cosas con desconocimiento del tema XPP

Bueno aún no me he puesto a implementarlo, pero será divertido. >:D >:D

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Código (cpp) [Seleccionar]
Sleep(2000);

Eso sobraría. Una vez hecho el unlock, si el otro hilo ha invocado lock(), se meterá. No necesitas esperar.

En cualquier caso, recorrer el vector con un índice es muy inapropiado. Podría el otro hilo eliminar una direccion, y entonces tu índice se podría saltar algún elemento.

Lo que deberías hacer, es copiar el vector, y liberar el mutex.

No hay cabidad a la suerte en la programación...

Kaxperday

Una cosa,

¿cuando hago unlock() en async1 entrará en el otro async2 si este habría llamado al lock(), pero como puedo hacer que si no tenga llamado el lock() aún espere y lo use cuanto antes, es decir sino coincidirían el unlock() de uno con el lock() del otro, bueno me estoy haciendo la picha un lío, cuando lo pruebe comentare avances mejor  :¬¬ :¬¬ :xD

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

A nivel práctico, el mutex es tan sencillo como lo dicho. Al llamar a lock(), se va a esperar hasta que se llame unlock, y sea su turno (puede haber varios hilos habiendo llamado al lock). No es más que eso. Ahora ya, impleméntalo como quieras.

Pero como he dicho, es atroz recorrer un array con un índice sabiendo que el array puede cambiar de tamaño en cualquier momento.