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 - 85

#151
Hola , estaba revisando un código que usaba en el Counter-Strike.
Es un namechanger o namestealer.
En un servidor de CS, de por ejemplo 32 slots, este hack lo que hace es cambiar tu nombre aleatoriamente por el de alguno de los demás jugadores. El tema es que no se permite tener el mismo exacto nombre, por lo que se le debe hacer un cambio. Tampoco se permite que tu nombre contenga el nombre de un administrador.

Este namechanger se encarga de lo primero, o sea recibe el nombre de alguien y lo modifica con un sólo cambio y devuelve el nombre modificado.

Se hace un sólo cambio por que la idea es que el nombre se pareza al del otro jugador.

Yo lo que hice fue reemplazar las funciones de cadena que se utilizaron en el primer código. Lo que quisiera es si alguien se anima a hacerlo de otra forma, sin salirse de la lógica de funcionamiento.

Otra cosa es lo de la escritura LEET, o 1337. Se trata de una equivalencia de letras con números, por ejemplo:

CASA = C454

o

AVIÓN = 4V10N

o

BS = 85

etc

Eso también es válido para este autoname.
Si encuentran algún error en mi code avizen.
Aunque no crean este autoname da buenos resultados para gambetear bans XD

Código (cpp) [Seleccionar]


//
// By 85
// elhacker.net
// etalking.com.ar
// 2013
//

#include<windows.h>
#include<stdio.h>

//

char objetivos[] = "ABEGLOST\0";
char reemplazos[]= "48361057\0";

//
void ModificadorDeNombresConSTR(char* str){

// Detección de doble whitespace
if(strstr(str,"  ")!=NULL)
       {
       strcpy(strstr(str,"  "),strstr(str,"  ")+1);
       return;
       }

// Detección de whitespace
if(strstr(str," ")!=NULL)
      {
       char buf[256];
       strcpy(buf,str);
       strcpy(strstr(buf," ")+1,strstr(str," "));
       strcpy(str,buf);
       return;
      }

// Char inicial y final iguales
      if(str[0]==str[strlen(str)-1])
      {
       char buf[256];
       char sbuf[2]="X";// Al asignarle valor se le agrega el 0 automáticamente.
       sbuf[0]=str[0];
       strcpy(buf,sbuf);
       strcat(buf,str);
       strcpy(str,buf);
       return;
      }

// Reemplazo de ocurrencias (para escritura 1337 XD)
if(strstr(str,"A")!=NULL)
       {
       *strstr(str,"A")='4';
       return;
       }

if(strstr(str,"B")!=NULL)
      {
       *strstr(str,"B")='5';
       return;
      }

if(strstr(str,"E")!=NULL)
       {
       *strstr(str,"E")='3';
       return;
       }

if(strstr(str,"G")!=NULL)
      {
       *strstr(str,"G")='6';
       return;
      }

if(strstr(str,"L")!=NULL)
       {
       *strstr(str,"L")='1';
       return;
       }

if(strstr(str,"O")!=NULL)
       {
       *strstr(str,"O")='0';
       return;
      }

if(strstr(str,"S")!=NULL)
       {
       *strstr(str,"S")='5';
       return;
      }

if(strstr(str,"T")!=NULL)
       {
       *strstr(str,"T")='7';
       return;
       }

// Char final y prefinal iguales
if(str[strlen(str)-1]==str[strlen(str)-2])
       {
       str[strlen(str)-1]=0;
       return;
       }

// Reducción de longitud
if(strlen(str)>16)
       {
       str[strlen(str)-1]=0;
       return;
       }

// Agrega un punto al final
strcat(str,".");
}

//

void ModificadorDeNombresSinSTR(char* str){

#define current (i-1)
int len=0;
for(;*str++;len++);// Obtener largo de cadena
str-=(len+1);// Arreglar el puntero que se ha desplazado!!!
{
int i=0;
while(str[i++]){

// Detección de doble whitespace
if((str[current] == ' ' && str[i] == ' ')){

printf("DOBLE ESPACIO\n");
system("pause");

char buf[256];
int pos=current;
while(str[pos++]!='\0'){// Reemplazo de STRCPY+STRSTR ;D

int bufcur = (pos-current)-1;
int strcur = (pos-1);
buf[bufcur]=str[strcur+1];
buf[bufcur+1]=str[strcur+2];
str[strcur]=buf[bufcur];
str[strcur+1]=buf[bufcur+1];
}
str[pos-1]=0;
return;
}}}

{
int i=0;
while(str[i++]){

// Detección whitespace
if(str[current] == ' '){

printf("ESPACIO\n");
system("pause");

str[len+1]=0;
int pos=len+1;
while(pos--){
if(pos==current) break;
str[pos]=str[pos-1];
}
return;
}}}


{
int i=0;
while(str[i++]){

// Char inicial y final iguales
if(str[0] == str[len-1]){

printf("INICIAL y FINAL IGUALES\n");
system("pause");

str[len+1]=0;
int pos=len+1;
while(pos--){// Reemplazo de STRCPY ;D
if(pos<1) break;
str[pos]=str[pos-1];
}
return;
}}}

{
int i=0;
while(str[i++]){

// Reemplazo de ocurrencias (para escritura 1337 XD)
if(str[current] == 'A') {str[current]='4'; return;}
else if(str[current] == 'B') {str[current]='8'; return;}
else if(str[current] == 'E') {str[current]='3'; return;}
else if(str[current] == 'G') {str[current]='6'; return;}
else if(str[current] == 'L') {str[current]='1'; return;}
else if(str[current] == 'O') {str[current]='0'; return;}
else if(str[current] == 'S') {str[current]='5'; return;}
else if(str[current] == 'T') {str[current]='7'; return;}
}}


// Char final y prefinal iguales
if(str[len-1] == str[len-2]){

printf("FINAL y PREFINAL IGUALES\n");
system("pause");
str[len-1]=0;
return;
}

// Reducción de longitud
if(len>16){

printf("LONGITUD\n");
system("pause");

str[len-1] =0;
return;
}


// Agrega un punto al final
str[len] ='.';
str[len+1] =0;
}

//
int main(){

// Nota: si STRCPY recibe el segundo argumento de mayor size que el primero
// no importa mientras la cadena sea igual o menor. Y terminada en 0.
// Aparte de que STRCPY recibe sus argumentos en forma de punteros.
// http://www.cplusplus.com/reference/cstring/strcpy/

char nombrelargo[256];

// char ingreso[512] = "RRRRRRRRRRRRRRRRX\0";
// char ingreso[512] = "LEE TL\0";
// char ingreso[512] = "LEETL \0";
// char ingreso[512] = "LEET";
// char ingreso[512] = "azucarada";
// char ingreso[512] = "azuc arada";
// char ingreso[512] = "hazuc  aradah";
// char ingreso[512] = "hazucaradahh";
// char ingreso[512] = "1azucaradahh";
// char ingreso[512] = "1  azucaradahh";
// char ingreso[512] = "1azucaradahhaaaa  ";
char ingreso[512] = "1azucaradahhaaaa ";


strcpy(nombrelargo, ingreso);
// ModificadorDeNombresConSTR(nombrelargo);
ModificadorDeNombresSinSTR(ingreso);
//printf("%s\n", nombrelargo);
printf("%s\n", ingreso);
system("pause");
return (0);
}

