lunes, 19 de abril de 2010

Paso de mensajes entre procesos en windows

En la plataforma Windows tanto para la comunicación entre procesos como para el manejo de eventos se usa un sistema de mensajes.

Una de las características del sistema de mensajes de Windows es no disponer de autentificación, se puede aprovechar este hecho para simular eventos en los programas que se están ejecutando y de esta forma controlarlos desde el API de mensajes.

Se puede por tanto manejar un programa de forma automática desde otro, con las posibilidades que ello ofrece. Orientándolo a la ingeniería inversa se puede hacer fuzzing a programas que tan solo admiten entradas desde la interfaz gráfica.

Supongamos que tenemos un programa cuya ventana principal se llama "Form1" y un botón con el texto "Boton" en el cual al hacer click en un botón muestra un mensaje.

...
private void button_Click(object sender, EventArgs e){
MessageBox.Show("Wow!", "Clicked", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
...

Podemos simular que hacemos click en ese botón si desde otro programa hacemos lo siguiente.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WFuzzing{
public partial class Form2 : Form{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string strClassName, string strWindowName);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(int hWnd, uint Msg, long wParam, long lParam);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr parameter);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_LBUTTONUP = 0x0202;

public Form2(){
InitializeComponent();
}

private void fuzzbutton_Click(object sender, EventArgs e){
IntPtr wHandle = FindWindow(null, "Form1");
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
EnumWindowsProc childProc = new EnumWindowsProc(EnumWindow);
EnumChildWindows(wHandle, childProc, GCHandle.ToIntPtr(listHandle));
}

private static bool EnumWindow(IntPtr handle, IntPtr pointer){
StringBuilder text = new StringBuilder(256); ;
GetWindowText(handle, text, text.Capacity);

if(text.ToString() == "Boton"){
long lngResult = SendMessage(handle.ToInt32(), WM_LBUTTONDOWN, 0, 0);
long lngResult2 = SendMessage(handle.ToInt32(), WM_LBUTTONUP, 0, 0);
}
return true;
}

}
}

Se le mandan dos mensajes, el primero el de hacer click con el ratón y el segúndo el de levantar el dedo del ratón.

Al ejecutar ese código el primer programa debería mostrar el mismo mensaje que si hacemos click en el botón.

De forma similar, se puede automatizar la búsqueda de fallos en programas de los cuales no disponemos del código fuente, tan solo manipulando la interfaz, rellenando campos de texto, activando y desactivando controles, todo de forma automática.

miércoles, 7 de abril de 2010

Metaprogramación en c#

Aunque c# no proporcione demasiadas ayudas sintácticas a la metaprogramación si que se pueden aprovechar sus estructuras y tipos de datos para generar métodos de fórma dinámica.

En el siguiente código hay un ejemplo.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;


namespace example1{
class Program{
[DllImport("msvcrt.dll")]
static extern bool system(string str);

static void Main(string[] args){
Dictionary<string, Action<string>> method = new Dictionary<string, Action<string>>();
Expression<Action<string>> exp;

for (int i = 0; i < 100; i++)
{
var number = i;
exp = (p => Console.WriteLine("Parametro: " +p+"\nMetodo numero: "+number));
method["print_" + i] = exp.Compile();

exp = (p => Console.WriteLine(p + number));
method["concat_" + i] = exp.Compile();
}

method["print_17"]("test");
method["concat_35"]("Concatenando el numero -> ");


system("pause");
}
}
}

En primer lugar se crea un diccionario llamado method para contener todas las funciones generadas automáticamente.

Luego, en el bucle se crean 200 métodos, tanto dependientes de parámetro como de su posición en el bucle, sin embargo, para esto es necesario un pequeño hack.
Se le asigna a number el valor del contador, creando un objeto en cada iteración, en caso contrario todos los métodos creados tendrán como valor de i el último que ha tomado en el bucle, es decir, 100.

martes, 6 de abril de 2010

Expresiones regular en C++ con boost

La mayoría lenguajes de programación modernos proporcionan la posibilidad de usar expresiones regulares de forma nativa desde el propio lenguaje, sin embargo, en C++ es necesario recurrir a alguna librería como Boost.Regex.

Boost.Regex ofrece la mayoría de funciones comunes de las expresiones regulares.

#include <iostream>
#include <string>
#include <boost/regex.hpp>

