APPEL DE POINTEUR DE FONCTIONS - API SANS LES DECLARER

e_NeX Messages postés 104 Date d'inscription mardi 9 mars 2004 Statut Membre Dernière intervention 30 novembre 2009 - 25 nov. 2009 à 20:14
cs_andrebernard Messages postés 404 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 4 septembre 2013 - 5 oct. 2012 à 14:18
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/50897-appel-de-pointeur-de-fonctions-api-sans-les-declarer

cs_andrebernard Messages postés 404 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 4 septembre 2013 1
5 oct. 2012 à 14:18
Bonjour Renfield,

J'ai besoin de changer le nom de la DLL dynamiquement
Apparement pas possible a faire avec VB6, du fait que DECLARE ne le permet pas :-(

Donc ce code pourrait etre une alternative a mon probleme
Peut on appeller une DLL standard perso, lui envoyer une structure et recevoir un pointeur de structure en retour ??
cs_DarkVader Messages postés 51 Date d'inscription samedi 21 octobre 2000 Statut Membre Dernière intervention 10 octobre 2011
5 août 2011 à 15:01
Bravo, j'en étais resté au code d'Ebart.
Un idée de perfectionnement, plutôt qu'Invoke0-4
il serait intéressant d'avoir des fonctions retournant des types autre que long
(Currency , String etc.) 8)
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
2 juil. 2010 à 14:21
En fait, on va se servir d'un objet ActiveX pour faire exécuter du code assembleur.
Pour cela, on réserve une plage mémoire de 512 octets qui a l'autorisation de stocker et exécuter du code ; pour éviter que le DEP ne se manifeste.

Quand on considère un objet ActiveX, le pointeur renvoyant vers celui-ci (ObjPtr) est en fait l'adresse vers la VTable de cet objet.
La VTable est un simple tableau de Long. Il s'agit de l'adresse des différentes méthodes de l'objet, dans l'ordre de déclaration de celles-ci ; en prenant en compte IUnknown et IDispatch (qui cumulent 7 méthodes à elles deux).
7 * 4 => 0x1C

La première méthode de notre classe est Invoke.
L'adresse de cette fonction se trouve donc a l'offset 0x1C de la VTable.

Ici:
GetMem4 ObjPtr(Me), pFirstVTEntry

On récupère le début de la VTable.

Et ici:
PutMem4 pFirstVTEntry + &H1C& + i * 4, pCode

On remplace l'adresse correspondante a Invoke puis InvokeArr dans la VTable par l'adresse mémoire voulue ; où on stocke les opCode assembleurs de notre choix.

De façon identique, pour Invoke0-4 :
PutMem4 pFirstVTEntry + &H24& + 4 * i, pCode

Désormais, la VTable de notre objet est hackée. Lorsque nous appellerons nos méthodes, c'est le code assembleur qui sera exécuté.

VB utilise StdCall comme convention d'appel. Dans le cadre de la technologie COM, nous avons droit à quelques subtilités supplémentaires.

Lors de l'appel, on trouve sur la pile :
- L'adresse de l'instruction à exécuter à la sortie de la procédure +0x4
- Le pointeur vers l'objet en cours (Me), automatiquement ajouté par VB +0x8
- Le premier paramètre +0xC
- Le second paramètre
- ...
- Un pointeur vers la variable qui recevra la valeur de retour s'il y a lieu.

Normalement, avec StdCall, le code retour des procédures est transmis via eax. Ici, eax sert à renvoyer le HRESULT. S_OK (0) si tout c'est bien passé, par exemple.

Decryptons un peu l'assembleur. Si on prend le cas de Invoke0 :

push ebp => Sauvegarde de ebp
mov ebp, esp => ebp permettra de 'figer' le pointeur de pile esp
mov ecx, [ebp+0Ch] => ecx contient le 1er param: l'adresse du code à lancer
call ecx => exécution du code assembleur indiqué par l’user
mov edx, [ebp+10h] => edx pointe l’adresse de la valeur de retour
mov [edx], eax => stocke la valeur retournée par la function dans [edx]
xor eax, eax => mise à 0 de eax : HRESULT = S_OK
pop ebp => restauration de ebp
ret => on quitte la procédure

