Autour du PC

Chevaux de Troie

Electronique

Trucs et astuces

Sécurité

 

CSS Valide !

Site optimisé en 1024x768



 

Troyens - Méthode de programmation

Les Chevaux de Troie sont en fait comme nous l'avons dit, de petits programmes écris le plus souvent à l'aide de logiciels de programmation ou de développement. Il existe (dans le fonctionnement) peu de différences entre un logiciel de "chatting" et un Troyen. En effet, le principe reste toujours et encore le même: "Allo tu es là ???....Oui, je suis là, je t'ecoute et j'attends tes instructions...". Nous allons donc tenter d'écrire et de mettre en application ce principe.
 Je ne vais pas donner ici un cours de programmation, ce n'est pas le but, de plus il faudrait y consacrer un site complet, il en existe sur le Web de très complets dont les auteurs sont compétents en ce domaine.
 J'ai choisi pour cela la programmation en pascal objet avec le fabuleux logiciel de développement "Delphi Professionel 4"...Pourquoi celui-là ?? Et bien à l'époque son prix était très attractif, le Web est très fourni sur ce sujet, de nombreux composants le plus souvent gratuits sont dispos sur le Net, ce qui permet de rendre la bibliothèque integrée de Delphi plus fournie, ainsi le développement de logiciels devient plus rapide.
 Je suppose donc que vous avez un minimum de connaissances concernant la programmation objets, le code exposé ici est très fragmenté et n'a pour but que d'expliquer un peu le principe de fonctionnement de la communication de deux PC en réseau.
Début de la section "mal de crâne" :
Nous allons utiliser deux composants intégrés par défaut dans Delphi :

icoclient.jpg (9088 octets) composant ClientSocket et    icoserv.jpg (9123 octets) ServerSocket.
Puis une vulgaire case de saisie Edit1 me permettant de faciliter la programmation et de suivre le fonctionnement.

inpectobj.jpg (40786 octets) 
Dans l'inspecteur d'objet, on peut spécifier le port sur lequel le ServerSocket va travailler (ici le port est 600 ).

Passons au code :
Code du fichier que l'on nommera "Serveur"

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;Socket: TCustomWinSocket);  // Déclaration de la procédure de lecture de la reception des infos

var f: integer; // Déclaration d'une variable f (utile pour plus tard) de type entier .

ligcmd:string;
  // Déclaration d'une variable ligcmd (utile pour plus tard aussi) de type chaîne .

sockcmd:string;
  // Déclaration d'une variable sockcmd de type chaîne où l'on place les instructions que reçoit ServerSocket .

begin 
   // Début de la procédure

sockcmd:=Socket.ReceiveText;
// On place les instructions que reçoit le ServerSocket dans la variable sockcmd déclarée plus haut.

edit1.text:=sockcmd;
// On place la valeur de sockcmd dans un edit pour visionner la réception de l'instruction .

end;
// Fin de la procédure

end.
// Fin du code.

Maintenant que le ServerSocket écoute le port, il faut lui dire quoi faire lorsque le ClientSocket lui envoie une instruction.
Pour ce faire on rajoute quelques lignes de code :

procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var f:integer;
ligcmd:string;
begin
sockcmd:=Socket.ReceiveText;
edit1.text:=sockcmd;

if sockcmd=' cdout ' then mciSendString('Set cdaudio door open wait', nil, 0, handle);  // (1)
if sockcmd=' cdin ' then mciSendString('Set cdaudio door closed wait', nil, 0, handle);  // (2)
end;
end.

(1) C'est là que le boulot du ServerSocket commence: S'il reçoit l'instruction "cdout" provenant du ClientSocket alors il ouvre la trappe du lecteur CDrom de la machine où il se trouve.
(2) S'il reçoit l'instruction "cdin" alors il la referme.

Pour faire un peu plus interressant (mais un peu plus complexe) :
Une petite boite de message Windows de ce type :

warning.jpg (22632 octets)

Ici, il y a deux paramètres à prendre en compte : L'instruction demandant au ServerSocket d'afficher la boite et le texte qu'il doit écrire à l'interieur (ça se complique encore...), j'ai dû utiliser le code suivant :

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;Socket: TCustomWinSocket);
var f:integer;
ligcmd:string;
begin
sockcmd:=Socket.ReceiveText;
edit1.text:=sockcmd;
if sockcmd='cdout' then mciSendString('Set cdaudio door open wait', nil, 0, handle);
if sockcmd='cdin' then mciSendString('Set cdaudio door closed wait', nil, 0, handle);


if Pos('warn', 'sockcmd') > 0 then    // le ServerSocket verifie les instructions, si l'une d'entre elles contient la chaine 'warn' il exécute les lignes suivantes. (Ex : warnEnvoi du ClientSocket !)
begin

for f:=5 to length (sockcmd) do      // une boucle partant de 5 à la longueur complète de la chaîne, concatène la nouvelle
chaîne caractères après caractères jusqu'à la fin.

