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ú

Mensajes - 0xDani

#241
Cita de: Oblivi0n en 18 Julio 2013, 16:04 PM
Si hacemos int* ptr1,ptr2,ptr3;  entonces ptr1,ptr2 y ptr3 son punteros a un entero.
Si hacemos int *ptr1,ptr2,ptr3;  entonces solo ptr1 es un punterom. El resto son variables enteras.

Seriously? Puedes darme una referencia fidedigna en la que se indique esto?
#242
Cita de: maxim_o en 18 Julio 2013, 14:29 PM
Pensaba que habian cambiado ya en esos aspectos y que muchos colegios y demas con esto del "bilinguismo" ya daban clases en español y ingles y practicaban todo eso.

Quizá en algunos colegios e/o institutos que vayan de elitistas sí... aunque al final suelen ser igual de malos... pero en un instituto corriente la cosa está así de mal.
#243
Foro Libre / Re: Cultura General
18 Julio 2013, 14:15 PM
Cita de: Constance en 18 Julio 2013, 13:40 PM
Es correcto ...Tachan tachan tachaannn  Prueba Superada  :-( :-(

Y cuál si cae con las patas hacia arriba pierde su nombre ??

El escarabajo??
#244
Foro Libre / Re: Cultura General
18 Julio 2013, 02:01 AM
Cita de: Constance en 18 Julio 2013, 01:36 AM
Un poquito más difícil, que veo que hay nivel ..

  Qué animal anda con los pies en la cabeza?

Los piojos y quizá algún contorsionista.
#245
Cita de: maxim_o en 17 Julio 2013, 15:28 PM
De hay el problema de España hace unos años (ahora esta cambiando) pero antes la gente salia con un nivel de ingles en reading y wrtting al acabar bachiller mas o menos bien...... Pero en listening y speaking practicamente nulo, salvo que se hubieran preparao por su cuenta... academias, irse de "campamentos a irlanda" etc etc etc

Eso sigue siendo así. Excepto lo de los campamentos a Irlanda, porque ya no hay dinero.

Un familiar mío es profesor de inglés, y desde hace dos o tres años se ha dado cuenta de esto, y ha cambiado su método de enseñanza. Donde antes todo eran ejercicios de rellenar huecos, ahora cuenta que invierte casi toda la clase en que sus alumnos practiquen oralmente, y ha incrementado bastante el rendimiento. Véase que esa es la manera natural de aprender una lengua, primero oralmente y luego de forma escrita.
#246
Cita de: eferion en 17 Julio 2013, 18:58 PM
_temp[i] = dat.topScore[i];

ahí estás sacando datos de dat y guardándolos en _temp... dat no lo estableces en ninguna parte del código que has puesto.

Exacto, te cargas lo que haya en _temp, la asignación está al revés.
#247
ASM / Re: como usar estructuras en nasm?
17 Julio 2013, 17:30 PM
https://jakash3.wordpress.com/2011/01/15/assembly-socket-example/

Está con sintaxis AT&T, espero que no tengas problema.
#248
Cita de: OmarHack en 17 Julio 2013, 17:06 PM
Muy bueno el aporte.
Tengo una duda, ¿los datos de ips se actualizan automáticamente? Es decir:
Si el objetivo ejecuta el server y tiene una ip dinámica el programa actualiza la ip del objetivo automáticamente? ¿O tendría que volver a ejecutar el server para que se tome su nueva ip?

Bueno, eso es flipar mucho y no depende del builder. La verdad no creo que haya ningún server que haga eso. Lo que se suele hacer es conseguirse un dominio de no-ip.

Yo nunca he encontrado como hacer esto en Linux y lo tuve que implementar mirando la man page, a ver si ahora alguien se anima a hacer alguna criatura para Linux.
#249
Bueno, tal y como me han pedido, aquí pongo el código de un server builder en Qt para Linux.

Lo primero, el código del server:

#include <iostream>
#include <iomanip>

static char ip[30] __asm__("__IP__") = "__IP__ here";
static char port[30] __asm__ ("__PORT__") = "__PORT__ here";

int main(int argc, char **argv)
{

std::cout << "ip address: " << std::hex << (void*) ip << std::endl;
std::cout << "port address: " << std::hex << (void*) port << std::endl;

std::cout << "IP: " << ip << std::endl;
std::cout << "Port: " << port << std::endl;


/* ... */

return 0;
}


Analicemos el código: tiene dos variables globales, para asegurarnos de que esas variables van a ser incluidas en la sección .data del ejecutable como símbolos. También nos aseguramos de que estos símbolos tengan el nombre que queramos ("__IP__" y "__PORT__") con la directiva de ensamblador.

Las cadenas que les asigno son para que se puedan ver en un editor hexadecimal.

Bien, ahora el builder, que se va encargar de que cuando ejecutemos el server, en esas dos variables estén la IP y el puerto.

mainwindow.hpp
Código (cpp) [Seleccionar]
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QMainWindow>
#include <QWidget>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>

#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <elf.h>
#include <stdint.h>
#include <cstring>

#include <iostream>
#include <iomanip>

class MainWindow : public QMainWindow
{
   Q_OBJECT
   
public:
   MainWindow(QWidget *parent = 0);
   ~MainWindow();

public slots:
   void onButton();

private:
   QWidget     *centralWidget; // Central widget
   QVBoxLayout *layout;        // Window's layout
   QLineEdit   *ipEdit;        // Edit for the IP
   QLineEdit   *portEdit;      // Edit for the port
   QPushButton *button;        // Button to build the server
};

#endif // MAINWINDOW_HPP


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

MainWindow::MainWindow(QWidget *parent)
   : QMainWindow(parent)
{
   /* Constructor to build the GUI */

   centralWidget = new QWidget();
   layout = new QVBoxLayout();

   ipEdit = new QLineEdit();
   portEdit = new QLineEdit();

   button = new QPushButton("Build!");

   layout->addWidget(ipEdit);
   layout->addWidget(portEdit);
   layout->addWidget(button);

   centralWidget->setLayout(layout);
   setCentralWidget(centralWidget);

   connect(button, SIGNAL(clicked()), this, SLOT(onButton()));
}

MainWindow::~MainWindow()
{
   /* Delete reserved objects */

   delete ipEdit;
   delete portEdit;
   delete button;
   delete layout;
   delete centralWidget;
}

void MainWindow::onButton()
{
   int fdIn, fdOut; // Input and output files

   fdIn = open("server", O_RDONLY); // Open input file

   struct stat st;
   fstat(fdIn, &st); // Get input file size

   /* Map input file into memory */
   void *map = mmap(0, st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fdIn, 0);

   Elf32_Ehdr *hdr = (Elf32_Ehdr*) map; /* Get the ELF header,
                                           that's at the start of the file*/

   /* Get pointer to the ELF sections */
   Elf32_Shdr *sections = (Elf32_Shdr*) ((char*) map + hdr->e_shoff);

   /* Get pointer to the .shstrtab section content */
   char *shStrTabData = (char*) map+sections[hdr->e_shstrndx].sh_offset;

   Elf32_Shdr tabs[2]; // First symtab, second strtab


   /* Find and save .symtab and .strtab sections */
   const char *sectionNames[] = {".symtab", ".strtab"};
   for(int i=0; i<2; i++)
   {
       for(int j=0; j<hdr->e_shnum; j++)
       {
           if(!strcmp(shStrTabData+sections[j].sh_name, sectionNames[i]))
           {
               tabs[i] = sections[j];
               break;
           }
       }
   }

   //std::cout << ".symtab at offset " << std::hex << tabs[0].sh_offset << std::endl;
   //std::cout << ".strtab at offset " << std::hex << tabs[1].sh_offset << std::endl;

   /* Get pointer to the .strtab section content */
   char *strTabData = (char*) map + tabs[1].sh_offset;

   /* Get pointer to the symbols in the .symtab section */
   Elf32_Sym *syms = (Elf32_Sym*) ((char*) map + tabs[0].sh_offset);

   Elf32_Sym toModify[2]; // First __IP__, second __PORT__

   const char *symbolNames[] = {"__IP__", "__PORT__"};


   // Find and save the symbols we want to modify
   for(int i=0; i<2; i++)
   {
       for(unsigned int j=0; j<(tabs[0].sh_size/sizeof(Elf32_Sym)); j++)
       {
           if(!strcmp(strTabData+syms[j].st_name, symbolNames[i]))
           {
               toModify[i] = syms[j];
           }
       }
   }

   //std::cout << "__IP__ value: " << std::hex << toModify[0].st_value << std::endl;
   //std::cout << "__PORT__ value: " << std::hex << toModify[1].st_value << std::endl;

   Elf32_Off ipOff, portOff;


   /* Find symbols offsets: get symbol offset into the section that
      contains the symbol: symbol_address - section_base_address; and then
      add the offset of the section into the file                       */
   ipOff = toModify[0].st_value - sections[toModify[0].st_shndx].sh_addr +
           sections[toModify[0].st_shndx].sh_offset;

   portOff = toModify[1].st_value - sections[toModify[1].st_shndx].sh_addr +
           sections[toModify[1].st_shndx].sh_offset;

   //std::cout << "__IP__ section: " << shStrTabData+sections[toModify[0].st_shndx].sh_name << std::endl;
   //std::cout << "__PORT__ section: " << shStrTabData+sections[toModify[1].st_shndx].sh_name << std::endl;


   //std::cout << "__IP__ offset: " << std::hex << ipOff << std::endl;
   //std::cout << "__PORT__ offset: " << std::hex << portOff << std::endl;

   // Put the text in the edit in the file at the offsets
   strcpy((char*) map+ipOff, ipEdit->text().toStdString().c_str());
   strcpy((char*) map+portOff, portEdit->text().toStdString().c_str());


   /* Open output file and write the memory map to it */
   fdOut = open("server-built", O_TRUNC|O_CREAT|O_WRONLY, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH);

   write(fdOut, map, st.st_size);

   ::close(fdOut);


   munmap(map, st.st_size);

   ::close(fdIn);
}


main.cpp
Código (cpp) [Seleccionar]
#include "mainwindow.hpp"
#include <QApplication>

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


Lo primero, este último código funciona sólo para ejecutables de 32 bits, pero se puede portar fácilmente.

¿Cómo funciona?

Pues los ejecutables ELF suelen tener una tabla de strings con los nombres de todas las secciones (la sección .shstrtab). Con esa tabla, encontramos las secciones .symtab (la tabla de símbolos) y la .strtab (la tabla de strings de símbolos).

Comparando los nombres de cada símbolo con los que hay en la tabla, encotramos los dos que queremos modificar. No tenemos el offset de estos símbolos directamente, así que tenemos que hallarlo. Tenemos la dirección del símbolo una vez cargado en memoria, la sección en la que se encuentra este símbolo (y por tanto la dirección de esta sección en memoria y el offset de esta sección en el archivo); así que hacemos la siguiente cuenta:

       Dirección del símbolo - Dirección base de la sección + Offset de la sección en el archivo

Eso corresponde a esta parte del código:

Código (cpp) [Seleccionar]
ipOff = toModify[0].st_value - sections[toModify[0].st_shndx].sh_addr +
          sections[toModify[0].st_shndx].sh_offset;

  portOff = toModify[1].st_value - sections[toModify[1].st_shndx].sh_addr +
          sections[toModify[1].st_shndx].sh_offset;


Luego escribimos el texto de los edits en el mapa de memoria en el offset de cada símbolo, de forma que cuando se carguen en memoria contengan esos datos, y nuestro server pueda conectar a la IP y por el puerto indicado.

Bueno, hace falta conocimiento del formato ELF para entender esto totalmente, así que más información aquí y también se pueden preguntar dudas.

Saludos!
#250
Programación C/C++ / Re: Duda con sockets C
17 Julio 2013, 14:54 PM
La función select() te permite comprobar cualquier descriptor y/o conjunto de descriptores. Vuelve a mirar la documentación de la función.