Finalement assez simple, compte tenu de la pile que nous avons pour Invoke0

Si on corse un peu la chose, pour Invoke1 :

push ebp => Sauvegarde de ebp
mov ebp, esp => ebp permettra de 'figer' le pointeur de pile esp
mov eax, [ebp+10h] => eax est 2nd param de Invoke1 : 1er param du code perso
push eax => on place ce parametre sur la pile
mov ecx, [ebp+0Ch] => ecx contient le 1er param: l'adresse du code à lancer
call ecx => exécution du code assembleur indiqué par l’user
mov edx, [ebp+14h] => edx pointe l’adresse de la valeur de retour
mov [edx], eax => stocke la valeur retournée par la function dans [edx]
xor eax, eax => mise à 0 de eax : HRESULT = S_OK
pop ebp => restauration de ebp
ret => on quitte la procédure

Assez peu de changement au final.

Pour Invoke2-4, on reprend les même et on recommence. Gaffe au fait que l’on empile les paramètres du dernier au premier.

Invoke et InvokeArr sont assez similaire (une seule instruction les différencie). Au début de l’appel, leur pile ressemble à cela :
- L'adresse de l'instruction à exécuter à la sortie de la procédure +0x4
- Le pointeur vers l'objet en cours (Me), automatiquement ajouté par VB +0x8

- L’adresse du SafeArray qui stocke nos paramètres dans le cas de Invoke
- L’adresse d’un VARIANT contenant un SafeArray qui stocke nos paramètres dans le cas de InvokeArr

- Un pointeur vers la variable qui recevra la valeur de retour s'il y a lieu.

Assez proches, donc.

push ebp => Sauvegarde de ebp
mov ebp, esp => ebp permettra de 'figer' le pointeur de pile esp
push esi => Sauvegarde esi

mov esi, [ebp+10h] => 1er paramètre du code a lancer
mov eax, [esi] => eax pointe vers mon SafeArray (tableau VB6)
mov ecx, [eax+10h] => ecx est le nombre d’éléments (voir type SAFEARRAY)
cmp ecx, [eax+14h] => comparaison ecx avec l’indice min du tableau
jle LBL_CALL (+38) => pas de paramètre, on saute les 38 octets suivants

mov edx, ecx => edx va etre un offset mémoire pour les paramètres
sub edx, 1 => -1 car on pars de 0
shl edx, 4 => on viens de faire: edx = (ecx-1) * 16

LBL_NEXT_ARG :
mov eax, [eax+0Ch] => eax va pointer vers les données du SafeArray
add eax, edx => on ajoute notre offset, eax pointe le dernier param
push [eax] => on place la valeur sur la pile, pour l’appel

mov eax, [esi] => on replace eax en tête du SafeArray
sub ecx, 1 => on vient de traiter ce paramètre
sub edx, 10h => on décale l’offset pour pointer sur le param précédent
cmp ecx, [eax+14h] => comparaison ecx avec l’indice min du tableau
jg LBL_NEXT_ARG => on boucle tant qu’il reste des paramètres a traiter

LBL_CALL:
call [ebp+0Ch] => on appelle le code perso
mov edx, [ebp+14h] => edx pointe l’adresse de la valeur de retour
mov [edx], eax => stocke la valeur retournée par la function dans [edx]
xor eax, eax => mise à 0 de eax : HRESULT = S_OK
pop ebp => restauration de ebp
ret => on quitte la procédure

pop esi => restauration de esi
pop ebp => restauration de ebp
ret => on quitte la procédure

La seule différence pour InvokeArr se situe dans la récupération de l’adresse du SafeArray (esi).
Pour Invoke, le second parametre est directement notre SafeArray :
mov esi, [ebp+10h]

Pour InvokeArr, nous avons là l’adresse d’un VARIANT de type Tableau de Variant (0x200C). Un variant se décompose ainsi :
- Type (4 octets)
- Donnée réservée 1 (2 octets)
- Donnée réservée 2 (2 octets)
- Donnée du Variant (notre SafeArray)

