User Tools

Site Tools


outil_d_analyse_des_fichiers_nanoreseau

This is an old revision of the document!


Outil d'analyse des fichiers Nanoréseau

Cet outil décode les entêtes des fichiers Nanoréseau et permet d'en extraire les sections binaires.

Exemple d'utilisation :

$ nrfile -e NRDOS.MO5

NRFile, version 1.0

File: NRDOS.MO5 (7552 bytes)

Header:
   Station identifier: "        " (default)
   File type: binary
   File mode: binary
   File status: read/write
   Nanoreseau version: 3.1
   Creation date: 27/05/85
   Last modification date: 27/05/85
   Created on a: TO7
   Created with: unreferenced application
   File attributes: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Binary contents:
   Format: extended
   Target computer: MO5
   Target application: unreferenced application
   Loading flags: broadcast, load application first
   Application: "NRDOS"

   Code section 1:
      Size: 7373 bytes
      Load address: 00-5000 (do not switch RAM page)

      Section has been dumped to NRDOS.MO5-00-5000.bin.

   Execution address: 00-5000 (do not switch RAM page)

Code source :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Undefine this for Unix-like systems
#define PATH_WINDOWS

int gExtract = 0;

FILE *gSource = NULL;
unsigned char *gBuffer = NULL;
char *gFilename = NULL;
long gSize = 0;

char gIdentifier[9] = {0};
unsigned char gFileType = 0;

void TargetApp(unsigned char xByte)
{
    switch (xByte)
    {
    case 0:
        printf("unreferenced application");
        break;
    case 1:
        printf("BASIC 1.0");
        break;
    case 2:
        printf("LOGO");
        break;
    case 3:
        printf("LSE");
        break;
    default:
        printf("unknown application");
    }

}

void TargetComputer(unsigned char xByte)
{
     switch (xByte)
    {
    case 0:
        printf("TO7");
        break;
    case 1:
        printf("MO5");
        break;
    case 2:
        printf("TO7/70");
        break;
    default:
        printf("unknown computer");
    }
}

void PageSwitch(unsigned char xPage)
{
  switch (xPage)
        {
        case 0:
            printf("do not switch RAM page");
            break;

        case 0x40:
        case 0x41:
        case 0x42:
        case 0x43:
        case 0x44:
        case 0x45:
            printf("switch to RAM page %d",xPage-0x40);
            break;

        case 0x80:
        case 0x81:
        case 0x82:
        case 0x83:
            printf("switch to 64K RAM expansion page %d",xPage-0x80);
            break;

        case 0xff:
            printf("switch to internal ROM [BASIC]");
            break;

        default:
            printf("unknown RAM page");
        }
        printf(")\n");
}

void AnalyseBinExt(unsigned char *xpBuffer)
{
    long lOffset = 38;
    unsigned int lSection = 1, lSize = 0, lAddress = 0;
    char lBuffer[33] = {0};
    char *lFilename = NULL;
    unsigned char lPage = 0;
    FILE *lDump = NULL;

    printf("   Target computer: ");
    TargetComputer(xpBuffer[1]);
    printf("\n");

    printf("   Target application: ");
    TargetApp(xpBuffer[2]);
    printf("\n");

    printf("   Loading flags: ");
    if (xpBuffer[3]&0x80)
    {
        printf("broadcast");
    }
    if (xpBuffer[3]&0x40)
    {
        if (xpBuffer[3]&0x80)
        {
            printf(", ");
        }
        printf("load application first");
    }
    printf("\n");

    strncpy(lBuffer,(char*)xpBuffer+6,32);
    printf("   Application: \"%s\"\n\n",lBuffer);

    while (xpBuffer[lOffset]!=3)
    {
        printf("   Code section %d:\n",lSection);
        lSize = xpBuffer[lOffset+1]*256+xpBuffer[lOffset+2];
        lPage = xpBuffer[lOffset+5];
        printf("      Size: %d bytes\n",lSize);
        lAddress = xpBuffer[lOffset+3]*256+xpBuffer[lOffset+4];
        printf("      Load address: %02X-%04X (",lPage,lAddress);

        PageSwitch(lPage);
        printf("\n");

        if (gExtract)
        {
            lFilename = (char*)malloc(strlen(gFilename+11));
            sprintf(lFilename,"%s-%02x-%04x.bin",gFilename,lPage,lAddress);
            lDump = fopen(lFilename,"wb");
            fwrite(xpBuffer+lOffset+6,lSize,1,lDump);
            fclose(lDump);
            printf("      Section has been dumped to %s.\n\n",lFilename);
            free(lFilename);
        }

        lOffset += 6+lSize;

        lSection++;
    }

    lPage = xpBuffer[lOffset+5];
    printf("   Execution address: %02X-%04X (",lPage,xpBuffer[lOffset+3]*256+xpBuffer[lOffset+4]);
    PageSwitch(lPage);
}

void AnalyseBinSimple(unsigned char *xpBuffer)
{
    long lOffset = 0;
    unsigned int lSection = 1, lSize = 0, lAddress = 0;
    char *lFilename = NULL;
    FILE *lDump = NULL;

    while (xpBuffer[lOffset]==0)
    {
        printf("   Code section %d:\n",lSection);
        lSize = xpBuffer[lOffset+1]*256+xpBuffer[lOffset+2];
        printf("      Size: %d bytes\n",lSize);
        lAddress = xpBuffer[lOffset+3]*256+xpBuffer[lOffset+4];
        printf("      Load address: %04X\n",lAddress);
        printf("\n");

        if (gExtract)
        {
            lFilename = (char*)malloc(strlen(gFilename+11));
            sprintf(lFilename,"%s-%04x.bin",gFilename,lAddress);
            lDump = fopen(lFilename,"wb");
            fwrite(xpBuffer+lOffset+6,lSize,1,lDump);
            fclose(lDump);
            printf("      Section has been dumped to %s.\n\n",lFilename);
            free(lFilename);
        }

        lOffset += 5+lSize;
        lSection++;
    }

    printf("   Execution address: %04X\n",xpBuffer[lOffset+3]*256+xpBuffer[lOffset+4]);
}

