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

#171
mi publicación es decente, el indecente sos vos amigo.

que tiene que ver que la IAT no está siempre en esa dirección?

para algo la busqué en el PE EXPLORER !! se trata de usar el desensamblador no de hacer algo automático. Si se trata de este programa específicamente!. Ni leer sabés, nice bepi


y si, tal parece que se ha publicado 1001 vez
#172
void cambiar(int &valor){
   valor=7;
}


claro la dirección..

sino
void cambiar(int* valor){
   *valor=7;
}


pero al llamarla tenés que hacer así

int valor;
cambiar(&valor);


#173
Hola, quería mostrar algo básico que puede aportar algunos conceptos. Más que nada, gente que está en sus comienzos con la programación y puede interesarse en algunos detalles técnicos.

NIVEL: Beginner
No consideren esto de nivel avanzado.

Lo primero:
IAT = IMPORT ADDRESS TABLE
http://sandsprite.com/CodeStuff/Understanding_imports.html
http://www.karmany.net/index.php/ingenieria-inversa/19-ingenieria-inversa-novatos/146-pe-header-que-es-la-iat-import-address-table
http://cboard.cprogramming.com/cplusplus-programming/99240-import-address-table-iat.html

La iat es un lugar que puede accederse fácilmente con un desensamblador y se pueden observar todos los símbolos que el ejecutable importa de ciertos módulos. Hay una forma de hacer que el ejecutable no contenga imports, pero fuera de esa técnica los ejecutables la utilizan.
Generalmente se dice que los EXE usan la IAT y las DLL las EAT,
véase EAT = EXPORT ADDRESS TABLA , es para exportar símbolos.

Más información
http://www.rohitab.com/discuss/topic/33541-assembling-an-executable-with-no-imports/
http://www.etalking.com.ar/showthread.php?400-llamar-funciones-winapi32-sin-imports


Volviendo al tema, veamos lo que uno puede hacer fácilmente, con un desensamblador:









Obteniendo la dirección específica en la IAT se puede proceder a crear el parche con el cual se logra interceptar GetProcAddress.
Se trata sólo de cambiar el valor de un puntero, poniéndole la dirección de nuestra función "de gancho" o hook, para que sea llamada en lugar de la original.



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

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

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

typedef FARPROC (WINAPI* GetProcAddress_t) ( HMODULE hModule, LPCSTR lpProcName );

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

DWORD PatchIAT( DWORD pOrgFunction, DWORD pNewFunction )
{
DWORD dwOldProtect;
DWORD dwOldProtect2;
DWORD pOldFunction = ((DWORD*)pOrgFunction)[0];

VirtualProtect( reinterpret_cast< void * >( pOrgFunction ), sizeof( DWORD ), PAGE_EXECUTE_READWRITE, &dwOldProtect );
((DWORD*)pOrgFunction)[0] = pNewFunction;
VirtualProtect( reinterpret_cast< void * >( pOrgFunction ), sizeof( DWORD ), dwOldProtect, &dwOldProtect2 );
return pOldFunction;
}

int main(){

//400000+2004= GPA IAT ENTRY (En este programa x64core!, no lo modifiques!)
DWORD dwGPA = (DWORD)(GetModuleHandle(NULL));
dwGPA+=0x2004;

// x64core lo quiere en ASM inline..
__asm {
mov ebx, dwGPA
mov edx, [ebx]
mov pGetProcAddress, edx
}

// pGetProcAddress = *(GetProcAddress_t*)dwGPA;// Ajam..

printf("pGetProcAddress 0x%X\n\n",pGetProcAddress);
printf("GetProcAddress antes 0x%X\n\n",*(DWORD*)dwGPA);
// printf("GetProcAddress antes 0x%X\n\n",GetProcAddress);//No referenciar GPA antes del parche!

// Parchear IAT
PatchIAT( dwGPA, (DWORD)&newGetProcAddress );

// Sin PatchIAT:
//Desproteger
//DWORD* pGPA=(DWORD*)0x00402004;//400000+2004= GPA IAT ENTRY
//*pGPA=(DWORD)&newGetProcAddress;
//Proteger

printf("dwGPA 0x%X\n",dwGPA);
printf("*dwGPA 0x%X\n",*(DWORD*)dwGPA);
printf("GetProcAddress ahora 0x%X\n",GetProcAddress);
printf("newGetProcAddress 0x%X\n",newGetProcAddress);
system("pause");

DWORD test = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
printf("test 0x%X\n",test);
printf("GetProcAddress ahora 0x%X\n",GetProcAddress);
system("pause");
return 0;
}