Du coup, une fois que nous avons en esi l’adresse du variant, un simple :
lea esi, [esi+8h]
Permet de placer en esi l’adresse pointée par esi+8h... notre SafeArray.

Ainsi, la suite du code exploite bien via esi notre SafeArray

Voilà, j’espère que cela vous aidera à bien comprendre ce code, les conventions d’appel et l’assembleur dans une moindre mesure.
sebastienrodriguez Messages postés 9 Date d'inscription jeudi 18 octobre 2007 Statut Membre Dernière intervention 2 juillet 2010
2 juil. 2010 à 13:17
Bon, ben Renfield, c'est vrai qu'au départ je trouvais que le code manquait de commentaires.
C'est vrai que depuis, y'a pas eu trop de rajout de commentaires.
N'empêche je mets quand même 10 parce que tu t'impliques dans les posts de tes lecteurs à un point qu'aucun commentaire ne saura jamais atteindre !

Merci beaucoup pour tout !
(on se recoisera sans doute... je poursuite ma quête: conquérir l'assembleur ! :-) )
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
1 juil. 2010 à 10:45
[mis a jour]
le Variant de InvokeArr est maintenant en tant que ByRef. J'ai corrigé le code assembleur de InvokeArr, ca va mieux, pas de crash et code retour bien récupéré...
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
30 juin 2010 à 10:01
le code ASM est placé dans une zone mémoire reservée en mentionnant qu'elle contiendra du code executable. Du coup, j'étais étonné de te voir encore confronté à des DEPs. C'etait valable pour la première mouture du code, soit.

Pour le crash de VB, j'avoue n'avoir que peu testé mon code...

Pour le LoadLibrary et FreeLibrary, ils ne sont pas directement présents.
j'utilise l'API DllFunctionCall. C'est ce qu'utilise VB6 lorsque tu fais tes appels API de manière classique.
sebastienrodriguez Messages postés 9 Date d'inscription jeudi 18 octobre 2007 Statut Membre Dernière intervention 2 juillet 2010
30 juin 2010 à 09:07
Info du jour,

Aprés correction du ~t - 1~ (arg, t'avais encore raison! ;-) ), tout fonctionne (à peu prés) correctement (pour le CreateProcessWithLogon):
- La commande passée en param à CreateProcessWithLogon est éxécutée
- DEP ne crie plus (j'ai enfin pu mettre le paramétre DEP OptOut. Désolé à tous "ceux qui voulaient faire planter mon PC")

Par contre, j'ai le message "Il y a eu une erreur inattendue, voulez-vous envoyer un rapport d'erreur à Microsoft..."

Au deboggage, il semble que VB (en tous cas en mode debug d'ActiveX) ne sorte jamais de InvokeArr :-/

Enfin, j'vais essayer de répondre (aussi) à tes questions:
- je ne souhaite pas déclarer les API parce que je veux profiter pleinement de l'extensibilité qu'amènent les chargements dynamiques de DLL et la technologie ActiveX. Du coup l'ActiveX obtenu permet (si besoin, par exemple) d'étendre un éventuel langage nativement incapable de faire des appels aux API ;-)
- Les paramètres devaient déjà être "long" lors de utilisation de CallWindowProcA. C'est juste qu'en commentant "à la va vite", j'ai squizzé cette ancienne conversion qui pourtant reste nécessaire ! :-)

J'vais essayer de trouver la raison qui fait que j'ai ce message Microsoft...

Ce que j'aimerai bien savoir maintenant c'est
- est-ce que LoadLibrary et FreeLibrary sont présent dans ton code assembleur ? Est-ce qu'au contraire tout fonctionne bien que parce que mes tests utilisent des fonctions d'API (déjà chargées par VB; kernel32, User32, AdvApi32) ? Est-ce que ça fonctionnerait aussi pour appeler une fonction de maBibliothequeBidule.dll (faite en C++ et présente près de mon exécutable) ?
- Comment on fait pour changer la note qu'on a déjà attribué à un post ?
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
29 juin 2010 à 19:49
t = UBound(FuncParams) indice max du tableau
du coup, je pige pas ton

To t - 1 ...

Pourquoi ne pas declarer les Apis auxquelles tu souhaites acceder ?
Il existe certaines raisons de le faire, hein ^^

Pour ton Array() faudrait que je checkes le UBound dans le SafeArray... a voir si on y trouve pas -1 ...

apres a voir pour tes parametres, je m'attend a des Longs, comme parametres... donc StrPtr au lieu de String, etc.
sebastienrodriguez Messages postés 9 Date d'inscription jeudi 18 octobre 2007 Statut Membre Dernière intervention 2 juillet 2010
29 juin 2010 à 19:22
le dernier de mes posts pour aujourd'hui:
ça marche mieux comme ça
' remplacer
' p(i) = FuncParams(i) ' par
p(i) = clng(FuncParams(i) ) ' boulet que je suis !!!

:-)
sebastienrodriguez Messages postés 9 Date d'inscription jeudi 18 octobre 2007 Statut Membre Dernière intervention 2 juillet 2010
29 juin 2010 à 19:15
C'est pas du harcellement... C'est à cause (ou grâce, à voir) aux tests de non regression.

J'ai, grâce aux armes que tu m'as données, pallier au dernier pb. En fait, si on n'a pas de parametre, autant passer par Invoke0 (encore que, ç'aurait été bien que InvokeArr fonctionne dans tous les cas).
ça se résume à quelque chose comme ça dans ma fonction intermédiaire entre ma DLL et ta classe:
Dim a As Long ' [a]dresse de la fonction dans le module API chargé
...
Dim p As Variant: p = Array() ' [p]arametres
Dim i As Long ' [i]ndice de parcours du tableau de parametres
Dim t As Long ' [t]aille du tableau de parametres
t = UBound(FuncParams) ' recuperation de la taille du tableau de parametres "FuncParams"
If t > -1 Then
ReDim p(t - 1)
For i = 0 To t - 1
p(i) = FuncParams(i)
Next
simplifiedCallApiByName = .InvokeArr(a, p)
Else
simplifiedCallApiByName = .Invoke0(a)
End If
...

Du coup, mes tests de non regression ont pu passer l'essai de Kernel32.GetTickCount. Mais, maintenant, ils bloquent sur ADVAPI32.CreateProcessWithLogonW (10 paramétres)
J'essairai d'intégrer l'appel à ton jeu de test, pour voir, si ça vient de mon implémentation, ou de quelque chose à coder en plus dans la classe CDelegate

A une prochaine (j'vais essayer d'être moins "à bloc" sur cette source...)
;-)
sebastienrodriguez Messages postés 9 Date d'inscription jeudi 18 octobre 2007 Statut Membre Dernière intervention 2 juillet 2010
29 juin 2010 à 18:36
Ce genre d'appel semble planter:
Private Sub Command2_Click()
With New CDelegate
MsgBox .InvokeArr(.API("Kernel32", "GetTickCount"), Array())
End With
End Sub

Je pense que c'est la faute au tableau vide (car ç'aurait pu être le retour. Mais sans le msgbox, la fonction plante aussi)

Voili...
sebastienrodriguez Messages postés 9 Date d'inscription jeudi 18 octobre 2007 Statut Membre Dernière intervention 2 juillet 2010
29 juin 2010 à 18:08
lol. J'étais tellement pris dans mes lectures que j'avais pas vu ton dernier post !!!
Quand tu dis "fait", ca veut même dire que t'as mis à jour le download !!!...

J'ai intégré la classe à mon ancien projet (celui qui plante à cause de DEP)
J'ai remplacé les appels aux API LoadLibrary, GetProcAddress et CallWindowProc par les appels aux méthode api et InvokeArr de la classe CDelegate et, là ...
me*de: ça plante... même avec (info pour ceux qui voudraient faire planter mon PC) ma config actuelle, DEP "AlwaysOff"

Bon, je débugg... et reviens !

Merci beaucoup !
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
29 juin 2010 à 17:26
trouves toi IDA, te permettra de faire du pas a pas.

concernant le code ASM, fournis moi une adresse mail par MP, je t'enverrai mon p'tit utilitaire pour composer les OPCode
sebastienrodriguez Messages postés 9 Date d'inscription jeudi 18 octobre 2007 Statut Membre Dernière intervention 2 juillet 2010
29 juin 2010 à 17:08
Pour essayer de minimiser mon apparant aspect de "boulé", j'ai cherché quelques tutos.
Il y en a sur Codes-Sources. Il y en a de plus ou moins bien, surtout dans la forme. Les mieux que j'ai trouvé sur Codes-Sources, sont ceux de ShareVB. Même s'ils sont encore mieux en pdf, sur le propre site de ShareVB (Cher ShareVB, Il y a un souci de présentation sur les tutos posés sur Codes-Sources, lorsqu'on les lit avec IE - c'est mieux avec FireFox).

Mais, je pense avoir trouvé celui qu'il me fallait. Il est là:
ftp://ftp-developpez.com/asm/cours/noteworthy/pas-a-pas-vers-l-assembleur-par-lord-noteworthy.pdf

Le but de ce post est donc:
- de faciliter la vie des gens qui cherche un tuto ASM
- t'informer que je ne suis pas en train de tout attendre de toi. Au contraire mon silence signifie que je suis en train de m'instruire (et la durée varie à la fois à cause du nombre de pages et de ma capactité à les lire, les retenir, les apprendre... Bref, ça peut être long !)

@ +
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
29 juin 2010 à 16:56
Fait.
Assez peu de changement au final.

PutMem4 pFirstVTEntry + &H20& + 4 * i, pCode
remplacé par
PutMem4 pFirstVTEntry + &H24& + 4 * i, pCode

pour pouvoir intercaller InvokeArr entre Invoke et Invoke0

Code de invoke dupliqué...
On enregistre dans la VTable le hack de InvokeArr (en reprenant la place nouvellement liberée)
PutMem4 pFirstVTEntry + &H20&, pCode

ensuite, là ou le second parametre effectif (hormis l'adresse de retour et le pointeur this) était un pointeur vers notre tableau de parametre :

'mov esi, [ebp+10h] => Récupération du pointeur vers le tableau

on a maintenant un Variant, dont le type est tableau de variant : 0x200C
et les données sont notre pointeur vers le SafeArray.
+ 3 x 2 word reservés (voir structure du type VARIANT) on arrive donc à 18 :

'mov esi, ebp
'add esi, 18h

Tout le reste est identique, on place en eax l'adresse stockée en esi : l'adresse vers notre SafeArray
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
29 juin 2010 à 14:20
IDA permet ce pas a pas, et une jolie presentation...

pour le code, j'ai pris un compilo externe, JWASM.EXE

je code en ASM, je ne fais pas en VB6 pour en retirer du code ASM.
pour
mov eax, [esi]
j'obtiens 8B06

pour
mov eax, [esi+4]
8B4604

suffit alors de grouper les instructions pour les ranger en octets.

le tout est de bien cerner la methode de passage des parametre, la presence du pointeur 'this' ajouté en tête des parametres lors de l'appel a une methode COM, par exemple.

je vois plus tard ce que je peux faire pour toi.
ce +4 n'est que ma réponse rapide a ce probleme, j'ai pas testé, etc.

néanmoins, pas simple de te detailler la chose, sans tracer de graph pas a pas,
faut juste cerner cette logique.

on extraies du SAFEARRAY le nombre d'arguments passés dans le tableau au Invoke, ainsi que le pointeur aux données. Ensuite, on push chaque parametre pour simplement faire un call au pointeur de la fonction.
sebastienrodriguez Messages postés 9 Date d'inscription jeudi 18 octobre 2007 Statut Membre Dernière intervention 2 juillet 2010
29 juin 2010 à 11:41
Bonjour,

Bon, j'ai cherché quelques débuggers ASM: j'ai trouvé une liste là: http://www.asmfr.com/forum/sujet-DESASSEMBLEUR_439606.aspx
J'ai, en dépit de ton conseil, installé PEExplorer (qui semble ne pas être limité, comme semble l'être IDA dans sa version d'évaluation)

J'ai essayé de décompiler une DLL (ActiveX VB). Cette DLL faisait (entre autre) un appel à CallWindowProcA (cette DLL est bloquée par DEP car l'adresse pointée par cette fonction semblent se trouver dans une zone mémoire réservée aux "données").
Pas d'bol, la source (assembleur) ne m'est pas trés parlante, je sais même pas s'il est possible de faire du "pas à pas" (comme je sais le faire, au besoin, sous VB).