void AnalyseBin(unsigned char *xpBuffer)
{
    printf("Binary contents:\n   Format: ");
    if (xpBuffer[0] == 1)
    {
       printf("extended\n");
       AnalyseBinExt(xpBuffer);
    } else
    {
       printf("simple\n\n");
       AnalyseBinSimple(xpBuffer);
    }
}

void ExtractFilename(char *xSrcStr, char **xStrDst)
{
    char *lPtr = strrchr(xSrcStr,
#ifdef PATH_WINDOWS
    '\\'
#else
    '/'
#endif // PATH_WINDOWS
    );

    if (lPtr==NULL)
    {
        *xStrDst = (char*) malloc(strlen(xSrcStr));
        strcpy(*xStrDst,xSrcStr);
    }
    else
    {
        *xStrDst = (char*) malloc(strlen(lPtr));
        strcpy(*xStrDst,lPtr+1);
    }
}

void usage()
{
    printf("Usage: nrfile [-e] filename\n");
}

int main(int argc, char *argv[])
{
    long i;

    printf("NRFile, version 1.0\n");
    if ((argc!=2)&&(argc!=3))
    {
        usage();
        return -1;
    }

    if (argv[1][0]=='-')
    {
        if (argc!=3)
        {
           usage();
           return -1;
        }
        if (argv[1][1] == 'e')
        {
            gExtract = 1;
        }
        else
        {
           usage();
           return -1;
        }
    } else if (argc!=2)
    {
           usage();
           return -1;
    }



    if (gExtract)
    {
        ExtractFilename(argv[2],&gFilename);
        gSource = fopen(argv[2],"rb");
    } else
    {
        ExtractFilename(argv[1],&gFilename);
        gSource = fopen(argv[1],"rb");
    }

    if (gSource == NULL)
    {
        printf("Error: cannot open file.\n");
        free(gFilename);
        return -2;
    }

    fseek(gSource,0,SEEK_END);
    gSize = ftell(gSource);
    fseek(gSource,0,SEEK_SET);

    gBuffer = malloc(gSize);
    if (gBuffer == NULL)
    {
        printf("Error: cannot allocate memory.\n");
        free(gFilename);
        fclose(gSource);
        return -3;
    }
    memset(gBuffer,0,gSize);

    fread(gBuffer,1,gSize,gSource);
    fclose(gSource);

    if (strnicmp((char*)gBuffer,"*NRUSTL*",8))
    {
        printf("Error: this file is not Nanoreseau compatible.\n");
        free(gBuffer);
        free(gFilename);
        return -4;
    }

    printf("\nFile: %s (%lu bytes)\n\n",gFilename,gSize);
    printf("Header:\n");

    strncpy(gIdentifier,(char *)gBuffer+8,8);
    printf("   Station identifier: \"%s\"",gIdentifier);
    if (strncmp(gIdentifier,"        ",8) == 0)
    {
        printf(" (default)");
    }
    printf("\n");

    gFileType = gBuffer[17];
    printf("   File type: ");
    switch (gFileType)
    {
    case 0:
        printf("BASIC program");
        break;
    case 1:
        printf("BASIC data");
        break;
    case 2:
        printf("binary");
        break;
    case 3:
        printf("source code");
        break;
    case 5:
        printf("indexed data");
        break;
    default:
        printf("unknown");
    }
    printf("\n");

    printf("   File mode: ");
    switch (gBuffer[18])
    {
    case 0:
        printf("binary");
        break;
    case 0xff:
        printf("ASCII");
        break;
    default:
        printf("unknown");
    }
    printf("\n");

    printf("   File status: ");
    switch (gBuffer[23])
    {
    case 0:
        printf("read/write");
        break;
    case 0xff:
        printf("write protected");
        break;
    default:
        printf("unknown");
    }
    printf("\n");

    printf("   Nanoreseau version: %d.%d\n",gBuffer[24],gBuffer[25]);

    printf("   Creation date: %02d/%02d/%02d\n",gBuffer[28],gBuffer[27],gBuffer[26]);
    printf("   Last modification date: ");
    if ((gBuffer[29] == 0)&&(gBuffer[30] == 0)&&(gBuffer[31] == 0))
    {
        printf("never");
    }
    else
    {
        printf("%02d/%02d/%02d",gBuffer[31],gBuffer[30],gBuffer[29]);
    }
    printf("\n");

    printf("   Created on a: ");
    TargetComputer(gBuffer[32]);
    printf("\n");

    printf("   Created with: ");
    TargetApp(gBuffer[33]);
    printf("\n");

    printf("   File attributes: ");
    for (i=80;i<96;i++)
    {
        printf("%02X ",gBuffer[i]);
    }
    for (i=96;i<128;i++)
    {
        if (i%16==0)
        {
            printf("\n                    ");
        }
        printf("%02X ",gBuffer[i]);

    }
    printf("\n\n");

    if (gFileType == 2)
    {
        AnalyseBin(gBuffer+128);
    }

    free(gBuffer);
    free(gFilename);
    return 0;
}
outil_d_analyse_des_fichiers_nanoreseau.1742247856.txt.gz · Last modified: (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki