Newsgroup: it.comp.programmare.win32
Titolo: Aggancio al NOTEPAD

ho realizzato una DLL per il notepad che mi funziona come un filtro ,
cioè blocca le funzioni che mi interessano facendogli fare un
pezzettino di codice mio e rimanda le altre alla kernel32.dll.
per esempio:
void _ExitProcess(UINT code)
{
   ...........................................

ho realizzato una DLL per il notepad che mi funziona come un filtro ,
cioè blocca le funzioni che mi interessano facendogli fare un
pezzettino di codice mio e rimanda le altre alla kernel32.dll.
per esempio( non centra nienete con il Notepad , per spiegarmi):
void _ExitProcess(UINT code)
{
	MessageBoxA(0,"HelloWorld","Api Hooking Sample",0);
	ExitProcess(code);
}
Mi servirebbe capire come posso fare a far agganciare alla mia
Applicazione(NotePAD) la mia Dll senza modificare l'eseguibile(cosa
non lecita).
Mi spiego meglio. Sono riuscito a far vedere al notePAD la mia DLL
modificando internamente il nome della kernel32.dll con la mia
vernel32.dll. Quindi la mia applicazione passa prima per la
vernel32.dll che filtra le chiamate che mi interessano. Questo non è
legale, per cui cerco un modo alternativo.
Vi ringrazio per le eventuali risposte. Mi interesserebbe trovare
anche alcuni articoli che spiegano come farlo nel modo più dettagliato
possibile.

 legale, per cui cerco un modo alternativo.
Guarda la mia risposta al thread "Programs memory editor".
Detours č una possibilitą "elegante" per intercettare le chiamate alle API 
con delle funzioni 'trampoline'
Puoi usare la stessa tecnica anche senza quella libreria ... vedi tu.
-- 
Raffaele Rialdi
Microsoft .NET MVP 
http://mvp.support.microsoft.com
 -
http://italy.mvps.org
 UGIdotNET - User Group Italiano .NET
http://www.ugidotnet.org
 Weblog: 
http://blogs.ugidotnet.org/raffaele

Potresti darmi qualcosa di più preciso e se possibile in Italiano. A
me servirebbe un esempio completo di una iniezione di una Dll su una
applicazione. Ti ringrazio per l'eventuale suggerimento

 applicazione. Ti ringrazio per l'eventuale suggerimento
Mi dispiace ma in Italiano non conosco questo genere di risorse.
Per l'inglese ti ho proprio suggerito detours perché ha tanti esempi già 
pronti.
Se devi fare poche cose l'API CreateRemoteThread è il punto di partenza e su 
google trovi diversi esempi su come usarla. Per esempio:
http://www.codeproject.com/threads/taskex.asp
I miei listati che ne fanno uso sono decisamente molto più complessi ed 
estrapolarne una parte funzionante è un lavoro piuttosto lungo.


Mi dici dove sbaglio.
//
************************************************************************************************************
//* LIBRERIE
//
************************************************************************************************************
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <shlwapi.h>
#pragma comment(lib, "user32")	// permette di gestire il MessageBox
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD |
PROCESS_QUERY_INFORMATION | PROCESS VM OPERATION | PROCESS VM WRITE |
PROCESS VM READ )
#define PROC_NAME "NOTEPAD.EXE" 		//  Programma bersaglio da
intercettare
#define DLL_NAME "dll Injection.dll" 	// DLL da iniettare
//
*************************************************************************************************************
//* Funzione GetProcId
//
*************************************************************************************************************
unsigned long GetProcID(char *procName)
{
	PROCESSENTRY32 pe;
	HANDLE thSnapshot;
	BOOL retval, ProcFound = FALSE;
	thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if(thSnapshot == INVALID_HANDLE_VALUE)
	{
		MessageBoxA(0,"Errore, nessun Toolhelp Snapshot creato ", "Finestra
di Dialogo",0);
		return FALSE;
	}
	pe.dwSize = sizeof(PROCESSENTRY32);
	retval = Process32First(thSnapshot, &pe);
	while(retval)
	{
		if(StrStrI(pe.szExeFile, procName))
		{
			ProcFound = TRUE;
			break;
		}
		retval = Process32Next(thSnapshot, &pe);
		pe.dwSize = sizeof(PROCESSENTRY32);
	}
	return pe.th32ProcessID;
}
//
**************************************************************************************************************
//* Funzione InjectDLL
//
**************************************************************************************************************
BOOL InjectDLL(DWORD ProcID, char *dllName)
{
	HANDLE proc;
	LPVOID RemoteString, LoadLibAddy;
	char buf[50]={0};
	if(!ProcID)
		return FALSE;
	// * Ottengo un Handle al processo bersaglio( mi serve come
rififerimento al processo)
	proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE , ProcID);
	if(!proc)
	{
		sprintf(buf, "OpenProcess() failed: %d", GetLastError());
		MessageBoxA(0,buf, "Finestra di Dialogo",0);
		return FALSE;
	}
	LoadLibAddy =
(LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA");
	//* Allochiamo lo spazio necessario nella memoria del processo
vittima per inserire il nome della DLL che vogliamo caricare in
memoria
	RemoteString =(LPVOID) VirtualAllocEx(proc, NULL, strlen(dllName),
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
	//* Inseriamo la funzione che deve scrivere sulla memoria ilnome
della DLL da caricare
	WriteProcessMemory(proc, (LPVOID)RemoteString, dllName,
strlen(dllName), NULL);
	//* Viene eseguita una funzione remota che carica ilcodice della DLL
che vogliamo eseguire
	CreateRemoteThread(proc, NULL, 0,
(LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL);
	CloseHandle(proc);
	return TRUE;
}
//
**************************************************************************************************************
//* Funzione LoadDll
//
**************************************************************************************************************
BOOL LoadDll(char *procName, char *dllName)
{
   DWORD ProcID = 0;
   ProcID = GetProcID(procName); 	// Mi trova l'ID del processo
bersaglio da intercettare che mi serve poi nella SeWindowsHookEx
	if(!(InjectDLL(ProcID, dllName)))
	{
		MessageBoxA(0,"Processo Trovato, ma iniezione fallita","Finestra di
Dialogo",0);
	}
	return TRUE;
}
//
**************************************************************************************************************
//* Questa funzione permette di stabilire se siamo in un sitema
operativo NT o no
//
**************************************************************************************************************
BOOL IsWindowsNT()
{
	DWORD version = GetVersion();
	DWORD majorVersion = (DWORD) (LOBYTE(LOWORD(version)));
	DWORD minorVersion = (DWORD) (HIBYTE(LOWORD(version)));
	return (version< 0x80000000);
}
//
***************************************************************************************************************
//* MAIN
//
***************************************************************************************************************
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,int nCmdShow)
{
	if(IsWindowsNT())
	{
		MessageBoxA(0,"OK","Finestra di Dialogo",0);
		LoadDll(PROC_NAME, DLL_NAME);
	}
	else
		MessageBoxA(0,"Error","Finestra di Dialogo",0);
    return 0;
}
In fase di compilazione mi dà errore ( external link per StrStrI).

Per spiegarmi meglio non mi funziona la trovaPID

 Per spiegarmi meglio non mi funziona la trovaPID
la funzione delle CRT è strstr e non capisco bene da dove spunti la strstrl
A parte che non condivido quel codice perchè non usa safe crt, è ansi, fa 
assunzione sul nome del processo, etc. etc.


  
StrStrI č una API di windows definita nella Shlwapi.
Se non ti linka, prova ad aggiungere la Shlwapi.lib al linker.
Da me il tuo codice compila e funziona perfettamente.

 Da me il tuo codice compila e funziona perfettamente.
sono fuso e cercavo con la "L" finale :)
In alternativa può usare _stricmp ...


Si funziona tutto. Grazie per l'aiuto.
Adesso ho un altro problema. Vorrei fare un Hook globale non su un
processo , ma su una funzione della kernel32.dll tipo la open process,
in modo tale che tutte le applicazioni che la usano vvengono
indirizzate al mio pezzo di codice. Ho letto che per fare ciò side
deve mettere l'hook all'interno di una DLL. Ho fatto questo come prova
con il codice per l'aggancio al NOTEPAD; ma quando provo a registrare
la DLL mi dice che la DLL non può essere registrata poichè non viene
trovato il punto d'ingresso. Come posso fare a risolvere questo
problema. éPotreste spiegarmelo brevemente o indirizzarmi a qualche
esempio. Vi ringrazio

 trovato il punto d'ingresso.
se per "registrare" la DLL intendi con regsvr32.exe allora devi esporre
un'interfaccia ben definita, a partire da qui:
http://msdn2.microsoft.com/en-us/library/ms682162.aspx
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Se non sbaglio una proxy DLL è un clone di una DLL( nel mio caso
dovrei clonare la kernel32.dll). Sbaglio? Dovrei andare a sostituire
il clone all' originale?

 un'interfaccia ben definita, a partire da qui:
http://msdn2.microsoft.com/en-us/library/ms682162.aspx
Ho visto il link , se non ho capito male devo inserire la
DllRegisterServer e la DllUnregisterServer all'interno della mia DLL
e fare la registrazione tramite il comando regsvr32.exe come al
solito. Giusto?

 solito. Giusto?
no: se esponi l'interfaccia di cui ho parlato nel post precedente vuol
dire che stai programmando degli oggetti COM, non un API hook. puoi anche
sfruttare  regsvr32.exe per l'avvio del codice della DLL, ma mi pare un
exploit stupido: fai un tuo loader eseguibile e vivi felice. se invece
vuoi proprio creare oggetti COM è un altro discorso.


 il clone all' originale?
si, dovresti rimpiazzare il file di sistema con una tua DLL che contiene
esattamente tutti gli exports dell'originale sotto forma di semplici
redirects all'originale, fatta eccezione per l'API che vuoi hookare.
l'originale chiaramente va semplicemente rinominato, e non cancellato.
non è la soluzione migliore perché come l'utente fa un aggiornamento da
Windows Update che riguardi kernel32.dll (o la DLL che hai rimpiazzato) il
"proxy" se ne va a quel paese. ma più in generale non è la soluzione
migliore perché fa assunzioni orientativamente sempre vere, come il fatto
che kernel32.dll venga utilizzata esclusivamente in esecuzione, o che tu
possa anche solo accedere a kernel32.dll; però non si sa mai: la minima
atipicità nel sistema può impedire il funzionamento del tuo programma.


Ho questo problema. Riesco ad iniettare la DLL sul mio processo
bersaglio, ma io vorrei che la Dll rimanesse registrata nel sistema
operativo in modo tale che in seguito ad un riavvio non debba andare
nuovamente a ricaricare la Dll. Vorrei in un certo modo che ogni volta
che avvio il programma bersaglio, nel mio caso "NOTEPAD.EXE"  esso
riconosca automaticamente la mia Dll senza che io la debba lanciare ad
ogni avvio del programma. Mi potreste spiegare con semplici parole
come fare?
Da quello che io ho capito dovrei introdurre il codice in una DLL  e
registrarla nel sistema. Non ho capito bene quello che mi voleva dire
"mnrt".

Altro problema: Ho provato a inetttare la Dll in un processo
(Notepad.exe) tramite la SetWindowsHookEx(), vi inserisco il codice
che uso io:
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <shlwapi.h>
#pragma comment(lib, "user32")	// permette di gestire il MessageBox
#pragma comment(lib, "shlwapi")	// permette di gestire la funzione
StrStrI
#define PROC_NAME "NOTEPAD.EXE" 		//  Programma bersaglio da
intercettare
#define DLL_NAME "dll Injection.dll" 	                   // DLL da
iniettare
//
**********************************************************************************************************************
// FUNZIONE GetTargetThreadIdFromProcname  -->questa funzione permette
di trovare il PID del processo bersaglio
//
**********************************************************************************************************************
unsigned long GetTargetThreadIdFromProcName(char *procName)
{
   PROCESSENTRY32 pe;
   HANDLE thSnapshot, hProcess;
   BOOL retval, ProcFound = FALSE;
   unsigned long pTID, threadID;
   thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   if(thSnapshot == INVALID_HANDLE_VALUE)
   {
      MessageBoxA(0,"Errore, nessun Toolhelp Snapshot creato ",
"Finestra di Dialogo",0);
      return FALSE;
   }
   pe.dwSize = sizeof(PROCESSENTRY32);
    retval = Process32First(thSnapshot, &pe);
   while(retval)
   {
      if(StrStrI(pe.szExeFile, procName) )
      {
         ProcFound = TRUE;
         break;
      }
      retval    = Process32Next(thSnapshot,&pe);
      pe.dwSize = sizeof(PROCESSENTRY32);
   }
   CloseHandle(thSnapshot);
   _asm {
      mov eax, fs:[0x18]
      add eax, 36
      mov [pTID], eax
   }
   hProcess = OpenProcess(PROCESS_VM_READ, FALSE, pe.th32ProcessID);
   ReadProcessMemory(hProcess, (const void *)pTID, &threadID, 4,
NULL);
   CloseHandle(hProcess);
   return threadID;
}
//
***********************************************************************************************************************
// FUNZIONE LoadDll
//
***********************************************************************************************************************
BOOL LoadDll(char *procName, char *dllName)
{
    HMODULE hDll;
	LPVOID cbtProcAddr;
	hDll        = LoadLibrary(dllName);
	cbtProcAddr = (LPVOID)GetProcAddress(hDll, "MessageBoxA");
    SetWindowsHookEx(WH_CBT, cbtProcAddr, hDll,
GetTargetThreadIdFromProcName(procName) );
    return TRUE;
}
//
***********************************************************************************************************************
// MAIN
//
***********************************************************************************************************************
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,int nCmdShow)
{
	LoadDll(PROC_NAME, DLL_NAME);
}
****************************************************************************************************************************************
Quello di strano che mi succede e che viene effettuata l'iniezione del
codice all'interno della Dll anche se commento La SetWindowsHookEx.
Una volta che lui chiama la  LoadLibrary, inietta la Dll. Non gli
interessa se il processo bersaglio è avviano o no.
Come mai? Dove sbaglio?

nessuno mi può aiutare. Mi interesserebbe principalmete risolvere il
problema esposto sopra riguardo al fatto divolermantenere la Dll
registrata nel sistema. Come posso fare?