|
171
|
Programación / Programación C/C++ / Re: Parchear la IAT para interceptar GPA
|
en: 27 Febrero 2013, 07:40 am
|
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
|
|
|
173
|
Programación / Programación C/C++ / Parchear la IAT para interceptar GPA
|
en: 27 Febrero 2013, 04:56 am
|
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: BeginnerNo consideren esto de nivel avanzado. Lo primero: IAT = IMPORT ADDRESS TABLEhttp://sandsprite.com/CodeStuff/Understanding_imports.htmlhttp://www.karmany.net/index.php/ingenieria-inversa/19-ingenieria-inversa-novatos/146-pe-header-que-es-la-iat-import-address-tablehttp://cboard.cprogramming.com/cplusplus-programming/99240-import-address-table-iat.htmlLa 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-importsVolviendo 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/?2sowg12a6vora4nHasta Luego
|
|
|
174
|
Programación / Programación C/C++ / Re: ATOI + ITOA remake
|
en: 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#msg1735068A 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 1hecha 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 2Decidí 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
|
|
|
176
|
Programación / Programación C/C++ / Tutorial: Crear un parche 1
|
en: 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 { ...
// // 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/?j7s6a85bp4k5p3tEste tutorial está orientado a gente principiante en la programación, no sea considerado un tutorial avanzado Hasta Luego
|
|
|
177
|
Programación / Programación C/C++ / Re: [?] Problemas con código en C++
|
en: 24 Febrero 2013, 21:46 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... 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... 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.. int 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, void Medida(int& Val, int& Dist)
reciba los parámetros por referencia, para poder modificarlos. después esto, _PI = (float)((float)Longitud/(float)Diametro);
olvidate , es sólo figurativo hasta luego
|
|
|
178
|
Programación / Programación C/C++ / Re: [?] Problemas con código en C++
|
en: 24 Febrero 2013, 19:52 pm
|
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 / Programación C/C++ / Re: Consulta C++
|
en: 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 / Programación C/C++ / Re: ATOI + ITOA remake
|
en: 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
|
|
|
|
|
|
|