Newsgroup: it.comp.programmare.win32
Titolo: Shared memory in una DLL

Sempre per il log dei programmi...
Nella Hook procedure che ho installato su WH_SHELL, devo richiamare
CallNextHookEx per far funzionare gli altri hook gia' presenti, ma
l'hook e' attaccato a tutti i processi, e quindi la DLL viene caricata e
rimappata per ognuno e quindi avro' che i dati statici sono N copie una
per ogni proceso.
Come faccio a far sapere ad ogni istanza della mia DLL qual'e' l'handle
della funzione di hook, che conosce solo la prima istanza che ha
chiamato SetWindowHookEx?
Ho letto della shared memory, utilizzabile attraverso CreateFileMapping
e MapViewOfFile, ma non ci sarebbe un altro metodo/scappatoia piu'
rapido e semplice, per l'unico specifico dato che mi serve? (cioe'
l'handle della funzione di Hook)
Per ora ho implementato il salvataggio su file, ma mi sembra 'na
str***ata!
grazie, ciao
donCiccio

 l'handle della funzione di Hook)
Certamente. Nella tua DLL:
#pragma data_segment(".sharedata")
__declspec(dllexport) HHOOK hHook = NULL;
#pragma data_segment()
Poi crei un file .DEF per definite la sezione .sharedata come memoria
condivisa:
SECTIONS
    .sharedata READ WRITE SHARED
Poi in qualunque modulo in cui utilizzi quella variabile:
__declspec(dllimport) HHOOK hHook;
--
Bye! Lorenzo Lutti
http://antani.virtualave.net/


grazie Lorenzo per aver risposto,
approfitto ancora un po del tuo aiuto, per sottoporti il codice della
mia DLL, si perche' ho provato quello che mi hai suggerito (almeno
credo), ma non mi funziona.
Tieni presente che il dato condiviso io lo vorrei utilizzare nelle varie
istanze della DLL, all'interno di funzioni della DLL stessa e non tra
DLL e modulo che l'ha caricata.
dammi il tuo giudizio su questo codice:
-----------------------------------------------------------------------
#include "stdio.h"
#include "windows.h"
#pragma data_segment(".sharedata")
__declspec(dllexport) static HINSTANCE hdll;
__declspec(dllexport) static HHOOK     hhook;
#pragma data_segment()
static void savehhook ( HHOOK hh )
{
  FILE * f=fopen( "C:\\HHOOK.TMP","wb" );
  if( !f )     return;
  fwrite( &hh,sizeof( hh ),1,f );
  fclose( f );
}
static HHOOK readhhook ( void )
{
  HHOOK hh;
  FILE * f=fopen( "C:\\HHOOK.TMP","rb" );
  if( !f )     return 0;
  fread( &hh,sizeof( hh ),1,f );
  fclose( f );
  return hh;
}
static void writelog ( char * op,HWND hwnd )
{
  char date[20];
  char time[20];
  char ptitle[256];
  SYSTEMTIME systime;
  FILE * f=fopen( "C:\\file.log","at" );
  if( !f )     return;
  GetLocalTime( &systime );
  GetDateFormat( LOCALE_SYSTEM_DEFAULT,
                 LOCALE_NOUSEROVERRIDE,
                 &systime,NULL,date,sizeof( date ) );
  GetTimeFormat( LOCALE_SYSTEM_DEFAULT,
                 LOCALE_NOUSEROVERRIDE,
                 &systime,NULL,time,sizeof( time ) );
  GetWindowText( hwnd,ptitle,sizeof( ptitle ) );
  fprintf( f,"[%8s - %8s] ; %s ; %s\n",date,time,op,ptitle );
  fclose( f );
}
LRESULT CALLBACK ShellProc( int nCode, WPARAM wParam, LPARAM lParam )
{
  if( nCode<0 ) return CallNextHookEx( hhook,nCode,wParam,lParam );
  else switch( nCode )
  {
  case HSHELL_WINDOWCREATED:
    writelog( "CREATE ",(HWND)wParam );
    break;
  case HSHELL_WINDOWDESTROYED:
    writelog( "destroy",(HWND)wParam );
    break;
  }
  CallNextHookEx( hhook,nCode,wParam,lParam );
  return 0;
}
__declspec( dllexport ) void setHook ( char * title )
{
  if( !hdll ) return;
  hhook=SetWindowsHookEx( WH_SHELL, (HOOKPROC)ShellProc, hdll, NULL );
  savehhook( hhook );
}
__declspec( dllexport ) void resHook ( void )
{
  if( hhook )  UnhookWindowsHookEx( hhook );
  hhook = NULL;
}
BOOL WINAPI DllEntryPoint( HINSTANCE hinstDLL,DWORD fdwReason,LPVOID
lpvReserved )
{
  if(fdwReason==DLL_PROCESS_ATTACH)
  {
    hdll=hinstDLL;
    if( hhook!=readhhook() )
      MessageBox( GetActiveWindow(),
                  "     non sono uguali     ",
                  "HOOK.DLL",MB_OK );
  }
  return TRUE;
}
------------------------------------------------------------
La MessageBox e' messa per debug.
Nel codice funzionante non c'e' l'if ma solo hhook=readhhook();
grazie, ciao
donCiccio

 static HHOOK readhhook ( void )
