API de Win32: al intentar leer el archivo, se trunca, ¿por qué?

Estoy tratando de leer un archivo y luego mostrar el archivo en ASCII o HEX en hEdit. Eventualmente, ejecutaré otros cálculos en la información del archivo, pero ahora solo quiero verlo todo.

Actualmente, el código muestra el primer bit, "MZ", pero eso es todo. De alguna manera, accidentalmente estoy truncando la variable pszFileText, quiero poder ver el ejecutable completo en mi ventana.

BOOL ReadInEXEFile(HWND hEdit, LPCTSTR pszFileName)
{
HANDLE hFile;
BOOL bSuccess = FALSE;

hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
    OPEN_EXISTING, 0, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
    DWORD dwFileSize;

    dwFileSize = GetFileSize(hFile, NULL);
    if(dwFileSize != 0xFFFFFFFF)
    {
        LPSTR pszFileText;

        pszFileText = GlobalAlloc(GPTR, dwFileSize + 1);
        if(pszFileText != NULL)
        {
            DWORD dwRead;
            if(ReadFile(hFile, pszFileText, dwFileSize, &dwRead, NULL))
            {
                pszFileText[dwFileSize] = 0; // Add null terminator
                if(SetWindowText(hEdit, pszFileText))
                {
                    bSuccess = TRUE; // It worked!
                }
            }
            GlobalFree(pszFileText);
        }
    }
    CloseHandle(hFile);
}
return bSuccess;

}

preguntado el 01 de julio de 12 a las 01:07

Está pasando el contenido del archivo al control de edición como una cadena terminada en cero. Lo que significa que si hay un cero en algún lugar en el medio del archivo, se terminará allí mismo. Entonces, aparentemente nuestro archivo tiene un cero justo después del "MZ". Esto es básicamente lo que debe esperar cuando interpreta binario archivos como cadenas terminadas en cero. -

En cualquier caso, el porqué ¿Estás tratando de probar tu código en un binario ¿¿¿Archivo??? Evidentemente estaba destinado a texto archivos solamente. -

Quiero ser capaz de analizar ejecutables. Así es como encontré cómo leer archivos dentro de una interfaz gráfica de usuario win32, así que esto es lo que estoy tratando de aumentar para poder usar para exe. -

Bien tu no se ser capaz de "analizar ejecutables" tratando de verlos como texto en un control de edición. -

No tienes que PANTALLA los datos para ANALIZAR eso. Esas son dos operaciones separadas. Usted puede ANALIZAR los datos binarios originales tal como están directamente en su código, pero tendrá que codificar los datos si desea PANTALLA eso. -

3 Respuestas

Los archivos EXE son binarios, pero está tratando de mostrar los datos binarios sin procesar tal cual, lo que no funcionará. Estaba en el camino correcto pensando que necesita codificar los datos binarios en hexadecimal antes de mostrarlos. Los datos binarios no se pueden mostrar, pero sí los hexadecimales.

Prueba esto en su lugar:

static const TCHAR Hex[] = TEXT("0123456789ABCDEF");

BOOL ReadInEXEFile(HWND hEdit, LPCTSTR pszFileName) 
{ 
    BOOL bSuccess = FALSE; 

    HANDLE hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 
    if (hFile != INVALID_HANDLE_VALUE) 
    { 
        DWORD dwFileSize = GetFileSize(hFile, NULL); 
        if (dwFileSize != INVALID_FILE_SIZE)
        { 
            LPTSTR pszFileText = (LPTSTR) LocalAlloc(LMEM_FIXED, ((dwFileSize * 3) + 1) * sizeof(TCHAR)); 
            if (pszFileText != NULL)
            {
                BYTE buffer[1024];
                DWORD dwOffset = 0;
                DWORD dwRead; 

                for (DWORD dwFilePos = 0; dwFilePos < dwFileSize; dwFilePos += dwRead)
                {
                    if (!ReadFile(hFile, buffer, sizeof(buffer), &dwRead, NULL)) 
                    {
                        CloseHandle(hFile);
                        return FALSE;
                    }

                    if (dwRead == 0)
                        break;

                    for (DWORD idx = 0; idx < dwRead; ++idx)
                    {
                        pszFileText[dwOffset++] = Hex[(buffer[idx] & 0xF0) >> 4];
                        pszFileText[dwOffset++] = Hex[buffer[idx] & 0x0F];
                        pszFileText[dwOffset++] = TEXT(' ');
                    }
                }

                pszFileText[dwOffset] = 0; // Add null terminator 

                bSuccess = SetWindowText(hEdit, pszFileText);
                LocalFree(pszFileText);
            } 
        } 

        CloseHandle(hFile); 
    } 

    return bSuccess; 
}

Respondido 01 Jul 12, 02:07

Remy, realmente aprecio tu ayuda. Voy a mirar en esto. - Joe Norton

¡Aprecio tu ayuda! Desafortunadamente, Visual Studio me está dando errores debido a la declaración de tipos en la instrucción for. Eventualmente, averiguaré de qué manera quiere que esté formateado y podré intentarlo. Lo resolveré y te lo haré saber. - Joe Norton

Si a Visual Studio no le gusta este código, entonces está siendo tonto porque el código es perfectamente válido tal como está. Es legal declarar variables dentro de for Declaraciones. Documentación propia de Microsoft muestra ejemplos de eso. - Rémy Lebeau

Por supuesto. Hice pequeños cambios y ahora funciona. Gran trabajo, gracias por tu ayuda. ¡Ahora estoy trabajando en cómo convertirlo a ASCII y Unicode! - Joe Norton

Dos razones:

1) Si está leyendo un ejecutable, es probable que el tercer byte sea un cero, lo que podría terminar la cadena, aunque esté pasando la longitud a SetWindowText.

2) Esta línea está mal: pszFileText[dwFileSize + 1] = 0;. Debería ser pszFileText[dwFileSize] = 0;. Está escribiendo un byte cero en algún lugar incorrecto, no se sabe qué podría estar haciendo.

Respondido 01 Jul 12, 01:07

Gracias por el # 2, arreglado ahora. Pero sigue siendo el mismo problema. ¿Cómo podría intentar imprimir la variable sin que termine prematuramente? - Joe Norton

La forma en que lo muestra probablemente depende de que los datos sean una cadena terminada en NUL, y los datos binarios tienen NUL incorporados, por lo que solo muestra los datos hasta el primer NUL.

Deberá imprimirlo usted mismo y usar la longitud de los datos para saber cuánto imprimir en lugar de depender de que sea una cadena C terminada en NUL.

Respondido 01 Jul 12, 01:07

Estoy de acuerdo. Los primeros 4 bytes de todos los archivos .exe son 0x4D 0x5A 0x90 0x00, Donde 0x4D 0x5A es la secuencia ASCII MZ y 0x90 no es un personaje visual. - Rémy Lebeau

@joenorton con un bucle; bucle de 0 a la cantidad de bytes que lee e imprime cada byte. - Seth Carnegie

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.