Bref, je patauge un peu, et rien que le remplacement que tu proposes, je sais pas le faire :-(
Comment traduire "mov eax, [esi+4]" en "putMem4 pCode,{valeur Hexa}" ? (d'autant que selon les commentaires VB, une instruction PutMem, peut traduire plusieurs instructions assembleur :-/ )

Plus généralement, comment fais-tu pour isoler dans le code ASM du décompilé, les instructions qui t'interressent ? Comment sais-tu vers quelles instructions (plus ou moins) VB les traduires ? (le "plus ou moins" était là pour montrer que je parle de ces instructions inscrites parmis le code VB, mais qui, amenées par alias de DLL, ne sont pas natives au VB. Il s'agit de PutMem4, etc ...)

Est-ce que tu, ou un lecteur du post, connaitriez un tutoriel pour expliquer tout ça, un peu pragmatiquement et "pas à pas" ?

Merci encore... Et,
Merci déjà !
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
28 juin 2010 à 22:31
je prendrai du temps demain pour te coder ca si tu le souhaites...
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
28 juin 2010 à 22:22
Pour ce qui est de l'asm, le mieux est de charger IDA ou tout autre debugger. Une feuille de papier peut aider egalement ^^

"Actuellement"
ParamArray => Tableau de Variant

tu souhaites lui transmettre un Variant
un Variant, c'est deux Long.
le type de contenu et la donnee.

Actuellement, les arguments sont extrais du tableau, pour les pusher dans la pile.
mov ecx, [eax+10h]
ecx contiendra le nombre d'arguments.

dans ton cas... sans avoir teste...
je remplacerais
mov esi, [ebp+10h]
mov eax, [esi]

par

mov esi, [ebp+10h]
mov eax, [esi+4]

pour pointer sur la partie donnees du Variant
sebastienrodriguez Messages postés 9 Date d'inscription jeudi 18 octobre 2007 Statut Membre Dernière intervention 2 juillet 2010
28 juin 2010 à 18:41
Super code; Super cool qui révèle un niveau en VB et Assembleur qui laissent bouche bée !
Je ne mets cependant que 8/10 parce que les commentaires du code assembleur ne me semble pas assez clairs... (m'obligeant à ce post d'ailleurs :-D )

J'ai du coup une petite question: si on veut utiliser Invoke mais que le tableau de parametres soit un Variant initialisé, à l'appel, avec array() au lieu d'un paramArray, qu'est ce qu'il faut changer ? J'ai bien essayé de ne changer que la déclaration d'Invoke. Le résultat n'est pas concluant. Je pense donc, que cette nouvelle signature devrait induire aussi quelques modifs dans le code assembleur (dans class_initialize); et là, ben j'suis (malheureusement) pas assez balaise dans ce langage là :-/

Merci

PS:
L'appel que je cherche à obtenir donnerait un code comme ça:

With New CDelegate
.Invoke .API("User32", "MessageBoxW"), _
array( 0&, StrPtr(ChrW(&HFEBE&) & ChrW(&HFECF&)), StrPtr("MsgBox supportant l'affichage de l'Unicode"), vbQuestion Or vbYesNoCancel)
r = .Invoke (.API("Kernel32", "GetTickCount"), _
array())
End With

ça peut servir lorsqu'une fonction d'un niveau suppérieur fait appel à Invoke, et que cette fonction reçoit elle même les paramètres à passer à Invoke dans un ParamArray.
cs_JLN Messages postés 371 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 17 juin 2013
4 mars 2010 à 10:59
J'avais oublié la note.
cs_JLN Messages postés 371 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 17 juin 2013
4 mars 2010 à 10:57
Bonjour à tous,
Non VB n'est pas mort !
De mieux en mieux, de l'assembleur dans VB, etonnant non !

Bravo Renfield tu me surprendras toujours...
(10/10)
@+ JLN
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
10 déc. 2009 à 21:12
en fait on passe en premier parametre de Inkke & co l'adresse de la fonction a appeller.

la fonction API permet de récuperer facilement cette addresse :

API("User32", "MessageBoxA")

concernant le bytecode que tu me montres, c'est un 'bête' shift right => division par 2, rien de trancendant...
juste un exemple
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
10 déc. 2009 à 17:54
bonjour,
de l'asm en VB6 ;) le genre de code que j'adore.

une question toute fois, comment spécifie-t-on les api que l'on souhaiter apeler ? le fichier dll utilisé ? celui-ci ne doit-il pas être lancé ? (service démarré ?)

les lignes suivants du codes doivent être la clée, mais elles mériteraient êtres commentés et les valeurs mises dans des constantes avec un nom explicite
"
xbCode(0) = &H424448B
xbCode(1) = &H9090E8D1
xbCode(2) = &H900004C2
"

si ces chiffres sont bien les adresses de démarrage des fonctions, comment les obtenir ?

encore bravo pour cette Nième source bien faite. ;)
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
8 déc. 2009 à 22:36
Pour le DEP : VirtualAlloc ou VirtualProtect, même combat !