//


Proyecto: http://www.mediafire.com/?k6os3q63sxrw0ff

#152
NIVEL: Beginner
Test: WinXP SP3

Hola de nuevo,
Bueno voy a contar una experiencia que le puede servir de ayuda si les pasa algo parecido.
Cuando estaba armando el proyecto para este tema:
http://foro.elhacker.net/programacion_cc/gltest_1_interceptar_opengl32_con_gpa-t384878.0.html

Antes de publicarlo, había tenido un problema con la convención de llamada de una función. En realidad se trata de un error mio en el código, pero que había pasado desapercibido y cuando el programa se cerraba no entendía por qué, lo que me llevó a tener que depurarlo.

Primero muestro la imagen del error en el código:


Opengl32 es __stdcall y al no especificarlo en el puntero, la llamada iba a ser __cdecl, que es la que usa el compilador VC++ por defecto. (aunque hay una opción para cambiar esto).

Antes es importante entender las características de las dos convenciones de llamada involucradas.

__cdecl
http://msdn.microsoft.com/en-us/library/zkwh89ks(v=vs.80).aspx

__stdcall
http://msdn.microsoft.com/en-us/library/zxk0tw93(v=vs.71).aspx

Esto da más información
http://en.wikipedia.org/wiki/X86_calling_conventions
http://www.codeproject.com/Articles/1388/Calling-Conventions-Demystified

Y esto tiene que ver directamente con la pila, por lo que si no saben acerca de ella, es una estructura con un ordenamiento LIFO y es usada por el programa para guardar direcciones. Las direcciones son de parámetros, de retorno, y de variables locales. Los registros del procesador relacionados a la pila son ESP y EBP (Apuntadores).
No menciono SS que es de segmento, sólo ESP y EBP.
EBP es el registro que se usa para referenciar la base de la pila,
ESP apunta siempre al tope de la pila. El tope de la pila es la última posición,  no la que le sigue..
ESP se modifica automáticamente para agrandar o achicar la pila (Es el puntero de pila).  EBP cambia según el 'stack frame' actual, pero siempre se guarda una copia del frame anterior. No cambia dentro del frame como lo puede hacer ESP, ya que es necesario para referenciar la base de la pila. Pero el programador si puede alterar EBP, y en esta demostración se
trata de eso XD.

Esta es la representación de una pila (relativa a EBP , no a ESP)

CitarHIGH MEMORY (crece de arriba hacia abajo)
EBP+18h   Quinto Parámetro
EBP+14h   Cuarto Parámetro
EBP+10h   Tercer Parámetro
EBP+0Ch   Segundo parámetro
EBP+08h   Primer Parámetro
EBP+04h   Direccion de retorno
EBP+0     Valor original de EBP
EBP-4h    Primera variable local
EBP-8h    Segunda variable local  <-----------------------------> ESP apunta a la última
LOW MEMORY

En el caso de la función glBegin que tiene un parámetro sólo, entonces nuestra pila inicial cuando se llama a nuestro Hook de glBegin es así:
CitarHIGH MEMORY (crece de arriba hacia abajo)
EBP+08h   Primer Parámetro       //cmp dword ptr [ebp+0x8], 0x00000009 //mode
EBP+04h   Direccion de retorno   // return address (0x401318 (EXE))
EBP+0     Valor original de EBP // agregado
LOW MEMORY
El tema es que dentro de la función de hook de glBegin el compilador agregó código que modifica el EBP. Este es el código insertado:


push ebp
mov ebp, esp
...


de esa forma cambia la pila, porque se agregó un elemento más (EBP), y cambia EBP mismo.

Supongamos que ESP se desplaza 4 posiciones,
eso significa que si el primer parámetro es EBP+0x8, desde la perspectiva de EBP, es ESP+0x14 desde la perspectiva de ESP.

Un comentario, ESP cambia cuando se usan las instrucciones PUSH y POP

Citar*--ESP = value;   // push
value = *ESP++;   // pop

y también cuando vemos:
CitarADD ESP, X
o
CitarSUB ESP, X
, que se usan para agrandar y achicar la pila.

Este es el desensamblado del Hook a glBegin


Con respecto a la 2da imagen, vamos a hacer una explicación paso por paso:

1: se guarda el registro EBP anterior (porque se ha modificado)
2: se ejecuta el código intermedio de la función normalmente.
3: se restaura el EBP
4: se limpia el stack por el valor de lo que había demás en la pila hasta el momento,
  Ver en la imagen, se calcula 0x10 lo cual es (4*4bytes), osea los 4 PUSHs del
  principio. La pila ahora queda equilibrada con sus datos originales intactos. la dirección de retorno y el primer parámetro (tiene uno sólo glBegin).
5: Se utiliza un salto incondicional para ir hacia la función original.
  (No se usa CALL).

Lo de calcular cuanto se debe limpiar se hace obteniendo la información del depurador (OllyDBG) con el programa en ejecución, y obviamente traceando cada línea, y observando la pila. Yo en realidad lo hice con OllyDBG porque no sabía del error en el código (no me había dado cuenta), pero para la demostración me resulta más fácil observar el desensamblado directamente con este explorador PE, ahora que se lo que pasaba XD.

En conclusión, el arreglo se hacía con inline ASM en la función de reemplazo (Hook) de glBegin

Código (cpp) [Seleccionar]


int glBegin_saved_ebp;

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void __stdcall HOOK_glBegin(GLenum mode)
{
//--------------------------------------
__asm mov eax, [esp+0xc] // calculado en esta posición
__asm mov glBegin_saved_ebp, eax // guardamos el ebp anterior
//--------------------------------------

if(!once){

printf("\n");
printf("DLL -> HOOK_glBegin: ebp guardado!\n");
system("pause");
once=true;
}

if (mode==GL_POLYGON)
{
   glClearColor(1.0, 1.0, 1.0, 1.0);
   glColor3f(0, 0, 0);
}

//--------------------------------------
__asm mov ebp,glBegin_saved_ebp // restauramos el ebp
       __asm add esp,0x10 // limpiamos stack (calculado como 4 * 4 bytes = 0x10)
       __asm jmp pOrig_glBegin // saltamos a la original
//--------------------------------------
//(*pOrig_glBegin)(mode);
}


Otra información que es importante conocer:
Prólogo y Epílogo
http://msdn.microsoft.com/es-ar/library/tawsa7cb(v=vs.80).aspx
http://msdn.microsoft.com/es-es/library/8ydc79k6(v=vs.80).aspx
http://msdn.microsoft.com/es-es/library/t2wt9aez(v=vs.110).aspx
http://msdn.microsoft.com/es-es/library/21d5kd3a.aspx

