Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - The Swash

#81
Programación C/C++ / Re: [C]Resource Dumper.
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
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
ASM / Re: Acerca de DOS stub
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
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
ASM / Re: Acerca de DOS stub
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.
#86
Hola,

Estás leyendo bien los datos del ejecutable?, los punteros se se me hacen un poco altos como para el tamaño de un "notepad". Y sin duda, si esos fuesen los valores están alineados. Para verificar si un valor está alineado o no debes hacer (valor módulo FileAlignment), si esto es igual a 0, está alineado.

Un saludo,
Iván Portilla.
#87
Programación C/C++ / [C]Resource Dumper.
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("####  ####\n");
    printf("#  #  #   #\n");
    printf("# #   #    #\n");
    printf("##    #    #\n");
    printf("# #   #   #\n");
    printf("#  #  ####\n\n");
    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.");
    getchar();
    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
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.
#89
Hola,

En cuanto a lo que dice @Karcrack estoy muy de acuerdo, ensamblador te permite algo muy liviano pero además tu mismo puedes encargarte de "todo". Pero siempre hay el "pero" y es que debes ser muy cuidadoso con todo, debes tener un buen controlador de excepciones y tratar de que sea lo más óptimo posible.

Un saludo,
Iván Portilla.
#90
Hola,

@Maurice_Lupin podría especificar si se refiere a la detección "pro-activa", osea le salta al ejecutar el exe que use dicha técnica con algo como: "El ejecutable está intentando acceder a la memoria de..."?

Un saludo,
Iván Portilla.