Tras mucho tiempo de no postear en este foro, me decidí hacer este pequeño y tonto crackme para el que tenga ganas de jugar con el... cabe aclarar que es demasiado simple como para parchearlo por lo que la idea es obtener un usuario y clave válido por lo menos (aunque un keygen no es muy complicado una vez entendido el algoritmo)...
Buenas, estoy haciendo un programa con clases y me encontré con una incompatibilidad muy rara de Visual C, el siguiente código funciona perfectamente con GCC pero con Visual C me da error :S
Código
class XX{
public:
};
class XY{
public:
};
typedefvoid(XX::*pfun)(void);
class X:public XX,XY{
public:
int ff(int a){
return a;
}
static pfun f;
staticstruct _t{
pfun f;
}t;
};
pfun X::f=pfun(&X::ff);//??????
struct X::_t X::t={pfun(&X::ff)};//??????
Citar
1>main.cpp(28): error C2440: '<function-style-cast>' : no se puede realizar la conversión de 'int (__thiscall X::* )(int)' a 'pfun' 1> Los punteros a miembros tienen distintas representaciones; no se puede realizar la conversión entre ellos 1>main.cpp(29): error C2440: '<function-style-cast>' : no se puede realizar la conversión de 'int (__thiscall X::* )(int)' a 'pfun' 1> Los punteros a miembros tienen distintas representaciones; no se puede realizar la conversión entre ellos
si utilizo herencia simple funciona... el tema es con la herencia múltiple:
Código
class X:public XX,XY
alguno que utilice ese compilador me puede tirar un cable?
buenas, tras tiempo depurando programas con códigos en parte virtualizados se me planteó la duda como hacer un sistema de virtualización de código, por eso armé "esto" que no está completo ni nada, pero que puede llegar a servir de ejemplo supongo
el conjunto de instrucciones no está totalmente definido, solo definí un par de opcodes para hacer pruebas (faltan muchas instrucciones), además no está implementado la parte de modificación de flags del proceso.
Código
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
/*
REGISTERS
=========
0 eax
2 ebx
E ecx
4 edx
C ebp
6 esp
A edi
8 esi
OPCODES
=======
00 YYYYYYYY -> jmp long
01 YYYY -> jmp short
02 YY -> jmp word
03 YYYY -> je short
04 YY -> je word
05 YYYY -> jne short
06 YY -> jne word
//MOV REG, 00000
14 YYYYYYYY -> mov eax, long
15 YYYYYYYY -> mov ecx, long
16 YYYYYYYY -> mov edx, long
17 YYYYYYYY -> mov ebx, long
18 YYYYYYYY -> mov esp, long
19 YYYYYYYY -> mov ebp, long
1A YYYYYYYY -> mov esi, long
1B YYYYYYYY -> mov edi, long
//MOV [REG-X], XXXXXXXX
1C XX YYYYYYYY -> mov (R) , long -> X reg X offset
//MOV REG, [REG-X]
1E XX -> mov eax, (R) -> X reg X reg
1F XX -> mov ebx, (R)
20 XX -> mov ecx, (R)
21 XX -> mov edx, (R)
22 XX -> mov ebp, (R)
23 XX -> mov esp, (R)
24 XX -> mov edi, (R)
25 XX -> mov esi, (R)
//MOV REG, REG
26 XX -> mov R, R
//MOV [REG-X], REG
28 XX -> mov (R), eax -> X reg X offset
29 XX -> mov (R), ebx
2A XX -> mov (R), ecx
2B XX -> mov (R), edx
2C XX -> mov (R), ebp
2D XX -> mov (R), esp
2E XX -> mov (R), edi
2F XX -> mov (R), esi
//SUB EDX, EAX
32 XX -> sub R, R -> X reg X reg
//LEA EAX, [EBP-8]
3C XX -> lea eax, (R) -> X reg X reg
3D XX -> lea ebx, (R)
3E XX -> lea ecx, (R)
3F XX -> lea edx, (R)
40 XX -> lea ebp, (R)
41 XX -> lea esp, (R)
42 XX -> lea edi, (R)
43 XX -> lea esi, (R)
*/
typedefstruct _REGISTERS{
ULONG Edi;//00
ULONG Esi;//04
ULONG Ebp;//08
ULONG Esp;//0C
ULONG Ebx;//10
ULONG Edx;//14
ULONG Ecx;//18
ULONG Eax;//1C
ULONG Flg;//20
ULONG Eip;//24
}REGISTERS,*PREGISTERS;
PULONG GetReg(PREGISTERS p,WORD reg){
PULONG ret=NULL;
switch(reg){
case0x0:// eax
ret=&p->Eax;
break;
case0x2:// ebx
ret=&p->Ebx;
break;
case0xE:// ecx
ret=&p->Ecx;
break;
case0x4:// edx
ret=&p->Edx;
break;
case0xC:// ebp
ret=&p->Ebp;
break;
case0x6:// esp
ret=&p->Esp;
break;
case0xA:// edi
ret=&p->Edi;
break;
case0x8:// esi
ret=&p->Esi;
break;
}
return ret;
}
void decrypt(REGISTERS p){
PBYTE b=(PBYTE)p.Eip;
BYTE Reg=0,RegEx=0;
PULONG pReg=0,pRegEx=0;
CHAR Offset=0;
//FIX ME!
b+=2;//lo ideal sería un long jmp, pero gcc no deja setearlo (o no se como)
el código fue compilado sobre GCC sin ningún tipo de optimización (si se optimiza puede no funcionar correctamente porque el compilador elimina las variables sin referencias directas u otros tipos de optimizaciones)
el código:
Código
asm(
" call jmp1;\n\t"
"jmp1:jmp _vmachine;\n\t"
);
se lo podría meter en una macro pero como era solo para probar lo posteo así (de paso queda a la vista para el que le interese portarlo a otro compilador).
el resultado es el siguiente, el código sin virtualizar en un debugger como olly sale:
lo que se podría agregar al código es (como ya dije) un conjunto más variado de instrucciones y luego un "virtualizador" que convierta las instrucciones normales a las virtualizadas, pero, ese ya es un arduo trabajo y si a alguien le interesa tomarlo como proyecto podría ayudar
Un Pattern Scanner es una función capaz de "encontrar" algo que nos interesa en un módulo externo (puede utilizarse incluso sobre otro proceso aunque ya es más complicado) sin importar la versión de ese módulo (dll,exe,etc.), la única condición para que nuestro Pattern Scanner funcione es que lo que tomamos de referencia no varíe en las distintas versiones de dicho módulo.
Lo primero que se debe hacer es definir que se quiere obtener (esto puede ser una variable o función de dicho módulo del cual no se tengan referencias para llegar), para hacerlo se puede hacer uso de ingeniería inversa (o sea, desensamblar el módulo).
Veamos un ejemplo (en nuestro propio módulo con el fin de visualizarlo): creamos un simple programa con una sola función:
Código
#include <windows.h>
char titulo[]="titulo";
char mensaje[]="un mensaje";
void funcionascanear(void){
MessageBox(0,mensaje,titulo,0);
}
int main(void){
funcionascanear();
return0;
}
abrimos nuestro programa con ollydbg y buscamos nuestra función:
lo que está en rojo será nuestro patrón (se lo puede complicar más, y es preferible, pero para nuestro ejemplo servirá), por lo tanto generamos una función que lo detecte:
Un detalle a destacar de la función es que &p[26] nos devolverá la dirección de memoria de la instrucción, pero no de la variable, entonces mediante el *(void**) obtendremos la verdadera dirección.
Ahora ya podemos escanear nuestro código, y en caso de encontrar nuestra variable modificarla:
Solo cabe aclarar que en el caso de modificar un string la variable original debe ser de un tamaño adecuado para nuestra modificación.
S2
PD: El ejemplo fue compilado con Mingw (GCC), es casi seguro que no funcione en otros compiladores (VC, etc), para hacerlo funcionar hay que rearmar el patrón.
PD2: Existen librerías que permiten buscar patrones de forma más sencilla, como por ejemplo (formato olly):
bueno, dado que estaba sufriendo varios ataques en mi web (no se ni me interesa de quien) tube que implementar un antibot parecido al que se usaba en este sitio (inspirado en lo que puso el-brujo en un post aunque mucho más simple)
die("<a href='index.php?antibotkey=$antibotkey'>Haz Click Aquí para Entrar al Sitio</a><br/><br/>Este Mensaje es mostrado para evitar el ingreso de Bots y solo lo verás una vez.<br/><br/>Disculpe las molestias.");
/********************************* Anti Bot ************************************/
se puede optimizar, se le pueden agregar más checkeos, etc... pero es para tener una base dado que la que se utilizó acá en el foro no es público el código... je , pero como supongo es algo temporal no me calenté mucho en mejorarlo
2º Este es mi primer y único wall... así que no me vayan a estar mandando msg pidiéndome otro... si les funciona y les gusta... ok... sinó... lo siento...
acá el video (Anti Local Ban):
acá el video (Cheat FX 6):
Fix FX 6 (Test Mode)[Fuera el wall]
Activación por teclado/menu:
Citar
====================================================== F3: Panic Key F4: Menu ======================================================
Este Fix no supone modificación alguna a la versión FX 5 más que la activación por menu y el anti local ban... así que quedan vigentes las características anteriores...
Mayor cantidad de placas de video... (hasta acá llego... si no les funciona su placa de video es incompatible!) Compatibilidad con Counter-Strike 1.5 Compatibilidad con Windows Vista (en la PC de un amigo anda... )
S2
Nota: El cheat solo funciona en OPENGL MODE, dejen de mandarme privados diciendo que no anda y tienen el juego en DIRECTX
PD: A partir de ahora no daré mas soporte, lucio32( Gabriel@Privated.com.ar ) se encargará del mismo y cualquier problema groso me lo comunicará...
buenas, estoy desarrollando un proyecto bajo PHP (antiormente hable de el) y el tema es que me topé con una duda de como hacer lo siguiente:
Tengo un conjunto de módulos los cuales pueden necesitar sus propias tablas en la base de datos, el tema es que cada uno de estos módulos puede tener múltiples instancias (algo así como: blog de pepito, blog de josesito), pero en si, el código que maneja el módulo "blog" es uno solo, entonces mi duda es como crear esas tablas en la base de datos:
1º Una única tabla con un identificador de instancia (1 petito, 2 josesito), el tema de esta opción es que siquiero borrar un determinado blog, tendría que hacer todo un laburo extra para eliminar unicamente las entras del X blog, y si ya no hay instancias, borrar toda la tabla...
2º Una tabla por instancia cuyo nombre esté relacionada con el nombre de esta (blog_pepito,blog_josesito), con esta opcion desaparecen las complicaciones anteriores pero aparece la complicación de mantener ese nombre de tabla en algún lado (en mi caso tengo a dispoción "variables del módulo"), pero si dicha "variable" por alguna razón desaparece (o se borra) perdería la relación con la base de datos...
3º Una tabla por instancia cuyo nombre esté relacionado con el módulo/instancia (blog_1,blog_2), con esta otra opción desaparecen las complicaciones de las anteriores pero se dificulta la lectura de la base de datos... (en realidad me parece un poco complicada...)
bueno... espero se entienda la idea y me dén alguna opinión...
Bueno, los que me hayan leído mis últimos post verán que arme una clase para desarmar la clásica estructura PE... el tema es que hacía un tiempo había visto el código de un crypter simple en este foro (para ser más exacto http://foro.elhacker.net/programacion_cc/source_crypter_simple-t204227.0.html;msg969905#msg969905) el cual no funcionaba muy bien (con algunos ejecutables el resultado era desastroso) porque no tenía en cuenta un par de cosas que he agregado a este nuevo crypter...
Antes que nada paso a explicar un par de cosas para que a los que le interese el código puedan seguirlo...
1º y fundamental... los tipos de direccionamiento (la parte más complicada... ), bueno... en esta clase que cree hay 3 tipos básicos de direccionamiento: A:Por Offset: la clase lo que hace es subir a memoria el archivo, entonces este tipo de direccionamiento nos lleva directamente a una posición de memoria del archivo, osea suponiendo que nuestra variable que contiene el contenido del archivo se llame buffer:
B: Por RVA: la clase es capaz de resolver direcciones virtuales, en este caso al setear un valor, se calculará el offset de acuerdo a este valor y obtendremos la posición de memoria del archivo... por ejemplo:
si una sección empieza físicamente en 400, pero tiene una dirección virtual de 1000, al hacer:
Citar
RVA(1024) = &buffer[424]
sin importar en cual sección se encuentre... (el algoritmo se encarga de eso) C: por dirección referenciada: esta última opción (que agregué en esta versión) permite obtener el offset real de una dirección (la inversa de Offset), por ejemplo si tenemos una dirección 0x431212 y queremos saber en que punto del archivo se encuentra:
Detalles a destacar a diferencia de la primera versión del cripter: 1º Checkeo "de qué se cifra": el código no cifra toda la sección CODE, ya que muchos compiladores tienen la opción de combinar dentro de la sección CODE otras estructuras (IMPORT por ejemplo), y al cifrar esta estructura el programa ya no es válido (el cifrado de la IAT va más allá de este simple código, además de que desconozco como realmente se hace)...
2º Corrección de secciones: nuevamente el código anterior agregaba su código dentro de la sección CODE, pero no verificaba que esta modificación esté dentro de los valores definidos en la sección...
3º El código para descifrar mantiene cierta "lógica" secuencial, (aunque no logré hacer funcionar el código original) cuando lo intentaba debuggear los debuggers no lo entendían...
Buenas, estoy desarrollando un miniframework con el cual estoy armando páginas para varios clientes con distintas bases de datos y configuraciones de servidor... (dos puntos que me han quebrantado hasta hoy), la idea de este post es exponer como lo estoy desarrolando para ver si se puede mejorar y obviamente facilitar mi vida..
La idea actual es la siguiente, está totalmente programado en objetos y tiene un solo archivo direccionador (index.php)
Hay una clase base X(base), que es la index.php crea, esta clase se encarga de inicializar la base de datos (objeto), obtener información de la versión del software y otras configuraciones generales (en DB), inicializar sesiones(objeto), obtener datos de usuarios(objeto), (si sesiones le dice que hay alguno) y obtener parámetros enviados...
Si todo ok... index.php llama a "X->visualizar", función que se encarga de crear un objeto Módulo que se crea en base a los parámetros enviados... cada módulo está en DB y tiene su grupo de variables de módulo y dos especiales que son Archivos y Secciones...
El método principal del Objeto módulo tiene únicamente dos respuestas... Falso si no existe el módulo o el usuario no tiene permisos, o el resultado del modulo en si (aclaro que trabajo con Smarty ), el módulo (dependiendo de las variables del mismo) crea dos subclases (secciones y archivos), dichas clases son dependientes del módulo, otorgando o restringiendo permisos dependiendo del módulo y usuario (un módulo no puede borrar un archivo de otro módulo o un usuario con pocos permisos no puede eliminar una sección de un usuario con más permisos, etc...), osea quedaría esta estructura (mas o menos)
Citar
index.php | sistema / | \ DB sesiones usuarios \ | / modulo / | \ archivos | secciones (o categorías) \ | / modulo en si (noticias, descargas, etc...)
falta el identificador del tabla pero es solo un campo auto incremental...
el tema es que: necesito obtener todos los datos que no pertenezcan a un "eid", que pertenezcan a un "sid" y que no se repitan... por ejemplo:
Código:
eid | sid | data 1 1 "lara lara" 2 1 "asdfasdf"
cuando el eid sería 3 y el sid sería 1... actualmente lo estoy haciendo de una forma un tanto embrollada:
obtengo todos los "data"'s distintos que pertenezcan al sid 1, todos los "dats"'s distintos del eid 3 sid 1, y hago una diferencia de arreglo, eso me devuelve:
Código:
"lara lara","asdfasdf"
por lo que luego tengo que buscar la primera referencia en la tabla a un "lara lara" o un "asdfasdf" y obtengo el resultado... pero es muy embrollado y no me parece eficiente...