[ASM] Que la vie était simple sous MS-DOS 16 bits (scan mémoire physique)
dogloop
Messages postés14Date d'inscriptiondimanche 28 mars 2010StatutMembreDernière intervention27 décembre 2010
-
4 avril 2010 à 04:46
dogloop
Messages postés14Date d'inscriptiondimanche 28 mars 2010StatutMembreDernière intervention27 décembre 2010
-
23 avril 2010 à 18:57
J'ouvre ce topic pour essayer de mieux comprendre quelles sont les différentes façons pour accéder à toute la RAM (et aussi peut être la ROM) de mon PC. Ok le principe de la mémoire "protégée" est que j'accéde à la RAM sans déranger les autres programmes et utilisateurs.
Mais si j'ai envie de scanner toute la mémoire de mon PC juste pour voir ce qui s'y passe avec un petit programme simple en assembleur, comment je fais ?
A titre d'exemple voilà un programme simple de scan. mémoire pouvant tourner sous MS-DOS 8088 et me montrant tout ce qui se passe dans un vieux PC disposant de 640 Ko de RAM :
cld
; open 80 x 50 x 16 text mode (font 8x8)
mov ax, 2
int 16
mov ax, 0x1112
xor bl, bl
int 16
; DS = memory source
; ES = target (video ram)
xor ax, ax
mov ds, ax
mov ax, 47104
mov es, ax
loop_scan:
; displaying memory
xor si, si
xor di, di
mov cx, 80 * 49
loop_disp:
movsb
inc di
loop loop_disp
; displaying segmentation value
mov ax, 0x0C20 ; space char & bright red
mov word [es:49*160 ], ax
mov word [es:49*160 + 2], ax
mov word [es:49*160 + 4], ax
mov word [es:49*160 + 6], ax
mov word [es:49*160 + 8], ax
mov ax, ds
mov di, 49 * 160 + 8
call disp_number
; key tests
; 8, 2, 9, 3, ESC
xor ah, ah
int 22
cmp al, '8'
jne no_up
mov bx, ds
sub bx, 5
mov ds, bx
jmp loop_scan
no_up:
cmp al, '2'
jne no_down
mov bx, ds
add bx, 5
mov ds, bx
jmp loop_scan
no_down:
cmp al, '9'
jne no_page_up
mov bx, ds
sub bx, 80 * 49 / 16
mov ds, bx
jmp loop_scan
no_page_up:
cmp al, '3'
jne no_page_down
mov bx, ds
add bx, 80 * 49 / 16
mov ds, bx
jmp loop_scan
no_page_down:
cmp al, 27
jne loop_scan
ret
disp_number:
; AX = number to display
; ES = video RAM (usually 0xB800)
; DI = position in video RAM
mov bx, 10
xor dx, dx
mov cx, ax
div bx
add dl, 48
mov byte [es:di], dl
dec di
dec di
mov ax, cx
xor dx, dx
div bx
cmp ax, 0
jne disp_number
ret
à compiler avec NASM.
Au démarrage le segment lu est placé sur 0, en appuyant sur n'importe quelles touches vous verrez le buffer clavier se remplir dans le milieu de l'écran. Les vecteurs d'interruptions tout au début.
Autour de 7840, en appuyant sur les touches vous verrez la pile.
Un peu avant 40000 l'interpréteur de commandes
ensuite 47104 (0xB800) la video ram donc avec l'effet mirroir vous verrez des blocs de caractères changer
et enfin la ROM ... avec du ASCII incompréhensible puisque c'est le code assembleur des routines de bases du PC.
Est-ce que quelqu'un peut me dire quels moyens j'ai pour faire l'équivalent pour visualiser mes 2 Go de RAM ... au moins le début voir ce qui se passe réellement et physiquement (la table d'allocation des blocs de mémoire, le noyau, les programmes, la VIDEO RAM, etc ... )
Est-ce déjà possible, faut il nécassairement que ça soit ROOT qui le fasse ? ou que le programme soit executé comme si c'était un DRIVER ?
Merci
A voir également:
[ASM] Que la vie était simple sous MS-DOS 16 bits (scan mémoire physique)
cs_ghuysmans99
Messages postés3983Date d'inscriptionjeudi 14 juillet 2005StatutMembreDernière intervention30 juin 201316 4 avril 2010 à 08:12
Si tu veux faire ça c'est plus facile de le faire sans aucun autre OS. Tu codes ton propre OS en mode protégé avec une GDT qui te permet de lire/écrire où tu veux et après il te suffit de te faire une petite gestion écran.
---
VB.NET is good ... VB6 is better
cs_ghuysmans99
Messages postés3983Date d'inscriptionjeudi 14 juillet 2005StatutMembreDernière intervention30 juin 201316 5 avril 2010 à 10:17
Les antivirus ne scannent pas la mémoire : ils ne font que lire la mémoire de chaque process via l'API ReadProcessMemory sous Windows. Faire un driver demande de très bonnes connaissances du noyau Windows/Linux et c'est beaucoup plus simple de faire un OS "comme ça" si tu veux seulement voir le contenu de ta RAM.
---
VB.NET is good ... VB6 is better
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 5 avril 2010 à 18:51
salut,
sous linux, le bootloader s'occupe de passer en mode protégé. Tu trouveras souvent un programme qui s'appele memtest qui peut être lancé au boot mais que je n'ai jamais testé.
Logiquement, la source du code doit également être disponible, c'est le principe même de l'open source.
Sous MS-DOS, scanner l'ensemble de la mémoire suppose la gestion d'un extender memoire type emm386 et donc de passer en mode protégé de toutes manières, je trouve cela bien plus compliqué que de faire son propre bout de code. C'est très simple et en mode protégé, tu n'as pas besoin d'activer la memoire virtuelle pour pouvoir acceder à l'ensemble de la mémoire physique.
Faire ce truc sous windows suppose effectivement la mise en place d'un driver qui s'executera en ring 0. Il y a des fonctions du noyau qui permettent cela du style MapPhysicalToLinear. Tu devras pour cela apprendre la programmation avec D.D.K. de Windows (Device Developpement Kit). Tu devrais également pouvoir trouver des trucs interessants chez sysinternals.
Si tu jettes un oeil sur quelques'unes de mes sources, la plupart traitent de cela mais je ne suis pas un commenteur hors pair. Il y a même un début de Live-CD codé avec nasm.
@++
Vous n’avez pas trouvé la réponse que vous recherchez ?
dogloop
Messages postés14Date d'inscriptiondimanche 28 mars 2010StatutMembreDernière intervention27 décembre 2010 8 avril 2010 à 01:47
Merci pour toutes ces précisions ...
Oui d'accord que passer par MS-DOS est tordu, ce n'est pas mon but de toutes façons ;-)
C'est quand même incroyable que juste pour utiliser mon processeur comme s'il était presque seul avec une RAM comme sur une carte électronique en lui faisant ignorer l'O.S. le mode protégé et le basculement de contexte, il faille passer par une connaissance de toutes ses docs.
L'informatique des temps modernes devient comme les voitures modernes ; tu l'utilises mais t'as pas à savoir ce qui se passe en dessous ... c'est les "personnes compétentes" qui elles seulent ont le droit de mettre le nez dedans ... enfin c'est mon impréssion pour l'instant ... je changerai d'avis peut être dans quelques temps :-)
Sinon j'ai téléchargé ton code "debugger" ... très utile et bravo pour cette initiative qui permet encore à ceux qui aiment l'informatique de ce savoir ce qui se passe en-dessous.
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 8 avril 2010 à 10:33
Il est normal que tout necessite un minimum d'apprentissage. Une voiture, il faut apprendre à la conduire. Faire sa vidange est une chose, changer son joint de culasse en est une autre qui necessite plus de connaissances dans le domaine.
Pour moi, le plus regrettable en informatique, c'est plutôt qu'il faut connaître l'anglais pour pouvoir se documenter.
L'utilisation du processeur et de la mémoire ne necessite que la lecture de la doc d'intel sur le 386, ce n'est pas si énorme que cela.
Quand j'ai commencé l'informatique, je n'avais pas internet, c'est ce qui m'a le plus manqué: l'accès à la bibliothèque.
dogloop
Messages postés14Date d'inscriptiondimanche 28 mars 2010StatutMembreDernière intervention27 décembre 2010 13 avril 2010 à 06:24
Bien sûr que tout nécessite un minimum d'apprentissage ... mais changer un joint de culasse sur une voiture d'aujourd'hui sera beaucoup plus décourageant que le changer sur une voiture d'il y a 30 ans ... pourtant le principe fondamental du moteur est le même ...
De la même manière que lire ma mémoire sous MS-DOS 16 bits ou un micro. 8 bits demande un peu d'apprentissage et le faire sous un Windows 95 like ou un Linux ... il faut biaiser l'O.S. en lui faisant croire qu'il démarre un driver en ring 0 ...
A force de faire trop de protections et de confort paradoxalement l'informatique devient plus compliquée ...
cs_ghuysmans99
Messages postés3983Date d'inscriptionjeudi 14 juillet 2005StatutMembreDernière intervention30 juin 201316 13 avril 2010 à 09:18
Pas vraiment plus compliquée : sans protection mémoire (donc en ring 0 ou en développant ton propre OS) c'est toujours aussi simple.
---
VB.NET is good ... VB6 is better
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 14 avril 2010 à 08:07
re,
La protection est de toute manière dépendante du materiel et non du système. Il faudra toujours se plier aux specifications du système sur lequel on veut programmer. Rien d'anormal pour moi.
L'informatique, contrairement à la mécanique dispose d'une compatibilité avec les vieilles spécifications. Que demander de plus ? Nos vieux programmes BIOS/DOS fonctionnent encore. Une aubaine pour une éducation en mal de se mettre à jour...
Tu fais également une erreur en disant qu'acceder à sa mémoire sous D.O.S. est plus facile. Comme déjà dit, l'utilisation d'un extendeur mémoire est moins simple pour moi mais à chacun ses goûts.
Trop de protection ? Eviter que le système ne plante par la faute d'une application buguée ne me paraît pas si excessif. C'est plutôt une amélioration sous jacente à une experience vécue.
De même qu'empêcher l'execution de code dans la pile evite les buffer overflow...
dogloop
Messages postés14Date d'inscriptiondimanche 28 mars 2010StatutMembreDernière intervention27 décembre 2010 22 avril 2010 à 15:49
Bonjour à tous et merci pour vos réponses,
pour la compatiblitée des vieux programmes BIOS / DOS, il y avait moyen d'émuler au niveau logiciel sans se décharger des fardaux sur le "nouveau" 80386.
L'évolution rapide de la vitesse des processeurs aurai permi sans problème de faire tourner nos vieux programmes DOS sans que les nouveaux intel aient à se trimballer le génial SEGMENT : OFFSET
Quand on pense qu'en 1979 le 68000 pouvait adresser de façon linéaire 16 Mo ...
Je pense qu'ils ont été dépassé par la rapide popularité du PC et qu'ils ne voulaient pas sacrifier de la compatibilitée, mais c'est à ce moment qu'il aurai fallu faire quelques choix et sacrifices.
Bien sûr que l'extender mémoire sous DOS c'est compliqué, je parlais d'un adressage de 1 Mo sous DOS qui se faisait presque "normalement".
Enfin je me plaindrai moins quand j'arriverai à faire ce que je veux.
Alors j'ai réussi à lancer mon programme de scan dans le secteur boot d'une disquette, ce qui fait que je me retrouve avec un PC "pur" qui me montre sa mémoire ... mais toujours avec cet éternel
adressage 16 bits qui j'ai l'impression me poursuivra jusqu'à la mort.
Donc j'aimerai faire la même chose en mode 32 bits et parcourir la totalité de ma mémoire, voici mon code qui est placé dans le secteur de boot : (compilé NASM)
[bits 16]
mov eax, cr0
or ax, 1
mov cr0, eax
[bits 32]
mov byte [0XB8000], 'B'
mov byte [0XB8002], 'O'
mov byte [0XB8004], 'O'
mov byte [0XB8006], 'T'
halt:
jmp halt
times 510-($-$$) db 0
dw 0xAA55
Si ce ridicule code m'affiche "BOOT", j'aurai l'impression de faire un pas de géant ... mais ça marche pas et le PC reboote carrément
J'en déduis que je suis obligé de construire une table GDT, même si je veux juste lire la mémoire entiérement sans aucune option de protection, segmentation ou pagination ?
cs_ghuysmans99
Messages postés3983Date d'inscriptionjeudi 14 juillet 2005StatutMembreDernière intervention30 juin 201316 22 avril 2010 à 18:18
Je l'avais déjà dit dans un post précédent, la GDT est obligatoire. Sinon, GPF au premier 18ème de seconde après le passage en mode protégé et plus d'accès à la mémoire.
---
VB.NET is good ... VB6 is better
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 22 avril 2010 à 23:01
re,
%define DESC_D32 0xC092
%define DESC_C32 0xC09A
[ORG 0x7C00]
[bits 16]
; initialise le registre gdtr.
lgdt [GDTR]
; inhibe les interrruptions.
cli
; inhibe la NMI.
in al,0x70
or al,0x80
out 0x70,al
; active le mode protégé.
mov eax,cr0
or al,1
mov cr0,eax
; initialise CS=(1<<3)=FLAT_CODE0
; & vide le cache d'instructions
jmp FLAT_CODE0:start32
dogloop
Messages postés14Date d'inscriptiondimanche 28 mars 2010StatutMembreDernière intervention27 décembre 2010 23 avril 2010 à 14:47
Encore merci, mais j'ai l'impression d'être encore plus largé qu'avant ...
concernant la construction de ta GDT :
1 er descripteur : tout à 0, par convention requise par le processeur
ça OK
2 ème descripteur :
- tu mets la base à 65535
- le dw DESC_C32+0x0F00 renseigne les bits (P, DPL, type, etc ... )
11001111 10011010
0 donc le segment n'a jamais été accédé auparavant
101 donc segment no-conforming avec possibilitée de lecture
1 ce bit indique qu'on a à faire à un segment de code
00 pleins priviléges
1 apparemment on le met à 1 pour ne pas utiliser la mémoire virtuelle (accès au disk ?)
1111 ???
0 bit disponible pour le programmeur
0 ?
1 granularité = 4096 octets
mais alors finalement je n'ai pas compris quelle limite tu as défini
et pourquoi avoir mis une base de 65535 ?
la base c'est bien l'adresse physique ? puisque je veux tout lire ça devrai être 0 ...