une méthode de réaliser un anticopie est de patcher l'exe avec des infos propres
à la plateforme. Cependant on ne peut pas demander avant à l'utilisateur de
donner des infos sur sa machine ...
Donc il faut récupérer ses infos via l'execution, les enregistrer en registie
par exple, le tout chiffré pour que ce ne soit ni évident à comprendre ni
falscifiable.
Ensuite il faut faire comprendre à l'exe qu'il a déjà créé cette clé de registre
afin qu'en cas d'effacement il en déduise que c'est une tentative de bidouillage
et donc pour celà, on patch l'exe lui même avec un info fixe, qu'on appelle tag,
magic, ou autre terme.
Lorsque l'exe se lance il regarde si il contient cette valeur au bon endroit et
dans ce cas en déduit qu'il a déjà été lancé / installé.
L'exple ci dessous se compote ainsi :
un script externe à compilet, est à embarquer dans l'exe finale par fileinstall qui
patchera son hôte lors de sa première execution.
déroulement :
l'exe se lance, il regarde à la fin si il se termine par 0x1111111128021977
(c'est le tag que j'ai pris). Je l'ai mis à la fin pour simplifier l'exple, mais
il est préférable de trouver une zone fixe de l'exe proche d'un padding qui ne
perturbe pas le fonctionnement de l'exe (si si il y en a qq unes ...).
Lors de la première utlisation, ceci n'est pas le cas.
Le script en déduit qu'il n'a pas été lancé.
Alors il vérifie si la clé de registre existe, dans ce cas, nous avons un
bidouilleur qui à dégager la zone de patch et laissé la registrie => erreur
Sinon, il la crée. Dans mon cas j'ai chiffré la concaténation du chemin/nom_exe
avec le numéro de série du microprocesseur. La clé utilisée sera dans cette exple
le tag concaténé au poids du 1er exe.
Ainsi impossible de renommer / déplacer le fichier au sein de la machine et de le
copier sur une autre (la copie est possible, mais l'exe ne marchera pas)
Si après, la clé de registre seule est effacée et pas la zone de patch, alors
on sera également en erreur
en fin de prmeière utilisation, le petit exe embarqué est lancé en fin d'execution et
patch son hôte avant de s'auto détruire
Le seul moyen est donc de détruire la clé de registre et dégager la zone patchée
, d'où la necessité dans un cas réel de la mettre ailleurs qu'à la fin ...
Au passage, faite attention au fileinstall, penser à le modifier en fonction de votre
chemin, car je rappelle que le 1er arg est le chemin absolue de la machine qui
compile
script du patcher (à compiler en 1er) :
Code : Tout sélectionner
;fichier patch me.au3
AutoItSetOption ( " TrayIconHide " , 1 )
AutoItSetOption ( " Onexitfunc " , " my_exit " )
if $CmdLine[0] <> 1 then Exit 1
$fic = FileOpen ( $CmdLine[1] , 17 )
if $fic <> - 1 Then
FileWrite ( $fic , Binary ( " 0x1111111128021977 " ) )
FileClose ( $fic )
EndIf
exit 0
Func my_exit ( )
;Run ( @ScriptDir& " \del_tmp.bat " , @ScriptDir , @SW_HIDE )
Run ( @ComSpec& " /c del /F " &FileGetShortName ( @ScriptFullPath ) , @ScriptDir , @SW_HIDE )
EndFunc
script de l'exe à compiler, une fois le premier compilé, et une fois que vous avez mis votre chemin d'accès en 1er arg de fileinstall
Code : Tout sélectionner
AutoItSetOption ( " TrayIconHide " , 1 )
#include <String.au3>
$tag = Binary ( " 0x1111111128021977 " ) ; tag de reference qui sera présent à la fin du fichier lorsque celui - ci a été éxécuter une fois
; libre choix de cette valeur ...
If StringRight ( @ScriptName , 4 ) <> " .exe " Then
MsgBox ( 0 , " Pas dans la source ! " , " attention , tu fais un f5 au lieu d'une compil ! " )
exit 0
EndIf
$admin_error = 0 ; globale d'erreur pour plus tard ...
AutoItSetOption ( " Onexitfunc " , " my_exit " ) ; à partir d'ici on désigne comme fonction de sortie , le lancement du patch de cet exe
$fic = FileOpen ( @ScriptName , 16 ) ; ouverture de l'exe en lecture binaire
If $fic = - 1 Then exit 1
$size = FileGetSize ( @ScriptName )
$binary = FileRead ( $fic , $size ) ; on lit tout l'exe
FileClose ( $fic )
$binary = BinaryMid ( $binary , $size - 7 ) ; lecture des 8 derniers octer pour savoir si l'exe est déjà patcher avec $tag
$ctrl = RegRead ( " HKEY_LOCAL_MACHINE\SOFTWARE\Test_anticopy " , " Myctrl " )
If $tag = $binary Then
AutoItSetOption ( " Onexitfunc " , " my_exit2 " ) ; on est déjà tagué donc on ne repatch pas
;maintenant on vérifie que notre exe est dans son endroit légitime
;déchiffremnt de la clé de registre
if $ctrl = " " Then copieur ( ) ; tag ok , mais pas registre donc bidouille ...
$ctrl = _StringEncrypt ( 0 , $ctrl , BinaryToString ( $tag ) & ( $size - 8 ) )
If StringLen ( $ctrl ) <> 16 + StringLen ( @ScriptFullPath ) Then copieur ( ) ; check de la cohértence de taille
$path = StringLeft ( $ctrl , StringLen ( @ScriptFullPath ) )
$id = StringRight ( $ctrl , 16 )
If @ScriptFullPath <> $path Or $id <> get_processor_id ( ) Then copieur ( )
ElseIf $ctrl <> " " Then
copieur ( ) ; pas de tag en fin de fichier , mais présence de la registrie = > bidouille
Else
; première utilisation de l'exe , on vérifie qu'on peut écrire dans la registrie
if not IsAdmin ( ) Then
$admin_error = 1
Exit MsgBox ( 16 , " Pb admin " , " Vous n'êtres pas admin pour cette installation " )
EndIf
; on inscrit en registre le chemin et le nom actuel de l'exe concaténé avec le num de série du microprocesseur chiffré le tag concaténé à la taille de l'exe
RegWrite ( " HKEY_LOCAL_MACHINE\SOFTWARE\Test_anticopy " , " Myctrl " , " REG_SZ " , _StringEncrypt ( 1 , @ScriptFullPath&get_processor_id ( ) , BinaryToString ( $tag ) &$size &$size ) )
EndIf
; on a passé tous les contrôles , le prog débute ici :
MsgBox ( 0 , " coucou " , " tout ça pour ça ! " )
exit 0
func my_exit ( )
If not $admin_error Then
FileInstall ( " I:\dev\autoit\forum\patch_me.exe " , @TempDir& " \update.exe " , 1 )
;attention !! le chemin si dessus correspond à chez moi , vous devez adapter à votre cas !!!!
; il s'agit du chemin où vous venez de compiler le script patch_me.au3 qui porte le nom de patch_me.exe
run ( @TempDir& " \update.exe " &@ScriptFullPath , @ScriptDir , @SW_HIDE )
EndIf
EndFunc
func my_exit2 ( )
;nothing
EndFunc
func my_exit_err ( )
MsgBox ( 16 , " Bouh!! " , " le copieur ! " )
EndFunc
func get_processor_id ( )
$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = " "
$strComputer = @ComputerName
$objWMIService = ObjGet ( " winmgmts:\\ " & $strComputer & " \root\CIMV2 " )
$colItems = $objWMIService.ExecQuery ( " SELECT * FROM Win32_Processor " , " WQL " , $wbemFlagReturnImmediately + $wbemFlagForwardOnly )
For $objItem In $colItems
$procesor = $objItem.ProcessorId
return $procesor
next
return ( " 1111111128021977 " ) ; retourne cette valeur si échec
EndFunc
func copieur ( )
AutoItSetOption ( " Onexitfunc " , " my_exit_err " )
exit 1
EndFunc
Toi qui cherche à mettre le doigt sur la solution, appuie sur F1.