|
181
|
Programación / Programación C/C++ / Re: convertir minúscula a mayúscula
|
en: 24 Febrero 2013, 19:05 pm
|
Si estás de acuerdo en usar la librería standart: http://es.wikipedia.org/wiki/Ctype.htenés una lista como la siguiente para hacer conversiones de ese tipo: tolower toupper strlwr strupper islower isupper etc Eso en primer lugar, ahora sino querés usar el código ASCII podés hacer algo más costoso pero efectivo. Osea que tu cadena va a ser examinada char por char para comprobar que se trate de una letra, ya sea mayúscula o minúscula. No se si es lo que pedís realmente, espero haberte ayudado bool SonLetras(const char* buf) { #define MAX_ALFA 53 const char alfabetico[] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0}; int ok=0; int len = strlen(buf); for(int i=0; i<len; i++){ for(int j=0; j<MAX_ALFA; j++){ if(buf[i]==alfabetico[j]){ ok++; break; }}} if(ok==len) return true; return false; }
|
|
|
182
|
Programación / Programación C/C++ / MSVCRT hook
|
en: 24 Febrero 2013, 18:50 pm
|
Un ejemplo interesante en donde se intercepta a modo de prueba la función STRLWR , no voy a tomar crédito del hook ya que se trata de un simple parche que lo he googleado en 5 segundos XD, lo que si voy a mostrar un par de fotos al respecto.. Como se compiló el ejecutable, para que sea dependiente de la DLL msvcrt Como se buscó el export en la DLL, se puede observar su índice y su símbolo. El resto del código no es nada especial, dejo el proyecto en vc6 http://www.mediafire.com/?s9vic23mvrjxrwg// // By 85 // elhacker.net // InterceptAPI: (googleado en 5 segundos XD) // 2013 //
#pragma comment (lib,"Shlwapi.lib") #include<windows.h> #include <Shlwapi.h> #include<stdio.h>
///////////////////////////////////////////////////////////
char* mystrlwr(char* a){
static bool onlyonce=false; if(!onlyonce){ onlyonce=true; printf("\nSTRLWR INTERCEPTADA!\n"); // MessageBox(0,0,0,0); } return a; }
// BOOL InterceptAPI(HMODULE hLocalModule,const char* c_szDllName,const char* c_szApiName, DWORD dwReplaced) { DWORD dwOldProtect; DWORD dwAddressToIntercept=(DWORD)GetProcAddress(GetModuleHandle((char*)c_szDllName),(char*)c_szApiName); printf("add: %x\n", dwAddressToIntercept); printf("dll: %s\n", c_szDllName); printf("api: %s\n", c_szApiName); // system("pause"); if(!dwAddressToIntercept) return false; BYTE *pbTargetCode = (BYTE *) dwAddressToIntercept; BYTE *pbReplaced = (BYTE *) dwReplaced; VirtualProtect((void *) dwAddressToIntercept, 5, PAGE_WRITECOPY, &dwOldProtect); *pbTargetCode++ = 0xE9; // jump rel32 *((signed int *)(pbTargetCode)) = pbReplaced - (pbTargetCode +4); VirtualProtect((void *) dwAddressToIntercept, 5, PAGE_EXECUTE, &dwOldProtect); FlushInstructionCache(GetCurrentProcess(), NULL, NULL); return TRUE; }
// void Dummy(){
strlwr(new char[] = "85 de elhacker.net :D\0"); }
// int main(){
Sleep(500); char l_s11[] = {'m','s','v','c','p','6','0','.','d','l','l',0}; char l_s12[] = {'m','s','v','c','p','7','1','.','d','l','l',0}; char l_s13[] = {'m','s','v','c','p','1','0','0','.','d','l','l',0}; char l_s[] = {'m','s','v','c','r','t','.','d','l','l',0}; char l_api[] = {'_','s','t','r','l','w','r',0}; char l_exe[] = {'m','s','v','c','r','t','_','h','o','o','k','.','e','x','e',0}; char FileName[256]; if(!GetModuleHandle(l_s)) ExitProcess(0); GetModuleFileName(GetModuleHandle(NULL), FileName, sizeof(FileName)); PathStripPath(FileName); if (strcmp(FileName, l_exe) == 0){ InterceptAPI(GetModuleHandle(NULL), l_s, l_api, (DWORD)mystrlwr); /* else: no se ha interceptado ! */ } else { /* no se ha interceptado ! */ return 0;} Dummy(); printf("\n"); system("pause"); return 0; }
|
|
|
183
|
Programación / Programación C/C++ / Re: ATOI + ITOA remake
|
en: 24 Febrero 2013, 17:57 pm
|
EDITADO: Discusión no objetiva Dejando la discusión de lado, si vamos a hablar de optimizaciones en serio vayamos directamente al código ensamblador, porque jugar con palabras de código humanizado no representa precisamente una optimización para la PC, sino más bien para REDUCIR líneas de texto que dan la impresión VISUAL de una simplificación. Encontré una versión en ASM, hecha por sk0r __declspec(naked) int __stdcall m_atoi(char* szTarget, unsigned int dwLength) { #define SUB_OFFS 48
__asm { push ebp; //Save old framepointer value mov ebp, esp; //Copy ESP into EBP -> EBP:[Old-EBP:4][Ret-Addr:4][dwLength:4][szTarget:4] sub esp, 5; //Allocate 5 bytes [EBP-4]: unsigned int dwResult, [EBP-5]:char cMinusChar mov dword ptr [ebp-4], 0; //Zero bytes of dwResult value. dwResult holds entire result value mov byte ptr[ebp-5], 0; //Zero byte of cMinusChar. cMinusChar holds first char @szTarget for '-' check
cmp szTarget, 0; //Check if szTarget is a null pointer je fEnd; //If so goto function end cmp dwLength, 0; //Check if string length is zero je fEnd; //If so goto function end
//Save registers for use push ebx; //Holds mulitplied value of current positon. push ecx; //Used for loop cmd push edx; //For saving temporary stuff push esi; //Holds start address + length of string pushf; //For modifying direction flag
mov ebx, 1; //Set to one. The first position is the ones, second tens, third hundrets, etc. mov ecx, dwLength; //Copy length to ECX for counting
mov esi, szTarget; //Copy string address to ESI add esi, ecx; //Add string length dec esi; //Decrement not to go too far (because of zero position)
push eax; //Save EAX temorarly mov eax, szTarget; //Copy string address to EAX mov al, byte ptr[eax]; //Copy the first byte to AL mov byte ptr[ebp-5], al; //Copy it to EBP-5 (cMinusChar) pop eax; //Restore EAX
cmp byte ptr[ebp-5], '-'; //Check if the char is a minus char jne fOvr1; //If not goto fOvr1 dec ecx; //Decrement, because we ignore the '-' char to not corrupt the entire number
fOvr1: std; //Set direction flag to 1 to go from hight to low addresses fLoop: xor eax, eax; //Clear bits of EAX lodsb; //Copy byte at [ESI] to AL and extend ESI (in this case decrement) sub al, SUB_OFFS; //Substract offset to make from char to real number mul ebx; //Multiplicate EAX with EBX depending on its current position. Ones with 1, Tens with 10, Hundrets with 100, etc. mov edx, dword ptr[ebp-4]; //Copy entire result value to EDX add edx, eax; //Add EAX on it mov dword ptr [ebp-4], edx; //Copy back to result value
mov eax, ebx; //Copy EBX to EAX mov ebx, 10; //Copy 10 to EBX mul ebx; //Multiply with 10 to go to the next positon: 1*10 = 10, 10*10 = 100, 100*10 = 1000, etc mov ebx, eax; //Copy back to EBX
loop fLoop; //Goto fLoop and decrement ECX if not already zero
cmp byte ptr[ebp-5], '-'; //Check if first char was '-' jne fOvr2; //If not goto fOvr2 mov eax, [ebp-4]; //Copy result value to EAX mov ebx, -1; //Copy -1 to EBX imul ebx; //Make signed multiplication to make a positive value to a negative one mov [ebp-4], eax //Copy back to result value fOvr2: //Restore all used registers popf; pop esi; pop edx; pop ecx; pop ebx; fEnd: mov eax, dword ptr[ebp-4]; //Copy result value to EAX for result add esp, 5; //Remove both stack variables pop ebp; //Restore EBP ret 8; //Restore Ret-Address and remove the 8 argument bytes } }
|
|
|
184
|
Programación / Ingeniería Inversa / Re: crackeáte esta cuenta
|
en: 24 Febrero 2013, 08:24 am
|
Si digamos que lo que vos estás intentando sería la primer parte del objetivo, es decir obtener el mensaje correcto. La segunda parte es demasiado complicada me parece, lo que se puede hacer es publicar el código de la librería de cifrado que utiliza para cifrar/descifrar. El problema es que de esa forma pueden hacer una especie de keygen y no se trata de eso, sino de forzar al programa a que muestre los datos de usuario. se requeriría un parche, que aunque no está hecho puede servir de base si alguno le interesa. El código del crackme lo subo en otro momento, no hay apuro XD http://www.mediafire.com/?xwkwblc1euo9269
|
|
|
185
|
Programación / Ingeniería Inversa / Re: crackeáte esta cuenta
|
en: 24 Febrero 2013, 06:26 am
|
Nooooo ese cartel no es el requerido ! el requerido dice algo así como:
"Entraste o estás dentro" XD
perdón, si por ese cartel no está puesto con la intención de insultar XD, en verdad tenía que decir algo como:
"Por este lado nooooo!" XD
pero lo puse en inglés, ni idea pero no lo tomen a modo insultante, de hecho no hay otros carteles que digan cosas así, sólo ese..
Saludos
Si hace falta algo más diganme, porque hasta ahora no me dijeron si necesitaban algo más..... se requiere llegar al segundo cartel correcto y si es posible exponer los datos de la cuenta.
|
|
|
186
|
Programación / Programación C/C++ / Re: ATOI + ITOA remake
|
en: 24 Febrero 2013, 02:14 am
|
EDITADO: Discusión no objetiva Amigo te cuento algo, esto: >=48&&<=57 SI, lo deberías usar ya que te vuelvo a decir SI es necesario si te gusta optimizar las cosas. no es necesario que hagás un salto a una rutina en otra parte para ejecutar un código innecesario, sabiendo que comparando algo directamente así: Pseudocódigo if(>=48&&<=57); else NO ES UN ESPACIO NI CUALQUIER OTRA COSA SINO SÓLO NÚMEROS
Esto: while(1) { if(copia>=10) { copia /= 10; unidades_decimales++; } else { break; } }
Y esto: int unidades_decimales = 1; int copia; for (copia = num; copia >= 10; copia /= 10) unidades_decimales++;
es lo mismo al traducirse a ASM ya que lo que vos plantéas es un cambio al nivel de TEXTO en el código humanizado o de alto nivel (C). Prestá atención que realizan las mismas operaciones y sino lo hicieran, termina siendo lo mismo porque el compilador te cuento que optimiza el código automáticamente, a lo máximo tal REDUCCiÓN termina siendo algo así como un par de instrucciones insignificantes: push push call ....... push ebp mov ebp, esp
mov esp, ebp pop ebp retn
add esp, 0x8
y asumiento que no cambiás la convención de llamada a __stdcall o __fastcall, en cuyo caso la pila se limpia automáticamente por el código que hace la llamada (callee)
|
|
|
187
|
Programación / Ingeniería Inversa / crackeáte esta cuenta
|
en: 24 Febrero 2013, 01:15 am
|
Bueno este es un crackme , supongo que para muchos puede resultar de nivel principiante. En realidad yo no estoy familiarizado con el cracking, pero encontré un código con una rutina interesante y me pareció que podía servir para un crackme. Si y sólo si están interesados en resolver un crackme más en sus vidas, háganlo , no es mi intención quitarles su tiempo XD. Disculpen si falta algo XD Nivel:Principiante, conocimiento de hooking/patching, desensamblado, depurado, etc Objetivo:Que salga un cartel contando que el resultado fue exitoso. Se requiere mostrar los datos de usuario que fueron encontrados y explicar como se resolvió. Los datos son un nombre de usuario y la contraseña. Pueden exponer un código si lo desean. Elementos: XP SP3 x86, MSVCPP6 Premio: Ninguno. Un código con la rutina utilizada. Necesitan algo más ? avisen. http://www.mediafire.com/?bb4xz7ta4qrfr6e
|
|
|
188
|
Programación / Programación C/C++ / ghostwriting? cadenas que no son detectadas
|
en: 24 Febrero 2013, 01:02 am
|
Estaba mirando cuando uno desensambla un programa en c++, no protegido obviamente.... no hablo de un editor hexadecimal ni de ollyDBG, un desensamblado normal que muestre el código ensamblador. Algunas strings son detectadas y otras no, en realidad no se si esto se llama ghostwriting porque parece que ghostwriting es otra cosa aparte. Suponiendo el siguiente código que muestra algunas de las formas más conocidas de declarar cadenas: // // By 85 // elhacker.net // 2013 //
#include<windows.h> #include<stdio.h>
void Test(){ char test1[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0}; char test11[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0}; char test111[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0}; char test1111[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0}; char test11111[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0}; char testA[256]; strcat(testA,test1); strcat(testA," 85\0"); printf(test1); printf("\n\n"); char test2[] = "ochentaycinco1\0"; char test22[] = "ochentaycinco2\0"; char test222[] = "ochentaycinco3\0"; char test2222[] = "ochentaycinco4\0"; char test22222[] = "ochentaycinco5\0"; const char* testX = "ASD\0"; char testB[256]; strcat(testB,test2); strcat(testB," 85\0"); printf(test2); printf("\n\n"); printf(testX); printf("\n\n"); }
int main() { Test();
char test11111[] = {'o','c','h','e','n','t','a','y','c','i','n','c','o',0}; char test22222[] = "ochentaycinco11\0"; const char* testX = "WWW\0"; printf("TEST1\n"); printf(testX); printf("\n"); printf(new char[] = "wwwwwww\n"); printf(new char[] = "xxxxxxx\n"); printf(new char[] = "AAAAAAA\n"); system("pause"); return 0; }
podemos ver las cadenas que son detectadas y las que no: Si alguno quiere agregar algo con referencia al tema XD, en realidad yo si tuviera que recurrir a ocultar cadenas utilizaría algún tipo de encriptamiento interno, como XORSTR, pero esto se usa también
|
|
|
189
|
Programación / Programación C/C++ / Re: ATOI + ITOA remake
|
en: 24 Febrero 2013, 00:19 am
|
Aún se puede cambiar las CTYPE por algo como >=48&&<=57 , evitaríamos código extra la tabla no es realmente necesaria es cierto, viene quedando de anteriores versiones; me gusta la ITOA como quedó Saludos
|
|
|
190
|
Programación / Programación C/C++ / Re: Cadena de bytes a string
|
en: 24 Febrero 2013, 00:18 am
|
Hola, te cuento algo acerca de las recomendaciones, en verdad te digo que se trata de un 'Test' osea una prueba , no tanto de una publicación que intenta reemplazar una funcionalidad ya bastante conocida. void Test1(BYTE* array_de_bytes, char* cadena_de_bytes_en_formato_string){ //Cadena de bytes a string
el nombre es parte de una prueba pero tiene el comentario que indica lo que hace, los nombres de las variables son demasiado descriptivos, la gente los va a entender mejor, al menos los principiantes.. STRLEN realmente está mal implementada en mi edición, lo raro es que no lo hayas notado, ya que dentro de un FOR está ejecutándose muchas veces, se debe utilizar como estaba antes. Incluso STRCAT puede ser reemplazada a como se copiaba en la primera edición, pero bueno son detalles que se me escaparon. te muestro otra solución para la función 2, en este caso no hecha por mi, pero vale igualmente void Test2(char* cadena_de_bytes, BYTE* cadena_de_bytes_resultante) { static BYTE Tabla[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int Position; int Length_de_bytes_resultante; // :)
Position = 0; while (cadena_de_bytes[Position] != '\0') { cadena_de_bytes_resultante[Position >> 1] = (Tabla[cadena_de_bytes[Position]] << 4) + Tabla[cadena_de_bytes[Position + 1]]; Position = Position + 2; } Length_de_bytes_resultante = Position >> 1;
for (Position = 0; Position < Length_de_bytes_resultante; Position = Position + 1) { printf("%02X", cadena_de_bytes_resultante[Position]); } printf("\n");
}
Saludos
|
|
|
|
|
|
|