Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Romualdo23 en 24 Abril 2015, 04:45 am



Título: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: Romualdo23 en 24 Abril 2015, 04:45 am
Hola amigos.

Tengo una funcion en C que me muestra en consola el perfil wireless que yo le indique, hasta aqui todo bien. El problema esta en que recibo los datos en ese formato:

Código
  1. <?xml version="1.0"?>
  2. <WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
  3. <name>NombrePerfil</name>
  4. <SSIDConfig>
  5. <SSID>
  6. <hex>75775657685794438794</hex>
  7. <name>NombrePerfil</name>
  8. </SSID>
  9. </SSIDConfig>
  10. <connectionType>ESS</connectionType>
  11. <MSM>
  12. <security>
  13. <authEncryption>
  14. <authentication>WPA2PSK</authentication>
  15. <encryption>AES</encryption>
  16. <useOneX>false</useOneX>
  17. </authEncryption>
  18. <sharedKey>
  19. <keyType>passPhrase</keyType>
  20. <protected>false</protected>
  21. <keyMaterial>1234567890</keyMaterial>
  22. </sharedKey>
  23. <keyIndex>1</keyIndex>
  24. </security>
  25. </MSM>
  26. </WLANProfile>



Entonces necesitaria una funcion que extraiga los datos que hay entre <name> y </name>, <connectionType> y </connectionType> y asi con todos los valores.

Quedaria algo asi en consola:

Nombre del perfil: NombrePerfil
Tipo de conexion: ESS
Aunenicacion: WPA2PSK

etc..

Aclaracion: los datos no los recibo de un archivo, sino del PC, de los perfiles almacenados en la WLAN con esta llamada:

hp = Device->GetProfile(ARRAYSIZE(profBuffer), profBuffer);

He probado con este codigo que vi por inernet, pero se bloquea la aplicacion y se termina (creo que se bloquea porque es codigo de C++ y al tratar de usarlo en C se bloquea, no lo se):


    
Código
  1. int size = 0;
  2.  
  3.    wchar_t* Perfil = profBuffer;
  4.  
  5.    std::string text(Perfil, Perfil + size);
  6.  
  7.    // define what we're looking for
  8.    std::string begin_text("<name>");
  9.    std::string end_text("</name>");
  10.  
  11.    // find the start and end of the text we need to extract
  12.    size_t begin_pos = text.find(begin_text) + begin_text.length();
  13.    size_t end_pos = text.find(end_text);
  14.  
  15.    // create a substring from the positions
  16.    std::string extract = text.substr(begin_pos,end_pos);
  17.  
  18.    // test that we got the extract
  19.    wprintf(L"\nINFO: Nombre del perfil: ", extract);

Espero que me puedan ayudar. Saludos!!


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: ivancea96 en 24 Abril 2015, 11:48 am
En primer lugar, size es siempre 0. Tendrás que poner ahí el tamaño de la cadena.

En segundo lugar, pon esta linea en sustitucion de la antigua:
Código
  1. std::string extract = text.substr(begin_pos,end_pos-begin_pos);

En tercer lugar, en caso de que quieras agarrar todos los datos, tal vez te interese crear un método para leer un xml y guardarlo ordenadamente, eso ya como veas.


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: Romualdo23 en 24 Abril 2015, 20:43 pm
En primer lugar, size es siempre 0. Tendrás que poner ahí el tamaño de la cadena.

¿Como puedo saber que tamaño tiene la cadena?

En segundo lugar, pon esta linea en sustitucion de la antigua:
Código
  1. std::string extract = text.substr(begin_pos,end_pos-begin_pos);

He reemplazado lo que me has dicho pero sigue colgandose y cerrandose la aplicacion..

En tercer lugar, en caso de que quieras agarrar todos los datos, tal vez te interese crear un método para leer un xml y guardarlo ordenadamente, eso ya como veas.

Si, estuve mirando tambien esa opcion, pero los ejemplos que encontre eran solo para abrir archivos xml y yo en este caso no necesito abrir ningun archivo, ya que los datos los recibo del pc y se almacenan en un buffer..

Gracias por la ayuda.


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: Romualdo23 en 24 Abril 2015, 22:35 pm
¿¿¿ Tan dificil es hacer eso en C ????