Perche` carichi/salvi l'hhook in un file?
E in ogni caso, non hai chiarito quale sia il problema. "Non funziona" e` un
po' generico. :)


Ciao,
non sono sicuro di aver capito fino in fondo di cosa avevi bisogno ma provo
a risponderti lo stesso....
se il tuo scopo è condividere la variabile "HHOOK hhook" tra tutte le
istanze della tua dll che vengono caricate nei processi in cui viene
iniettata la libreria credo dovresti eliminare il "__declspec(dllexport)"
davanti alla dichiarazione delle variabili, quindi:
#pragma data_segment(".sharedata")
    static HINSTANCE hdll;
    static HHOOK     hhook;
#pragma data_segment()
in questo modo non verrà creata un'istanza diversa delle variabili ogni
volta che la dll viene inettata ma verrà usata sempre la stessa zona di
memoria per la variabile "hhook". Quindi quando cambi valore, la modifichi
per tutte le istanze della dll che esistono.
Il modificatore "__declspec(dllexport)" serve invece per rendere le
variabili o le funzioni della libreria "esportabili" nell'eseguibile che
crei tu.
A questo punto le funzioni savehhook e readhhook secondo me non ti servono
più! La variabile hhook viene settata quando richiami SetWIndowsHookEx e poi
la usi in tutte le istanze...
Spero di esserti stato utile
Bye
Johnny

 memoria
__declspec(dllexport) serve soltanto per esportare il simbolo, ma le
variabili restano sempre allocate in una zona di memoria condivisa fra tutte
le istanze della DLL. E` vero, se la variabile e` utilizzata solo
all'interno della DLL non serve nemmeno metterlo, ma in ogni caso non
dovrebbe influire sul funzionamento del codice.


 po' generico. :)
il problema e' semplice:
la variabile hhook vale zero nelle istanze successive alla prima, e
quindi la funzione CallNextHookEx fallisce, e non funziona piu' la barra
delle applicazioni (o comunque tutti gli altri hook installati prima del
mio).
help!
ciao
donCiccio

 la usi in tutte le istanze...
non so dove sbaglio ma il problema persiste, nelle istanze seguenti
hhook vale zero.
non so se e' un dato utile, io uso BC++5.0
ciao
donCiccio

 aggiungo che uso BC++5.0
Io uso BCB5 ed anch'io non sono riuscito ad usare la memoria condivisa,
ho dovuto fare ricorso ad un file mappato in memoria creato con
CreateFileMapping a cui passo hFile = (HANDLE)0xFFFFFFFF
<SDK CreateFileMapping>
...
If hFile is (HANDLE)0xFFFFFFFF, the calling process must also specify a
mapping object size in the dwMaximumSizeHigh and dwMaximumSizeLow
parameters. The function creates a file-mapping object of the specified
size *backed* *by* *the* *operating-system* *paging* *file* rather than
by a named file in the file system. The file-mapping object can be shared
through duplication, through inheritance, or by name.
</SDK>
Ho letto sul Petzold che comunque anche la shared memory
viene implementata tramite mapped file per cui...
<chapter 21>
...
Shared Memory in DLLs
It's very nice that Windows isolates applications that are using the same
dynamic-link libraries at the same time. However, sometimes it's not
preferable. You may want to write a DLL that contains some memory that can
be shared among various applications, or perhaps among multiple instances
of the same application. This involves using shared memory, which is
actually a memory-mapped file.
...


Bye
Johnny

str***ata!
Tempo fa ho scritto un keylogger a livello di sistema.
Sfrutta i memory mapped file e funziona ancora benissimo.
Se vuoi ti mando il sorgente (e' in Delphi, pero').
--
Andrea Laforgia - walkietalkie(at)
libero.it
http://www.geocities.com/AndreaLaforgia

 prima
Prova a togliere "static".



sei molto gentile.
devo dire che ho gia' dato un'occhiata ad un tuo altro prog sempre in
Delphi, e non ci ho capito molto. (io oltre a C e ASM non so altro)
cmq se non ti secca mandarmelo, lo studio volientieri.
ciao
donCiccio

 Prova a togliere "static".
si ho provato, non e' quello.
il problema e' proprio BC5 (come detto da Massimo Valentini) che non
riconosce la linea:
#pragma data_segment(".sharedata")
e il bello e' che non da' nessun errore.
si puo' scrivere di tutto anche "#pragma pippo", e non si ottiene
nemmeno un warning.
ciao
donCiccio

 #pragma data_segment(".sharedata")
Ma che pieta`... :)
Allora prova a studiati un po' le opzioni del compilatore che utilizzi, puo`
darsi che sia possibile definire da riga di comando l'appartenenza dei
simboli alle zone di memoria.
