none
memtest.exe, option du linker /subsystem:BOOT_APPLICATION -> code 16 bits en mode réel ?

    Question

  • Bonjour,

    Cela fait un moment que je me pose cette question: comment créer une application de boot installable grâce à bcdedit dans le magasin de configuration de démarrage en tant qu'outil, à la manière de memtest.exe ?

    Répondre à cette question implique de répondre à d'autres questions:

    1. Le fichier memtest.exe est un fichier PE. Un Dumpbin (sur ma machine, sous W7 Pro x86) me donne les quelques infos suivantes:

            Entête du fichier:

            - champ "machine": x86

            - champ "number of sections": 8

            - Aucun symbole (champ "number of symbols": 0)

            - champ "characteritics": 0102: Executable, 32 bit word machine

            Entête optionnel:

            - "base of code": 0x00001000

            - "base of data": 0x000A0000

            - "Image base": 0x000400000

            - "Section alignement": 0x1000

            - "file alignement": 0x0200

            - "operating system version": 0.00

            - "image version": 0.00

            - "subsystem version": 1.00

            - "subsystem": 10 (Boot Application)

            - "dll characteritics": 0x0400 (no structured exception  handler)

    Je vois une section .text (le code exécutable du fichier), mais j'en vois que je ne connaissais pas, par exemple la section PAGER32R (on dirait un genre de section .data).

    J'en déduit les éléments suivants: pas d'import/export (par exemple de fonction), l'addresse de base de l'image en RAM doit être fixée à 0x00400000, avec un alignement des sections en RAM sur 0x1000 o = 4 ko (en sachant que l'alignement dans le fichier doit être inférieur à cela, ici 0x0200 o = 512 o). Les champs (enfin, les champs, ce seraient plutôt les propriétés de l'entête) de versions devant être à 0.00 à l'exception du champ de la version du sous-système qui doit être à 1.00 (cf plus bas). Ces déductions sont-elles correctes et suffisantes ?

    2. Le linker de MS-VC dispose d'une option /SUBSYSTEM:BOOT_APPLICATION, la propriété de la version du sous-système doit impérativement être à 1.00 (vu sur la librairie MSDN). Cependant, faut-il lier à une bibliothèque (par exemple, msvcrt.lib) ? Rien qu'au niveau du code source, quels fichiers d'entête inclure ?

    3. J'ai tenté de lancer memtest.exe depuis Windows, et comme je m'y attendais, "Le programme C:\Boot\Memtest.exe ne peut être exécuté en mode Win32". S'agirait-il d'une application en mode réel (16 bits) ? Dans ce cas, il doit être possible de programmer directement en asm et d'assembler avec ml (çà me plairait bien, çà).

    4. J'ai testé avec un petit bout de code asm (ml et link ok) qui ne fait rien qu'un ret, l'option de démarrage "nointegritychecks On" sur l'entrée du magasin de configuration du démarrage adéquate m'évite l'erreur de l'exécutable non signé (code 0xc0000428, je crois), mais bootmgr m'affiche une erreur (code 0xc0000001): "L'application ou le système d'exploitation n'a pas pu être chargé, car un fichier requis est ou contient des erreurs". J'ai même essayé en signant grâce à un certificat de test. Pareil.

    D'où ma question: qu'est-ce qui ne va pas ?

    N'hesitez pas à me corriger en cas d'erreur, même au niveau terminologie.

    Désolé pour le pavé, j'ai pris le temps de chercher une réponse satifaisante, et je souhaitais vous apporter tous les éléments en ma possession.

    Merci d'avance pour votre aide, et désolé d'avoir posté sur le forum "Visual Studio en général", si je me trompe au niveau de bcdedit, le sujet risque de ne pas être à sa place.

    vendredi 1 février 2013 21:02

Réponses

