[Delphi]Cacher une application sous WinXP/2000 (vista je sais pas)

    Publicités

Users Who Are Viewing This Thread (Total: 0, Members: 0, Guests: 0)

Leplayze

Frite...euse (jeu de mot)
V
Ancien staff
Dec 4, 2009
12,649
5
1,303
30
www.youtube.com
Sous windows 95/98/ME c'était très simple une appli qui se cache elle même dans le gestionnaire de tâches:
Code:
function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer; stdcall; external 'KERNEL32.DLL';

implementation

procedure TForm1.Button1Click(Sender: TObject);
begin 
//On cache notre appli
	if not (csDesigning in ComponentState) then
	RegisterServiceProcess(GetCurrentProcessID, 1);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
//On le montre de nouveau
	if not (csDesigning in ComponentState) then
	RegisterServiceProcess(GetCurrentProcessID, 0);
end;
Tout ce passe dans la fonction RegisterServiceProcess, dans la bibliothèque Kernel32.dll. On faisait passer notre appli pour un service système. Comme ça... à la volée. Mais Windows 2000 et XP, enfin basés sur la technologie NT (qui veut dire tout bêtement New Technology :lol: ) ça ne marche malheureusement pas. :|

Après avoir parlé un peu avec l'admin de ce forum (Superman) qui, m'a demandé de faire quelques tutos, je me suis dis: pourquoi pas cacher une appli? Cela peut être utile, si les jeux pour lesquels on code des progs de l'exploit ont un guard et qui essaye de les détecter? Mais j'ai rencontré ce problème - gné?! comment ça?! ça marche passssss!!!!!!!! (censored). Du coup je me suis mis à googler. Et partout où je ne tombe, je trouve des réponses bidon, soit des "je sais pas", soit la vielle méthode... Bref le plus potable dans tout cela était une idée de je sais plus qui, qui à proposé un truc "génial" (entre guillemets!): -Faire tourner un timer dans son appli (à l'infini) et une fois qu'on ouvre le gestionnaire de tâches, supprimer son processus de la liste... POUAH!!! Je vois le genre: tu fais ctrl+alt+suppr et tu vois cash un truc disparaitre (enfin dépend aussi de la patate de la machine... si quelqu'un le fait avec un PC surchargé, bien il va attendre que l'appli se cache lol). Et quand tu vois un truc disparaitre tu te dis: Hein?! Quelque chose ne va pas!!!
Enfin bref... j'ai trop chauffé les méninges mais... J'AI TROUVE une solution! Et je vous la presente ;)

La DLL: nthide.dll
Code:
library hide; 
uses 
 Windows, 
 SysUtils, 
 ImageHlp, 
 TlHelp32; 
type SYSTEM_INFORMATION_CLASS = ( 
 SystemBasicInformation, 
 SystemProcessorInformation, 
 SystemPerformanceInformation, 
 SystemTimeOfDayInformation, 
 SystemNotImplemented1, 
 SystemProcessesAndThreadsInformation, 
 SystemCallCounts, 
 SystemConfigurationInformation, 
 SystemProcessorTimes, 
 SystemGlobalFlag, 
 SystemNotImplemented2, 
 SystemModuleInformation, 
 SystemLockInformation, 
 SystemNotImplemented3, 
 SystemNotImplemented4, 
 SystemNotImplemented5, 
 SystemHandleInformation, 
 SystemObjectInformation, 
 SystemPagefileInformation, 
 SystemInstructionEmulationCounts, 
 SystemInvalidInfoClass1, 
 SystemCacheInformation, 
 SystemPoolTagInformation, 
 SystemProcessorStatistics, 
 SystemDpcInformation, 
 SystemNotImplemented6, 
 SystemLoadImage, 
 SystemUnloadImage, 
 SystemTimeAdjustment, 
 SystemNotImplemented7, 
 SystemNotImplemented8, 
 SystemNotImplemented9, 
 SystemCrashDumpInformation, 
 SystemExceptionInformation, 
 SystemCrashDumpStateInformation, 
 SystemKernelDebuggerInformation, 
 SystemContextSwitchInformation, 
 SystemRegistryQuotaInformation, 
 SystemLoadAndCallImage, 
 SystemPrioritySeparation, 
 SystemNotImplemented10, 
 SystemNotImplemented11, 
 SystemInvalidInfoClass2, 
 SystemInvalidInfoClass3, 
 SystemTimeZoneInformation, 
 SystemLookasideInformation, 
 SystemSetTimeSlipEvent, 
 SystemCreateSession, 
 SystemDeleteSession, 
 SystemInvalidInfoClass4, 
 SystemRangeStartInformation, 
 SystemVerifierInformation, 
 SystemAddVerifier, 
 SystemSessionProcessesInformation 
); 
_IMAGE_IMPORT_DESCRIPTOR = packed record 
  case Integer of 
   0:( 
    Characteristics: DWORD); 
   1:( 
    OriginalFirstThunk:DWORD; 
    TimeDateStamp:DWORD; 
    ForwarderChain: DWORD; 
    Name: DWORD; 
    FirstThunk: DWORD); 
   end; 