Si eso mismo en VB.NET lo hago en 1 minuto con esta funcion...

 
Código
  1.    Dim Cadena As String = XmlProfile
  2.    Dim Delimitador_Ini As String = "<name>"
  3.    Dim Delimitador_Fin As String = "</name>"
  4.  
  5.    Cadena = Split(Cadena , Delimitador_Ini, , CType(CompareMethod.Text, Microsoft.VisualBasic.CompareMethod))(1)
  6.    Cadena = Split(Cadena , Delimitador_Fin, , CType(CompareMethod.Text, Microsoft.VisualBasic.CompareMethod))(0)
  7.  
  8.    Label1.Text = "Nombre del perfil: " & Cadena


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: ivancea96 en 24 Abril 2015, 23:30 pm
Lo que tratas de hacer en C++ es ese Split() de VB. No es dificil.

wcslen(cadena) retorna el tamaño de la cadena. Intuyo que si no conoces el tamaño, es porque no lo puedes conseguir mediante las funciones de windows.

Si aun asi no te va, trata de usar wstring en vez de string, ya que estás usando wchar_t


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: Romualdo23 en 25 Abril 2015, 01:20 am
Nada, no hay forma de hacerlo. Lo dejo ya por imposible porque llevo dos dias con esta tonteria y estoy empezando a ponerme de mala hosia.


Título: Re:
Publicado por: ivancea96 en 25 Abril 2015, 09:57 am
No, no es imposible, es sencillo. Busca en que punto se cuelga, y sabrás que error es. Puede ser un out_of_range exception en substr. Tal vez porque no encuentre la cadena. Saca por pantalla begin_pos y end_pos despues de calcularlos, y verás cual puede ser el error.


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: Romualdo23 en 25 Abril 2015, 16:34 pm
¿Puede que el error sea porque "profBuffer" ya este declarado como WCHAR y yo lo estaba declarando mas abajo como wchar_t?

El codigo que muesra el perfil xml completo en consola es el siguiente:

Código
  1. UINT status = ERROR_SUCCESS;
  2.  
  3.                WCHAR profBuffer[WPA_API_MAX_BUFFER_SIZE] = {0};
  4.        HANDLE wlanHandle = 0;
  5.        GUID interfaceGuid = {0};
  6.        DWORD wlanResult = 0;
  7.  
  8.                status = WlanGetProfile(wlanHandle, &interfaceGuid, 0, profBuffer, NULL, TRUE, NULL, &wlanResult);
  9.  
  10.                wprintf(profBuffer);

Con ese codigo obtengo esta salida:

(http://i.imgur.com/SRai2hB.png)

Por otra parte, he probado lo que comentas y nunca recibo ningun valor al comprobar "begin_pos" y "end_pos", es como si no leyera la cadena de texto por algun motivo..

Asi lo estoy haciendo ahora, ya no declaro"profBuffer" como  wchar_t y le he asignado un tamaño a int:

    
Código
  1.  
  2.    int size = 2000;
  3.  
  4.    std::string text(profBuffer, profBuffer + size);
  5.  
  6.    // define what we're looking for
  7.    std::string begin_text("<name>");
  8.    std::string end_text("</name>");
  9.  
  10.    // find the start and end of the text we need to extract
  11.    size_t begin_pos = text.find(begin_text) + begin_text.length();
  12.    size_t end_pos = text.find(end_text);
  13.  
  14.    wprintf(L"\nINFO: begin_pos: ", begin_pos);
  15.    wprintf(L"\nINFO: end_pos: ", end_pos);
  16.  
  17.    // create a substring from the positions
  18.    std::string extract = text.substr(begin_pos, end_pos);
  19.  
  20.     //test that we got the extract
  21.     wprintf(L"\nINFO: Nombre del perfil: ", extract);

De esta forma ya no se cuelga, pero tampoco me muestra nada en consola..

(http://i.imgur.com/bBaaHFW.png)

Parece que el mtoivo de que se colgara era que antes ponia "int size = 0;", Ahora con "int size = 2000;" ya no se cuelga, pero como digo, parece que no lee la cadena..


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: ivancea96 en 25 Abril 2015, 16:58 pm
wprintf y printf no se utilizan así. http://www.cplusplus.com/reference/cstdio/printf/ (http://www.cplusplus.com/reference/cstdio/printf/)

Código
  1. wprintf(L"\nINFO: begin_pos: %u", begin_pos);

En cualqueir caso, y dado que es C++, puedes evitar wprintf utilizando wcout de iostream:

Código
  1. wcout << endl << L"INFO: begin_pos: " << begin_pos;


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: Romualdo23 en 25 Abril 2015, 17:02 pm
Me dice que wcout y endl no esan definidos..


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: ivancea96 en 25 Abril 2015, 17:44 pm
Son de la librería <iostream>.

Cuando tengas esas dudas, te es más cómodo escribir "cout" en Google, y ya obtienes la solución :/


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: Romualdo23 en 25 Abril 2015, 17:51 pm
Vale, vamos avanzando, habia que añadir esto:

Código
  1. using std::string;
  2. using std::cout;
  3. using std::endl;

Ahora si me devuelve la posicion con:

Código
  1. cout << endl << L"INFO: begin_pos: " << begin_pos;
  2. cout << endl << L"INFO: end_pos: " << end_pos;

(http://i.imgur.com/DvftLB9.png)

Ahora solo falta extraer la cadena, he probado con

Código
  1. wprintf(L"\nINFO: Nombre del perfil: ", extract);

Pero no devuelve nada.

Edito:

Bueno, esto va mejorando.. Ahora ya me muestra algo, pero parece que por algun motivo, no se selecciona bien la longitud de los datos que tiene que extraer y me muestra mas caracteres de los que deberia:

(http://i.imgur.com/PqHS40o.png)

El comienzo lo hace bien ya que se puede ver que comienza a extraer desde "MiRed", pero como digo, la longiud de los datos que captura no es la correcta, deberia capturar solo hasta "</name>", quedando en consola solamente "MiRed"

Este es el codigo que utilizo:

    
Código
  1. int size = 1000;
  2.  
  3.    std::string text(profBuffer, profBuffer+ size);
  4.  
  5.    std::string begin_text("<name>");
  6.    std::string end_text("</name>");
  7.  
  8.    size_t begin_pos = text.find(begin_text) + begin_text.length();
  9.    size_t end_pos = text.find(end_text);
  10.  
  11.    std::string extract = text.substr(begin_pos,end_pos);
  12.  
  13.    const char* NombrePerfil = extract.c_str();
  14.  
  15.    std::cout << NombrePerfil << std::endl;

Edito de nuevo:

Pues ya esta resuelto, con tantos cambios habia olvidado reemplazar otra vez la linea que me dijiste ayer:

Código
  1. std::string extract = text.substr(begin_pos,end_pos);

                                                                         Por

Código
  1. std::string extract = text.substr(begin_pos,end_pos-begin_pos);


Una ultima pregunta..

Es posible guardar los datos extraidos en una variable, para utilizar posteriormente esos datos sin tener que volver a consultar el perfil xml?


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: ivancea96 en 25 Abril 2015, 20:33 pm
Vale, vamos avanzando, habia que añadir esto:

Código
  1. using std::string;
  2. using std::cout;
  3. using std::endl;

Si quieres puedes poner solo:
Código
  1. using namespace std;


Los datos extraidos ya los tienes en extract, no?


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: Romualdo23 en 25 Abril 2015, 21:29 pm
Si, pero me refiero a si quiero utilizar los datos en otra funcion. Primero habria que crear una variable global para pasarle los datos extraidos y luego esa variable poder usarla en cualquier parte del codigo.

En vb.net se hacerlo, pero no en C++



Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: ivancea96 en 25 Abril 2015, 21:57 pm
Código
  1. std::string text(profBuffer, profBuffer+ size)
Esa variable haces con ella lo que quieras.


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: Romualdo23 en 25 Abril 2015, 22:13 pm
Pero ilustrame un poco hombre, que nunca he tocado este lenguaje de programacion..

Un pequeño ejemplo o algo, no se..


Título: Re: ¿Como extraer cadenas especificas de un perfil wireless xml?
Publicado por: ivancea96 en 25 Abril 2015, 22:20 pm
Como en VB, son variables. No hay mucho no obvio que decir de ellas. En VB son paredicas. Con esa string haces lo que quieras, se la mandas a funciones, la copias en otra variable, lo que sea.