int main(){
std::string s = "BEGIN->Cadena_entre_delimitadores<-END";
std::string s2 = "Cadena de texto con 3 numeros para sustituir 1, 4 por incognitas";
boost::regex r("BEGIN->(\\w+)<-END");
boost::regex r2("\\d");
boost::smatch result;

if (boost::regex_search(s, result, r)){
for(int i=0; i<result.size(); i++){
std::cout << "Ocurrencia n " << i+1 << ": "<< result[i] << std::endl;
}
}
else{
std::cout << "Ninguna coincidencia" << std::endl;
}

std::cout << "---" << std::endl;
std::string number("X");
std::cout << "Cadena modificada con una expresion regular: ";
std::cout << boost::regex_replace(s2, r2, number) << std::endl;

}

Con regex_search se pueden encontrar coincidencias de una expresión regular r dentro de una cadena s. Como resultado también tendrá en cuenta los grupos de captura.

Con regex_replace se pueden hacer sustituciones, cambiando las ocurrencias encontradas en la cadena s2 según el patrón r2, sustituyéndolas por number.

Papra compilar es necesario incluir tanto los headers como la librería correspondiente, en mi caso.

g++ -lboost_regex-mt -I/opt/local/include/ -L/opt/local/lib/ regex.cpp -o regex

viernes, 19 de marzo de 2010

Programación de callbacks con Boost

Usando las librerías Boost.Function y Boost.Bind se pueden crear fácilmente callbacks en c++ sin necesidad de usar punteros a función.

Un ejemplo.

#include <boost/function.hpp>
#include <boost/bind.hpp>

#include <iostream>


using namespace boost;

class Example{
private:
int a;
public:
function<void(std::string)> callback;

void setA(int value){
a = value;
changeA();
if(callback){callback("setA");}
}

void changeA(){
a++;
if(callback){callback("changeA");}
}
};


void debug(std::string s){
std::cout << "Method called: " << s << std::endl;
}

int main(){
Example e;
e.callback = bind(&debug, _1);
e.setA(123);
}

Siguiendo el planteamiento anterior obtendríamos la cadena de llamadas a las funciones de la clase Example.

Si no establecemos el callback (en este caso se hace en la segunda línea de main) el comportamiento será el normal, sin embargo, en caso de necesidad se le puede hacer un bind al objeto que queramos con una función de debug.

La programación usando callbacks es especialmente útil en programación concurrente, para más información en la página de Boost.Function.

domingo, 14 de marzo de 2010

Usar OpenGL desde ruby

Es interesante poder crear demos o escenarios en 3D desde un lenguaje dinámico como ruby (cuando el rendimiento no sea un problema).

Hay unos bindings para opengl llamados ruby-opengl que nos permiten acceder directamente a la API de OpenGL desde ruby.

Os dejo un ejemplo (inspirado en los tutoriales de NeHe) para que os hagáis una idea de la sintaxis.

require 'rubygems'
require 'opengl'

require "gl"
require "glu"
require "glut"
require "mathn"

include Gl, Glu, Glut

window = ""

def init_gl_window(width = 640, height = 480)
glClearColor(0.0, 0.0, 0.0, 0)
glClearDepth(1.0)
glDepthFunc(GL_LEQUAL)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)

glMatrixMode(GL_PROJECTION)
glLoadIdentity
gluPerspective(45.0, width / height, 0.1, 100.0)

glMatrixMode(GL_MODELVIEW)

draw_gl_scene
end

def reshape(width, height)
height = 1 if height == 0

glViewport(0, 0, width, height)

glMatrixMode(GL_PROJECTION)
glLoadIdentity

gluPerspective(45.0, width / height, 0.1, 100.0)
end

$color1_intensity = 0
$color2_intensity = 0
$color3_intensity = 0

$rotation = 0

def draw_gl_scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

glMatrixMode(GL_MODELVIEW)
glLoadIdentity
glTranslatef(0, 0, -6)

# Draw a triangle
glBegin(GL_POLYGON)
glColor3f($color1_intensity, $color2_intensity, $color3_intensity)
glVertex3f( 0.0, 1.0, 0.0)
glColor3f($color3_intensity, $color1_intensity, $color2_intensity)
glVertex3f( 1.0, -1.0, 0.0)
glColor3f($color2_intensity, $color3_intensity, $colo1r_intensity)
glVertex3f(-1.0, -1.0, 0.0)
glEnd

