Wciskanie .dll do procesu za pomocą rejestru

0

Tak jak w:

http://4programmers.net/Forum/viewtopic.php?id=108632
//EDIT
Uwaga - Opisane tu zjawiska Mogą Zabić Twój System na Śmierć :-D
Odwiedz Link powyżej.
Zastanów się... i to nie jest żart..
Dlatego chyba tylko sapero podszedł konstruktywnie do tematu.
.... myli się tylko raz :-D

Ewentualnie Proszę Moderatorów o usunięcie Tematu , odpowiedz już uzyskałem
a nie chcę mieć kogoś na sumieniu .
//EDIT
Sposób wydał mi się kuszący ze względu na prostotę
wykonania jednak natrafiłem na pewne problemy.

Przykład 1.

Tworzę katalog na dysku w celu odizolowania 'test.dll'
od ładowania przez wszystkie aplikacje.
W katalogu umieszczam plik 'test.dll' i 'Notepad.exe'.
Kluczowi rejestru:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs

(przy pomocy regedit) nadaję wartość test.dll.

Uruchamiam Notepad.exe.
Biblioteka zostaje załadowana do pamięci procesu Notepad
i pozostaje w niej aż do zakończenia programu Notepad.
Biblioteka zawiera funkcję FunTest wyświetlającą okno
MessageBox jest ona wywoływana podczas ładowania
test.dll i usunięcia test.dll.
Obecność biblioteki sprawdzaiłem 'procdumpem' siedzi
cały czas.Zresztą widać to przy kończeniu Notepad.exe,
z test.dll jest wywołana FunTest wyświetlająca MessageBox.

Problem 1 (mało istotny) :
Okno pojawia się tylko podczas usuwania biblioteki przy
kończeniu programu Notepad.exe.

Nie pojawia się podczas ładowania biblioteki przez program.
FunTest jest wywoływana i inne funkcję mogą w niej działać
poprawinie (np.WriteFile itp ..) natomiast MessageBox
się nie wyświetla.Dlaczego ?
Kod biblioteki test.dll:

//-------------------------- PLIK test.cpp --------------------------------
//-----------------    Kompilator Borland C++ 3                    --------
//-----------------    biblioteka test.dll       --------------------------
#include <windows.h>
//-------------------------------------------------------------------------

#ifdef __cplusplus
extern "C"{
#endif

int __declspec(dllexport) FunTest(void);

#ifdef __cplusplus
       }
#endif

//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
    switch (reason)
	{
		case DLL_PROCESS_ATTACH:
             FunTest();            // wywołanie podczas ładowania
                                   // biblioteki 'test.dll'
         break ;
		case DLL_THREAD_ATTACH:
         break ;
		case DLL_THREAD_DETACH:
         break ;
         
		case DLL_PROCESS_DETACH:
             FunTest();            // wywołanie podczas zwolnienia
                                   // biblioteki 'test.dll'
			break;
    }
    return true;
}
//--------------------------------------------------------------------------
int FunTest(void)
{
  return MessageBox(NULL,"Test.DLL","Test Biblioteki",MB_OK);
}

=================================================

Przykład 2 :
Hook na MessageBoxW
Analogicznie jak w przykładzie 1 .
Ale tym razem biblioteka ma za zadanie po załadowaniu
a)utworzyć plik tekstowy 'log.txt'
b)odnaleźć punkt wejścia w IAT Notepada do funkcji 'MessageBoxW'
( Notepad z Win XP używa funkcji MessageBoxW )
c)przekierować Wywołanie MessageBoxW na funkcję Hook_MessageBox
z biblioteki 'test.dll'.
d)Funkcja Hook_MessageBox ma wywołać poprawnie MessageBoxW
i zdarzenie to zapisać do pliku 'log.txt'.

Przy ładowaniu biblioteki uruchamiane są w niej funkcja
tworząca plik 'log.txt' i funkcja zakładająca Hook na MessageBoxW.

Do odszukania tablicy IAT używam funkcji z biblioteki imagehlp.dll
o nazwie 'ImageDirectoryEntryToData'

Problem 2 (istotny) :