Más información
http://en.wikipedia.org/wiki/Call_stack
http://es.wikipedia.org/wiki/Pila_de_llamadas
http://securityetalii.es/tag/marco-de-pila/
http://learnassembler.com/procedim.html
http://msdn.microsoft.com/es-es/library/5sds75we(v=vs.90).aspx
http://www.pmzone.org/chapter06.html

"ENTER" y "LEAVE" para crear y liberar el stack frame.
http://en.wikipedia.org/wiki/X86_instruction_listings#Added_with_80186.2F80188

Así que todo resultó ser un problema del código, que faltaba __stdcall, no era necesario ningún arreglo con ASM XD.
Pero espero que haya resultado instructivo al menos.



Saludos

CODE VC++6
http://www.mediafire.com/?xzxvrc3ri3toz9t
#153
Si CodeBlocks es lo mejor de lo que es libre. Sino tenés Visual C++ Express

Si tu PC no es muy rápida usá un Visual Studio anterior al 2010, es muy pesado o desactivale funciones sino; no están actualizados pero para aprender te sirven.
#154
sizeof es un operador
http://msdn.microsoft.com/es-es/library/0w557fh7.aspx

por qué una función?

en varios lugares le dicen función  :o
http://www.it.uc3m.es/labas/course_notes/dynamic_memory_sizeof_es.html

será porque se usa como una función?

#155
Cita de: Luchoz95 en  7 Marzo 2013, 00:56 AM
Hola que tal , hace poco empeze a programar en c, lo llevo bastante bien que digamos , pero como recien empiezo , tengo un par de dudas , no sobre el lenguaje si no sobre los compiladores, son estas


  • Es lo mismo Dev C++, CodeBlocks, y Microsoft Visual Studio?
  • Que es MinGW y y GCC ?
  • Que es un proyecto en Win32 y en que lenguaje se programa ?
  • Que son los Windows Form y en que lenguaje se programa ?

por ahora son estas dudas las que me han surgido , espero que alguien me pueda ayudar

Saludos!

No es lo mismo a pesar de que son IDE's, pero tienen diferencias que los hacen distintos.

gcc es un compilador (lo he usado en linux), mingw también

un proyecto win32 es para crear una aplicación gráfica de windows.
O sea, que va  a contener diálogos o ventanas.

Se programa en C/C++

Windows Forms, hace referencia a formularios. Yo que sepa eso es para Visual Basic 6, y según mi experiencia, en .NET con c# (C Sharp), también

También podés investigar acerca de MFC para el desarrollo de aplicaciones gráficas en C/C++ , necesitás Visual Studio

Hasta luego



#156
Cita de: leosansan en  6 Marzo 2013, 11:08 AM
No sé dónde me he perdido  :P pero por lo que entiendo tratas de generar números aleatorios en coma flotante y punto. ¿O es algo más?. Porque si sólo es eso con esto tiras bien:

.................................................... CODE

Saluditos!, y ya me diras si la intención era otra. ...

P.D: Se me ha" escapado" en C, espero que no te importe.

http://es.wikipedia.org/wiki/Coma_flotante
http://es.wikipedia.org/wiki/Punto_flotante
Claro en inglés es FLOATING POINT, por eso

El código de arriba se usa en un hack para obtener ciertos valores aleatorios que se usan en una función que compensa el efecto de dispersión de los disparos (En el Counter-Strike).

tu code está bueno también XD


#157

NIVEL: Beginner
Test: WinXP SP3

Esto es una demostración de como puede aplicarse un IAT hook para interceptar funciones en un proceso. En este caso , se trata de un ejecutable que utiliza funciones de Opengl32 para crear una ventana y representar una imagen.



Para hacer uso de las funciones Opengl32 desde un ejecutable .EXE como en este caso, se puede hacer mediante vinculación dinámica (con DLL) o vinculación estática (con LIB).

Antes dejo unos enlaces donde consultar información:
http://msdn.microsoft.com/es-ar/library/253b8k2c.aspx
http://msdn.microsoft.com/es-es/library/1ez7dh12(v=vs.80).aspx
http://msdn.microsoft.com/es-ar/library/9se914de.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681914(v=vs.85).aspx
http://msdn.microsoft.com/es-es/library/ms235636(v=vs.80).aspx
http://msdn.microsoft.com/es-es/library/9yd93633(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681938(v=vs.85).aspx
http://msdn.microsoft.com/es-es/library/ms235627(v=vs.90).aspx
http://msdn.microsoft.com/es-es/library/ms235627(v=vs.80).aspx
http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/bed8a074-afe0-46a8-bdc5-5e4244ca55a6
http://msdn.microsoft.com/en-us/library/ms235627(v=vs.80).aspx
http://msdn.microsoft.com/es-es/library/abx4dbyh.aspx
http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx

Para construir este ejecutable de ejemplo, usé un código de ejemplo que ofrece el sitio oficial de Opengl..
http://www.opengl.org/archives/resources/code/samples/glut_examples/advanced/textrim.c
http://www.opengl.org/resources/libraries/glut/
http://www.opengl.org/archives/resources/code/samples/simple/
http://www.opengl.org/archives/resources/code/samples/glut_examples/examples/examples.html
http://www.opengl.org/archives/resources/code/samples/glut_examples/contrib/contrib.html

El programa de ejemplo original usa la vinculación estática, pero para poder realizar esta demostración tuvo que ser modificado XD.

Las modificaciones se dan para las llamadas a 3 funciones de Opengl32 que fueron elegidas para poder realizar la demostración.

las funciones son: glBegin, glBlendFunc y glViewport
Para saber acerca de estas funciones van a tener que recurrir a un manual de Opengl32, o busquen en el sitio oficial.

A estas 3 funciones se las desea interceptar para lograr cambiar el comportamiento del programa, la idea es cambiar lo que el programa muestra por pantalla.

Lo que se hace en el ejecutable es arreglar las llamadas a estas 3 funciones, que normalmente son llamadas por vinculación estática. En cambio ahora fueron modificadas para que la vinculación sea dinámica. Por eso se declararon punteros a función y se resuelven las direcciones correspondientes a las funciones dentro de Opengl32.DLL , en tiempo de ejecución. Esto se hace usando GetProcAddress.

Ahora que sabemos que el ejecutable de la demostración, hace uso de GetProcAddress para conseguir las direcciones de estas 3 funciones mencionadas, vamos a interceptar GetProcAddress para que devuelva otras direcciones. Digamos, las direcciones de nuestras funciones de reemplazo.

Esas funciones de reemplazo, o HOOKs, van a estar dentro de una DLL aparte que va a ser cargada al proceso. Una vez cargada en el proceso va a parchear la IAT en la entrada de GetProcAddress, de esa forma GetProcAddress queda interceptada.

Veamos el código del EXE:
Los includes necesarios, y las librerías estáticas requeridas para que compile.
Código (cpp) [Seleccionar]