Je préférais quand même l'ancienne version, moins de ligne, plus simple.
L'histoire des variants c'était plus une remarque générale sachant que de
toute façon on ne peut pas faire mieux et aussi simple. Quoi que... si on
se donne du mal :)

Par contre kit a jouer avec les variants autant proposer une panel complet d'api
qui ne renvoi pas qu'un long. enfin c'est une idée.
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
8 déc. 2009 à 11:13
bon, ben, les cinq méthodes décrites au dessus ajoutées.
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
8 déc. 2009 à 09:29
Bien que ça ne soit pas extremement grave

Ce que je pourrais faire pour endiguer ce phénomène... c'est de placer 5 méthodes supplémentaires.
0 à 4 arguments (Long) renvoyant un Long. Ca permettrait d'avoir une méthode plus ou moins passe partout, et d'avoir des choses plus spécifiques.

Dans mon code, je m'en sert pour appeler une fonction de quelques dll, au chargement de mon appli. Ce n'est pas la mer a boire donc que d'avoir ces Variant. Je veux dire: c'est peut etre un poil plus lent (et lourd sur la stack) que de passer directement le bon nombre d'arguments directs, mais bon, c'est pas le Pérou non plus...

A utiliser hors des boucles critiques cela dit ^^

à voir, donc (j'ajoutes ces 5 méthodes dans la matinée).

mon vb6.exe était dans les bonnes grâces du DEP (exception) mais tous les exe compilés avec ma classe posaient le même soucis que ceux utilisant la tienne. Pour cette raison que je fais un VirtualAlloc plutot que de jouer avec un tableau de Byte. Depuis, plus de souci.
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
8 déc. 2009 à 09:16
Tout claquer dans du variant c'est pas tip/top mais bon c'est une bonne fonction pour un script excel.

Ahaha je rigole on sent que c'est soigné, mais quand même du variant :)
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
26 nov. 2009 à 16:39
"expert"
cs_Alain Proviste Messages postés 908 Date d'inscription jeudi 26 juillet 2001 Statut Modérateur Dernière intervention 1 février 2015 2
26 nov. 2009 à 12:02
c'est le niveau NCIS
cs_pacadebord Messages postés 113 Date d'inscription lundi 31 mars 2003 Statut Membre Dernière intervention 19 décembre 2011 2
26 nov. 2009 à 11:51
C'est quoi déjà le niveau après "initié" ?
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
26 nov. 2009 à 10:05
A noter que l'utilisation directe de code compilé (exemple de la division)
lève une erreur DEP quand on compile...

je bosse a améliorer ce point. Il suffit de faire un VirtualAlloc plutot que jouer avec un tableau de Byte. Ainsi, l'espace mémoire créé a le droit d'etre executé.
e_NeX Messages postés 104 Date d'inscription mardi 9 mars 2004 Statut Membre Dernière intervention 30 novembre 2009
25 nov. 2009 à 20:14
tu sais quoi?

j'y comprends pas grand chose mais je trouve ce code sexy lol!