SOUCLASSEMENT SANS MODULE STANDARD

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 - 7 sept. 2006 à 06:28
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 - 24 juil. 2007 à 19:00
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/39467-souclassement-sans-module-standard

cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
24 juil. 2007 à 19:00
Cool je vais voir la maj chez toi
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
24 juil. 2007 à 11:32
j'ai ajouté un test (en mode IDE) qui s'assure que le code tourne (EbMode) et si on est en BreakPoint, on appelle la proc standard.
(ce code de test n'est pas greffé en mode compile)

au final, on peut debugger tranquille, et même presser le bouton STOP, sans que VB en crashes...

bref, ce que j'avais suggeré dans mon tout premier commentaire sur ta source.
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
24 juil. 2007 à 09:50
j'ai codé ce forward d'appel en C, puis j'ai modifié un tout petit peu le listing asm que m'a filé le compilateur de VS2005...

ça me donne donc 41 octets :

MovB Ofs, &H51 'push ecx
MovL Ofs, &H14244C8B 'mov ecx, DWORD PTR _lParam$[esp] (_lParam$=20)
MovL Ofs, &H1024548B 'mov edx, DWORD PTR _wParam$[esp] (_wParam$=16)
MovB Ofs, &H8D 'lea eax, DWORD PTR _RetValue$[esp+4] (_RetValue$=-4)
MovB Ofs, &H4
MovB Ofs, &H24
MovB Ofs, &H50 'push eax
MovL Ofs, &H1024448B 'mov eax, DWORD PTR _uMsg$[esp+4] (_uMsg$=12)
MovB Ofs, &H51 'push ecx
MovL Ofs, &H10244C8B 'mov ecx, DWORD PTR _hWnd$[esp+8] (_hWnd$=8)
MovB Ofs, &H52 'push edx
MovB Ofs, &H50 'push eax
MovB Ofs, &H51 'push ecx
MovB Ofs, &H68 'push 0x55555555
MovL Ofs, ObjPtr(x)
MovB Ofs, &HBA 'mov edx, 0x22222222
MovL Ofs, Ptr
MovB Ofs, &HFF 'call edx
MovB Ofs, &HD2
MovB Ofs, &H58 'pop eax
MovB Ofs, &HC2 'ret 16 ; 00000010H
MovB Ofs, &H10
MovB Ofs, &H0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
23 juil. 2007 à 22:32
ah... ouais, remarques, c'est assez logique...
enfin, j'étais content d'avoir (enfin) réussi a ce que ca plante pas :p => voir le coté positif ^^

ba, j'vais trouver autre chose...(où utiliser ton code :p)
là, j'appelais une fonction de mes objets (ISubClasser), donc j'ai pas a me soucier de l'emplacement de la procedure dans le code...
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
23 juil. 2007 à 19:37
La pile c'est le plus long ! Car c'est un acces memoire + une incrementation/decrementation de registre. Donc moins il y en as mieu on ce porte.

Cela dit comme disait le grand maitre cinquante : "il ne faut presumer de rien"

@+
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
23 juil. 2007 à 15:14
A voir avec les spécialistes de l'Asm... mais je pense que c'est plus rapide ainsi. Je ne passe que par la pile et les registres.

j'ai mis le nez dans la windowproc, (et après moultes crash, quelques heures passées sous IDA) :

MovB Ofs, &H55 ' PUSH EBP on sauvegarde EBP
MovB Ofs, &H5B ' POP EBX on fais avancer la pile
MovB Ofs, &H5D ' POP EBP on récupère l'adresse de retour
MovB Ofs, &H5A ' POP EDX on dépile ensuite les parametres... lParam
MovB Ofs, &H59 ' POP ECX wParam
MovB Ofs, &H58 ' POP EAX uMsg
MovB Ofs, &H5B ' POP EBX hWnd
MovB Ofs, &H55 ' PUSH EBP On replace l'adresse de retour
MovB Ofs, &H52 ' PUSH EDX Allocation sur la pile de la valeur de retour
MovB Ofs, &H54 ' PUSH ESP Le parametre RetValue de la méthode COM appelée sera placé sur la pile
MovB Ofs, &H8B ' MOV EBP, [ESP-0Ch] On recupère la valeur de EBP, placée temporairement dans la pile
MovB Ofs, &H6C '
MovB Ofs, &H24 '
MovB Ofs, &HF4 '
MovB Ofs, &H53 ' PUSH EBX On empile les paramètres... lParam
MovB Ofs, &H50 ' PUSH EAX wParam
MovB Ofs, &H51 ' PUSH ECX uMsg
MovB Ofs, &HBB ' MOV EBX, 22222222h Pointeur de la fonction à appeler
MovL Ofs, Ptr '
MovB Ofs, &H52 ' PUSH EDX hWnd
MovB Ofs, &H68 ' PUSH 55555555h ObjPtr de l'objet concerné
MovL Ofs, ObjPtr(Me) '
MovB Ofs, &HFF ' CALL EBX On effectue l'appel proprement dit
MovB Ofs, &HD3 '
MovB Ofs, &H58 ' POP EAX Et on récupère la valeur de retour
MovB Ofs, &HC3 ' RET Pas de parametre ici, ils ont d'ores et deja été dépilés

soient 32 octets de bytecode.
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
7 sept. 2006 à 13:10
Oui lol mais je voulais pas plus compliqué le truc :p
mais en effet il faut empiler l'adresse de l'objet apres tout les autres prametres. Comme c'est "après" ça ne pose pas trop de probleme un pop, deux push le tour est joué.

@+
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
7 sept. 2006 à 12:34
Pour les objets COM, c'est même :

Function X(ByRef Me As IUnkown, ByVal P1 As Long, ByRef RetVal As Long) As Long

me semble-t'il ^^
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
7 sept. 2006 à 12:29
En faites c'est "presque" ça Renfield :p

Les modules de classe et autres objet VB (form, control etc...) ne peuvent pas renvoyer de valeur telle qu'on les concois dans du code C ou Assembleur c'est a dire si l'on ecris Function X() As Long dans un module standard c'est EAX qui aura la valeur de retour mais pas dans un module de classe ou la c'est un HRESULT qui sera renvoyé comme cela est exposé dans la documentation COM. Hors vb permet tout de même le renvoi de valeur ?!? C'est ce principe que j'ai mi un peu de temps a comprendre en faite lorsque vous ecrivez ceci :

Function X(byval P1 as long) As Long

Cela devient en machine :

Function X(ByVal P1 As Long, ByRef RetVal As Long) As Long

La valeur retourné par la fonction est un code d'erreur COM
La vrais valeur de retour est dans RetVal qui prend le type de la fonction de depart en byref biensur ce qui nous oblige a créer une variable temporaire lors d'un appel. Donc le code transforme simplement l'appel a WindowProc classique par un appel a une WindowProc de type COM et le tour est joué.

On ne modifie en rien les objets crée par VB on crée juste une mini fonction ASM que windows va appelé a chaque WM_MESSAGE et qui va en quelques sorte traduire l'appel ! C'est tres simple et en même temps complexe. Le plus dure est de recuperer le bon pointeur de fonction car AddressOf n'est pas compatible avec les module de classe.

Pour cela vous trouverez dans les exemples un code encore tres simple qui permet de retrouver le bon pointeur en fonction du type d'objet hôte. Le tout est bien entendu modulable a souhait puisque l'on ce debarrasse une fois pour toute de ce maudit module trop trop trop rigide a mon gout.

Pour ce qui est de la restriction syntaxique Ren a encore raison si on place une autre routine public devant la windowproc elle perdra sa premiere place dans la VTable (ou table d'adressage) ce qui a pour consequence de tout fausser. On peux le faire a condition de changé l'index dans le code d'initialisation. Pour comprendre comparez les code Form,Class,Usercontrol

Voila pour les explications

B@nne prog
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
7 sept. 2006 à 12:04
On en apprend tout les jours.
Merci.
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
7 sept. 2006 à 11:57
Bouv, c'est parce que sinon, elle ne sera pas retrouvée.
les objets COm on un tableau (VTable) qui contient l'addresse des fonctions en mémoire

si on ajoute une fonction avant, par exemple, WindowProc sera dans la case suivante de la VTable, et tout sera faussé.

EB, ici, remplace 'simplement' le pointeur de fonction de la VTable, pour pointer vers un tableau contenant du Bytecode ASM. Ce faisant, c'est ce code qui est executé en lieu et place de la fonction WindowProc que tu vois.

en passant, ShareVB, clair, très bon bouquin ^^
ShareVB Messages postés 2676 Date d'inscription vendredi 28 juin 2002 Statut Membre Dernière intervention 13 janvier 2016 26
7 sept. 2006 à 11:49
salut à tous,

génial et chapeau bas... parce que même l'auteur de Avanced VB6 For Everyday Programs ne l'expose pas dans son bouquin...

Pour ceux qui voudrait en savoir plus sur le fonctionnement interne de VB6 et comprendre un peu plus ce merveilleux code :
http://www.vbfrance.com/tutoriaux/OBJETS-COM-VB_162.aspx
http://www.vbfrance.com/tutoriaux/OBJETS-LEGERS-CONCEPT-POUR-OPTIMISER-CLASSES-VB_173.aspx
http://www.vbfrance.com/tutoriaux/APPELER-POINTEURS-FONCTIONS-DEPUIS-VB_176.aspx
http://www.vbfrance.com/tutoriaux/METTRE-ASSEMBLEUR-DANS-VB-FONCTIONNE-DANS-IDE-COMPILE_186.aspx

et accessoirement :
http://www.vbfrance.com/tutoriaux/BIBLIOTHEQUES-TYPES-TYPELIB-TLB-LANGAGE-ODL_165.aspx
http://www.vbfrance.com/tutoriaux/FOURNIR-FONCTIONS-CALLBACKS-AUTRES-STDCALL_187.aspx

ou pour plus de lisibilité, les articles sont aussi là :
http://www.sharevb.net/-VB-.html

et enfin, le bouquin "Advanced Visual Basic 6"

désolé pour la pub...

ShareVB
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
7 sept. 2006 à 11:41
Bon, j'ai pense avoir pigé l'essentiel (dans le principe).
J'ai juste une question : pourquoi la fonction 'WindowProc' ne peut-elle pas être déplacée ?
cs_moustachu Messages postés 1079 Date d'inscription jeudi 14 novembre 2002 Statut Membre Dernière intervention 1 janvier 2012
7 sept. 2006 à 08:40
Ca démèresachire....

Très bien organisé. Pour l'optimiser, je ne sais pas, je vais d'abord essayé de le comprendre ;o)

++
Moustachu
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
7 sept. 2006 à 06:28
Sympa, comme toujours ^^
bel exemple d'injection ASM, une fois de plus ^^

coté IDE, j'ai pu constater dans mes propres codes que l'API EbMode (vba6.dll) permettait de bien stabiliser la chose...
Elle renvoie 1 si tu es en mode execution, et indique, dans le cas contraire un BreakPoint.
Si tel est le cas (BP), tu pourrais alors ne pas invoquer (test dans le code ASM) la WindowProc de l'utilisateur, qu'en pennses-tu ?
Rejoignez-nous