#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "GLUT32/glut32.lib")
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "GLUT32/glut.h"
#include <gl\gl.h>
#include <gl\glu.h>

#include "texture.h"


Los punteros a función para las 3 funciones que vamos a interceptar.
Código (cpp) [Seleccionar]

// Opengl32 es APIENTRY
typedef void(__stdcall* t_glBegin)(GLenum);
typedef void(__stdcall* t_glBlendFunc)(GLenum, GLenum);
typedef void(__stdcall* t_glViewport)(GLint,GLint,GLsizei,GLsizei);

// Declaramos unos punteros que van a contener la dirección de las funciones OGL32 que usemos.
t_glBegin pOrig_glBegin = NULL;
t_glBlendFunc pOrig_glBlendFunc = NULL;
t_glViewport pOrig_glViewport = NULL;


Punto de entrada. Como podemos ver, la DLL se carga con un simple LoadLibrary. No hacemos inyección de DLL o cualquier otra forma de cargar una DLL. "glhack1.dll" es la DLL la cual se encarga del patch a la IAT y contiene los hooks de GPA y Opengl32.
Código (cpp) [Seleccionar]

int main(int argc, char **argv)
{
  SetConsoleTitle("glTest");

  int opc=0;
  while( 1){

system("cls");
printf("Bienvenido!\n");
printf("1: Interceptar OPENGL32\n");
printf("2: NO Interceptar OPENGL32\n");
printf("3: Salir\n");
scanf("%d",&opc);

if(opc == 1||opc == 2||opc == 3) break;
  }

  if(opc==3) ExitProcess(45);

  if(opc==1) //Al cargar la DLL, esta instala el hook a GPA para poder interceptar OGL32
  {
  if(!LoadLibrary("glhack1.dll")){
 
  MessageBox(0,0,0,0);
  ExitProcess(0);
  }
  }

  printf("\n");
  printf("EXE: GPA 0x%X\n", GetProcAddress);
  printf("EXE: glBegin 0x%X\n", glBegin);
  if(GetModuleHandle("opengl32.dll"))
  {
  pOrig_glBegin = (t_glBegin)GetProcAddress(GetModuleHandle("opengl32.dll"), "glBegin");
  pOrig_glBlendFunc = (t_glBlendFunc)GetProcAddress(GetModuleHandle("opengl32.dll"), "glBlendFunc");
  pOrig_glViewport = (t_glViewport)GetProcAddress(GetModuleHandle("opengl32.dll"), "glViewport");
  printf("EXE: glBegin 0x%X\n", pOrig_glBegin);
  printf("EXE: glBlendFunc 0x%X\n", pOrig_glBlendFunc);
  printf("EXE: glViewport 0x%X\n", pOrig_glViewport);
  }
  else
  {
  MessageBox(0,0,0,0);
  ExitProcess(0);
  return 0;
  }

  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  glutInitWindowSize(450, 450);
  glutCreateWindow("glTest");
  // glutFullScreen();
  init(argv[1]);
  glutDisplayFunc(display);
  glutKeyboardFunc(key);
  glutReshapeFunc(reshape);
  glutIdleFunc(tick);
  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}

//


Estas funciones son originales del código que conseguí en opengl.org
Los cambios que se ven son que las llamadas a función originales para las 3 funciones elegidas,
fueron cambiadas por los punteros a función que creamos.
Código (cpp) [Seleccionar]

void bfunc(void)
{
  static int state;
  if (state ^= 1)
  {
    pOrig_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
  } else {
    glDisable(GL_BLEND);
  }
}


Código (cpp) [Seleccionar]

void bfunc(void)
{
  static int state;
  if (state ^= 1)
  {
    pOrig_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
  } else {
    glDisable(GL_BLEND);
  }
}


Código (cpp) [Seleccionar]

void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
  glPushMatrix();
  glTranslatef(transx, transy, 0.f);
  glRotatef(rotx, 0., 1., 0.);
  glRotatef(roty, 1., 0., 0.);
  glScalef(scale, scale, 0.);
  pOrig_glBegin(GL_POLYGON);
  glTexCoord2f(0.0, 0.0);
  glVertex2f(-1.0, -1.0);
  glTexCoord2f(1.0, 0.0);
  glVertex2f(1.0, -1.0);
  glTexCoord2f(1.0, 1.0);
  glVertex2f(1.0, 1.0);
  glTexCoord2f(0.0, 1.0);
  glVertex2f(-1.0, 1.0);
  glEnd();
  glPopMatrix();
  glutSwapBuffers();
}



Código (cpp) [Seleccionar]

void reshape(int w, int h)
{
  pOrig_glViewport(-50, -50, w+120, h+120);
}


La DLL hace un patch a la IAT del EXE, el tema es que esta función la traje de un conocido creador de hacks que se llama h1web.
http://50hz.ws/devel/iathook.c.txt

El tema es que tuve que modificar la función para que funcione correctamente. Los cambios fueron en el 4to parámetro y dentro de la función. El problema era que estas estructuras que recorre, contienen cadenas sin terminación en 0, por lo que STRCMP no encontraba en nombre de GetProcAddress.
Código (cpp) [Seleccionar]
BOOL HookIAT(char* szModule, char* szFunc, DWORD dwOwn, DWORD& dwOrg)
{
    DWORD dwBase = (DWORD)GetModuleHandle(NULL);
    PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)dwBase;
    PIMAGE_NT_HEADERS pNTHdr = (PIMAGE_NT_HEADERS)(dwBase + pDosHdr->e_lfanew);
    DWORD ImportData = (DWORD)pNTHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    PIMAGE_IMPORT_DESCRIPTOR pImportD = (PIMAGE_IMPORT_DESCRIPTOR)(dwBase + ImportData);
    while(pImportD->Name != 0)
    {
// CUIDADO! En estas estructuras se encuentran strings no terminadas en 0
// por lo que STRCMP no sirve.
// Un cambio fácil puede ser usar STRSTR que encuentra una cadena dentro de otra.
// if(!strcmp((char*)(dwBase + pImportD->Name), szModule))
        if(!strstr((char*)(dwBase + pImportD->Name), szModule))
            break;
        pImportD++;
    }

//printf("pImportD->Name: %s\n",(char*)(dwBase + pImportD->Name));
//system("pause");
    if(pImportD->Name == 0) return FALSE;
//printf("pImportD->Name: 0x%X\n",pImportD->Name);
//system("pause");

    PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)(dwBase + pImportD->FirstThunk);
    DWORD OrgFunc = (DWORD)GetProcAddress(GetModuleHandle(szModule), szFunc);
    while(pThunk->u1.Function != 0)
    {
        if(pThunk->u1.Function == (DWORD*)OrgFunc)
        {
            dwOrg = OrgFunc;
            DWORD dwOldProt = 0;
            VirtualProtect((void*)&pThunk->u1.Function, 4, PAGE_EXECUTE_READWRITE, &dwOldProt);
            pThunk->u1.Function = (DWORD*)dwOwn;
            VirtualProtect((void*)&pThunk->u1.Function, 4, dwOldProt, &dwOldProt);
            if(pThunk->u1.Function == (DWORD*)dwOwn)
                return TRUE;
            else
                return FALSE;
        }
        pThunk++;
    }
    return FALSE;
}