IMAGE_IMPORT_DESCRIPTOR=_IMAGE_IMPORT_DESCRIPTOR; 
PIMAGE_IMPORT_DESCRIPTOR=^IMAGE_IMPORT_DESCRIPTOR; 
PFARPROC=^FARPROC; 
procedure ReplaceIATEntryInOneMod(pszCallerModName: Pchar; pfnCurrent: FarProc; pfnNew: FARPROC; hmodCaller: hModule); 
var     ulSize: ULONG; 
   pImportDesc: PIMAGE_IMPORT_DESCRIPTOR; 
    pszModName: PChar; 
        pThunk: PDWORD; ppfn:PFARPROC; 
        ffound: LongBool; 
       written: DWORD; 
begin 
 pImportDesc:= ImageDirectoryEntryToData(Pointer(hmodCaller), TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, ulSize); 
  if pImportDesc = nil then exit; 
  while pImportDesc.Name<>0 do 
   begin 
    pszModName := PChar(hmodCaller + pImportDesc.Name); 
     if (lstrcmpiA(pszModName, pszCallerModName) = 0) then break; 
    Inc(pImportDesc); 
   end; 
  if (pImportDesc.Name = 0) then exit; 
 pThunk := PDWORD(hmodCaller + pImportDesc.FirstThunk); 
  while pThunk^<>0 do 
   begin 
    ppfn := PFARPROC(pThunk); 
    fFound := (ppfn^ = pfnCurrent); 
     if (fFound) then 
      begin 
       VirtualProtectEx(GetCurrentProcess,ppfn,4,PAGE_EXECUTE_READWRITE,written); 
       WriteProcessMemory(GetCurrentProcess, ppfn, @pfnNew, sizeof(pfnNew), Written); 
       exit; 
      end; 
    Inc(pThunk); 
   end; 
end; 
var 
 addr_NtQuerySystemInformation: Pointer; 
 mypid: DWORD; 
 fname: PCHAR; 
 mapaddr: PDWORD; 
 hideOnlyTaskMan: PBOOL; 
function myNtQuerySystemInfo(SystemInformationClass: SYSTEM_INFORMATION_CLASS; SystemInformation: Pointer; 
 SystemInformationLength:ULONG; ReturnLength:PULONG):LongInt; stdcall; 
label onceagain, getnextpidstruct, quit, fillzero; 
asm 
 push ReturnLength 
 push SystemInformationLength 
 push SystemInformation 
 push dword ptr SystemInformationClass 
 call dword ptr [addr_NtQuerySystemInformation] 
 or eax,eax 
 jl quit 
 cmp SystemInformationClass, SystemProcessesAndThreadsInformation 
 jne quit 
 onceagain: 
 mov esi, SystemInformation 
 getnextpidstruct: 
 mov ebx, esi 
 cmp dword ptr [esi],0 
 je quit 
 add esi, [esi] 
 mov ecx, [esi+44h] 
 cmp ecx, mypid 
 jne getnextpidstruct 
 mov edx, [esi] 
 test edx, edx 
 je fillzero 
 add [ebx], edx 
 jmp onceagain 
 fillzero: 
 and [ebx], edx 
 jmp onceagain 
 quit: 
 mov Result, eax 
end 
procedure InterceptFunctions; 
var hSnapShot: THandle; 
         me32: MODULEENTRY32; 
begin 
 addr_NtQuerySystemInformation:=GetProcAddress(getModuleHandle('ntdll.dll'),'NtQuerySystemInformation'); 
 hSnapShot:=CreateToolHelp32SnapShot(TH32CS_SNAPMODULE,GetCurrentProcessId); 
  if hSnapshot=INVALID_HANDLE_VALUE then exit; 
   try 
    ZeroMemory(@me32,sizeof(MODULEENTRY32)); 
    me32.dwSize:=sizeof(MODULEENTRY32); 
    Module32First(hSnapShot,me32); 
     repeat 
      ReplaceIATEntryInOneMod('ntdll.dll',addr_NtQuerySystemInformation,@MyNtQuerySystemInfo,me32.hModule); 
     until not Module32Next(hSnapShot,me32); 
   finally 
    CloseHandle(hSnapShot); 
   end; 
end; 
procedure UninterceptFunctions; 
var hSnapShot: THandle; 
         me32: MODULEENTRY32; 
