|
81
|
Programación / Programación C/C++ / Re: [C]Resource Dumper.
|
en: 1 Junio 2012, 16:29 pm
|
Hola,
@daniyo, se incluye <windows.h> porque este tienes declaradas las estructuras de recursos que empleamos y el API que necesitamos para trabajar con ficheros mapeados en memoria. No te confundas, dije claramente "No utilizo API de recursos".
Un saludo, Iván Portilla.
|
|
|
82
|
Programación / Programación Visual Basic / Re: Crear .exe a partir de código VB?
|
en: 1 Junio 2012, 14:50 pm
|
Hola,
Muy seguramente la parte del mensaje está referenciada en la sección de datos de tu ejecutable ".data", creo que con que desde tu "builder" leas el archivo y modifiques o añadas justo donde comienza puedes generar dichos ejecutables. No en cualquier parte, puesto que en memoria cuando llaman a MsgBox (desconozco su nombre en VB), pasan parámetros y la dirección del texto es una. Por lo cual, edita desde el punto donde comienza el mensaje en la sección de datos.
Un saludo, Iván Portilla.
|
|
|
83
|
Programación / ASM / Re: Acerca de DOS stub
|
en: 1 Junio 2012, 06:34 am
|
Hola,
@H1tchclock permiteme aclarar el asunto, yo soy el autor de dicho documento en base al documento oficial proporcionado por Microsoft sobre el tema, y solo lo aclaro porque no quiero que se confundan al decir que es de Microsoft, toda la información que proporciona Microsoft sobre el tema está en ingles.
Un saludo, Iván Portilla.
|
|
|
84
|
Seguridad Informática / Análisis y Diseño de Malware / Re: [Taller en construcción]Secciones en archivos PE.
|
en: 1 Junio 2012, 05:56 am
|
Hola, Si leemos los datos (recuerda lo del endian byte). Tenemos que: - .text:
- VirtualAddress: 0x1000
- VirtualSize: 0xA68C
- PointerToRawData: 0x400
- SizeOfRawData: 0xA800
- .data:
- VirtualAddress: 0xC000
- VirtualSize: 0x2164
- PointerToRawData: 0xAC00
- SizeOfRawData: 0x1000
- .rsrc:
- VirtualAddress: 0xF000
- VirtualSize: 0x1F160
- PointerToRawData: 0xBC00
- SizeOfRawData: 0x1F200
- .reloc:
- VirtualAddress: 0x2F000
- VirtualSize: 0xE34
- PointerToRawData: 0x2AE000
- SizeOfRawData: 0x1000
Ahora resulta que los tamaños de las secciones a intercambiar no son iguales, por ende deberás "desbaratar" y rearmar todo el cuerpo del archivo. Para ello deberás trabajar con sus SizeOfRawData y cambiarles el orden, luego actualizar las cabeceras. Si vamos a cambiar ".reloc" por ".text" primero que todo analizamos que todas las otras secciones se desplazarán debido a que ".text" es más grande. Entonces vamos de a poco:- .reloc:
- VirtualAddress: 0x1000
- VirtualSize: 0xE34
- PointerToRawData: 0x2AE000
- SizeOfRawData: 0x1000
Luego seguiría: - .data:
- VirtualAddress: 0xC000
- VirtualSize: 0x2164
- PointerToRawData: 0x2000 -> Suma de PointerToRawData y SizeOfRawData de ".reloc".
- SizeOfRawData: 0x1000
Luego: - .rsrc:
- VirtualAddress: 0xF000
- VirtualSize: 0x1F160
- PointerToRawData: 0x3000 -> Hacemos lo mismo con ".data".
- SizeOfRawData: 0x1F200
Y por último: - .text:
- VirtualAddress: 0x1000
- VirtualSize: 0xA68C
- PointerToRawData: 0x22200
- SizeOfRawData: 0xA800
Y en base a estos datos es que debes ubicar las secciones en el cuerpo del archivo en el orden tal cual porque ese era el cambio que querías hacer. Recuerda CUERPO DEL ARCHIVO, no en la cabecera de secciones, en la cabecera solo actualizas los nuevos valores pero no el orden. Un saludo, Iván Portilla.
|
|
|
85
|
Programación / ASM / Re: Acerca de DOS stub
|
en: 1 Junio 2012, 05:30 am
|
Hola,
El MS-DOS STUB es una aplicación válida que solo se ejecutaría en MS-DOS, no voy al cargador de MS-DOS ni nada pero muy seguramente el IMAGE_DOS_HEADER permita que el MS-DOS STUB se ejecute bajo esa plataforma. Tu puedes especificar otro "STUB" bajo parámetros del enlazador (Linker).
El que uno sea más grande que otro es porque comúnmente varios PE generados bajo compiladores de microsoft pueden tener agregado algo que llaman "Rich Signature" que proporciona algunos "metadatos" sobre el entorno de compilación.
Un saludo, Iván Portilla.
|
|
|
87
|
Programación / Programación C/C++ / [C]Resource Dumper.
|
en: 31 Mayo 2012, 21:48 pm
|
Hola, Hoy les vengo a traer una aplicación que programé y lo que en realidad hace es extraer todos los recursos de un ejecutable. Más que por su utilidad seguro pueden entender como funciona el directorio de recursos de un archivo ejecutable. No utilizo ninguna función API de recursos proporcionada por Windows, todo está hecho a mano. Un saludo, Iván Portilla. Actualizado 22 de junio de 2012, ahora soporta parámetros en su función principal y tiene corregidos errores de manejo de memoria y está mucho más optimizado./************************************************** * Resource Dumper v0.1 . * Programado por Iván Portilla. * Actualizado 22 de junio de 2012 * http://www.h-sec.org & http://www.elhacker.net **************************************************/ #include <stdio.h> #include <windows.h> #include <Strsafe.h> #define STATIC_SIZE 0x20 void GetResources(PBYTE MappedFile, DWORD ResourceRVA, PCHAR Path, PIMAGE_SECTION_HEADER ish, DWORD NumberOfSections); int RVA_TO_OFFSET(int RVA, PIMAGE_SECTION_HEADER ish, int NumberOfSections); int RESOURCE_DUMP(PCHAR lFile, PCHAR MappedName, PCHAR DumpPath); int RESOURCE_TO_FILE(PCHAR Path, PBYTE ResourceRVA, DWORD Size); PCHAR ResourceType(DWORD ResType); PCHAR UNICODE_TO_STRING(PIMAGE_RESOURCE_DIR_STRING_U String); typedef BOOL (WINAPI * _PathIsDirectory)(PCHAR Directory); typedef BOOL (WINAPI * _PathFileExists)(PCHAR Directory); char STR_ID[STATIC_SIZE]; char STR_ID2[STATIC_SIZE]; char STR_ID3[STATIC_SIZE]; char STR_ID4[STATIC_SIZE]; char * RESOURCES[25] = {"RT_CURSOR","RT_BITMAP","RT_ICON","RT_MENU","RT_DIALOG", "RT_STRING","RT_FONTDIR","RT_FONT","RT_ACCELERATOR","RT_RCDATA", "RT_MESSAGETABLE","RT_GROUP_CURSOR","","GROUP_ICON","","RT_VERSION", "RT_DLGINCLUDE","","RT_PLUGPLAY","RT_VXD","RT_ANICURSOR","RT_ANIICON", "RT_HTML","RT_MANIFEST","UNKNOWN"}; int main(int argc, char * argv[]) { _PathIsDirectory PathIsDirectoryA = (_PathIsDirectory)GetProcAddress(LoadLibraryA("Shlwapi.dll"), "PathIsDirectoryA"); _PathFileExists PathFileExistsA = (_PathFileExists)GetProcAddress(LoadLibraryA("Shlwapi.dll"), "PathFileExistsA");; printf("Resource Dumper Base Model v0.1\n\n"); if ((PathFileExistsA != NULL) && (PathIsDirectoryA != NULL)) { if (argc == 4) { if ((PathFileExistsA(argv[1]) == 1) && (PathIsDirectoryA(argv[3])) && (argv[2] != NULL)) { RESOURCE_DUMP(argv[1], argv[2], argv[3]); } else printf("Check your parameters [File path, File Mapped Name, Path To Save Resources] (ALL STRINGS)"); } else printf("This software should be execute with params [File path, File Mapped Name, Path To Save Resources] (ALL STRINGS)"); } else printf("Fail to load API functions of shlwapi.dll."); return 0; } int RESOURCE_DUMP(PCHAR iFile, PCHAR MappedName, PCHAR DumpPath) { HANDLE lFile, lMap; PBYTE Mapped; PIMAGE_DOS_HEADER IDH; PIMAGE_NT_HEADERS INH; DWORD Resource; lFile = CreateFileA(iFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,0,0); if (lFile != INVALID_HANDLE_VALUE) { lMap = CreateFileMappingA(lFile, NULL, PAGE_READONLY, 0, 0, MappedName); Mapped = (PBYTE)MapViewOfFile(lMap, FILE_MAP_READ, 0, 0, 0); IDH = (PIMAGE_DOS_HEADER)Mapped; if (IDH->e_magic == IMAGE_DOS_SIGNATURE) { INH = (PIMAGE_NT_HEADERS)&Mapped[IDH->e_lfanew]; if(INH->Signature == IMAGE_NT_SIGNATURE) { Resource = INH->OptionalHeader.DataDirectory[2].VirtualAddress; if (Resource > 0) { printf("Getting resources..\n"); GetResources(Mapped, Resource, DumpPath,(PIMAGE_SECTION_HEADER)&Mapped[IDH->e_lfanew + 24 + INH->FileHeader.SizeOfOptionalHeader], INH->FileHeader.NumberOfSections); } else printf("Resource directory not present\n"); } } UnmapViewOfFile(Mapped); CloseHandle(lMap); CloseHandle(lFile); } else { return -1; } return 0; } void GetResources(PBYTE MappedFile, DWORD ResourceRVA, PCHAR Path, PIMAGE_SECTION_HEADER ish, DWORD NumberOfSections) { PIMAGE_RESOURCE_DIRECTORY IRD, SUBIRD, SSUBIRD; PIMAGE_RESOURCE_DIRECTORY_ENTRY IRDRE, SUBIRDRE, SSUBIRDRE; PIMAGE_RESOURCE_DATA_ENTRY IRDTE; PIMAGE_RESOURCE_DIR_STRING_U IRDS; DWORD NumberOfEntries, NumberOfSubEntries, NumberOfSSubEntries, Counter = 0, Tick = 0, lBytes = 0; PCHAR UNICODE_STR_PARSED = NULL; PCHAR RES_TYPE = NULL; Tick = GetTickCount(); IRD = (PIMAGE_RESOURCE_DIRECTORY) &MappedFile[RVA_TO_OFFSET(ResourceRVA, ish, NumberOfSections)]; NumberOfEntries = (IRD->NumberOfNamedEntries + IRD->NumberOfIdEntries); IRDRE = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((int)IRD + sizeof(IMAGE_RESOURCE_DIRECTORY)); printf("[Root resource directory entries: %X]\n\n", NumberOfEntries ); while(NumberOfEntries > 0) { if (IRDRE->DataIsDirectory == 1) { SecureZeroMemory(STR_ID3, STATIC_SIZE); if (IRDRE->NameIsString == 0) { RES_TYPE = RESOURCES[(IRDRE->Id)-1]; printf(" [Resource type: %s]\n", RES_TYPE ); StringCchCopyA(STR_ID3, STATIC_SIZE, RES_TYPE); StringCchCatA(STR_ID3, STATIC_SIZE, "_"); } else { IRDS = (PIMAGE_RESOURCE_DIR_STRING_U) (IRDRE->NameOffset + (int)IRD); UNICODE_STR_PARSED = UNICODE_TO_STRING(IRDS); printf(" [Resource type: %s]\n", UNICODE_STR_PARSED ); StringCchCopyA(STR_ID3, STATIC_SIZE, UNICODE_TO_STRING(IRDS)); StringCchCatA(STR_ID3, STATIC_SIZE, "_"); GlobalFree(UNICODE_STR_PARSED); } SUBIRD = (PIMAGE_RESOURCE_DIRECTORY) ((int)IRD + IRDRE->OffsetToDirectory); NumberOfSubEntries = SUBIRD->NumberOfNamedEntries + SUBIRD->NumberOfIdEntries; SUBIRDRE = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((int)SUBIRD + sizeof(IMAGE_RESOURCE_DIRECTORY)); printf(" [Number of sub entries: %x]\n", NumberOfSubEntries ); while(NumberOfSubEntries > 0) { if(SUBIRDRE->DataIsDirectory == 1) { printf(" [Resource Id: %i]\n", SUBIRDRE ->Id ); SSUBIRD = (PIMAGE_RESOURCE_DIRECTORY) ((int)IRD + SUBIRDRE->OffsetToDirectory); NumberOfSSubEntries = SSUBIRD->NumberOfNamedEntries + SSUBIRD->NumberOfIdEntries; SSUBIRDRE = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((int)SSUBIRD + sizeof(IMAGE_RESOURCE_DIRECTORY)); printf(" [Number of re-sub entries: %x]\n", NumberOfSSubEntries ); while(NumberOfSSubEntries > 0) { IRDTE = (PIMAGE_RESOURCE_DATA_ENTRY) ((int)IRD +SSUBIRDRE->OffsetToData); printf(" [RVA: 0x%X Size: 0x%X]\n", IRDTE ->OffsetToData , IRDTE ->Size ); SecureZeroMemory(STR_ID, STATIC_SIZE); SecureZeroMemory(STR_ID2, STATIC_SIZE); SecureZeroMemory(STR_ID4, STATIC_SIZE); StringCchCatA(STR_ID4, STATIC_SIZE, STR_ID3); _itoa(SUBIRDRE->Id, STR_ID, 10); StringCchCatA(STR_ID, STATIC_SIZE, "_"); _itoa(SSUBIRDRE->Id, STR_ID2, 10); StringCchCatA(STR_ID4, STATIC_SIZE, STR_ID); StringCchCatA(STR_ID4, STATIC_SIZE, STR_ID2); RESOURCE_TO_FILE(Path, (PBYTE)((int)MappedFile + RVA_TO_OFFSET(IRDTE->OffsetToData, ish, NumberOfSections)), IRDTE->Size); NumberOfSSubEntries = NumberOfSSubEntries - 1; SSUBIRDRE++; Counter++; lBytes += IRDTE->Size; } } NumberOfSubEntries = NumberOfSubEntries - 1; SUBIRDRE++; } } NumberOfEntries = NumberOfEntries - 1; IRDRE++; } printf("\nResources dumped: 0x%X.", Counter ); printf("\nTime of dumped: %i miliseconds.", (GetTickCount ()-Tick )); printf("\nBytes dumped: 0x%X.", lBytes ); } int RVA_TO_OFFSET(int RVA, PIMAGE_SECTION_HEADER ISH, int NumberOfSections) { int i, Offset = 0; if (ISH != NULL) { for (i = 0; i < NumberOfSections; i++) { if ((RVA >= (int)ISH[i].VirtualAddress) && (RVA <= (int)(ISH[i].VirtualAddress + ISH[i].Misc.VirtualSize))) { Offset = (RVA - ISH[i].VirtualAddress) + ISH[i].PointerToRawData; } } } else Offset = 0; return Offset; } PCHAR UNICODE_TO_STRING(PIMAGE_RESOURCE_DIR_STRING_U String) { PCHAR nStr = (PCHAR) GlobalAlloc(GPTR, String->Length + 1);; WideCharToMultiByte(CP_ACP, 0, String->NameString, String->Length * 2, nStr, String->Length, NULL, NULL); return nStr; } int RESOURCE_TO_FILE(PCHAR Path, PBYTE ResourceRVA, DWORD Size) { PCHAR lFile = (PCHAR)GlobalAlloc(GPTR, lstrlenA(Path) + STATIC_SIZE); PCHAR Buffer = (PCHAR)GlobalAlloc(GPTR, Size); HANDLE sFile; DWORD Bytes = 0, Rest; CopyMemory(Buffer, ResourceRVA, Size); StringCchCopyA(lFile, lstrlenA(Path) + STATIC_SIZE, Path); if ((Path[lstrlenA(Path)-2] == 92) & (Path[lstrlenA(Path)-1] == 92)) StringCchCopyA(&lFile[lstrlenA(Path)], lstrlenA(Path) + STATIC_SIZE, STR_ID4); else { lFile[lstrlenA(Path)+1] = 92; lFile[lstrlenA(Path)] = 92; StringCchCopyA(&lFile[lstrlenA(Path)+2], lstrlenA(Path) + STATIC_SIZE, STR_ID4); } sFile = CreateFileA(lFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0); if (sFile != INVALID_HANDLE_VALUE) { WriteFile(sFile, Buffer, Size, &Bytes, NULL); CloseHandle(sFile); Rest = 0; } else Rest = -1; GlobalFree(Buffer); GlobalFree(lFile); return Rest; }
|
|
|
88
|
Seguridad Informática / Análisis y Diseño de Malware / Re: [Taller en construcción]Secciones en archivos PE.
|
en: 31 Mayo 2012, 15:44 pm
|
Hola, Mira te respondo lo primero. Acabo de hacer la prueba y en realidad con el ejecutable de Visual Basic sigue funcionando correctamente y mostrando el icono. Debes tratar de cambiar bien los valores y nada más. Además si quieres darme valores por aquí hazlo especificando a que campos se refiere y de que sección. Te doy enlace del el ejecutable en Visual Basic al que intercambié la sección .text -> .rsrc: https://dl.dropbox.com/u/26610132/Change.exe En cuanto a lo segundo. He verificado y en ningún momento te he siquiera mencionado el valor 0x100, quizá si 0x1000 porque es un múltiplo de los FileAlignment con que hemos trabajado en el taller. Te vuelvo a explicar con 2 ejemplos distintos, pero la teoría es la misma, si tienes un valor, debes hacer que ese valor cumpla que (valor módulo FileAlignment) == 0. Y dicho valor no puede ser menor que el original, por lo tanto decimos que deberás alinearlo o redondearlo a su múltiplo mayor inmediato. Ejemplo:FileAlignment: 0x200 Valor 0x17 Si miras 0x17 módulo 0x200 = 0x17. Ya que es un valor menor, el más próximo que vas a encontrar múltiplo de 0x200 es el mismo 0x200. ya que 0x200 módulo 0x200 = 0. Valor: 0x405 0x405 módulo 0x200 = 0x05. Es un valor mayor, pero ahora igual que en el anterior debes buscar el múltiplo mayor inmediato a 0x405 que haga que el módulo sea 0. En este caso, 0x600. Si no lo entiendes aún te doy la siguiente fórmula, pero se trata de que tú seas capaz de entenderlo. Aligned = (Valor + FileAlignment)-(Valor módulo FileAlignment). Prueba:Aligned = (0x405 + 0x200) - (0x405 módulo 0x200) => 0x605 - 0x05 = 0x600. Aligned = (0x17 + 0x200) - (0x17 módulo 0x200) => 0x217 - 0x17 = 0x200. Aligned = (0x340 + 0x200) - (0x340 módulo 0x200) => 0x540 - 0x140 = 0x400. Un saludo, Iván Portilla.
|
|
|
|
|
|
|