DLL: main.cpp
Código (cpp) [Seleccionar]


//
// By 85
// HookIAT (h1web, Thanks to Ashkbiz Danehkar)
// elhacker.net
// etalking.com.ar
// 2013
//

///////////////////////////////////////////////////////////////////////////////////////////////////////////

#define WIN32_LEAN_AND_MEAN
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include"opengl.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////

FARPROC (WINAPI* pGetProcAddress) ( HMODULE hModule, LPCSTR lpProcName );

//
FARPROC WINAPI newGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
FARPROC nResult;
nResult=GetProcAddress(hModule, lpProcName);
if (HIWORD(lpProcName))
{
if (!lstrcmp(lpProcName, "GetProcAddress"))
{
return (FARPROC) &newGetProcAddress;
}
else
{
CheckForOpenGlHook(&nResult, lpProcName);
        }
}
return nResult;
}

//
BOOL HookIAT(char* szModule, char* szFunc, DWORD dwOwn, DWORD& dwOrg)
{
     // Ya mostrado
}

//
bool WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
if (fdwReason==DLL_PROCESS_ATTACH)
{
//printf("GetProcAddress 0x%X\n", GetProcAddress);// No refenciar GPA antes!
if(!HookIAT("kernel32.dll","GetProcAddress",(DWORD)newGetProcAddress,
(DWORD&)pGetProcAddress)){

MessageBox(0,0,0,0);
return (false);
}

printf("\n");
printf("DLL: newGetProcAddress 0x%X\n", newGetProcAddress);
printf("DLL: GetProcAddress 0x%X\n", GetProcAddress);
printf("DLL: pGetProcAddress 0x%X\n", pGetProcAddress);

}
return (true);
}


Los Hooks o funciones de gancho, como quieran decirles, son estas siguientes. Vemos que dentro de las de Opengl32 se hicieron cambios para modificar el resultado del programa.
El Hook de GetProcAddress se encarga de cambiar la dirección de retorno por una de los Hooks de Opengl32, y de inicializar los punteros a función con las direcciones de las originales.

DLL: opengl32.cpp
Código (cpp) [Seleccionar]

//
// By 85
// elhacker.net
// etalking.com.ar
// 2013
//

///////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma comment(lib, "opengl32.lib")
#include<windows.h>
#include<stdio.h>
#include "opengl.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////

// Opengl32 es APIENTRY
typedef void(__stdcall* t_glBegin)(GLenum);
typedef void(__stdcall* t_glBlendFunc)(GLenum, GLenum);
typedef void(__stdcall* t_glViewport)(GLint,GLint,GLsizei,GLsizei);

t_glBegin pOrig_glBegin = NULL;
t_glBlendFunc pOrig_glBlendFunc = NULL;
t_glViewport pOrig_glViewport = NULL;

bool once=false;
bool oglSubtractive = false;
bool NewDimension = true;

int posx = 200;
int posy = 200;
int neww = 50;
int newh = 50;

//
void __stdcall HOOK_glBegin(GLenum mode)
{
if(!once){
once=true;
}

if (mode==GL_POLYGON)
{
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glColor3f(0, 0, 0);
}

(*pOrig_glBegin)(mode);
}

void __stdcall HOOK_glBlendFunc(GLenum sfactor, GLenum dfactor)
{
if(oglSubtractive){
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

} else {
glBlendFunc(sfactor,dfactor);
}
}

void __stdcall HOOK_glViewport( GLint x,GLint y,GLsizei width,GLsizei height )
{
if(NewDimension){

(*pOrig_glViewport)(posx,posy,neww,newh);
}
else
{
(*pOrig_glViewport)(x,y,width,height);
}
}

void CheckForOpenGlHook(FARPROC* pProc,LPCTSTR lpProcName)
{
if (!strcmp(lpProcName,"glBegin"))
{
pOrig_glBegin = (t_glBegin)*pProc;
*pProc = (FARPROC)&HOOK_glBegin;
}
else if(!strcmp(lpProcName,"glBlendFunc"))
{
pOrig_glBlendFunc = (t_glBlendFunc)*pProc;
*pProc = (FARPROC)&HOOK_glBlendFunc;
}
else if(!strcmp(lpProcName,"glViewport"))
{
pOrig_glViewport = (t_glViewport)*pProc;
*pProc = (FARPROC)&HOOK_glViewport;
}
}


Espero que les haya gustado. Es un tutorial básico por lo tanto sólamente usé un parche a la IAT. Se puede experimentar con otro tipo de Hook más avanzado.

El programa ofrece la opción de interceptar Opengl32 o no:


Archivos utilizados:


Resultados:


Si me preguntan por qué hacer que usen GetProcAddress cuando no era necesario, la respuesta es que algunos juegos lo han hecho así, y servía para demostrar la utilidad de interceptar GPA.
Interceptar Opengl32 se podía haber hecho parcheando la IAT en las entradas de Opengl32 también.

Proyecto vc6:
http://www.mediafire.com/?p673twh7in70ys1
#158
Por ahí el muchacho quiso poner:


f[0]+=1;


lo cual incrementa en 1.. Pero le faltaba el '='  :rolleyes:

#159
NIVEL: Beginner
La continuación de este tutorial:
http://foro.elhacker.net/programacion_cc/tutorial_crear_un_parche_1-t384060.0.html

En este caso contamos con 2 ejecutables .EXE ;
dummy.EXE va a ser el proceso víctima y parche1_externo.EXE
va a ser el proceso atacante, por decirlo así..


Cuando se abre el 2do ejecutable mencionado, el proceso atacante queda a la espera de encontrar al proceso víctima.








Dummy.EXE
Código (cpp) [Seleccionar]


//
// By 85
// elhacker.net
// etalking.com.ar
// 2013
//

///////////////////

#include<windows.h>
#include<stdio.h>

//////////////////////
//////////////////////

DWORD dwPatchPlace = 0x00000000;
BYTE Opcode_JZ = 0x74;

///////////
////////////////////

void Target(){

while(1){


#define MASTERNUM 85
int master=0x99999997;
char* ingreso = new char[256];

system("cls");
printf("Ingrese la llave maestra\n");
scanf("%s", ingreso);

if(!strcmpi(ingreso, new char[]= "key85\0")){

master = 85;
}

delete []ingreso;
if(master==MASTERNUM)
{
printf("FELICITACIONES! USTE HA INGRESADO\n");
printf("\n");
system("pause");
break;
}

// if(GetAsyncKeyState(VK_END)) break;// En otro hilo
if(!strcmpi(ingreso, new char[]= "exit\0")) break;
}
}

