|
72
|
Programación / Programación C/C++ / Re: principiante
|
en: 2 Julio 2014, 00:50 am
|
¿El char cadena[4000] y el FILE *fichero los colocaste en el segundo código?
Creo que si lo ha copiado, debe pensar que no se pueden declarar las variables dentro del case y no las ha puesto
Saludos
|
|
|
73
|
Seguridad Informática / Análisis y Diseño de Malware / Re: [?] Duda PE Crypter
|
en: 2 Julio 2014, 00:42 am
|
Era eso a lo que me refería, gracias
Otra pregunta, Karcrack me ha recomendado que monte el fichero en memoria y haga las modificaciones en memoria
He estado investigando sobre el tema, y me he hecho este mini código, pero no se si es del todo correcto... PIMAGE_DOS_HEADER DOS_Header; char Fichero[] = "Test.exe"; HANDLE hFile = CreateFile((LPCTSTR)Fichero,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile == INVALID_HANDLE_VALUE) { printf("No se puede abrir el fichero: %s Error: %lu\n", Fichero , GetLastError ()); return EXIT_FAILURE; } HANDLE FMapped = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0); if(FMapped == INVALID_HANDLE_VALUE) { printf("No se puede mapear el fichero en memoria. Error: %lu\n" , GetLastError ()); CloseHandle(hFile); return EXIT_FAILURE; } BYTE *FileMapped = (BYTE*)MapViewOfFile(FMapped, FILE_MAP_READ, 0, 0, 0); if(FileMapped == NULL) { printf("No se puede mapear el fichero en memoria. Error: %lu\n" , GetLastError ()); CloseHandle(FMapped); CloseHandle(hFile); return EXIT_FAILURE; } DOS_Header = (PIMAGE_DOS_HEADER)&FileMapped[0]; // ....
Alguien me puede decir si es la manera correcta de cargar el ejecutable en memoria? (Mapear el archivo en memoria) O si hay alguna manera mas fácil..
Buenas noches!
|
|
|
74
|
Seguridad Informática / Análisis y Diseño de Malware / Re: [?] Duda PE Crypter
|
en: 1 Julio 2014, 11:10 am
|
no se mucho del formato pe , pero te recomiendo que no uses fopen sino la api de windows createfile y readfile y writefile Y eso? Se supone que eso son instrucciones en ASM? Saludos Sí Que bien, que yo sepa el ASM no es así (visualmente), pero ya me ha contestado daryo
Cuando he dicho lo de la sección, era que mas o menos se lo que tengo que hacer, pero la lío tal y como lo hago, ya me habia leido el Taller en construcción que has pasado, y estaba intentando automatizar la Practica 1, agregar una sección, pero no se por donde seguir con el código porque siempre se rompe el ejecutable
|
|
|
75
|
Seguridad Informática / Análisis y Diseño de Malware / [?] Duda PE Crypter
|
en: 1 Julio 2014, 00:53 am
|
Hello!
Estoy intentando entender la estructura PE para poder entender como se hacen los crypters y esas cosas, y me he quedado estancado en una parte, llevo dos dias buscando para no preguntar porque quizás es algo obvio...
Si yo quiero añadir una sección a un ejecutable, tengo que incrementar el NumberOfSections y el SizeOfImage, y luego añadir los datos de la nueva sección, lo estaba programando y tengo de momento esto// .... IMAGE_DOS_HEADER DOS_Header; IMAGE_NT_HEADERS NT_Header; IMAGE_SECTION_HEADER *SECTION_Header; FILE *Archivo = fopen("Test.exe", "rb"); if(Archivo) { CopyFile("Test.exe", "Backup.exe", TRUE); printf("Basic File Information\n\n"); printf("File Name: Test.exe\n"); /* Obtenemos el tamaño del fichero */ fseek(Archivo ,0, SEEK_END ); unsigned long Tamanyo = ftell(Archivo ); fseek(Archivo ,0, SEEK_SET ); printf("File Size: %lu (%lx)", Tamanyo , Tamanyo ); /* Obtenemos la estructura DOS_HEADER */ fread(&DOS_Header , sizeof(IMAGE_DOS_HEADER ), 1, Archivo ); /* Saltamos hasta la posicion donde empieza NT_HEADER, esa posicion se almacena en e_lfanew */ fseek(Archivo , DOS_Header. e_lfanew, SEEK_SET ); fread(&NT_Header , sizeof(IMAGE_NT_HEADERS ), 1, Archivo ); NT_Header.FileHeader.NumberOfSections += 1; //NT_Header.OptionalHeader.SizeOfImage +=; /* Reservamos memoria para las secciones */ SECTION_Header = (IMAGE_SECTION_HEADER *)malloc(NT_Header. FileHeader. NumberOfSections*sizeof(IMAGE_SECTION_HEADER )); /* Guardamos las secciones */ for(unsigned int i=0;i<NT_Header.FileHeader.NumberOfSections-1;i++) { fread(&SECTION_Header [i ], sizeof(IMAGE_SECTION_HEADER ), 1, Archivo ); } // .... // ....
Entonces lo que había pensado era hacer esto:// .... IMAGE_DOS_HEADER DOS_Header; IMAGE_NT_HEADERS NT_Header; IMAGE_SECTION_HEADER *SECTION_Header; FILE *Archivo = fopen("Test.exe", "rb+"); if(Archivo) { CopyFile("Test.exe", "Backup.exe", TRUE); /* Obtenemos el tamaño del fichero */ fseek(Archivo ,0, SEEK_END ); unsigned long Tamanyo = ftell(Archivo ); fseek(Archivo ,0, SEEK_SET ); /* Obtenemos la estructura DOS_HEADER */ fread(&DOS_Header , sizeof(IMAGE_DOS_HEADER ), 1, Archivo ); /* Saltamos hasta la posicion donde empieza NT_HEADER, esa posicion se almacena en e_lfanew */ fseek(Archivo , DOS_Header. e_lfanew, SEEK_SET ); fread(&NT_Header , sizeof(IMAGE_NT_HEADERS ), 1, Archivo ); NT_Header.FileHeader.NumberOfSections += 1; /* Reservamos memoria para las secciones (+1 para la nueva sección)*/ SECTION_Header = (IMAGE_SECTION_HEADER *)malloc((NT_Header. FileHeader. NumberOfSections)*sizeof(IMAGE_SECTION_HEADER )); /* Guardamos las secciones */ for(int i=0;i<NT_Header.FileHeader.NumberOfSections-1;i++) { fread(&SECTION_Header [i ], sizeof(IMAGE_SECTION_HEADER ), 1, Archivo ); } DWORD Tamanyo_RawData = 0x10; DWORD VirtualAddressEnd = SECTION_Header[NT_Header.FileHeader.NumberOfSections-2].VirtualAddress; /* Escribimos los datos de la nueva sección */ BYTE NombreSeccion[8] = ".mecra"; memcpy(SECTION_Header [NT_Header. FileHeader. NumberOfSections-1]. Name, NombreSeccion , 8); SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].SizeOfRawData = Tamanyo_RawData; SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].PointerToRawData = Tamanyo; SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].Characteristics = 0xE0000020; SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].VirtualAddress = VirtualAddressEnd+NT_Header.OptionalHeader.SectionAlignment; SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].Misc.VirtualSize = Tamanyo_RawData; /* Incrementamos el SizeOfImage */ NT_Header.OptionalHeader.SizeOfImage += Tamanyo_RawData; /* Escribimos los datos en el archivo */ //Nos situamos al inicio de la NT Header fseek(Archivo , DOS_Header. e_lfanew, SEEK_SET ); //Escribimos la cabecera fwrite(&NT_Header , sizeof(IMAGE_NT_HEADERS ), 1, Archivo ); //Saltamos al Section Header fseek(Archivo , DOS_Header. e_lfanew + sizeof(IMAGE_NT_HEADERS ), SEEK_SET ); //Escribimos los datos y la cagamos porque nos cargamos lo que sigue al insertar la sección asi ^^ for(int i=0;i<NT_Header.FileHeader.NumberOfSections;i++) { fwrite(&SECTION_Header [i ], sizeof(IMAGE_SECTION_HEADER ), 1, Archivo ); } // .... // ....
Los que sepan del tema ya sabrán donde estoy fallando, y yo me hago una ligera idea
Según he estado leyendo, tiene que haber espacio para poder insertar la sección, cosa que no compruebo, pero donde está el contenido de cada sección? Justo despues de IMAGE_SECTION_HEADER?
Lo que habia pensado era guardar el contenido que hay justo después de la última sección, insertar la mia, insertar el contenido que he guardado, y modificar de cada sección el PointerToRawData sumando el tamaño de la cabecera de la nueva sección, para apuntar de nuevo donde empieza la sección
Si no se hace así, a ver si alguien me puede dar una idea de como se hace.. Tengo los conceptos un poco liados Dos cositas mas
He estado leyendo el código de [Zero] de como añadir una sección..
http://foro.elhacker.net/analisis_y_diseno_de_malware/srcc_anadir_una_seccion-t261801.0.html
Y veo que utiliza PIMAGE_DOS_HEADER; PIMAGE_NT_HEADERS; PIMAGE_SECTION_HEADER; En vez de utilizar estoIMAGE_DOS_HEADER; IMAGE_NT_HEADERS; IMAGE_SECTION_HEADER; Hay alguna diferencia? (Ventajas)
PIMAGE_DOS_HEADER sería un puntero a IMAGE_DOS_HEADER?
Y ya por último...
He visto en un crypter que he encontrado por internet esta rutina para descifrar una sección//Rutina encargada de descifrar la sección cifrada char uncryptroutine[] = //21 bytes "\xB8\x00\x10\x40\x00" //B8 00104000 MOV EAX, 401000 Section Start ||Este valor será modificado "\x80\x30\xBB" //8030 BB XOR BYTE[EAX], BB Key "\x40" //40 INC EAX "\x3D\x00\x45\x40\x00" //3D 00454000 CMP EAX, 404500 Section End ||Este valor será modificado "\x75\xF5" //75 F5 JNZ SHORT -11 (Complemento a dos de 11 = F5) "\xB8\x00\x20\x40\x00" //B8 00204000 MOV EAX, 402000 Pone en EAX el OEP || Este valor será modificado "\xFF\xE0"; //FFE0 JMP EAX Salta al OEP
Se supone que eso son instrucciones en ASM?
Saludos
|
|
|
76
|
Programación / Programación C/C++ / Re: comprobar numero repetido en un vector
|
en: 26 Junio 2014, 02:05 am
|
#include <stdio.h> int main(void) { int poderes[100]; int usados[100]; int i,poderElegido,x; for(i=0; i<100;i++) //Lleno el array de poderes del 0 al 99 poderes[i] = i; for(i=0;i<100;i++) //lleno el array de usados de '-1' usados[i] = -1; i = 0; while(i<5) { //Pido un poder y lo voy guardando en el array 'usados' scanf("%d",&poderElegido ); for(x=0;x<100;x++) { if(usados[x] == poderElegido) { printf("Ya has elegido este poder"); i = 5; //salimos del bucle si ya hemos usado ese poder } } usados[i] = poderElegido; i++; } return 0; }
Puedes quitar todos los bucles for que has puesto, y si te fijas, poderes[100], no lo utilizas para nada, asi que malgastas memoria, este codigo es mas simple#include <stdio.h> int main() { int usados[100] = {0}; int i=0, poderElegido=0; while(i<5) { //Pido un poder y lo voy guardando en el array 'usados' printf("Elige un poder: "); scanf("%d",&poderElegido); if(poderElegido>=0 && poderElegido<100) { if(usados[poderElegido] != 0) { printf("Ya has elegido este poder"); i = 5; //salimos del bucle si ya hemos usado ese poder } else { usados[poderElegido] = 1; } i++; } else { printf("Poder invalido\n"); } } return 0; }
Saludos
|
|
|
77
|
Programación / Programación C/C++ / Re: Ayuda funciones de strings
|
en: 26 Junio 2014, 01:43 am
|
Hola twiny14,
Nadie te va a hacer la tarea, pero como ayuda te puedo decir que lo que te piden es esto:
/* strtok example */ #include <stdio.h> #include <string.h> int main () { char str[] ="- This, a sample string."; char * pch; printf ("Splitting string \"%s\" into tokens:\n",str); pch = strtok (str," ,.-"); while (pch != NULL) { printf ("%s\n",pch); pch = strtok (NULL, " ,.-"); } return 0; }
Puedes leer un poco sobre la función en http://www.cplusplus.com/reference/cstring/strtok/
Lo que puedes hacer dentro de esa funcion es recorrer con un bucle la cadena que quieres separar y contar las veces que aparece el caracter, luego declaras una matriz con ese tamaño y simplemente vas copiando hasta que encuentres ese caracter, luego incrementas el indice de la matriz y sigues copiando, asi hasta el final
Espero que te sirva de ayuda,
Saludos
|
|
|
|
|
|
|