Déploiement de fichiers binaires embarqués en VBScript
Date de publication : 6 octobre 2010
Par
omen999 (Contributions d'omen999)
Cet exemple de déploiement de la DLL DynamicWrapperX embarquée illustre
et complète la première partie de mon
article
concernant l'utilisation des composants ActiveX sans inscription dans la base de registre.
Vous pouvez également poser vos questions et laisser vos commentaires et suggestions sur le forum :
Commentez
1. Présentation de DeployBin
2. Analyse
3. Le script VBS
4. Lien
5. Remerciements
1. Présentation de DeployBin
La première partie de l'article précité fournissait un exemple (section 3.3) illustrant
la façon d'appeler, à partir de VBScript, une DLL en évitant toute intervention préalable sur l'ordinateur
concerné. Cette solution avait toutefois l'inconvénient de faire intervenir trois fichiers supplémentaires,
en complément du script lui-même, le fichier batch hello.bat ainsi que deux fichiers binaires :
wscript.exe et dynwrapx.dll.
Il était donc tentant de rechercher une solution plus compacte, qui réunirait au sein d'un même fichier script,
le code proprement dit ainsi que les deux binaires cités plus haut. Cette solution aurait en outre l'avantage
de rendre inutile le fichier batch.
Inclure un fichier binaire dans un fichier script suppose de résoudre deux difficultés : la première est le choix
du format de stockage qui doit être compatible avec celui du script hôte, la seconde, corollaire de la précédente,
est de retenir la routine de décodage et de sauvegarde la plus performante possible tout en lui conservant une grande
polyvalence. Cette inclusion a toutefois un prix : la taille minimale du script le plus simple sera de l'ordre
de 225 ko et le temps de démarrage en cas de création des binaires sera allongé de deux à trois secondes.
Afin de faciliter la compréhension du code, vous trouverez ci-dessous son analyse succincte.
 |
L'exécutable wscript.exe correspond à la version 5.7 et la DLL dynwrapx.dll à la version 1.0. Vous
noterez que ces fichiers incorporent une ressource manifest SxS grâce à l'utilitaire MS mt.exe dont l'usage
sera évoqué dans la deuxième partie de l'article consacré à ce sujet.
|
 |
Pour des raisons d'encombrement, le code des fichiers binaires n'a pas été reproduit dans le script ci-dessous mais
il est présent dans l'exemplaire téléchargeable dont le lien se trouve à la section 4.
|
2. Analyse
Les scripts VBS sont des fichiers au format texte et qui, à ce titre, ne peuvent contenir sans encodage préalable
des données binaires brutes dont certaines valeurs sont incompatibles avec ce format. Ce problème, aussi vieux que
l'informatique ou presque, a donné naissance à de nombreux algorithmes dont le plus répandu est le Base64.
Ce n'est pas le plus performant, particulièrement en termes d'encombrement (+33%), mais il est disponible dans des
composants très souvent présents sur les postes de travail Windows et il répond ainsi au critère de polyvalence.
Ainsi, le script définira deux constantes imgWScript et imgDynWrapX qui contiendront les deux
fichiers binaires qui auront été préalablement encodés en Base64 par un outil quelconque.
Pour garantir la bonne exécution de notre script quelque soit le contexte de l'ordinateur, nous devons assurer
l'instanciation de l'objet wrapper exposé par le composant DynamicWrapperX. La fonction Initialize
a pour seul objet de garantir cette instanciation et de renvoyer la valeur True lorsque celle-ci est effective.
À l'appel de la fonction
Initialize deux cas de figure peuvent se présenter :
- la DLL est déjà enregistrée dans la BDR, l'instanciation est immédiate et la fonction renvoie
True ;
- la DLL n'est pas enregistrée, il faut donc vérifier l'existence des fichiers binaires sur le disque et, le cas échéant, les
générer à partir des données embarquées. VBScript n'a pas d'accès natif au système de fichiers
et doit s'appuyer sur des composants COM externes.
DeployBin essaie d'utiliser en priorité l'objet
ADO.Stream
et seulement à défaut l'objet
FileSystem qui peut sous
certaines réserves générer des fichiers binaires.
L'absence simultanée de ces deux objets entraine l'affichage d'un message d'échec.
Si l'un au moins des fichiers binaires est absent, DeployBin teste la présence de l'objet Microsoft.XMLDOM.
Ce composant est très souvent installé et contient une fonction de décodage beaucoup plus performante que la fonction script
B64ToBin utilisée à défaut.
L'existence des fichiers binaires étant désormais acquise, il convient maintenant de relancer le script dans un contexte
d'exécution capable de reconnaitre l'objet wrapper que nous souhaitons mettre en œuvre. Il suffit de demander au script
de se relancer dans un nouveau processus à partir de son emplacement courant afin que l'hôte wscript.exe généré en
assure l'exécution.
La bonne exécution de votre script est désormais garantie quel que soit son environnement (ou presque).
3. Le script VBS
Option Explicit
Const _
MB_ICONWARNING = &H30, _
MB_YESNO = &H4
Dim _
oWrap, _
iRep
Function Initialize
Const _
GWL_HINSTANCE = -6, _
adTypeBinary = 1, _
adTypeText = 2
Dim _
oStream, _
oShell, _
oFso, _
oXml, _
oElm
On Error Resume Next
Set oWrap = CreateObject("DynamicWrapperX")
If oWrap Is Nothing Then
Set oStream = CreateObject("ADODB.Stream")
If oStream Is Nothing Then
Set oFso=CreateObject("Scripting.FileSystemObject")
If oFso Is Nothing Then
MsgBox "Le composant DynamicWrapperX indispensable au bon fonctionnement du script est absent." & Chr(13) & _
"Veuillez procéder à son enregistrement avant de continuer.",vbCritical,"Erreur DeployBin 1.0"
Exit Function
Else
If Not oFso.FileExists("dynwrapx.dll") Then
Set oStream = oFso.CreateTextFile("dynwrapx.dll")
B64ToBin imgDynWrapX,oStream,False
oStream.Close
End If
If Not oFso.FileExists("wscript.exe") Then
Set oStream = oFso.CreateTextFile("wscript.exe",True)
B64ToBin imgWScript,oStream,False
End If
End If
Else
oStream.Open
Set oXml = CreateObject("Microsoft.XMLDOM")
If oXml Is Nothing Then
oStream.Type = adTypeText
oStream.CharSet = "Windows-1252"
Else
oStream.Type = adTypeBinary
Set oElm = oXml.createElement("tmp")
oElm.DataType = "bin.base64"
End If
oStream.LoadFromFile "dynwrapx.dll"
If oStream.Size = 0 Then
If oXml Is Nothing Then
B64ToBin imgDynWrapX,oStream,True
Else
oElm.Text = imgDynWrapX
oStream.Write oElm.NodeTypedValue
End If
oStream.SaveToFile "dynwrapx.dll",2
End If
oStream.Position = 0
oStream.LoadFromFile "wscript.exe"
If oStream.Size < 100000 Then
If oXml Is Nothing Then
B64ToBin imgWScript,oStream,True
Else
oElm.Text = imgWScript
oStream.Write oElm.NodeTypedValue
End If
oStream.SaveToFile "wscript.exe",2
End If
End If
oStream.Close
Set oStream = Nothing
Set oShell = CreateObject("WScript.Shell")
oShell.Run "WScript.exe " & Chr(34) & WScript.ScriptFullName & Chr(34)
Initialize = False
Exit Function
End If
Initialize = True
End Function
Sub B64ToBin(ByRef sB64, ByRef oStrm, ByVal bAdo)
Const cB64Charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Dim iPointer
Dim iGSize
Dim iOffset
Dim cChar
Dim cBin
Dim iGBuffer
Dim hGBuffer
Dim cGBuffer
iGSize = 3
For iPointer = 1 To Len(sB64) Step 4
iGBuffer = 0
For iOffset = 0 To 3
cChar = Mid(sB64,iPointer + iOffset,1)
If cChar = "=" Then
iGSize = iGSize - 1
cBin = 0
Else
cBin = InStr(1,cB64Charset,cChar,vbBinaryCompare) - 1
End If
iGBuffer = 64 * iGBuffer + cBin
Next
hGBuffer = Hex(iGBuffer)
hGBuffer = String(6 - Len(hGBuffer), "0") & hGBuffer
cGBuffer = Chr(CByte("&h" & Mid(hGBuffer, 1, 2))) + _
Chr(CByte("&h" & Mid(hGBuffer, 3, 2))) + _
Chr(CByte("&h" & Mid(hGBuffer, 5, 2)))
If bAdo Then
oStrm.WriteText Left(cGBuffer,iGSize)
Else
oStrm.Write Left(cGBuffer,iGSize)
End If
Next
End Sub
If Initialize Then
oWrap.Register "user32.dll", "MessageBoxW", "i=hwwu","r=l"
iRep = oWrap.MessageBoxW(0, "Hello world !", "RegFreeSxS par omen999", MB_YESNO + MB_ICONWARNING)
End If
Const imgWScript = <code disponible dans le script à télécharger dans la section ci-dessous>
Const imgDynWrapX = <code disponible dans le script à télécharger dans la section ci-dessous>
|
4. Lien
5. Remerciements


Les sources présentées sur cette page sont libres de droits
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ©
2010 omen999. Aucune reproduction,
même partielle, ne peut être faite de ce site et de l'ensemble de son contenu :
textes, documents, images, etc. sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 €
de dommages et intérêts.
Cette page est déposée.