//
void Check()//Función que representa un método de seguridad
{
if(*(PBYTE)dwPatchPlace != Opcode_JZ)
{
printf("0x%X\n",*(PBYTE)dwPatchPlace);
printf("Memoria alterada!, se sale del programa..\n");
printf("\n");
system("pause");
ExitProcess(45);
}
}

/////////

int main(){

SetConsoleTitle("Dummy");

dwPatchPlace=(DWORD)GetModuleHandle(NULL);//Retorna la BaseAddress

//Sumamos el offset obtenido del desensamblado
dwPatchPlace+=0x00001000;
dwPatchPlace+=0x6C;

//Logs

printf("LOG DE SEGURIDAD PRIMARIO:\n");
printf("0x%X\n",(DWORD)GetModuleHandle(NULL));
printf("0x%X\n",dwPatchPlace);
printf("0x%X\n",*(PBYTE)dwPatchPlace);
printf("\n");
system("pause");

//Llamamos a la función
Target();

printf("LOG DE SEGURIDAD SECUNDARIO:\n");
printf("0x%X\n",(DWORD)GetModuleHandle(NULL));
printf("0x%X\n",dwPatchPlace);
printf("0x%X\n",*(PBYTE)dwPatchPlace);
printf("\n");
system("pause");

//Se deja que las comprobaciones de seguridad sigan su curso
Check();

return 0;
}


parche1_externo.EXE
Código (cpp) [Seleccionar]


//
// By 85
// GetModuleBase (googleada en 5 segundos XD)
// elhacker.net
// etalking.com.ar
// 2013
//

///////////////////

#include<windows.h>
#include<stdio.h>
#include<tlhelp32.h>

//////////////////////

HANDLE hProcess;  
HANDLE hModule;
DWORD dwPatchPlace = 0x00000000;
BYTE Opcode_JZ = 0x74;
BYTE Opcode_JNZ = 0x75;
BYTE pReaden;

///////////

VOID Patch() {

// printf("0x%X\n",pReaden);
// system("pause");

if(!hProcess) return;
if(pReaden!=Opcode_JZ) return;

DWORD dwOldProtect;
   VirtualProtect( (LPVOID)dwPatchPlace,
                   1,
                   PAGE_EXECUTE_WRITECOPY,
                   &dwOldProtect );

   WriteProcessMemory( hProcess,
                       (LPVOID)dwPatchPlace,
                       &Opcode_JNZ,
                       1,
                       NULL );

   VirtualProtect( (LPVOID)dwPatchPlace,
                   1,
                   dwOldProtect,
                   &dwOldProtect );
}

//
////////////////////

DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId)
{
  MODULEENTRY32 lpModuleEntry = {0};
  HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );

  if(!hSnapShot)
     return NULL;
  lpModuleEntry.dwSize = sizeof(lpModuleEntry);
  BOOL bModule = Module32First( hSnapShot, &lpModuleEntry );
  while(bModule)
  {
  //printf("%s\n",lpModuleEntry.szModule);
     if(!strcmp( lpModuleEntry.szModule, lpModuleName ) )
     {
        CloseHandle( hSnapShot );
        return (DWORD)lpModuleEntry.modBaseAddr;
     }
     bModule = Module32Next( hSnapShot, &lpModuleEntry );
  }
  CloseHandle( hSnapShot );
  return NULL;
}

int main(){

// We have to replace JZ with JNZ.

//TODO: Obtener privilegios
//

char l_exe[] = {'d','u','m','m','y','.','e','x','e',0};
char l_window[] = {'D','u','m','m','y',0};
HWND hwnd;          
hwnd = FindWindow(0, l_window);    
if (!hwnd)    
{        
printf("Abre %s ahora.\n", l_exe);        
while (1)      
{            
Sleep(1000);            
hwnd = FindWindow(0, l_window);            
if (hwnd) break;
if (GetAsyncKeyState(VK_END)>0) ExitProcess(45);
}            
}

unsigned long pid;    
GetWindowThreadProcessId( hwnd, &pid);    
// hProcess=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_QUERY_INFORMATION,0,pid);
// hProcess=OpenProcess(PROCESS_VM_WRITE|PROCESS_VM_OPERATION,0,pid);
hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,pid);

HANDLE baseAddress = (HANDLE)GetModuleBase(l_exe, pid);
if(!baseAddress)
{
printf("No se obtubo la baseAddress!\n");
system("pause");
ExitProcess(45);
}

//Lugar del parche
dwPatchPlace=(DWORD)baseAddress;
dwPatchPlace+=0x00001000;
dwPatchPlace+=0x6C;

//Logs
printf("hProcess: 0x%X\n",hProcess);
printf("pid: %d\n",pid);
printf("dwPatchPlace: 0x%X\n",dwPatchPlace);
// printf("0x%X\n",*(PBYTE)dwPatchPlace);//No se puede hacer esto para otro proceso
if(ReadProcessMemory(hProcess,(void*)(dwPatchPlace),&pReaden,sizeof(pReaden),0))
{
printf("Lugar antes de parchear: 0x%X\n",pReaden);
}
else
printf("ReadProcessMemory failed: %d\n",GetLastError());

system("pause");

//Se procede a parchear el proceso objetivo
Patch();

if(ReadProcessMemory(hProcess,(void*)(dwPatchPlace),&pReaden,sizeof(pReaden),0))
{
printf("Lugar luego de parchear: 0x%X\n",pReaden);
}
else
printf("ReadProcessMemory failed: %d\n",GetLastError());


CloseHandle(hProcess);
system("pause");
return 0;
}

//