Wszystko pięknie działa do pewnego momentu .
Okazało się że użycie funkcji 'ImageDirectoryEntryToData' z imagehlp.dll
w funkcji zakładającej hook powoduje usunięcie mojej biblioteki
z procesu Notepad .
Najdziwniejsze jest to że funkcja 'ImageDirectoryEntryToData' wykonuje
się chyba poprawnie , ponieważ zwraca wartość za pomocą której
jest poprawnie lokalizowane przekierowanie na MessageBoxW,zakładany
hook , zapis do 'log.txt' .
Dopiero po dojściu do końca funkcji 'InitHookProc' z test.dll
bez jakich kolwiek oznak
że coś idzie nie tak biblioteka zostaje usunięta ('test.dll') .
Powoduje to przekierowanie wywołania MessageBoxW do funkcji
Hook_MessageBox w bibliotece której już nie ma w pamięci czyli
Notepad się wywala jeśli wywoła MessageBox ( np.monit o zapisaniu
zmienionego pliku).

Po zamknięciu Notepad.exe usuwam 'test.dll' lub ( wpis w rejestrze)
aby załadowanie biblioteki nie zniszczyło pliku 'log.txt',
zostałby nadpisany przy ogladaniu go w Notepad .
Czytam log.txt ----- i tak 3 dni .

Dlaczego biblioteka jest usuwana .
wszystko jest ok jeśli nie użyję funkcji ImageDirectoryEntryToData ,
pozostaje w pamięci .

Jeśli zaistniał by jakiś wyjątek wykonanie funkcji z mojej
biblioteki zostalo by przerwane po użyciu ImageDirectoryEntryToData.
Tak nie jest , funkcja z 'test.dll' śledzona pod Debugerem przechodzi
poprawnie przez wywołanie ImageDirectoryEntryToData dalej zapisuje
do pliku i wykonuje się do ostatniej instrukcji return funkcji InitHookProc .
Niestety nie ma gdzie już powrócić bo biblioteka zostaje wyładowana.
Dopiero tutaj następuje Access Violator.

Kompilator Borland C++ 3 .
Nie ma nagłowka "imagehlp.h" dlatego ładuję imagehlp.dll dynamicznie.
(Nie chce mi się kombinować z implibami)
Ale nie ma to znaczenia bo podobna biblioteka utworzona w Builder 4
z łaczeniem statycznym imagehlp działa podobnie , lub gorzej
,są problemy z ładowaniem przez notepad.I nie mogę się pozbyć
z niej odniesień do VCL , dziadostwo cholerne .

Przypuszczam że to powinno działać tak jak założyłem , pewności jednak
nie mam .
Fakt -> Nie działa .
???

Kod (roboczy :-)) biblioteki test.dll:

//-------------------------- Plik test.cpp ----------------------------------
//-------------------------- Biblioteka test.dll
#include <windows.h>
#include <string.h>
#include <stdlib.h>
//---------------------------------------------------------------------------
#define MESSAGEBOXW     // <-- wykomentować jeśli ma być poszukiwana
                        //             MessageBoxA
#ifdef __cplusplus
extern "C"{
#endif

int   InitLog(void) ;
int   InitHookProc(void);
#ifdef MESSAGEBOXW
int __declspec(dllexport)   Hook_MessageBox(HWND hWnd,PCWSTR lpText,
                           LPCWSTR lpCaption,UINT uType);
#else
int __declspec(dllexport)   Hook_MessageBox(HWND hWnd,PCSTR lpText,
                           LPCSTR lpCaption,UINT uType);
#endif
#ifdef __cplusplus
       }
#endif
//---------------------------------------------------------------------------
//-------------------- komunikaty do log.txt
char info[]           = "Ladowanie Biblioteki przez: " ;
char info_Hook[]      = "\r\nUżyto Funkcji MessageBox ." ;
char info_Mod[]       = "\r\nZnaleziono User32.dll" ;
char info_Error_Proc[]= "\r\nNie znaleziono MessageBox" ;
char info_Error_Mod[] = "\r\nNie znaleziono User32.dll" ;
char info_Error_Img[] = "\r\nNie znaleziono imagehlp.dll" ;
char info_Error_ImgProc[] = "\r\nNie znaleziono ImageDirectoryEntryToData" ;
char info_Error_Import[]  = "\r\nNie znaleziono sekcji importów" ;
char info_Error_NoProc[]  = "\r\nModul nie importuje takiej Funkcji. " ;
char info_Proc[]          = "\r\nZnaleziono MessageBox w IAT ." ;
char info_Error_Base[]    = "\r\nNie znaleziono test.dll" ;
char info_Return[]        = "\r\nKoniec Funkcji InitHookProc(void)\r\n" ;

char AddrProc[25] ;

PCSTR pszModName = "user32.dll" ;
PSTR temp ;

HANDLE hLog ;
DWORD  buf ;
HMODULE hModule ;
HMODULE hModule_user32 ;
HMODULE hTest_dll ;
HINSTANCE h_imagehlp ;

char buf_name[MAX_PATH] ;
bool status_log  ;
bool status_hook ;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc ;
PIMAGE_THUNK_DATA pThunk ;
ULONG ulSize ;

#define IMAGE_DIRECTORY_ENTRY_IMPORT  1

typedef PIMAGE_IMPORT_DESCRIPTOR (*pImageDirectoryEntryToData)(HMODULE h,
                                               DWORD a ,DWORD b,DWORD * c ) ;
pImageDirectoryEntryToData pImpDirToData ;

#ifdef MESSAGEBOXW
typedef int __declspec(dllexport)(*pMsgProc)(HWND hWnd,PCWSTR lpText,
                                          LPCWSTR lpCaption,UINT uType);
#else
typedef int __declspec(dllexport)(*pMsgProc)(HWND hWnd,PCSTR lpText,
                                          LPCSTR lpCaption,UINT uType);
#endif

PROC pOrgProc ;
pMsgProc pNewProc ;
PROC * ppOrgProc ; // adres do adresu funkcji
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
    switch (reason)
	{
		case DLL_PROCESS_ATTACH:

        status_log = InitLog();
        if(status_log)
        {
           status_hook = InitHookProc();
        }
         break ;

		case DLL_THREAD_ATTACH:
         break ;
		case DLL_THREAD_DETACH:
         break ;

		case DLL_PROCESS_DETACH:
        MessageBox(NULL,"Zwolniono bibliotekę.","test.dll",MB_OK);
        if(status_log)
        {
          CloseHandle(hLog);
          // FreeLibrary(h_imagehlp);
        }
			break;
    }
    return true;
}
//--------------------------------------------------------------------------
//  Funkcja otwiera plik do zapisu zdarzeń :
//  1)Załadowanie biblioteki
//  2)Użycie przechwyconej Funkcji
int  InitLog(void)
{
         hModule = GetModuleHandleA(NULL);
         if(hModule)
         {
         GetModuleFileNameA(hModule,buf_name,255);
         hLog = CreateFile("log.txt",GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS
                                       ,FILE_ATTRIBUTE_NORMAL,NULL);
        if(INVALID_HANDLE_VALUE != hLog)
        {
            WriteFile(hLog,info,strlen(info),&buf,NULL);
            WriteFile(hLog,buf_name,strlen(buf_name),&buf,NULL);
            return true ;
        }

         }
             return false ;
}
//--------------------------------------------------------------------------
#ifdef MESSAGEBOXW
int  Hook_MessageBox(HWND hWnd,PCWSTR lpText,
                       LPCWSTR lpCaption,UINT uType)
{
    int nresult = ((pMsgProc)pOrgProc)(hWnd ,lpText ,lpCaption,uType );
    // zapisz użycie MessageBoxW do pliku
     WriteFile(hLog,info_Hook,strlen(info_Hook),&buf,NULL);
     return nresult ;

}
#else
int  Hook_MessageBox(HWND hWnd,PCSTR lpText,
                       LPCSTR lpCaption,UINT uType)
{
    int nresult = ((pMsgProc)pOrgProc)(hWnd ,lpText ,lpCaption,uType );
    // zapisz użycie MessageBoxA do pliku
     WriteFile(hLog,info_Hook,strlen(info_Hook),&buf,NULL);
     return nresult ;

}
#endif
//-------------------------------------------------------------------------
int  InitHookProc(void)
{
        h_imagehlp = LoadLibraryA("imagehlp.dll");
        if(NULL == h_imagehlp)
        {
          WriteFile(hLog,info_Error_Img,strlen(info_Error_Img),&buf,NULL);
          return false;
        }

pImpDirToData =(pImageDirectoryEntryToData)GetProcAddress(h_imagehlp,
                                                   "ImageDirectoryEntryToData");
        if(NULL == pImpDirToData)
        {
          WriteFile(hLog,info_Error_ImgProc,strlen(info_Error_ImgProc),&buf,NULL);
          return false;
        }

        //  Poniżej wywołanie ImageDirectoryEntryToData
        //  wywołanie powoduje problemy , biblioteka zostaje zwolniona
        //  PO ZAKONCZENIU InitHookProc(void)

pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)pImpDirToData(hModule,true,
                   IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
         if(NULL == pImportDesc)
         {
          WriteFile(hLog,info_Error_Import,strlen(info_Error_Import),&buf,NULL);
          return false;
        }



        hModule_user32 = GetModuleHandle(pszModName); // user32.dll

        if(NULL == hModule_user32 )
        {
          WriteFile(hLog,info_Error_Mod,strlen(info_Error_Mod),&buf,NULL);
          return false ;
        }

#ifdef MESSAGEBOXW

        pOrgProc =GetProcAddress(hModule_user32,"MessageBoxW");
#else
        pOrgProc =GetProcAddress(hModule_user32,"MessageBoxA");
#endif
        if(NULL == pOrgProc)
        {
           WriteFile(hLog,info_Error_Proc,strlen(info_Error_Proc),&buf,NULL);
           return false ;
        }
        // jedziemy po imporcie

        for( ; pImportDesc->Name ; pImportDesc++)
        {
            temp =(PSTR)((PBYTE) hModule + pImportDesc->Name);
            if(lstrcmpiA(temp,pszModName) == 0)
            break;
        }
        if(pImportDesc->Name == 0 )
        {
             WriteFile(hLog,info_Error_NoProc,strlen(info_Error_NoProc),&buf,NULL);
             return false ;
        }

        pThunk = (PIMAGE_THUNK_DATA)((PBYTE)hModule + ((DWORD)(pImportDesc->FirstThunk)));

        for( ; pThunk ->u1.Function; pThunk++)
        {
            ppOrgProc = (PROC*) &pThunk ->u1.Function ;
            if(*ppOrgProc == pOrgProc)
            {

                    ultoa((DWORD)*pOrgProc,AddrProc,16); //dla loga
                   // znaleziono
          // zapisz nowy adres procedury w IAT
          pNewProc = Hook_MessageBox ;
          WriteProcessMemory(GetCurrentProcess(),ppOrgProc ,&pNewProc,
                                     sizeof(pNewProc),NULL);

           WriteFile(hLog,info_Proc,strlen(info_Proc),&buf,NULL);
           WriteFile(hLog,AddrProc,strlen(AddrProc),&buf,NULL);
           WriteFile(hLog,info_Return,strlen(info_Return),&buf,NULL);
                return true ;
             }

         }

         WriteFile(hLog,info_Error_NoProc,strlen(info_Error_NoProc),&buf,NULL);
         WriteFile(hLog,info_Return,strlen(info_Return),&buf,NULL);
             return false ;

}

Uwaga :
Biblioteka była testowana na Notepad.exe (z XP) plik nie posiada
informacji o sekcji importu w IMAGE_SECTION_HEADER ,
a jedynie wpis w IMAGE_DATA_DIRECTORY .
Skoro jednak funkcja 'ImageDirectoryEntryToData' zwraca wartość różną od NULL
to znaczy że potrafi trafić do symboli importowanych.

Testowana na WinRar.exe ( Poszukiwanie MessageBoxA ) i też lipa .
WinRar posiada "normalny" opis sekcji importu i sekcję.
Biblioteka zostaje wyrzucona z pamięci.

Aplikacje testowe napisane w C++ Builder i wołające Funkcję
MessageBoxA i MessageBoxW napisane aby sprawdzić bibliotekę
nie chcą załadować 'imagehlp.dll' poprzez 'test.dll'.
A jeśli dołączę statycznie 'imagehlp.dll' do 'test.dll' to niechcą
w ogóle załadować biblioteki 'test.dll'
Normalnie to jakaś kicha(ku..ca mnie już bierze).
Sposób użycia 'ImageDirectoryEntryToData' i poszukiwanie
importowanych symboli zaczerpnąłem z "Programowanie aplikacji dla Ms Windows"
Jeffrey'a Richtera ....

0

Inicjacja dll wykonuje się w trybie chronionym, jakikolwiek wyjątek spowoduje wyładowanie dlla. Wyjątek ma miejsce w problemie 2, ponieważ host (użyłem regsvr32.exe) skacze w kosmiczny adres NULL, bo źle zdefiniowałeś kilka funkcji:
typy pImageDirectoryEntryToData i pMsgProc powinny być stdcall.

//imagehelp.h

#define IMAGEAPI __stdcall
PVOID IMAGEAPI ImageDirectoryEntryToData(
	PVOID Base,
	BOOLEAN MappedAsImage,
	USHORT DirectoryEntry,
	ULONG* Size);

No a MessageBox jest typu WINAPI, co sam mozesz sprawdzić - stdcall+dllimport.

Pierwszy problem przypuszczalnie polega na tym, że user32 ładuje Twojego dll ze swojego DllMain, zanim połączy wątek z desktopem/windowstation, wtedy nie masz szans na jakiekolwiek operacje z gdi. Ale możesz wywołać FunTest() z dodatkowego wątku.

Zmodyfikowałem troszkę pierszy kod:

int WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void*)
{
	int rrr;
	DWORD e;
	char firstmsg[MAX_PATH];
	switch (reason)
	{
		case DLL_PROCESS_ATTACH:
			GetModuleFileName(0,firstmsg,MAX_PATH);
			CharLower(firstmsg);
			if (!strstr(firstmsg, "notepad")) return false;

			status_log = (bool)InitLog();
			rrr = MessageBox(0,"loading","",0);
			e = GetLastError();

			if(status_log)
			{
				wsprintf(firstmsg, "\nMessageBox error: %d\n", e);
				WriteFile(hLog,firstmsg,(DWORD)strlen(firstmsg),&e,NULL);
				status_hook = (bool)InitHookProc();
			}
			break ;

I w logu pojawiło się

MessageBox error: 1407
czyli ERROR_CANNOT_FIND_WND_CLASS, co oznacza że user32 ładuje dll zanim zarejestruje klasę okna dialogowego :)

0

@sapero
Ok. Dzięki , to wyjaśnia pierwszy problem .
Co do deklaracji Funkcji zmienię je , faktycznie to przeoczyłem z nadmiaru pomysłów ...
Przeniosę kod z funkcją ImageDirectoryEntryToData i poszukiwaniem do normalnego .exe i tam przeprowadzę na razie analizę , będzie wygodniej .
Do usłyszenia .
dzejo.

0

Już działa , s(a)uperowo ,dzięki za podpowiedz .
Kod:

//-------------------------- Plik test.cpp ----------------------------------
//-------------------------- Biblioteka test.dll
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
//---------------------------------------------------------------------------
// W celu Przechwycenia MessageBoxW usunąć komentarz MESSAGEBOXW
//#define MESSAGEBOXW     // <-- wykomentować jeśli ma być poszukiwana
                        //             MessageBoxA
#ifdef __cplusplus
extern "C"{
#endif

int   InitLog(void) ;
int   InitHookProc(void);
#ifdef MESSAGEBOXW
int WINAPI   Hook_MessageBox(HWND hWnd,PCWSTR lpText,
                           LPCWSTR lpCaption,UINT uType);
#else
int WINAPI   Hook_MessageBox(HWND hWnd,PCSTR lpText,
                           LPCSTR lpCaption,UINT uType);
#endif
#ifdef __cplusplus
       }
#endif
//---------------------------------------------------------------------------
//-------------------- komunikaty do log.txt
char info[]           = "Ladowanie Biblioteki przez: " ;
char info_Hook[]      = "\r\nUżyto Funkcji MessageBox ." ;
char info_Error_Proc[]= "\r\nNie znaleziono MessageBox" ;
char info_Error_Mod[] = "\r\nNie znaleziono User32.dll" ;
char info_Error_Img[] = "\r\nNie znaleziono imagehlp.dll" ;
char info_Error_ImgProc[] = "\r\nNie znaleziono ImageDirectoryEntryToData" ;
char info_Error_Import[]  = "\r\nNie znaleziono sekcji importów" ;
char info_Error_NoProc[]  = "\r\nModul nie importuje takiej Funkcji. " ;
char info_Proc[]          = "\r\nZnaleziono MessageBox w IAT ." ;
char info_Return[]        = "\r\nKoniec Funkcji InitHookProc(void)\r\n" ;
char buf_log[MAX_PATH] ;

char AddrProc[25] ;

PCSTR pszModName = "user32.dll" ;
PSTR temp ;

HANDLE hLog ;
DWORD  buf ;
HMODULE hModule ;
HMODULE hModule_user32 ;
HINSTANCE h_imagehlp ;

char buf_name[MAX_PATH] ;
bool status_log  ;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc ;
PIMAGE_THUNK_DATA pThunk ;
ULONG ulSize ;
bool rez ;
DWORD oldProtect ;

#define IMAGE_DIRECTORY_ENTRY_IMPORT  1

#define IMAGEAPI __stdcall
typedef PVOID IMAGEAPI (*pImageDirectoryEntryToData)(PVOID Base,BOOLEAN MappedAsImage,
        USHORT DirectoryEntry,ULONG* Size);

pImageDirectoryEntryToData pImpDirToData ;

#ifdef MESSAGEBOXW
typedef int WINAPI(*pMsgProc)(HWND hWnd,PCWSTR lpText,
                                          LPCWSTR lpCaption,UINT uType);
#else
typedef int WINAPI(*pMsgProc)(HWND hWnd,PCSTR lpText,
                                          LPCSTR lpCaption,UINT uType);
#endif

PROC pOrgProc ;
PROC pNewProc ;
PROC * ppOrgProc ; // adres do adresu funkcji
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
    switch (reason)
        {
                case DLL_PROCESS_ATTACH:

        status_log = InitLog();
        if(status_log)
        {
           InitHookProc();
        }
         break ;

                case DLL_THREAD_ATTACH:
         break ;
                case DLL_THREAD_DETACH:
         break ;

                case DLL_PROCESS_DETACH:
        if(status_log)
        {
          CloseHandle(hLog);
        }
                        break;
    }
    return true;
}
//--------------------------------------------------------------------------
//  Funkcja otwiera plik do zapisu zdarzeń :
//  1)Załadowanie biblioteki
//  2)Użycie przechwyconej Funkcji
int  InitLog(void)
{
         hModule = GetModuleHandleA(NULL);
         if(hModule)
         {
         GetModuleFileNameA(hModule,buf_name,MAX_PATH);
         hLog = CreateFile("log.txt",GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS
                                       ,FILE_ATTRIBUTE_NORMAL,NULL);
        if(INVALID_HANDLE_VALUE != hLog)
        {
            WriteFile(hLog,info,strlen(info),&buf,NULL);
            WriteFile(hLog,buf_name,strlen(buf_name),&buf,NULL);
            return true ;
        }

         }
             return false ;
}
//--------------------------------------------------------------------------
#ifdef MESSAGEBOXW
int WINAPI Hook_MessageBox(HWND hWnd,PCWSTR lpText,
                       LPCWSTR lpCaption,UINT uType)
{
    int nresult = ((pMsgProc)pOrgProc)(hWnd ,lpText ,lpCaption,uType );
    // zapisz użycie MessageBoxW do pliku
     WriteFile(hLog,info_Hook,strlen(info_Hook),&buf,NULL);
     return nresult ;

}
#else
int  WINAPI Hook_MessageBox(HWND hWnd,PCSTR lpText,
                       LPCSTR lpCaption,UINT uType)
{
    int nresult = ((pMsgProc)pOrgProc)(hWnd ,lpText ,lpCaption,uType );
    // zapisz użycie MessageBoxA do pliku
     WriteFile(hLog,info_Hook,strlen(info_Hook),&buf,NULL);
     return nresult ;

}
#endif
//-------------------------------------------------------------------------
int  InitHookProc(void)
{
       h_imagehlp = LoadLibraryA("imagehlp.dll");
        if(NULL == h_imagehlp)
        {
          WriteFile(hLog,info_Error_Img,strlen(info_Error_Img),&buf,NULL);
          return false;
        }

pImpDirToData =(pImageDirectoryEntryToData)GetProcAddress(h_imagehlp,
                                                   "ImageDirectoryEntryToData");
        if(NULL == pImpDirToData)
        {
          WriteFile(hLog,info_Error_ImgProc,strlen(info_Error_ImgProc),&buf,NULL);
          return false;
        }
        //Znajdz wejście do importów
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)pImpDirToData(hModule,true,
                   IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
         if(NULL == pImportDesc)
         {
          WriteFile(hLog,info_Error_Import,strlen(info_Error_Import),&buf,NULL);
          return false;
        }

        FreeLibrary(h_imagehlp);

        hModule_user32 = GetModuleHandle(pszModName); // user32.dll

        if(NULL == hModule_user32 )
        {
          WriteFile(hLog,info_Error_Mod,strlen(info_Error_Mod),&buf,NULL);
          return false ;
        }

#ifdef MESSAGEBOXW

        pOrgProc =GetProcAddress(hModule_user32,"MessageBoxW");
#else
        pOrgProc =(PROC)GetProcAddress(hModule_user32,"MessageBoxA");
#endif
        if(NULL == pOrgProc)
        {
           WriteFile(hLog,info_Error_Proc,strlen(info_Error_Proc),&buf,NULL);
           return false ;
        }
        // jedziemy po imporcie

        for( ; pImportDesc->Name ; pImportDesc++)
        {
            temp =(PSTR)((PBYTE) hModule + pImportDesc->Name);
            if(lstrcmpiA(temp,pszModName) == 0)
            break;
        }
        if(pImportDesc->Name == 0 )
        {
             WriteFile(hLog,info_Error_NoProc,strlen(info_Error_NoProc),&buf,NULL);
             return false ;
        }

        pThunk = (PIMAGE_THUNK_DATA)((PBYTE)hModule + ((DWORD)( pImportDesc->FirstThunk)));

        for( ; pThunk ->u1.Function; pThunk++)
        {
            ppOrgProc = (PROC*) &pThunk ->u1.Function ;
            if(*ppOrgProc == pOrgProc)// znaleziono
            {
               pNewProc =(PROC) Hook_MessageBox ;
          // zapisz nowy adres procedury w IAT
  // zmień atrybuty ochrony pamięci
  rez =VirtualProtectEx(GetCurrentProcess(),ppOrgProc,4,
                                PAGE_EXECUTE_READWRITE,&oldProtect);
  if(0 == rez)
  {
   sprintf(buf_log,"\nError -> VirtualProtect" ) ;
   WriteFile(hLog,buf_log,strlen(buf_log),&buf,NULL);
   return false ;
  }
         // podstaw Adres mojej procedury pod MessageBox w IAT
         // Można też tak -> *ppOrgProc = pNewProc ;
         rez = WriteProcessMemory(GetCurrentProcess(),ppOrgProc ,&pNewProc,
                                sizeof(pNewProc),NULL);
         if(false == rez)
         {
           sprintf(buf_log,"\nError -> WriteProcessMemory" ) ;
           WriteFile(hLog,buf_log,strlen(buf_log),&buf,NULL);
           return false ;
         }
  // przywróć ochronę pamięci
  rez =VirtualProtectEx(GetCurrentProcess(),ppOrgProc,4,
                                            oldProtect,&oldProtect);
  if(0 == rez)
  {
   sprintf(buf_log,"\nError -> VirtualProtect" ) ;
   WriteFile(hLog,buf_log,strlen(buf_log),&buf,NULL);
   return false ;
  }
           ultoa((DWORD)*pOrgProc,AddrProc,16); //dla loga
           WriteFile(hLog,info_Proc,strlen(info_Proc),&buf,NULL);//log
           WriteFile(hLog,AddrProc,strlen(AddrProc),&buf,NULL);//log
           WriteFile(hLog,info_Return,strlen(info_Return),&buf,NULL);
               return true ;
             }

         }
         // jeśli tu , brak Funkcji
         WriteFile(hLog,info_Error_NoProc,strlen(info_Error_NoProc),&buf,NULL);
         WriteFile(hLog,info_Return,strlen(info_Return),&buf,NULL);
             return false ;
}

Log z podrzucenia do WinRar 'log.txt' :

Ladowanie Biblioteki przez: C:\WinRAR\WinRAR.exe
Znaleziono MessageBox w IAT .77d5add7
Koniec Funkcji InitHookProc(void)

Użyto Funkcji MessageBox .
Użyto Funkcji MessageBox .

Wprawdzie występuje problem z aplikacjami Napisanymi w Builderze ,
niechcą ładować 'imagehlp.dll' poprzez moją bibliotekę (dynamicznie) ,ale co tam .

0

A ja sobie kiedyś chciałem wcisnąc DLLa przez rejestr i po restarcie Windows mi się nie chciał odpalić ;-P Musiałem ten syf z poziomu Linuxa usuwać dopiero potem poszło, więc nie mam zamiaru się więcej bawić w ten sposób. Dodam, że na pewno to nie była wina DLL.

0

Cha ,cha ... [green]

więc nie mam zamiaru się więcej bawić w ten sposób

Pisałem czym to grozi i jak się ustrzec problemów ( czyt . nie rozwalić systemu),
można spokojnie uruchomić .dll LOKALNIE nie zaśmiecając systemu.
Link w pierwszym Poście sobie zobacz...
Moja biblioteczka chodzi sobie i nie robi zamieszania (oczywiście nie wrzucam jej do katalogu
'system32' i inne systemowe, a także nie podaję pełnej ścieżki dostępu w rejestrze. :-D) .

Oczywiście jeśli dysk posiada system plików NTFS trzeba się dobrze zastanowić nad
eksperymentami tego typu ,bo odzyskanie sprawności systemu może być trudne .

No ale w końcu jest to Forum dla Programistów i jak ktoś sobie zrobi krzywdę
nie rozumiejąc o co chodzi to trudno ....niech się nie bawi [green] .

Dlatego edytuję PIERWSZY post , dobrze że zwróciłeś na to uwagę , dzięki .

                                                                         pozdro.
0

dzejo, lepiej by było gdyby biblioteka była na wierzchu partycji systemowej, w \windows lub \system32, bo wtedy będzie można ją usunąć z konsoli odzyskiwania w razie wpadki.
Ponadto każdy cwany programista używa RegSaveKey zanim zrobi coś nieznanego, aby mieć szansę na przywrócenie rejestru (HKLM) spod konsoli odzyskiwania lub natywnym programem uruchamianym podczas bootowania systemu

#include <windows.h>
#include <wchar.h>
#include <stdio.h>
#include <conio.h>

void Save(HKEY hkRoot, WCHAR* wszRoot, WCHAR* wszSubkey)
{
	wprintf(L"saving %s\\%s to c:\\%s\n", wszRoot, wszSubkey, wszSubkey);
	HKEY hk;
	UINT code;
	WCHAR msg[MAX_PATH];

	if (RegOpenKey(hkRoot, wszSubkey, &hk))
	{
		code = GetLastError();
		wprintf(L"failed to open key: ");
	}
	else
	{
		wsprintf(msg, L"c:\\%s", wszSubkey);
		code = RegSaveKey(hk, msg, 0);
		RegCloseKey(hk);

		if (code)
			wprintf(L"failed to save key: ");
	}
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|255, 0, code, 0, msg, MAX_PATH, 0);
	wprintf(L" - %s\n\n", msg);
}


int main()
{
	HANDLE hAccessToken;
	TOKEN_PRIVILEGES tp;

	OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hAccessToken);
	LookupPrivilegeValue( NULL, SE_BACKUP_NAME, &tp.Privileges[0].Luid);
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	AdjustTokenPrivileges(hAccessToken, FALSE, &tp, sizeof(tp), NULL, NULL );
	CloseHandle(hAccessToken);

	Save(HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE", L"HARDWARE");
	Save(HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE", L"SAM");
	Save(HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE", L"SECURITY");
	Save(HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE", L"SOFTWARE"); // to może potrwać
	Save(HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE", L"SYSTEM");

	system("pause");
	return 0;
}

Powstałe pliki należy przenieść do numerowanego folderu (najlepiej w \system32\config\repairXXX) gdzie X'y to kolejne numerki, a w razie konieczności uruchomić konsolę odzyskiwania systemu (z płytki xp) i podmienić pliki:

cd system32\config
ren system system.old
ren software software.old
copy restore1\system system
copy restore1\software software
  • ewentualnie resztę plików.

Te same pliki są tworzone przez usługę przywracania systemu w %SYSTEMDRIVE%\System Volume Information_restore{guid}\RP**\snapshot\ ale nie mamy dostępu do tego folderu z poziomu konsoli, możemy błądzić tylko w \windows i po 'wierzchu' partycji.

0

Ciekawe , ale trzeba desperata aby wypróbować podane przez Ciebie możliwości .
Ja przy swoich testach uzyskałem super efekt , a mianowicie
w trybie awaryjnym konsola nie dała się uruchomić .
Musiałem zaatakować z zewnątrz .

Z płyty nie próbowałem .(może jak zarchiwizuje wszystkie ważne dane :-) )
Hej .

Ps. Właściwie bibliotekę napisałem z zamiarem łatwego podrzucania jej do pojedyńczych
aplikacji , pakowanie się do wszystkich procesów z user32.dll w ten sposób to lekka przesada,
moim zdaniem .

1 użytkowników online, w tym zalogowanych: 0, gości: 1