ligcmd:=ligcmd+sockcmd[f];           // On place ensuite les caractères restant les uns derrière les autres pour obtenir juste "Envoi du ClientSocket !" initialisant ainsi la variable ligcmd déclarée plus haut.

MessageDlg(ligcmd, mtwarning, [mbOk], 0);  // Il reste plus qu'a lancer la boite de message avec comme texte le contenu de ligcmd.

serverSocket1.Socket.connections[0].SendText ('warok');  // ici on se permet le luxe de dire au ServerSocket d'envoyer une instruction  au ClientSocket, cette instruction c'est : "warok", on lui demande, lors de la  réception de cette instruction de considérer que le message a bien été fermé  par l'utilisateur.

ligcmd:='';    // Enfin on vide le contenu de ligcmd afin d'éviter les embrouilles et lui permettre de recevoir une nouvelle valeur.
  end;
  end;
end.

Passons maintenant au code du fichier que l'on nommera "Client" :
Comme on le dit souvent dans certain cas, le Client est roi, ici c'est pareil, c'est lui qui donne les instructions et c'est le Serveur qui exécute celles-ci.

inpectobj2.jpg (38676 octets) Comme pour le ServerSocket, le ClientSocket peut être initialisé via l'inspecteur d'objets, ici le port est encore fixé à 600, le reste sera paramétré dynamiquement lors de l'exécution du fichier. Notez que par defaut, la valeur Host du ClientSocket correspond à l'IP machine, elle sera modifiée par la suite.
C'est parti...
  Les objets mis en place sont: un ClientSocket, une case de saisie, 2 boutons (connection, déconnection) et d'autres boutons permettant l'envoi des instructions pour le ServerSocket.
procedure TForm1.SpeedButton12Click(Sender: TObject); // Procédure du bouton permettant la connection au ServerSocket.
begin

ClientSocket1.Port:='600'; // Le port du ClientSocket est initialisé à 600.

ClientSocket1.Host:=EditHost.Text;
// La propriété Host va chercher sa valeur dans un edit saisie par l'utilisateur (IP de la machine à connecter).

ClientSocket1.Open;  // La connection est ouverte.
end;

Bien sûr, il est à prévoir dans le programme des procédures évènementielles lors de la connection ou de l'échec de la connection, les composants ClientSocket et ServerSocket sont pourvus de ces procédures.
On envoie maintenant des instructions en reprenant l'exemple de la trappe du lecteur Cdrom :

procedure TForm1.SpeedButton3Click(Sender: TObject); // Procédure du bouton permettant l'envoi de l'instruction.
begin

ClientSocket1.Socket.SendText (' cdout ');  // Le ClientSocket envoie l'instruction 'cdout' au ServerSocket.

end;

Envoi de l'instruction permettant l'affichage de la boite de dialogue "Erreur" (voir ci-dessus).

procedure TForm1.SpeedButton9Click(Sender: TObject);
begin


ClientSocket1.Socket.SendText ('warn'+edit2.text); // Le ClientSocket envoie ici l'instruction 'warn' ainsi que le contenu d'une case de  saisie ayant comme valeur la chaîne à écrire dans le corps de la boite (Ex: "Envoi du Client Socket  !" ).

end;

Pour que le ClientSocket  puisse avoir un rapport de ce que se passe chez le ServerSocket et traiter les informations reçues par celui- ci on le mettra en position d'écoute en utilisant cette procédure :

procedure TForm1.ClientSocket1Read(Sender: TObject;Socket: TCustomWinSocket); // Procédure de lecture des informations venant du ServerSocket.

var
sockcmd:string;
  // Déclaration de la variable amenée a contenir la valeur de l'information, de type chaîne.

begin

sockcmd:=Socket.ReceiveText;  // Initialisation de la variable sockcmd .

if sockcmd='warok' then listbox1.items.add ('Le serveur a fermé le msg WARNING'); // Si la variable sockcmd reçoit comme contenu 'warok' alors, par exemple, une listebox pourra être mise à jour ou un journal d'évènement ou une boite de dialogue, permettant à l'utilisateur de voir que l'autre utilisateur (celui du ServerSocket) a fermé sa boite de dialogue.

end;

Pour rompre une connection on peut faire appel à la procédure suivante :

procedure TForm1.SpeedButton13Click(Sender: TObject); // Procédure du bouton permettant la déconnection
begin


ClientSocket1.Close;  // Instruction de déconnection.

end;

J'espére que tout ceci vous aura amené à mieux comprendre ces phénomènes qui semblent au premier abord compliqués mais qui en fait, avec un peu de persévérence pour amener à l'écriture d'applications plus complexes comme la maintenance d'une machine à distance ou tout simplement un logiciel de "chatting" perso.
Note :Ce code a été testé sur deux machines en réseau, client sur WinMe et serveur sur WinXP, il fonctionne dans le cas où le Firewall de WinXp a été désactivé, sinon il est impossible aux deux machines de communiquer en utilisant ces programmes tels que.   Donc un conseil, laissez votre Firewall en marche...

Vempyr