Toutes les réponses

  • Bonjour,

    et merci de votre réponse.

    L'utilitaire memtest.exe présent dans le répertoire /Boot de ma partition de démarrage (celui fourni avec Windows Vista/7/8 pour les éditions Desktop) est l'utilitaire memtest86 ?

    Ces deux utilitaires m'avaient semblé être distincts.

    Donc, il me suffirait de compiler memtest86 et de créer une entrée dans ma BCD pour voir si çà va, si oui, voir quelles sont les options de compilation et de liaison de memtest86 pour pouvoir commencer à écrire un bout de code de test (type Hello World), le compiler avec les même options puis de lui créer une entrée de ma BCD.

    Merci pour cette piste, je commence à l'explorer dès demain.

    [EDIT]

    Je parle de l'utilitaire Windows Memory Diagnotics, memtest.exe. Une question additionnelle me vient à l'esprit: comment cet outil peut-il indiquer à Windows les résultats des analyses, retourne-t-il à bootmgr un pointeur vers ces résultats, qui passe ce pointeur en paramètre au noyau ou intègre-t-il un pilote de système de fichiers de chaque fs pris en charge par Windows ?

    Merci encore pour votre aide.

    [/EDIT]

    ------------------------------------------------------------------------------

    L'erreur est humaine, mais pour un vrai désastre il faut un ordinateur



    • Modifié r62dany lundi 4 février 2013 20:40
    lundi 4 février 2013 20:31
  • mardi 5 février 2013 07:33
    Propriétaire
  • Bonjour,

    D'après ce que je vois du code source de memtest86, celui-ci intègre un bootloader 16 bits, qui charge et exécute le binaire de memtest86. memtest86 n'est pas un exécutable PE, alors que memtest (Windows Memory Diagnostic) est un exécutable PE de type "BOOT_APPLICATION" (et non "Win32" - pour une application Windows x86 -, "NATIVE" comme certains services lancés tôt dans le prcessus de boot, ou encore "CONSOLE" - exécutable 32 ou 64 bits exécuté par NTVdm).

    De plus, memtest est signé numériquement par Microsoft (un exécutable PE de type BOOT_APPLICATION non signé, avec une entrée BCD adéquate mais sans l'option NoIntegrityChecks On renvoie l'erreur d'exécutable non signé), si cela peut vous aider.

    Personellement, je n'ai rien trouvé sur la librarie MSDN. Après, il est possible que je sois passé à côté (vu le nombre d'API qui y sont décrites), et ce, bien que la librarie soit bien organisée. Je continue également mes recherches de ce côté.

    [Hors Sujet]

    D'ailleurs, je me pose une question au niveau de la gestion du mode plein écran par ntvdm/conhost, qui semble fonctionner avec un code 16 bits (appel de l'interruption 0x10 avec le registre ax = 0x0003 qui initialise le mode texte 80x25, puis appel de l'interruption 0x21 avec ax = 0x4C00 qui met fin au programme, par exemple) en mode sans échec mais pas en boot normal (messagebox "Le sous-système ne gère pas le mode plein écran"), mais c'est un autre sujet qui nécessite probablement son propre thread sur le forum Community (plutôt que sur le forum Visual Studio). Qu'en pensez-vous ?

    [/Hors Sujet]


    L'erreur est humaine, mais pour un vrai désastre il faut un ordinateur


    • Modifié r62dany mardi 5 février 2013 09:35
    mardi 5 février 2013 09:35
  • Bonjour

    J'ai trouvé cet exemple pour vous:

    https://bitbucket.org/linuxuser27/os373/src

    En effet c'est un mini OS, et il peut être compilé sous Windows.

    Et, le plus intéressant c’est le makefile pour le noyau, ou on a l’option /SUBSYSTEM:BOOT_APPLICATION 
    
    

    https://bitbucket.org/linuxuser27/os373/src/e0b0bb2f12fdca82ae4298f5628c4e5d472ec4b4/src/kernel/makefile?at=default

    Si vous étudies bien les sources vous allez trouver les réponses (beaucoup d’Assembleur).

    Aussi, j’ai trouvé des choses intéressantes dans les fichiers .BAT.  

    Cordialement,


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.


    mercredi 6 février 2013 14:21
    Propriétaire
  • Bonjour,

    après un rapide coup d'oeil aux liens que vous m'avez fournis, je vois que le noyau de ce mini-os est effectivement un exécutable PE, du même type que celui de l'utilitaire de diagnostique mémoire Windows, seule l'extension est renommée en .boot (au lieu de .exe), donc que du bon.

    Une piqûre de rappel pour tout ce qui est GDT, IDT, MSR, ... n'est jamais du luxe. Je l'ai déjà fait (à oartir d'une disquette, à partir d'un binaire sans format) il y a quelques temps. Votre réponse est donc doublement utile (je ne peux voter qu'une fois alors que votre réponse m'apporte en fait deux aides ? Comment puis-je faire ?).

    J'avais déjà vu pas mal de codes de mini-os (très intéressants aussi), mais aucun ne se présentait sous cette forme. Je retente un bout de code asm en m'aidant du makefile. De plus, les sources sont commentées (avec les références). Les fichiers peloader.S et peloader.inc sont eux aussi intéressants, je pense qu'ils fonctionnent d'une manière similaire à bootmgr au niveau du chargement et de l'exécution d'un exécutable PE, bien que des différences relativement importantes doivent exister (je présume que bootmgr récupère la valeur de retour lorsque l'exécutable est quitté).

    Je souhaite marquer votre réponse comme étant solution (via le lien "Marquer comme réponse"), dans ce cas, aurais-je la possibilité d'écrire encore dans ce fil (afin d'apporter les résultats de mes petites expérimentations, notamment sur le passage de paramètres de bootmgr vers le PE et le passage du retour du PE vers bootmgr) ?

    Encore merci !


    L'erreur est humaine, mais pour un vrai désastre il faut un ordinateur


    mercredi 6 février 2013 15:02
  • Bonjour
    Bien sûr que c'est possible d’ajouter des postes après avoir "Marquer comme réponse" (j'ai fait ça pour vous assurer).

    En plus, si vous trouvez que la réponse n'est pas bonne vous pouvez le enlever la réponse
    avec "Ne pas marquer comme réponse".


    Merci de nous tenir informées sur la suite de vos démarches.
    Cordialement,


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.



    mercredi 6 février 2013 15:10
    Propriétaire
  • Concernant l'utilisation du site, c'est noté.

    Je mettrais à jour au fur et à mesure que j'avancerais dans mon "exploration".


    L'erreur est humaine, mais pour un vrai désastre il faut un ordinateur

    mercredi 6 février 2013 15:30
  • Bonjour,


    Je déterre un peu le sujet, j'ai des réponses (et de nouvelles questions). Ce post sera assez long à lire, je remercie par avance toute personne prenant le temps de me lire. Tous les liens que je donne s'ouvrent dans une nouvelle fenêtre.


    D'après MSDN, on peut debugger bootmgr (c'est un debugging noyau). Tout en bas de cette page, c'est ce que fait l'auteur. On y voit notamment un appel à la fonction bootmgr!BlInitializeLibrary.

    D'après ce document pdf (aparemment écrit par deux chercheurs au sujet de vBootKit 2.0, lien direct vers le site www.nvlabs.in), bootmgr est chargé en 0x00400000.


    Je n'ai rien trouvé sur MSDN sur la fonction BlInitializeLibrary (pour, je suppose, Boot Loader Initialize Library). Qui dit librairie dit set de fonctions et de variables...


    bootmgr va chercher sa configuration dans un fichier sur le disque dur (ou le disque optique, peut-être aussi sur le réseau pour le boot par PXE, ou encore le vhd d'ailleurs).De plus, il peut logguer son activité dans un fichier.
    bootmgr affiche des infos à l'écran, il est capable de gérer le clavier. C'est déjà pas mal. Je pense qu'il en fait encore un peu plus (prise en charge du debugging par port série, USB 2.0 ou 1394, çà veut dire qu'il y du code qui accède à ce type d'interface, peut-être y aurait-il moyen de le "compléter" en ajoutant ce qu'il faut dans l'application pour accéder par ex à une clé usb).


    Par ex, on pourrait se servir de cette librairie pour scanner le mbr et le secteur de boot+ les 8 secteurs suivants de la partition active pour vérifier que le code contenu soit du code Microsoft et non le code d'autre chose(par ex un rootkit) puis, charger et lancer winload.exe en passant l'argument donné par bootmgr pour démarrer Windows (uniquement occasionnellement, et démarrer Windows normalement, sans l'application, lorsqu'on en a pas besoin) et ainsi éventuellemnt faciliter la recherche de code malicieux et le nettoyage.


    Seulement, pas de documentation.

    D'où mes questions:
    - Je crois que le désassemblage est interdit (sauf recherche il me semble), sachant que je ne suis pas chercheur, mais passionné (et j'espère chef d'entreprise dans ce domaine d'ici quelques mois), je n'ai l'intention d'inclure du code source ne m'appartenant pas dans mes programmes sans l'autorisation du propriétaire de ce code (c'est pour moi du plagiat, doublé de vol d'idées - propriété intellectuelle). Me confimez-vous ceci ?
    - Est-il légal d'ouvrir le pdb de bootmgr dans l'éditeur héxa pour en tirer une liste de noms de fonctions pour ensuite préparer une application de démarrage qui chercherait ces noms dans la RAM à partir de 00400000h et afficherait à l'écran le caractère précédent chaque nom+le nom+les 3 caractères suivants (pour en tirer les noms décorés afin de chercher les arguments expérimentalement pour pouvoir appeler ces fonctions avec les bons paramètres), le but étant de créer un/des programmes distribuables ? Le code source d'une application appelant lesdites fonctions avec les informations recueillies de cette manière (dans le pdb puis en RAM) serait-il légalement publiable ?

    Je sais que s'appuyer sur une librairie non documentée présente un risque d'incompatibilités, et c'est, je pense, pour cette raison principale que Microsoft recommande de ne pas s'appuyer sur ce type de fonctions.

     

    Je propose un petit code source, rien d'extraordinaire: juste lancer une application depuis bootmgr, attendre l'appui sur entrée et retourner. Je l'ai écrit pour nasm, je pense qu'il pourrait être facilement réécrit pour masm.

    bootmgr refusera de lancer l'application si elle n'est pas signée (et je pense par une autorité racine).
    Il faut donc créer une entrée adéquate, perso, j'ai copié l'entrée {memdiag} et ai modifié la copie (path et NoIntegrityChecks on), en n'oubliant pas de...l'afficher dans le menu (/toolsdisplayorder {guid de la copie de memdiag} /addfirst par ex), c'est pratique pour lancer le programme.


    Link m'affiche un warning lorsque la fonction du point d'entrée ne respecte pas la convention d'appel stdcall avec un argument de 4 octets.

    L'adresse de base ne semble pas être imposée. Personnellement, j'aurais tendance à mettre la base à 00100000h, c'est à cette adresse qu'étaient chargées les dll dans le temps. bootmgr se charge en 00400000h, ce qui laisse 00300000h octets (soient 3Mo) libres pour l'application, c'est large.

    Il ne faut lier aucune bibliothèque faisant appel aux MFC (logique), ni à aucune dll ni aucun exe(au revoir user32.lib kernel32.lib, ...), logique aussi, dans cet environnement , le noyau n'est pas chargé, le registre non plus, ni aucun pilote.


    Donc, il faut linker avec les options (adaptées au projet): /out:"<chemin\nom.exe>" /base:0x00100000 /SUBSYSTEM:BOOT_APPLICATION,1.00 /entry:"main" /machine:x86 <cheminversobj\nom.obj>


    Pour architecture x86, testé sous Windows 7 SP1 Professionnel:


    Fichier test_bootapp.asm


    section .data
      arg dd 00000000h
    
    section .code
    global _main@4
    
    
     _main@4:
    
      push ebp
      mov ebp, esp
    
      mov eax, [ebp + 8] 	; j'ignore ce qu'est cet argument, je pense a un pointeur vers une structure ou vers une chaîne contenant les options de l'entree de demarrage
      mov dword [arg], eax 	; meme si ca ne sert a rien ici, sauvons le quand meme, en plus, comme ca, on a une bonne excuse pour avoir une section data, autant
           			; eviter de se faire jeter par bootmgr parcequ'on a pas (j'ai pas essaye sans...)
    
     l1:    		;Test clavier via les IO (touche "Entree" pour quitter), c'est vrai quoi, on est en pmode et en ring0, non ?
      in al, 64h
      and al, 01h
      cmp al, 00h
      jz l1
      in al,60h
      cmp al,1Ch  		; touche entree = 1Ch, testez aussi la touche esc (01h, set scancode 1) par ex pour etre sur que nous avons le controle
      jnz l1
    
      pop ebp
      mov eax, 1
      ret 4
    


    Depuis la ligne de commande Visual Studio (nasm doit être dans le path, supposons que vous ayez une BCD qui ne craint rien dans F:\boot, par ex un disque virtuel avec Win7 installé):


    nasm -o test_bootapp.obj -f win32 test_bootapp.asm
    link /OUT:".\test_bootapp.exe" /SUBSYSTEM:BOOT_APPLICATION,1.00 /ENTRY:"main" /MACHINE:X86  /base:0x00100000 .\test_bootapp.obj

    depuis une invite administrateur:

    bcdedit /store f:\boot\bcd /copy {memdiag} /d "Test_BootApp" (bcdedit donne le guid de notre application, appelé ci dessous {guid})
    bcdedit /store f:\boot\bcd /set {guid} path \boot\test_bootapp.exe
    bcdedit /store f:\boot\bcd /set {guid} NoIntegrityChecks on
    bcdedit /store f:\boot\bcd /toolsdisplayorder {guid}
    bcdedit /store f:\boot\bcd /timeout 120
    copy [chemin de l'exe]\test_bootapp.exe f:\boot\test_bootapp.exe

    Si vous voulez debugguer bootmgr:
    bcdedit /store f:\boot\bcd /bootdebug {bootmgr} on

    Si vous voulez debugger l'exe:
    bcdedit /store f:\boot\bcd /bootdebug {guid} on

    Il n'y a plus qu'à tester (c'est censé marcher sans que bootmgr rechigne).


    J'ai fait un essai un peu plus complexe. Juste avant la boucle l1 du code de test, j'ai inséré ce qu'il faut pour basculer en real mode le temps d'appeler l'int 10h (repasser en mode 80x25 et afficher un texte quelconque) puis restaurer le pmode.
    Ca marche. C'est peut-être pas une bonne idée de switcher de mode comme çà (c'est long et pas très propre), j'aurais peut-être dû faire ce qu'il faut pour créer une tâche V86 pour l'appel à l'interruption 10h, mais juste pour test, çà va.

    Je pourrais peut-être commencer par un pacman like, histoire de voir tout ceci de plus près de manière ludique :)


    Merci encore pour le temps passé à me lire, et pour votre aide.


    L'erreur est humaine, mais pour un vrai désastre il faut un ordinateur

    mercredi 17 juillet 2013 21:58
  • Bonjour de nouveau r62dany

    J'essaye de vous répondre aux questions:

    1. désassemblage est interdit  - c'est vrai.

    2. Regarder dans le PDB - je dirais que c'est légale, mais le redistribuer non. En plus, l'ordinateur doit avoir installée un système Windows Vista, 7, 8 pour que bootmgr soit présente (avant c'était ntdlr si je me rappelle bien). Et ça c'est un peu contre l'idée d'écrire un logiciel PE. Donc comme astuce, je dirai de jeter un œil sur les sources des Boot Loader gratuits tel que Lilo, GRUB, etc....

    Vous pouvez vous inspirer et en plus, vous pouvez redistribuer votre code

    Cordialement,


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    jeudi 18 juillet 2013 08:58
    Propriétaire
  • Bonjour,

    L'objectif n'est pas d'intégrer/redistribuer le pdb de bootmgr, mais simplement de l'ouvrir dans l'éditeur hexa pour rechercher à la main les noms des fonctions afin d'en établir une liste manuellement, donc pas de soucis, impec.

    Toujours sur la légalité:

    - Qu'en est-il de scanner, lors du développement, de scanner la RAM (à partir de 00400000h) pour chercher les noms d'export trouvés correspondant à ceux lus dans le pdb, en affichant à l'écran  la décoration de ces noms avec leur décorations (permettant ainsi de connaître à la fois la convention d'appel, les nombre et le type de paramètres) ?

    - Qu'en est-il de scanner la RAM (à partir de l'adresse 00400000h, càd du début de bootmgr) à la recherche des noms décorés pour en établir une liste de pointeurs utilisable à l'exécution, sachant que ceci se fera à chaque exécution de l'application ?

    - Qu'en est-il au sujet de la distribution du code source d'une telle application (qui ne contiendrait par conséquent pas de code ni de pdb de Microsoft mais un moyen d'accéder au moins partiellement à la bibliothèque de fonctions de bootmgr à l'exécution) ?

    J'ai iinstallé bootmgr et une BCD sur un disque dur virtuel fixe sous VirtualPC (donc installer Windows, pour voir s'il est possible de debugguer tel quel), pour tester le code dans mon message précédent. J'ai aussi tenté de debugger bootmgr et l'application, mais pas de moyen de connecter windbg (waiting to reconnect). Peut-être une erreur de config de VirtualPC pour le debugging via un canal nommé (pas de port série physique sur la machine). Pourtant, çà devrait aller. Je cherche l'erreur.

    Quand je parle d'un exécutable PE, je fait référence au format COFF/PE32, et non d'un exécutable fonctionnant sans installation, j'aurais dû être plus précis, pardonnez-moi. L'intérêt est de pouvoir avoir une bonne intégration de l'application avec Windows. Par exemple, l'Outil de diagnostique de la mémoire de Windows permet, après les tests et le boot, d'indiquer à l'utilisateur loggué s'il y eu une erreur.

    De plus, il y a l'aspect "curiosité et challenge technique" qui m'attire, développer une application pour ce type d'environnement plutôt particulier et peu documenté est à la fois motivant et captivant.

    Je ne souhaite donc pas utiliser grub, lilo ou syslinux (bien que ces chargeurs soient très bien). En effet, comment comprendre bootmgr si je me sers d'un autre chargeur ?


    L'erreur est humaine, mais pour un vrai désastre il faut un ordinateur

    jeudi 18 juillet 2013 10:51
  • En ce qui concerne la légalité, rien n'est ni blanc ni noir.

    Je ne peux pas vous donner une réponse exacte sur les questions légales.

    Mais « logique », si on peut utiliser un objet/fonction MS pour créer une fenêtre en Windows, pourquoi ne pas utiliser une fonction du bootmgr ?

    Mais souvent, la légalité n’est pas logique.

    L’idée sur l’utilisation du Lilo/Grub/syslinux  c’était de ne plus utiliser les fonctions de bootmgr mais les recréer à l’aide de ces app.

    J’ai trouvé aussi quelques informations que je pense, vous allez les trouver intéressantes :

    http://www.stoned-vienna.com/

    http://stoned-vienna.com/downloads/The%20Art%20of%20Bootkit%20Development.pptx

    et le même document avec plus de détails :

    http://ek0box.ondule.fr/rootkit/The%20Art%20of%20Bootkit%20Development.pdf

    http://forums.mydigitallife.info/threads/24991-BOOTMGR-(-Documentation)

    Cordialement,


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.


    jeudi 18 juillet 2013 11:47
    Propriétaire
  • J'avais celui intitulé "The Art of Bootkit Developpement" (plus orienté Windows 8 mais effectivement détaillé), mais pas le second, merci.

    Je garde l'idée de consulter le code source de grub/lilo/syslinux, il y a probablement foule de techniques et d'informations intéressantes. L'idée de s'en servir pour recréer les fonctions de bootmgr est conservée au cas où.

    Première étape, réussir à debbuger bootmgr et la petite application de test dans VirtualPC.


    L'erreur est humaine, mais pour un vrai désastre il faut un ordinateur

    jeudi 18 juillet 2013 12:49