//


Dejo el proyectito para descargar
http://www.mediafire.com/?2sowg12a6vora4n

Hasta Luego
#174
Programación C/C++ / Re: ATOI + ITOA remake
27 Febrero 2013, 04:14 AM
Amí me preocupa que esos códigos que publicaste tengan partes parecidas a esto:
http://foro.elhacker.net/programacion_cc/atoi_itoa_personalizadas-t358459.0.html;msg1735068#msg1735068
A no ser que seas blackzero..

Mis modificaciones recientes no fueron probadas, sólamente se quitaron ciertas cosas que no son necesarias, tablas, funciones std, y otras cosas. La idea era quitar las tablas y los llamados innecesarios a funciones ajenas.
lamentable que no funcionen, si necesitás versiones funcionando usá las originales.

Otra cosa , las macros están hechas para simplificar y hacer el código más legible, entre otras cosas.. no se de qué libro aprendiste que no era así.
Todos sabemos que el código en las macros se copia adonde es invocada, no es en sí resumir código sino para simplificar el entendimiento.
No es lo mismo copiar 2 veces el código de la macro FACTORES, que poner 2 veces una sóla línea que diga FACTORES(). Me extraña que no lo entiendas porque eras el más interesado en resumir líneas de TEXTO..

Se entiende que el que usa la macro FACTORES la conoce, sabe su código, no necesita verlo repetido tantas veces. Si no entendés la macro no la uses porque en ese caso, si tenés razón, el código sería más ilegible.

Mi consejo entonces es que no uses macros que no entiendas..
Saludos.


EDITADO 1

hecha una revisión rápida del código, no estaba funcionando ni como las primeras versiones :/

atoi original ante esta situación:

"5f" o "11www"

devuelve 5 u 11

lo cual aunque parece tener sentido, mi función sólo devuelve 0
porque 11www no es 11.

para que cumpla con lo de pasar parámetros correctamente!

Por otro lado , comprueba el signo y guarda un resultado para usarse posteriormente a la hora de diferenciar entre significados y no:


int sig=0;
if((sig=str[0]=='+')||(sig=str[0]=='-'))
..


El índice que mostraste fue considerado como otra opción.
ITOA no fue mayormente revisada, sólo hice algunas pruebas generales, las que aparecen en el ENTRY. Tiene dos bloques de código bastante parecidos como muy bien notaste, y no estaría nada mal inventar algo para usar sólo un bloque de entre ambos.

Saludos

EDITADO 2

Decidí seguir tus sugerencias y quité el array y las macros.
Al mismo tiempo, ahora en MI_ITOA se usa 1 sólo bloque de procesamiento por factores.

Saludos


#175
si gracias, VirtualProtect y WriteProcessMemory deben comprobarse.. usando incluso GetLastError en caso de excepción , para obtener información.

atte

#176
Programación C/C++ / Tutorial: Crear un parche 1
25 Febrero 2013, 09:12 AM
Estaba mirando un tema acerca de como se pasaba por alto la detección de un anticheat y se me ocurrió la idea de mostrar como se puede hacer un parche básico dentro de un mismo proceso. Es decir tenemos un ejecutable, lo ejecutamos y parcheamos nuestra propia memoria. Esto se puede hacer de varias formas, una de ellas es inyectando una DLL , pero esto es algo más fácil :p

Cómo es una demostración el propio programa se parchea así mismo, por lo que necesitamos saber en que lugar vamos a querer modificar las cosas.
Para eso en el programa puse un bloque condicional que es el que me interesa parchear para poder accederlo aunque no se cumpla la condición.
Por Ejemplo:

if( 0 == 1){ /* no se cumple */ }

Eso no se cumple, pero parcheándolo se logra acceder de todas formas..

Con un desensamblador, abro el ejecutable (el archivo EXE) y procedo a mirar el código ensamblador.


Identifico el OPCODE que me interesa cambiar, en este caso es JZ (0x74), y procedo a obtener la posición en donde se encuentra (dirección de memoria).

Es 0x40106C

En realidad lo que nos interesa es saber el desplazamiento en bytes que hay desde la dirección base del ejecutable hasta el punto en el que queremos parchear.
Se puede tomar en cuenta la sección de código también pero no es la base del ejecutable, recordar al momento de hacer la cuenta..


Bueno el offset (desplazamiento) es 0x6C y 0x1000 de la sección de código.