La finalidad es la misma que la primer parte del tutorial, es decir parchear un OPCODE en la memoria del proceso víctima. Las novedades son que se hizo desde otro proceso por lo que SI se tuvo que usar ReadProcessMemory y WriteProcessMemory (Sin mencionar las otras API's).

Para detectar si la ventana del proceso víctima se encuentra abierta se ha usado FindWindow.

Para obtener un manejador (handle) del proceso víctima usamos OpenProcess.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx

Algo también que van a querer saber:
Citar
To open a handle to another local process and obtain full access rights, you must enable the SeDebugPrivilege privilege. For more information, see Changing Privileges in a Token.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms717797(v=vs.85).aspx

y conocer los posibles derechos de acceso a un proceso:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx

Al terminar las operaciones se debe cerrar el handle del proceso.

Sobre la forma de buscar los procesos activos, se usó la función googleada 'GetModuleBase' que utiliza TOOLHELP32, para obtener la dirección base:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686832(v=vs.85).aspx

Recuerden que son dos procesos separados con sus espacios de direcciones respectivos, por lo cual se requiere ReadProcessMemory para leer la memoria de otro proceso, y para modificarla, WriteProcessMemory.

O sea que algo como esto:

printf("0x%X\n",*(PBYTE)dwPatchPlace);//No se puede hacer esto para otro proceso


No sirve porque la dirección guardada en dwPatchPlace es del proceso víctima, no del proceso atacante.
Por eso se pasa como parámetro a ReadProcessMemory.

Si quieren saber como obtener su propia 'dwPatchPlace' de un programa cualquiera, van a tener que desensamblarlo (mejor si no está protegido) o en otro caso depurarlo en funcionamiento con un depurador como el OllyDBG.
Es decir, el tutorial da por sabido que cada uno ya sabe lo que quiere parchear y adonde debe parchear. El tutorial apunta a cómo se parchea.

Disculpen si faltan cosas en este humilde tutorial, pero es para beginners por lo tanto si faltan cosas pueden aportarlas  ;D.

Proyecto vc6: http://www.mediafire.com/?8a65cuufh2dd4um
#160
Programación C/C++ / Flotantes aleatorios
6 Marzo 2013, 03:18 AM
Hola,
hacía un tiempo había creado una optimización para un código que permitía obtener números flotantes aleatorios, que se usaban en una funcionalidad de un hack para Counter-Strike.
En realidad se necesitan 4 valores aleatorios para usarse en el hack y lo que hice fue optimizar el código original, que daba muchas vueltas antes de hacer la operación real. Supongo que para confundir a los hackers XD

pero fuera de lo que tiene que ver con el Counter-Strike, esto sirve para generar números aleatorios (de punto flotante), por eso el título..

Tengan en cuenta que se puede modificar la función que genera los números aleatorios, para que devuelva un sólo número en lugar de un vector de 4. También pueden hacer las modificaciones que quieran, pero tengan en cuenta que así como está es como sirve para el hack.
Para más información:
http://www.gamedeception.net/threads/26109-85-Customized-Spread-Class

Este es un programa demostrativo que hice para ver los resultados:


//
// By 85
// Credits: HL1 SDK, Paul Upton, Snipity (Tad)
// elhacker.net
// etalking.com.ar
// David Riedel
// 2013

#pragma warning(disable: 4390)
#include<windows.h>
#include<iostream>
#include<stdio.h>
#include<time.h>

//

class Random{

public:
Random()
{
Init();
}
private:
void Init();
float RandomFloat[4];
unsigned int glSeed;
unsigned int seed_table[ 256 ];
public:
void SetRandomFloatVector(unsigned int seed, int future);
float* getRandomFloatVector() { return RandomFloat; }
};

//

Random random;

//
void Random::Init(){
glSeed = 0;
int i=0;
seed_table[i] = 28985; i++;
seed_table[i] = 27138; i++;
seed_table[i] = 26457; i++;
seed_table[i] = 9451; i++;
seed_table[i] = 17764; i++;
seed_table[i] = 10909; i++;
seed_table[i] = 28790; i++;
seed_table[i] = 8716; i++;
seed_table[i] = 6361; i++;
seed_table[i] = 4853; i++;
seed_table[i] = 17798; i++;
seed_table[i] = 21977; i++;
seed_table[i] = 19643; i++;
seed_table[i] = 20662; i++;
seed_table[i] = 10834; i++;
seed_table[i] = 20103; i++;
seed_table[i] = 27067; i++;
seed_table[i] = 28634; i++;
seed_table[i] = 18623; i++;
seed_table[i] = 25849; i++;
seed_table[i] = 8576; i++;
seed_table[i] = 26234; i++;
seed_table[i] = 23887; i++;
seed_table[i] = 18228; i++;
seed_table[i] = 32587; i++;
seed_table[i] = 4836; i++;
seed_table[i] = 3306; i++;
seed_table[i] = 1811; i++;
seed_table[i] = 3035; i++;
seed_table[i] = 24559; i++;
seed_table[i] = 18399; i++;
seed_table[i] = 315; i++;
seed_table[i] = 26766; i++;
seed_table[i] = 907; i++;
seed_table[i] = 24102; i++;
seed_table[i] = 12370; i++;
seed_table[i] = 9674; i++;
seed_table[i] = 2972; i++;
seed_table[i] = 10472; i++;
seed_table[i] = 16492; i++;
seed_table[i] = 22683; i++;
seed_table[i] = 11529; i++;
seed_table[i] = 27968; i++;
seed_table[i] = 30406; i++;
seed_table[i] = 13213; i++;
seed_table[i] = 2319; i++;
seed_table[i] = 23620; i++;
seed_table[i] = 16823; i++;
seed_table[i] = 10013; i++;
seed_table[i] = 23772; i++;
seed_table[i] = 21567; i++;
seed_table[i] = 1251; i++;
seed_table[i] = 19579; i++;
seed_table[i] = 20313; i++;
seed_table[i] = 18241; i++;
seed_table[i] = 30130; i++;
seed_table[i] = 8402; i++;
seed_table[i] = 20807; i++;
seed_table[i] = 27354; i++;
seed_table[i] = 7169; i++;
seed_table[i] = 21211; i++;
seed_table[i] = 17293; i++;
seed_table[i] = 5410; i++;
seed_table[i] = 19223; i++;
seed_table[i] = 10255; i++;
seed_table[i] = 22480; i++;
seed_table[i] = 27388; i++;
seed_table[i] = 9946; i++;
seed_table[i] = 15628; i++;
seed_table[i] = 24389; i++;
seed_table[i] = 17308; i++;
seed_table[i] = 2370; i++;
seed_table[i] = 9530; i++;
seed_table[i] = 31683; i++;
seed_table[i] = 25927; i++;
seed_table[i] = 23567; i++;
seed_table[i] = 11694; i++;
seed_table[i] = 26397; i++;
seed_table[i] = 32602; i++;
seed_table[i] = 15031; i++;
seed_table[i] = 18255; i++;
seed_table[i] = 17582; i++;
seed_table[i] = 1422; i++;
seed_table[i] = 28835; i++;
seed_table[i] = 23607; i++;
seed_table[i] = 12597; i++;
seed_table[i] = 20602; i++;
seed_table[i] = 10138; i++;
seed_table[i] = 5212; i++;
seed_table[i] = 1252; i++;
seed_table[i] = 10074; i++;
seed_table[i] = 23166; i++;
seed_table[i] = 19823; i++;
seed_table[i] = 31667; i++;
seed_table[i] = 5902; i++;
seed_table[i] = 24630; i++;
seed_table[i] = 18948; i++;
seed_table[i] = 14330; i++;
seed_table[i] = 14950; i++;
seed_table[i] = 8939; i++;
seed_table[i] = 23540; i++;
seed_table[i] = 21311; i++;
seed_table[i] = 22428; i++;
seed_table[i] = 22391; i++;
seed_table[i] = 3583; i++;
seed_table[i] = 29004; i++;
seed_table[i] = 30498; i++;
seed_table[i] = 18714; i++;
seed_table[i] = 4278; i++;
seed_table[i] = 2437; i++;
seed_table[i] = 22430; i++;
seed_table[i] = 3439; i++;
seed_table[i] = 28313; i++;
seed_table[i] = 23161; i++;
seed_table[i] = 25396; i++;
seed_table[i] = 13471; i++;
seed_table[i] = 19324; i++;
seed_table[i] = 15287; i++;
seed_table[i] = 2563; i++;
seed_table[i] = 18901; i++;
seed_table[i] = 13103; i++;
seed_table[i] = 16867; i++;
seed_table[i] = 9714; i++;
seed_table[i] = 14322; i++;
seed_table[i] = 15197; i++;
seed_table[i] = 26889; i++;
seed_table[i] = 19372; i++;
seed_table[i] = 26241; i++;
seed_table[i] = 31925; i++;
seed_table[i] = 14640; i++;
seed_table[i] = 11497; i++;
seed_table[i] = 8941; i++;
seed_table[i] = 10056; i++;
seed_table[i] = 6451; i++;
seed_table[i] = 28656; i++;
seed_table[i] = 10737; i++;
seed_table[i] = 13874; i++;
seed_table[i] = 17356; i++;
seed_table[i] = 8281; i++;
seed_table[i] = 25937; i++;
seed_table[i] = 1661; i++;
seed_table[i] = 4850; i++;
seed_table[i] = 7448; i++;
seed_table[i] = 12744; i++;
seed_table[i] = 21826; i++;
seed_table[i] = 5477; i++;
seed_table[i] = 10167; i++;
seed_table[i] = 16705; i++;
seed_table[i] = 26897; i++;
seed_table[i] = 8839; i++;
seed_table[i] = 30947; i++;
seed_table[i] = 27978; i++;
seed_table[i] = 27283; i++;
seed_table[i] = 24685; i++;
seed_table[i] = 32298; i++;
seed_table[i] = 3525; i++;
seed_table[i] = 12398; i++;
seed_table[i] = 28726; i++;
seed_table[i] = 9475; i++;
seed_table[i] = 10208; i++;
seed_table[i] = 617; i++;
seed_table[i] = 13467; i++;
seed_table[i] = 22287; i++;
seed_table[i] = 2376; i++;
seed_table[i] = 6097; i++;
seed_table[i] = 26312; i++;
seed_table[i] = 2974; i++;
seed_table[i] = 9114; i++;
seed_table[i] = 21787; i++;
seed_table[i] = 28010; i++;
seed_table[i] = 4725; i++;
seed_table[i] = 15387; i++;
seed_table[i] = 3274; i++;
seed_table[i] = 10762; i++;
seed_table[i] = 31695; i++;
seed_table[i] = 17320; i++;
seed_table[i] = 18324; i++;
seed_table[i] = 12441; i++;
seed_table[i] = 16801; i++;
seed_table[i] = 27376; i++;
seed_table[i] = 22464; i++;
seed_table[i] = 7500; i++;
seed_table[i] = 5666; i++;
seed_table[i] = 18144; i++;
seed_table[i] = 15314; i++;
seed_table[i] = 31914; i++;
seed_table[i] = 31627; i++;
seed_table[i] = 6495; i++;
seed_table[i] = 5226; i++;
seed_table[i] = 31203; i++;
seed_table[i] = 2331; i++;
seed_table[i] = 4668; i++;
seed_table[i] = 12650; i++;
seed_table[i] = 18275; i++;
seed_table[i] = 351; i++;
seed_table[i] = 7268; i++;
seed_table[i] = 31319; i++;
seed_table[i] = 30119; i++;
seed_table[i] = 7600; i++;
seed_table[i] = 2905; i++;
seed_table[i] = 13826; i++;
seed_table[i] = 11343; i++;
seed_table[i] = 13053; i++;
seed_table[i] = 15583; i++;
seed_table[i] = 30055; i++;
seed_table[i] = 31093; i++;
seed_table[i] = 5067; i++;
seed_table[i] = 761; i++;
seed_table[i] = 9685; i++;
seed_table[i] = 11070; i++;
seed_table[i] = 21369; i++;
seed_table[i] = 27155; i++;
seed_table[i] = 3663; i++;
seed_table[i] = 26542; i++;
seed_table[i] = 20169; i++;
seed_table[i] = 12161; i++;
seed_table[i] = 15411; i++;
seed_table[i] = 30401; i++;
seed_table[i] = 7580; i++;
seed_table[i] = 31784; i++;
seed_table[i] = 8985; i++;
seed_table[i] = 29367; i++;
seed_table[i] = 20989; i++;
seed_table[i] = 14203; i++;
seed_table[i] = 29694; i++;
seed_table[i] = 21167; i++;
seed_table[i] = 10337; i++;
seed_table[i] = 1706; i++;
seed_table[i] = 28578; i++;
seed_table[i] = 887; i++;
seed_table[i] = 3373; i++;
seed_table[i] = 19477; i++;
seed_table[i] = 14382; i++;
seed_table[i] = 675; i++;
seed_table[i] = 7033; i++;
seed_table[i] = 15111; i++;
seed_table[i] = 26138; i++;
seed_table[i] = 12252; i++;
seed_table[i] = 30996; i++;
seed_table[i] = 21409; i++;
seed_table[i] = 25678; i++;
seed_table[i] = 18555; i++;
seed_table[i] = 13256; i++;
seed_table[i] = 23316; i++;
seed_table[i] = 22407; i++;
seed_table[i] = 16727; i++;
seed_table[i] = 991; i++;
seed_table[i] = 9236; i++;
seed_table[i] = 5373; i++;
seed_table[i] = 29402; i++;
seed_table[i] = 6117; i++;
seed_table[i] = 15241; i++;
seed_table[i] = 27715; i++;
seed_table[i] = 19291; i++;
seed_table[i] = 19888; i++;
seed_table[i] = 19847;
}

//
// Misma funcionalidad que random.cpp y nospread.cpp (Snipity Hook)
void Random::SetRandomFloatVector(unsigned int seed, int future){// By 85
for(int i=0; i<4; i++){
glSeed = seed_table[(int)(seed+future+i)&0xff];
for(int j=0; j<3;j++){
glSeed *= 69069;
glSeed += seed_table[glSeed&0xff];
(++glSeed & 0x0fffffff);
}
RandomFloat[i]=(-0.5+(float)(((glSeed&0x0fffffff)&65535)/65536.0f));
}
}

//
int main(){

unsigned int seed;
int future;
seed = time(NULL);
future=1;
int i =0;

while(1)
{
seed = time(NULL);//No es la seed original (Original es me.spread.random_seed)
       random.SetRandomFloatVector(seed, future);
printf("RandomFloat[0] %f\n",random.getRandomFloatVector()[0]);
printf("RandomFloat[1] %f\n",random.getRandomFloatVector()[1]);
printf("RandomFloat[2] %f\n",random.getRandomFloatVector()[2]);
printf("RandomFloat[3] %f\n",random.getRandomFloatVector()[3]);
printf("\n");

std::cout << "Press the ENTER key\n";
if (std::cin.get() == '\n');

if(i++==10) break;
}

system("pause > nul");
return 0;
}

//


Proyecto vc6: http://www.mediafire.com/?a93dsydc3gvrrdj