begin 
 addr_NtQuerySystemInformation:=GetProcAddress(getModuleHandle('ntdll.dll'),'NtQuerySystemInformation'); 
 hSnapShot:=CreateToolHelp32SnapShot(TH32CS_SNAPMODULE,GetCurrentProcessId); 
  if hSnapshot=INVALID_HANDLE_VALUE then exit; 
  try 
   ZeroMemory(@me32,sizeof(MODULEENTRY32)); 
   me32.dwSize:=sizeof(MODULEENTRY32); 
   Module32First(hSnapShot,me32); 
    repeat 
     ReplaceIATEntryInOneMod('ntdll.dll',@MyNtQuerySystemInfo,addr_NtQuerySystemInformation,me32.hModule); 
    until not Module32Next(hSnapShot,me32); 
  finally 
   CloseHandle(hSnapShot); 
  end; 
end; 
var HookHandle: THandle; 
function CbtProc(code: integer; wparam: integer; lparam: integer):Integer; stdcall; 
begin 
 Result:=0; 
end; 
procedure InstallHook; stdcall; 
begin 
 HookHandle:=SetWindowsHookEx(WH_CBT, @CbtProc, HInstance, 0); 
end; 
var hFirstMapHandle:THandle; 
function HideProcess(pid:DWORD; HideOnlyFromTaskManager:BOOL):BOOL; stdcall; 
var addrMap: PDWORD; 
       ptr2: PBOOL; 
begin 
 mypid:=0; 
 result:=false; 
 hFirstMapHandle:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,8,'NtHideFileMapping'); 
  if hFirstMapHandle=0 then exit; 
 addrMap:=MapViewOfFile(hFirstMapHandle,FILE_MAP_WRITE,0,0,8); 
  if addrMap=nil then 
   begin 
    CloseHandle(hFirstMapHandle); 
    exit; 
   end; 
 addrMap^:=pid; 
 ptr2:=PBOOL(DWORD(addrMap)+4); 
 ptr2^:=HideOnlyFromTaskManager; 
 UnmapViewOfFile(addrMap); 
 InstallHook; 
 result:=true; 
end; 
exports 
 HideProcess; 
var 
 hmap: THandle; 
procedure LibraryProc(Reason: Integer); 
begin 
 if Reason = DLL_PROCESS_DETACH then 
  if mypid > 0 then 
   UninterceptFunctions() 
 else 
  CloseHandle(hFirstMapHandle); 
end; 
begin 
 hmap:=OpenFileMapping(FILE_MAP_READ,false,'NtHideFileMapping'); 
  if hmap=0 then exit; 
  try 
   mapaddr:=MapViewOfFile(hmap,FILE_MAP_READ,0,0,0); 
    if mapaddr=nil then exit; 
   mypid:=mapaddr^; 
   hideOnlyTaskMan:=PBOOL(DWORD(mapaddr)+4); 
    if hideOnlyTaskMan^ then 
     begin 
      fname:=allocMem(MAX_PATH+1); 
      GetModuleFileName(GetModuleHandle(nil),fname,MAX_PATH+1); 
       if not (ExtractFileName(fname)='taskmgr.exe') then exit; 
     end; 
   InterceptFunctions; 
  finally 
   UnmapViewOfFile(mapaddr); 
   CloseHandle(Hmap); 
   DLLProc:=@LibraryProc; 
  end; 
end.
C'est le listing complet :)
 

Leplayze

Frite...euse (jeu de mot)
V
Ancien staff
Dec 4, 2009
12,649
5
1,303
30
www.youtube.com
et voici la suite

Et voici comment l'utiliser:

Il faut appeler la fonction HideProcess
Code:
function HideProcess(pid:DWORD; HideOnlyFromTaskManager:BOOL):BOOL,
où:
pid: l'identifiant du processus
HideOnlyFromTaskManager: (TRUE ou FALSE) Faut-il cacher le processus seulement du Gestionnaire de Tâches, ou bien le cacher aussi de toutes les autres applications qui obtiennent la liste de processus en appellent à la fonction NtQuerySystemInformation de la bibliothèque ntdll.dll

Exemple:
Code:
function HideProcess(pid: DWORD; HideOnlyFromTaskManager: BOOL): BOOL; stdcall; external 'nthide.dll'; 
...
procedure proc; 
begin 
//cache le processus courant (de l'appli qui exécute ce code)
 HideProcess(GetCurrentProcessId, false);
end;

Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris! (en russe :) )


Pour cacher la fenêtre:
(de la barre de tâches aussi)
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowWindow(Application.MainForm.Handle,SW_HIDE);
end;
Pour l'afficher de nouveau on utiliseras un code ressemblant:
ShowWindow(Application.MainForm.Handle,SW_SHOW);
par exemple dans un HotKey.

Enjoy :)