Bueno sabiendo estas cosas, ya vamos al código..
Con respecto al código, como decía antes, la idea viene de algo que estaba mirando sobre llamadas seguras a funciones para evitar detecciones de un anticheat por ejemplo,,
Por eso fui a crear una función (Check()) que trata de ser en forma figurativa la detección de modificaciones en la memoria.
Aunque en realidad una función de este tipo no tiene mucho sentido en el mismo hilo de ejecución, se debería hacer desde otro..

Y otro concepto que se puede apreciar en todo esto, es la importancia de restaurar la memoria luego de modificarla y lograr lo deseado.
Por eso , en este programa luego de realizar el parche y de llamar a la función de prueba (Target()) , se procede a restaurar la memoria a como estaba antes, para que las detecciones no se disparen.

Véase el bloque condicional donde se desea poder ingresar

...
if(master==MASTERNUM)//Aquí es donde queremos entrar XD
{ ...


Código (cpp) [Seleccionar]


//
// By 85
// Credits: Organner
// elhacker.net
// etalking.com.ar
// 2013
//

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

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

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

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

///////////

inline void Patch(){//Función de parcheadora

if(*(PBYTE)dwPatchPlace!=Opcode_JZ) return;

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

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

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

//
inline void UnPatch(){//Función restauradora

if(*(PBYTE)dwPatchPlace!=Opcode_JNZ) return;

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

WriteProcessMemory( GetCurrentProcess(),
                       (LPVOID)dwPatchPlace,
                       &Opcode_JZ,
                       1,
                       NULL );

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

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

void Target(){//Función objetivo para ser alterada

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)//Aquí es donde queremos entrar XD
{
printf("FELICITACIONES! USTED 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(){

// We have to replace JZ with JNZ.

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

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

//Logs
printf("0x%X\n",(DWORD)GetModuleHandle(NULL));
printf("0x%X\n",dwPatchPlace);
printf("0x%X\n",*(PBYTE)dwPatchPlace);
printf("\n");
system("pause");

//Parcheamos la memoria antes de llamar a la función
Patch();

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

//Volvemos a dejar la memoria como estaba antes
// UnPatch();

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

return 0;
}


Unas imágenes, aunque voy a dejar el proyecto para descargar.


La llamada a UnPatch() está comentada, por eso la detección se dispara..


Un comentario acerca del uso de WriteProcessMemory, no es necesario,,
ya que con simplemente hacer esto:
*(PBYTE)dwPatchPlace= Opcode_JNZ;
es suficiente, ya que es un mismo proceso.
lo que pasa que ambas funciones fueron sacadas de un post de un tal Organner, que algunos deben saber quien es, sólo les cambié una cosa y listo, aunque tampoco son algo especial como para que deban tener un autor XD

Proyecto MSVC6
http://www.mediafire.com/?j7s6a85bp4k5p3t

Este tutorial está orientado a gente principiante en la programación, no sea considerado un tutorial avanzado  ;D

Hasta Luego
#177
Cita de: MeCraniDOS en 24 Febrero 2013, 20:04 PM
Si, hace poco mas de un mes que estoy con el C++, muchas gracias por las soluciones, ahora lo cambio e intentaré entender las modificaciones.

En el código de los jugadores, lo único que falle fue en la tontería que me dijiste...


Código (cpp) [Seleccionar]
    printf("\n\nEl mejor resultado lo ha obtenido %s con una puntuacion de %d puntos.", punt_max, mej_jug);
    printf("\n\nEl peor resultado lo ha obtenido %s con una puntuacion de %d puntos.", punt_min, men_jug);


Y tendría que ser asi...

Código (cpp) [Seleccionar]
    printf("\n\nEl mejor resultado lo ha obtenido %s con una puntuacion de %d puntos.", mej_jug, punt_max);
    printf("\n\nEl menor resultado lo ha obtenido %s con una puntuacion de %d puntos.", men_jug, punt_min);


Pero el de PI no entiendo la modificación.... Pero aun así gracias  ;-) ;-)

Na en realidad, yo no te digo que son tonterías eso le pasa a cualquiera. Te conviene practicar la depuración de programas. No es necesario el windbg para hacerlo, se puede seguir la ejecución de un programa usando un mísero MessageBox o un printf+pause, cualquier cosa que te muestre por pantalla la situación del programa.

Con respecto al primer programa, estas dos asignaciones estaban invertidas y fueron arregladas..

Citarint main(void)
{
    int ValLongA;
    int DistDiamA;
    int ValLongB;
    int DistDiamB;
    Medida(ValLongA, DistDiamA);
    ValLongB = ValLongA;
    DistDiamB = DistDiamA;

    Algoritmo(ValLongB, DistDiamB);
   return 0;
}

Lo que también se hizo fue hacer que,
Código (cpp) [Seleccionar]
void Medida(int& Val, int& Dist)

reciba los parámetros por referencia, para poder modificarlos.

después esto,
Código (cpp) [Seleccionar]
_PI = (float)((float)Longitud/(float)Diametro);

olvidate , es sólo figurativo

hasta luego

#178

Tus códigos tienen ciertas faltas un tanto inocentes, pero se nota que estás aprendiendo, por eso te las arreglé para que funcionen tus programas.
Igualmente me puse a depurar algo que en realidad eran errores fáciles como ser un %d por un %s , pero eso dije faltas un tanto inocentes XD


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

void Medida(int& Val, int& Dist);
void Algoritmo(int Longitud, int Diametro);

int main(void)
{
    int ValLongA;
    int DistDiamA;
    int ValLongB;
    int DistDiamB;
    Medida(ValLongA, DistDiamA);
    ValLongB = ValLongA;
    DistDiamB = DistDiamA;
    Algoritmo(ValLongB, DistDiamB);
return 0;
}

void Medida(int& Val, int& Dist)
{
     printf("\n\nIntroduzca la longitud de la circumerencia: ");
     scanf("%d", &Val);
     printf("\n\nIntroduzca el diametro de la circumerencia: ");
     scanf("%d", &Dist);
}

void Algoritmo(int Longitud, int Diametro)
{
     float _PI;
     _PI = (float)((float)Longitud/(float)Diametro);
     printf("\nEl valor de PI para esos valores es...\n\n");
     printf("PI: %f\n", _PI);
     fflush(stdin);
     printf("\nPresione Intro para finalizar...\n\n");
     getchar();
}




#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct TJugadores
{
char nombre[75];
    int puntuacion;
};

int main(void)
{
    struct TJugadores name[6];
    int n;
    int punt_max;
    int punt_min;
    char mej_jug[75];
    char men_jug[75];
const int cant=2;


    for(n=0; n<cant; n++)
    {
printf("\nEscribe el nombre del jugador %d: ", n+1);  //Nombre del jugador
gets(name[n].nombre);
fflush(stdin);
printf("\nEscribe la puntuacion: "); //Puntuación del jugador
scanf("%d",&name[n].puntuacion);
fflush(stdin);
    }

// MessageBox(0,0,0,0);

    punt_max = name[0].puntuacion;
    strcpy (mej_jug, name[0].nombre);
    punt_min = name[0].puntuacion;
    strcpy (men_jug, name[0].nombre);   

// MessageBox(0,0,0,0);

    for(n=0; n<cant; n++)
    {
if (name[n].puntuacion > punt_max)
{
punt_max = name[n].puntuacion;
strcpy (mej_jug, name[n].nombre);
}

if (name[n].puntuacion < punt_min)
{
punt_min = name[n].puntuacion;
strcpy (men_jug, name[n].nombre);
}
    }

// MessageBox(0,0,0,0);

    printf("\n\nEl mejor resultado lo ha obtenido %d con una puntuacion de %s puntos.", punt_max, mej_jug);
    printf("\n\nEl peor resultado lo ha obtenido %d con una puntuacion de %s puntos.", punt_min, men_jug);
    fflush(stdin);
    printf("\nPresione Intro para finalizar...\n\n");
    getchar();
return 0;
}


#179
Programación C/C++ / Re: Consulta C++
24 Febrero 2013, 19:34 PM

la expresión mínima compilable XD, si algo no está funcionando revisá los métodos de la clase, no los podemos adivinar



#include <iostream>
#include <string>
using namespace std;
class Jugador {

private:
string str;
public:
void setNombre(string n){ str=n; }
string getNombre() {return str;}
};

void YumYum()
{
const int cant = 2;
Jugador j[cant];
for(int i=0;i<cant;i++){   
string n="";
cout<<i+1<<": ";
cin >> n;
j[i].setNombre(n);
cout<<endl;
}

// cout<<j[0].getNombre()<<endl;
}

int main(){
YumYum();
printf("\n");
system("pause");
return 0;
}


#180
Programación C/C++ / Re: ATOI + ITOA remake
24 Febrero 2013, 19:11 PM
Muy cierto, en realidad no debí haber creado el topic XD ya que siempre alguien lo va a hacer de una forma diferente, o arreglando uno existente, habría miles de implementaciones y en muchos lenguajes. Pero aveces está bueno para el aprendizaje