
Un outil pour manipuler les fichiers d'archives des automates programmables Schneider Electric
Cet outil permet d'extraire et de réassembler les fichiers d'archive des automates Schneider Electric, notamment les M580, M340 et Quantum. Les fichiers d'archive avec l'extension .sta sont en réalité des archives zip contenant quelques fichiers. Dans l'archive, le fichier vraiment important est nommé Station.apx. Le contenu de ce fichier est ce qui est transféré depuis/vers l'automate lors d'un téléchargement/téléversement complet du programme. Naturellement, il contient le code exécutable réel du programme de l'automate. Mais il contient également toutes les informations nécessaires pour éditer le programme de l'automate dans Control Expert Classic (ou Unity Pro). Le format du fichier .apx est propriétaire, et peu d'informations sont disponibles à son sujet. Un peu d'informations sont disponibles sur Liras en la red et Team82, mais ce travail va plus loin que ce qu'ils ont publié. Avec cet outil, les différentes « sections » du Station.apx peuvent être extraites (et décompressées si nécessaire) pour examen. L'outil peut également réassembler le Station.apx à partir de données de section et métadonnées précédemment extraites – et peut-être modifiées. Et ce fichier réassemblé s'ouvrira sans erreur dans Control Expert Classic / Unity Pro, à condition que les modifications apportées ne brisent pas la « logique des sections ».
Il n'y a jamais eu de grand plan avec ce projet. J'utilise des automates Schneider Electric de temps en temps, et j'étais intéressé par leur fonctionnement (ou non) à un niveau plus fondamental. Il s'est avéré que cette investigation était suffisamment complexe pour me divertir (probablement comme résoudre des mots croisés pour les gens normaux), et j'ai fini par créer cet outil.
L'outil fait de son mieux pour extraire et réassembler les fichiers avec lesquels il travaille. Cependant, l'utilisateur doit être conscient que l'outil a été développé avec :
L'utilisation de fichiers réassemblés sur un automate réel peut causer des problèmes, surtout si vous avez modifié les sections ou les métadonnées. Il est même possible que cela puisse briquer l'automate. Téléversez donc des fichiers d'archive modifiés sur l'automate à vos propres risques.
L'outil s'utilise en ligne de commande avec l'interpréteur Python :
python apxutil.py -h
usage: apxutil.py [-h] [-f filaname-apx] [-F filaname-sta] [-e dir] [-E dir] [-a manifestpath] [-A manifestpath] [-d]
[-x] [-B] [-r]
Outil pour manipuler les fichiers .sta et .apx de Schneider Electric
options:
-h, --help affiche ce message d'aide et quitte
-f, --apxfile filaname-apx
fichier .apx à lire ou à écrire
-F, --stafile filaname-sta
fichier .sta à lire ou à écrire
-e, --extract-apx dir
extraire le contenu du fichier Station.apx
-E, --extract-sta dir
extraire le contenu du fichier .sta
-a, --assemble-apx manifestpath
créer un fichier Station.apx basé sur apx_manifest.ini
-A, --assemble-sta manifestpath
créer un fichier .sta à partir des fichiers dans sta_manifest.ini
-d, --decompress décompresser les sections de Station.apx qui sont compressées
-x, --hexdump afficher un hexdump de Station.apx avec les informations d'en-tête
-B, --include-apd inclure Station.apd lors de la création de l'archive .sta
-r, --restart-offsets
redémarrer les offsets à 0 pour chaque section dans l'hexdump (utile pour le diff)
L'aide devrait être assez explicite. En général, les options raccourcies en lettres majuscules fonctionnent sur les fichiers .sta, et les lettres minuscules sur les fichiers .apx. Quelques exemples d'utilisation sont donnés ci-dessous.
Pour extraire le contenu d'un fichier .sta dans le répertoire « extracted », vous utiliseriez :
python apxutil.py -F archive.sta -E extracted
Pour extraire le contenu de Station.apx dans le répertoire « contents », vous utiliseriez :
python apxutil.py -f extracted/BinAppli/Station.apx -e contents -d
L'option « -d » signifie que les sections compressées seront décompressées, mais peut être omise si les données brutes de la section sont souhaitées.
Pour réassembler Station.apx, vous utiliseriez :
python apxutil.py -f extracted/BinAppli/Station.apx -a contents
Cela assemblera le Station.apx basé sur le apx_manifest.ini trouvé dans le répertoire contents, en compressant les données de section si elles étaient précédemment décompressées. Les tailles de section et les CRC seront recalculés, et non lus depuis le apx_manifest.ini.
Pour réassembler un fichier .sta, vous utiliseriez :
python apxutil.py -F modified-archive.sta -A extracted
Cela exclura par défaut le fichier Station.apd (qui semble être principalement une vérification d'intégrité pour l'en-tête du fichier Station.apx). Si vous souhaitez l'inclure, ajoutez l'option « -B ». Mais cela pourrait très bien signifier que Control Expert Classic échouera à ouvrir le fichier d'archive du projet.
Pour « visualiser » directement le contenu du fichier Station.apx, la commande suivante peut être utilisée :
python apxutil.py -F modified-archive.sta -x
Cela affichera un « hexdump canonique » du fichier Station.apx, ce qui signifie que vous voyez les offsets, les données hexadécimales et les données ASCII, 16 octets à la fois, y compris les métadonnées. L'option « -d » peut être utilisée pour décompresser les sections compressées (mais attention, les offsets n'ont alors plus beaucoup de sens). L'option « -r » peut être utilisée pour redémarrer l'offset à 0 pour chaque section. Ceci est utile si vous avez effectué des modifications et souhaitez pouvoir les « differ » sans offsets.
Si vous voulez comprendre le format de fichier APX (au niveau de moi-même et de cet outil), la meilleure façon est vraiment de regarder le code source de apxutil.py. Le code ne devrait pas être trop difficile à lire même avec peu d'expérience en programmation. Mais il pourrait rendre les vrais programmeurs nauséeux. En tout cas, un aperçu de haut niveau du format de fichier est donné ici. Le fichier APX commence par un en-tête de fichier de 32 octets. Le reste du fichier est divisé en différentes sections, chacune avec une structure similaire. Chaque section commence par un en-tête de section, dont la longueur dépend du type de section (défini au début de l'en-tête). L'en-tête de section est suivi d'un RTE (en-tête). Après le RTE viennent les données de la section (si présentes). Et après les données de la section, la section suivante (en-tête) commence. Il semble que l'en-tête de section soit plus lié au format Station.apx et le RTE plus lié à l'environnement d'exécution (RunTime Environment ou RealTime Environment peut-être ?), mais ce n'est pas une distinction claire.
L'en-tête du fichier APX a une longueur de 32 octets et commence par le texte ASCII « APX », suivi de quelques métadonnées. Peut-être le plus important, il définit le type et la taille du RTE utilisé. Le type 0x02 est celui que j'ai vu. Il semble probable que le type 0x01 soit pour un espace d'adressage 16 bits et le type 0x02 pour un espace d'adressage 32 bits, mais cela est loin d'être certain. Il y a quelques inconnues qui ont probablement une certaine signification. Quelques valeurs 32 bits et une valeur 16 bits sont « répétées » dans la section « SD » 0x0001, mais leur signification est inconnue. Les 11 derniers octets semblent toujours être des zéros. Un exemple ci-dessous (au format hexdump canonique, avec métadonnées) :
00000000 41 50 58 00 00 01 02 01 10 01 10 60 f6 c3 30 00 |APX........`..0.| ApxFileHeader(magic=0x00585041, version_maybe=0x0100, rte_type=0x02, header_count_maybe=0x01, sdsection_total_size=0x0110, rte_size=0x10, sdsection_39_4=0x30c3f660, sdsection_35_4=0x0b926500, sesection_8_2=0x0106, zero_pad_21_11=0000000000000000000000)
00000010 65 92 0b 06 01 00 00 00 00 00 00 00 00 00 00 00 |e...............|
L'en-tête de section APX commence par une valeur 16 bits définissant son type. Les types 0x0001 - 0x0004 semblent valides, mais je n'ai vu que les types 0x0000, 0x0001 et 0x0002. La longueur de l'en-tête de section dépend du type. Pour 0x0000, la longueur est de 8 octets, pour 0x0001 - 0x0002, elle est de 16 octets et pour les types 0x0003 - 0x0004, elle devrait être de 24 octets. Le numéro de section est donné par une valeur 16 bits à l'offset 4. Pour les types de section 0x0000 et 0x0001, c'est tout ce que je sais, et ils n'ont pas de données de section. Pour le type de section 0x0002, la valeur 32 bits à l'offset 10 spécifie la taille des données de la section, telles qu'elles sont présentes dans le fichier Station.apx.
L'en-tête RTE suivant l'en-tête de section a une longueur de 16 octets (du moins pour le type 0x02). La signification de la première valeur 32 bits est inconnue (mais nommée ici « block_count »). La valeur 32 bits commençant à l'offset 4 est la taille des données de la section (de l'en-tête de section) moins 1, dans le cas où la section a des données. Si la section n'a pas de données, la signification est inconnue (et la section 0x0011 enfreint cette règle). La valeur 32 bits commençant à l'offset 8 sont des attributs/drapeaux, dont la plupart ont une signification inconnue. Quelques réflexions sont listées à la fin de apxutil.py. La valeur 16 bits commençant à l'offset 12 est le CRC16/Kermit des données de la section (et encore, la section 0x0011 enfreint cette règle). Les 3 bits de poids fort de l'octet 14 définissent la zone mémoire et les 5 bits de poids faible le folio mémoire. Le dernier octet 15 est probablement inutilisé.
Les données de section sont généralement des données « brutes », qui peuvent contenir du code exécutable, des informations de projet, des données compressées, etc. Il semble que si le bit 13 dans les attributs RTE est défini, alors les données de la section sont compressées. Les types de compression observés sont zip/"pk", zlib avec en-tête non standard et « raw deflate ».
Bien que toutes les sections aient leur propre signification, il semble que les sections 0x0001 « RT » et 0x0011 « SD » soient fondamentales par rapport aux autres. Elles semblent liées aux RTE et à la disposition mémoire réelle de l'environnement d'exécution de l'automate. Un décodage partiel de ces sections est inclus vers la fin de apxutil.py, mais n'est actuellement pas utilisé par l'outil lui-même.
Il y a beaucoup de « fruits à portée de main » au cas où quelqu'un voudrait enquêter. Quelques questions ouvertes :