$color1_intensity += 0.0005 if($color1_intensity %gt; 0.5)
$color2_intensity += 0.0005 if($color2_intensity %gt; 0.5)
$color3_intensity += 0.0010 if($color3_intensity %gt; 1)

glutSwapBuffers
end

def idle
glutPostRedisplay
end

# Keyboard handler to exit when ESC is typed
keyboard = lambda do |key, x, y|
if(key == 27) then
GLUT.DestroyWindow($window)
exit(0)
end
end


glutInit
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
glutInitWindowSize(640, 480)
glutInitWindowPosition(0, 0)
window = glutCreateWindow("Example")
glutDisplayFunc(method(:draw_gl_scene).to_proc)
glutReshapeFunc(method(:reshape).to_proc)
glutIdleFunc(method(:idle).to_proc)
glutKeyboardFunc(keyboard)
init_gl_window(640, 480)
glutMainLoop()

Quizá sería interesante aportar un grado más de abstracción para hacer aún más sencillo la elaboración de gráficos desde este tipo de lenguajes.

miércoles, 3 de marzo de 2010

Unit Testing en C++ con Igloo

La realización de test unitarios aún siendo una buena práctica de programación puede ser muy tediosa si no se utiliza alguna librería que nos descargue de trabajo.

Igloo para C++ nos provee de una API muy sencilla, además tiene la ventaja de que no necesita instalación ya que Igloo es simplemente un conjunto de ficheros de cabecera.

Lo único que necesitamos para usar Igloo es bajarnos la última versión y compilar nuestro test incluyendo sus cabeceras:

g++ tests.cpp -o tests -I/path/de/igloo/

Dejo un ejemplo de como quedaría un conjunto de test unitarios a una clase.

#include <igloo/igloo.h>
#include <stdio.h>
#include <stdlib.h>

using namespace igloo;

class Example{
private:
int atrib1;
int atrib2;

public:
Example(int a1, int a2){
atrib1 = a1;
atrib2 = a2;
}

int getAtrib1(){return atrib1;}
int getAtrib2(){return atrib2;}

static int sum(int n){
int result = 0;
for(int i=1; i<=n; i++){result+=i;}
return result;
}
};

TestFixture(Assertions){
TestMethod(ShouldHandleIntegerEquality){
Assert::That(Example::sum(5), Is().EqualTo(15));
}

TestMethod(ShouldHandleStrings){
Example e(5,6);
char c1[100];

sprintf(c1, "%d", e.getAtrib1());
std::string a1(c1);
sprintf(c1, "%d", e.getAtrib2());
std::string a2(c1);

Assert::That(a1, Is().Not().EqualTo(a2));
}
};

int main(){
return TestRunner::RunAllTests();
}

Al ejecutar el programa anterior obtendríamos la salida: Test run complete. 2 tests run, 2 succeeded, 0 failed

viernes, 19 de febrero de 2010

Smart pointers de la librería Boost

Una de las ventajas que tiene la programación en Java sobre C++ es la recolección de basura.

Cuando escribimos un programa en Java no nos tenemos que preocupar de liberar la memoria que vamos usando, hay un recolector de la máquina virtual que lo hace por nosotros. De esta forma se reduce el número de memory leaks y se facilita la programación.

En C++ sin embargo la gestión de memoria debe realizarla el desarrollador, proporcionando más potencia pero también dificultando el desarrollo.

Para facilitar la programación en este apartado, la librería Boost cuenta con un concepto llamado smart pointers que liberan de complejidad a la hora de gestionar la memoria al programador.

Por ejemplo, usando el tipo scoped_ptr.

#include <boost/smart_ptr.hpp>

class Example{
public:
int a;
};

void scoped_pointer(){
boost::scoped_ptr<Example> ptr(new Example);
}

void pointer(){
Example *ptr = new Example;
}


int main(){
while(1){
pointer();
}
}


Al ejecutar este programa se irá reservando memoria constantemente hasta agotar la memoria total del sistema, puesto que en ningún momento se libera.

Sin embargo, si se modifica la llamada pointer por scoped_pointer el programa se ejecutará de forma estable, dado que al terminar el método, el scoped pointer libera la memoria utilizada de forma automática.

Hay smart pointers con otras políticas de gestión de memoria, para elegir cual nos conviene en la documentación de boost se detalla cada uno.