IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

hooking fonctions API


Sujet :

Windows

  1. #1
    Candidat au Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 4
    Points
    4
    Par défaut hooking fonctions API
    Bonjour à tous!

    Je vais essayer d'expliqué mon problème le plus simple possible.

    Le but de mon petit programme test est de faire un "hooking" sur les 3 fonctions de Registre "RegQueryValueEx", "RegCreateKeyEx", "RegOpenKeyEx" afin de tracer leur appel dans un fichier (log file).

    Mon problème se situe lorsque dans la méthode "MakeHook(...)" on essai de récupérer le PIMAGE_IMPORT_DESCRIPTOR du processus cible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
    	   ImageDirectoryEntryToData(hModCaller, true, IMAGE_DIRECTORY_ENTRY_IMPORT, &uSize);
    A chaque fois j'obtiens une erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Unhandled exception at 0x76c941f4 in testHook.exe: 0xC0000005: Access violation reading location 0x00000fd0.
    Est-ce que je crée le processus(ligne 326) avec les bons attributs de sécurité pour accéder à la mémoire du processus?

    Pourquoi cette erreur?

    @+

    InovaH

    PS. le code source
    Fichiers attachés Fichiers attachés

  2. #2
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    Pas compilé le code mais à la lecture :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	   HANDLE hproc= ProcessInfo.hProcess;	
     
           PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
    	   // le 1er param est la base du module, pas le HANDLE du process !
    	   ImageDirectoryEntryToData(hproc, true, IMAGE_DIRECTORY_ENTRY_IMPORT, &uSize);

    N'oublie pas de remplir le membre "cb" de STARTUPINFO :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	ZeroMemory( &StartupInfo, sizeof(STARTUPINFO) );
     
    	// ne pas oublier de remplir la taille de la struct.
    	StartupInfo.cb = sizeof(STARTUPINFO);

    Si ça ne fonctionne toujours pas j'essaierais de compiler pour voir ce qui ne va pas.

  3. #3
    Candidat au Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Hello,
    merci pour ta réponse Neitsa, il me semble que ça m'a permis de comprendre la structure..

    Dis-moi ci je me trompe, mais avant que je face appel à "ImageDirectoryEntryToData(...), il faut d'abord que:
    1. pointer sur IMAGE_DOS_HEADER
    2. Récupérer la valeur d'lfanew ->IMAGE_NT_HEADER
    3. Parcourir IMAGE_DATA_DIRECTORY
    4. puis enfin appeler IMAGE_IMPORT_DIRECTORY pour chaque DLL


    Mon raisonnement est juste ou pas besoin de toutes ces étapes?

    @+

  4. #4
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    J'ai regardé attentivement ton code ce matin et plusieurs choses me chiffonne :

    1) Tu sembles, dans ton code, supposer que ton exécutable et iexplore sont dans le même espace d'adressage, ce qui est faux. C'est pour cette raison (espace d'adressage séparés) qu'on préfère généralement injecter une DLL dans l'espace d'adressage du processus cible (dans ton cas, iexplore).

    2) Incidemment, ta recherche de fonction s'en trouve biaisée. Tu part du principe que le paramètre "Address" de MakeHook() sera le même dans ton espace d'adressage que dans celui d'iexplore, ce qui peut être juste... comme totalement faux.

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    bool MakeHook(bool bToActive, PROC Address, PROC FunctionHook);

    (j'imagine que PROC est un PVOID ?)

    Si on était dans une DLL injectée, ton code serait valide, mais pas dans le cas présent :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	   // Liste toutes les fonctions référencées dans l'address table 
           for(; pThunk->u1.Function ; pThunk++) {
     
              PROC *pFn = (PROC *)&pThunk->u1.Function;
    		  if(*pFn == Address) {
     
    			 AddressOfFunction = pFn;   // Overwrite à l'emplacement de l'adresse
    			 break;
    		  }
    	   }

    Autre chose que je ne comprend pas dans le code ci-dessus :

    Vue que "AddressOfFunction" est une var. statique dans ton code, tu ne remplace pas la fonction de iexplore directement par la tienne. Un code comme celui-ci me paraît plus parlant :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
        while ( pThunk->u1.Function != NULL)
        {
           if ( pThunk->u1.Function == Address)
            {
                // remplace la fonction d'iexplore par celle que l'on veut.
                pThunk->u1.Function = FunctionHook; 
     
                break;
            }
     
            pThunk++;
        }

    3) A propos du code suivant :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	      // Remplacement de l'adresse en question...
    	      VirtualProtect(AddressOfFunction, 4, PAGE_EXECUTE_READWRITE, &dwOld);

    VirtualProtect sert uniquement à changer la protection sur une page (ou une region de page) entière. Donc il faut changer la protection de la page où se trouve l'IAT (import address table) toute entière. Mais effectivement c'est bien vue puisque l'IAT est en lecture seule.

    Tu peux obtenir l'adresse de la page en comparant celle de l'IMAGE_DATA_DIRECTORY et celle de l'IMAGE_SECTION_HEADER correspondant (ou en utilisant ImageDirectoryEntryToData() comme tu le fais le problème étant qu'avec cette fonction tu n'aura pas la taille...).

    Note que dans le cas d'un DLL injectée dans iexplore, c'est bien VirtualProtect(), mais dans le cas d'un processus étranger à iexplore, c'est VirtualProtectEx() qu'il faut appeler.

    J'espère avoir été un peu clair (et avoir tout compris) . N'hésites pas si tu as des questions, ou si je dis n'importe quoi .

  5. #5
    Candidat au Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Hello!

    Avant d'aller plus loin, je voudrais te remercier sincèrement pour avoir lu mon code.
    Comme tu t'en es aperçu par le code, je débute dans le hooking, et j'ai pris des bouts de codes ça-et-là, ce qui à donner le patchwork que à lu.
    En Tous cas tes commentaires m'ont beaucoup aider pour comprendre et optimiser le code. Encore .

    Pour le point 1) et 2):

    Tu sembles, dans ton code, supposer que ton exécutable et iexplore sont dans le même espace d'adressage, ce qui est faux.
    En fait, c'est voulu et pas... je m'explique. Le but final bien est d'avoir une DLL, mais étant donné que je n'étais pas sûr de mon code, j'ai pensé qu'en faisant un projet app console on pourrait plus facilement debugger le fonctionnement et récupérer les addresses mémoires(imageBase, fonctions, thunk, ...)

    Après avoir lu ton commentaire, c'est vrai que c'est logique que les adressages ne sont pas correctes, vu que comme cela on travaille en même temps avec la mémoire du processus et celui du programme qui est en mode debugg.

    Le problème c'est que j'ai bien tenté de chercher les adresses des thunks et la IAT avec OllyDbg mais je ne trouve pas. Est-ce que tu utilises un autre programme pour tracer la mémoire des processus?

    Point 3):
    Tu peux obtenir l'adresse de la page en comparant celle de l'IMAGE_DATA_DIRECTORY et celle de l'IMAGE_SECTION_HEADER correspondant (ou en utilisant ImageDirectoryEntryToData() comme tu le fais le problème étant qu'avec cette fonction tu n'aura pas la taille...).
    J'ai tout à fait compris le principe, par contre il y a une moitié que je n'arrive pas à trouver en codant.
    En fait, il faudrait récupérer les IMAGE_DATA_DIRECTORY (1 par Dll), les parcourir pour obtenir la taille totale, non?
    Mais pour l'IMAGE_SECTION_HEADER je ne comprends pas comment la comparer pour obtenir les pages à modifier pour le VirtualProtect(...).


    En tout cas tu m'as bien aider et ça donne plein d'idées pour la suite

    @bientôt

    InovaH

  6. #6
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    De rien

    En fait, c'est voulu et pas... je m'explique. Le but final bien est d'avoir une DLL, mais étant donné que je n'étais pas sûr de mon code, j'ai pensé qu'en faisant un projet app console on pourrait plus facilement debugger le fonctionnement et récupérer les addresses mémoires(imageBase, fonctions, thunk, ...)
    C'est ce que je me suis dit rétrospectivement. Débugger du code injecter ou un hook, c'est vraiment galère...

    Le plus simple, quand on a du code qui n'est pas testable en tant que tel [parce qu'il est dépendant de l'injection] par exemple c'est de:

    - Mettre un debug break (Lien MSDN) dans son code, ce qui va faire crasher le programme.

    - S'attacher avec un debugger au programme.

    - Passer l'exception au debugger (ou patcher l'int3 (0xCC) du debugbreak) et tracer son code.

    -Sous Win XP et sup. on peut même, ensuite, se détacher du programme sans le tuer.

    Le problème c'est que j'ai bien tenté de chercher les adresses des thunks et la IAT avec OllyDbg mais je ne trouve pas. Est-ce que tu utilises un autre programme pour tracer la mémoire des processus?
    C'est un peu la galère sous Olly, je te le concède, même si c'est possible. En analyse statique j'utilise PeBrowse Pro (freeware) : http://www.smidgeonsoft.prohosting.com/software.html

    Tu peux avoir les thunks facilement (ex. avec iexplore) :

    Structure for Import
    Starting at: 0x0040E564
    Table #1 (ADVAPI32.dll):
    (+0x00) ImportLookupTableRVA: 0x0000E6DC
    (+0x0000) Thunk01: 0x0000E9C0 (554, RegCloseKey)
    (+0x0004) Thunk02: 0x0000E9CE (616, RegQueryValueExW)
    (+0x0008) Thunk03: 0x0000E9E2 (603, RegOpenKeyExW)
    (+0x000C) Thunk04: 0x0000E9F2 (588, RegEnumValueW)
    (+0x0010) Thunk05: 0x0000EA02 (586, RegEnumKeyW)
    ...
    J'ai tout à fait compris le principe, par contre il y a une moitié que je n'arrive pas à trouver en codant.
    En fait, il faudrait récupérer les IMAGE_DATA_DIRECTORY (1 par Dll), les parcourir pour obtenir la taille totale, non?
    Mais pour l'IMAGE_SECTION_HEADER je ne comprends pas comment la comparer pour obtenir les pages à modifier pour le VirtualProtect(...).
    En fait l'IMAGE_DATA_DIRECTORY (IDD) de l'IAT (le 13ième IDD) donne bien l'adresse et la taille de l'IAT, mais ça n'est pas suffisant pour "déprotéger" la page, même si on la calcule correctement à partir de ces données, car l'IAT peut être dans une autre section. Exemple frappant, Internet Explorer qui a son IAT dans la section de code...

    IMAGE_DATA_DIRECTORY de l'IAT pour IE7 :

    VirtualAdress = 0x1000.
    Size = 0x2E4.

    On pourrait se dire que la taille de la page fait 0x1000 (on doit aligner la taille sur le membre "SectionAlignement" de l'IMAGE_OPTIONAL_HEADER (IOH) qui vaut généralement 0x1000).

    Le problème c'est que 0x1000 c'est aussi l'adresse la section de code... Pour ça il faut aller chercher l'IMAGE_SECTION_HEADER ayant une adresse à 0x1000 pour obtenir la taille exacte de la section entière (code + IAT + ...).

    En résumé, il faut donc :

    - Obtenir l'IDD de l'IAT.
    - Obtenir l'adresse de l'IAT (IDD.VirtualAdress)
    - Chercher un IMAGE_SECTION_HEADER (ISH) ayant une VirtualAddress == IDD.VirtualAdress.
    - Obtenir la VirtualSize de l'ISH (ISH.VirtualSize).
    - Aligner la taille avec IOH.SectionAlignement.

    La taille alignée = taille de la page à dé-protégée.

    Exemple de code (c'est vite codé, donc pas forcément la panacée...). N'hésite pas à débugger pour voir de quoi il retourne :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
     
    // TestCpp.cpp : Defines the entry point for the console application.
    //
     
    #include <windows.h>
    #include <iostream>
     
    typedef struct _MemPage
    {
    	LPVOID PageAdress; // RVA de la page.
    	DWORD Size; // taille de la page.
    }MemPage, *PMemPage;
     
    bool GetIatPage(LPVOID pMapping, PMemPage aPage);
     
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	// ouverture du fichier PE.
    	HANDLE hFile = CreateFile(_T("C:\\Program Files\\Internet Explorer\\iexplore.exe"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    	if(hFile == INVALID_HANDLE_VALUE)
    	{
    		return -1;
    	}
     
    	HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
    	if(hMap == NULL)
    	{
    		return -1;
     
    	}
     
    	LPVOID pMap = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
    	if(pMap == NULL)
    	{
    		return -1;
    	}
     
    	PMemPage IeIatPage = new MemPage();
     
    	if(GetIatPage(pMap, IeIatPage))
    		std::cout << "IAT page address: 0x" << std::hex << IeIatPage->PageAdress \
    		<< std::endl << "IAT section page size : 0x" <<  IeIatPage->Size << std::endl;
     
    	CloseHandle(hFile);
    	UnmapViewOfFile(pMap);
    	CloseHandle(hMap);
     
    	return 0;
    } 
     
    bool GetIatPage(LPVOID pMapping, PMemPage IePage)
    {
    	BOOL bRet = FALSE;
     
    	// transtypage vers IMAGE_DOS_HEADER*
    	PIMAGE_DOS_HEADER pIDH = static_cast<PIMAGE_DOS_HEADER>(pMapping);
     
    	// check si "MZ" signature.
    	if(pIDH->e_magic != IMAGE_DOS_SIGNATURE)
    	{
    		return false;
    	}
     
    	PIMAGE_NT_HEADERS pINH = reinterpret_cast<PIMAGE_NT_HEADERS>(static_cast<BYTE*>(pMapping) + pIDH->e_lfanew);
     
    	if(pINH->Signature != IMAGE_NT_SIGNATURE)
    	{
    		return false;
    	}
     
    	//vérifie si PE (32 bits) ou PE+ (64 bits)
    	if(pINH->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
    	{
    		return false;
    	}
     
    	//obtient l'imagebase.
    	DWORD ImageBase = pINH->OptionalHeader.ImageBase;
     
    	// obtient l'IMAGE_DATA_DIRECTORY de l'IAT.
    	IMAGE_DATA_DIRECTORY IDH = pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT];
     
    	// On prend l'adresse de l'IAT
    	DWORD IatRva = IDH.VirtualAddress;
     
    	// obtient l'adresse du premier IMAGE_SECTION_HEADER
    	PIMAGE_SECTION_HEADER pISH = IMAGE_FIRST_SECTION(pINH);
     
    	// on cherche un IMAGE_SECTION_HEADER avec la même adresse.
    	bool bFoundISH = false;
    	int i = 0;
    	for (i = 0; i < pINH->FileHeader.NumberOfSections; i++)
    	{
    		if(pISH->VirtualAddress == IatRva)
    		{
    			bFoundISH = true;
    			break;
    		}
    		else
    			pISH++;
    	}
     
    	if(!bFoundISH)
    		return false;
     
    	// Calcule taille de la section.
    	DWORD SecAlign = pINH->OptionalHeader.SectionAlignment;
     
    	DWORD PageSize = (pISH[i].Misc.VirtualSize / SecAlign) * SecAlign;
    	PageSize += SecAlign;
     
    	// rempli la struct de retour.
    	IePage->PageAdress = reinterpret_cast<LPVOID>(pISH[i].VirtualAddress + ImageBase);
    	IePage->Size = PageSize;
     
    	return true;
    }

  7. #7
    Candidat au Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Salut à tous.. et plus particulièrement à Neitsa

    Merci encore pour les astuces de débug, j'ai tout de suite utilisé debugbreak()...

    Pour ce qui est de PeBrowse Pro, il me faut encore le prendre en main, mais il a l'air bien. (est-ce que tu aurais un PeBrowser pour les nuls pour voir les IAT/thunk address? )

    En résumé, il faut donc :

    - Obtenir l'IDD de l'IAT.
    - Obtenir l'adresse de l'IAT (IDD.VirtualAdress)
    - Chercher un IMAGE_SECTION_HEADER (ISH) ayant une VirtualAddress == IDD.VirtualAdress.
    - Obtenir la VirtualSize de l'ISH (ISH.VirtualSize).
    - Aligner la taille avec IOH.SectionAlignement.

    La taille alignée = taille de la page à dé-protégée.
    Après avoir lu et étudier ton code C++, je me suis rappelé d'un autre code exemple de hooking trouvé sur le web (http://www.codeproject.com/system/ap..._unleashed.asp)

    Et là le Monsieur il fait appel à MEMORY_BASIC_INFORMATION, et ça donne ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    // Replace current function address with new one
    	   while(pThunk->u1.Function!=NULL)
    	   {
    			// Get the address of the function address
    			PROC* ppfn = (PROC*) &pThunk->u1.Function;
    			// Is this the function we are looking for?
    			BOOL bFound = (*ppfn == pfnCurrent);		   
    		   
    			if(bFound)
    			{
    				MEMORY_BASIC_INFORMATION mbi;
    			
    				::VirtualQuery(ppfn, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
    				
    				// In order to provide writable access to this part of the 
    				// memory we need to change the memory protection
    
    				if (!::VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_READWRITE,&mbi.Protect))
    				return;
    
    				*ppfn = *NewFunctionPointer;
    
    				// Restore the protection back
    				DWORD dwOldProtect;
    
    				::VirtualProtect(mbi.BaseAddress,mbi.RegionSize,mbi.Protect,&dwOldProtect);
    				break;
    			}//if
    
    			pThunk++;
    	   }//while
    Après avoir lu la MSDN ça me paraît pas mal comme approche, tu en penses quoi toi?

    @+

    InovaH

  8. #8
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    est-ce que tu aurais un PeBrowser pour les nuls pour voir les IAT/thunk address?
    N.B : j'utilise la version non-interactive (je ne sais pas si ça change grand chose).

    Tu ouvres ton programme. Dans le treeview à gauche :

    - Optional Header > Imports > click droit sur "Imports" > Structure for imports.

    Même chose avec la section contenant l'IAT. Par exemple pour IE7 ou l'IAT est dans la section de code :

    - Sections > .text > Imports > click droit sur "Imports" > Structure for imports.

    Attention les adresses données sont des VA (c'est à dire sans l'image base).

    Après avoir lu la MSDN ça me paraît pas mal comme approche, tu en penses quoi toi?
    Oui effectivement, ça revient au même mais c'est plus compréhensible (j'avais complétement zappé VirtualQuery() ... ).

    Donc au final, l'utilisation de VirtualQuery(), oui c'est mieux

  9. #9
    Candidat au Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Salut,
    Tu ouvres ton programme. Dans le treeview à gauche :
    C'est vraiment le top à comparer de OllyDbg! Merci pour les astuces, c'est vraiment très pratique!

    Je ne veux pas abuser de ta gentillesse.. mais quand même un peu de ton savoir

    J'ai fais toutes les modifications que l'on a discuté et maintenant je teste la DLL avec Notepad.exe(Beaucoup moins de calls Registry)

    J'ai vu avec "Process Monitor" que lorsque l'on clique sur "A propos de Notepad", cela faisait les appels registre de l'image "notepad_regQuery.PNG"

    Avec le fichier log que crée la DLL, je peux confirmer que les fonctions registre ont bien été redirigées (hookées) dans le thunk.

    Le Hick, c'est quand je vais dans "A propos de Notepad", je ne Hook aucunes des fonctions, sauf RegCreateKey lorsque Notepad est fermé...

    Cela fait depuis hier que je suis bloqué dessus et je ne comprends pas pourquoi il n'y a que la fonction RegCreateKey() qui est traversées

    des idées?

    InovaH


    ci-joint: code de la DLL et capture des calls registry de notepad
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés

  10. #10
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Citation Envoyé par inovah Voir le message
    C'est vraiment le top à comparer de OllyDbg! Merci pour les astuces, c'est vraiment très pratique!
    De rien

    Je ne veux pas abuser de ta gentillesse.. mais quand même un peu de ton savoir
    Y'a pas de problèmes

    J'ai fais toutes les modifications que l'on a discuté et maintenant je teste la DLL avec Notepad.exe(Beaucoup moins de calls Registry)

    J'ai vu avec "Process Monitor" que lorsque l'on clique sur "A propos de Notepad", cela faisait les appels registre de l'image "notepad_regQuery.PNG"

    Avec le fichier log que crée la DLL, je peux confirmer que les fonctions registre ont bien été redirigées (hookées) dans le thunk.

    Le Hick, c'est quand je vais dans "A propos de Notepad", je ne Hook aucunes des fonctions, sauf RegCreateKey lorsque Notepad est fermé...

    Cela fait depuis hier que je suis bloqué dessus et je ne comprends pas pourquoi il n'y a que la fonction RegCreateKey() qui est traversées

    des idées?

    InovaH
    J'ai voulu vérifier ce matin et je me doutais bien du problème :

    - Tu as atteint les limites de l'IAT patching D'ailleurs c'est un cas intéressant pour démontrer les limites de cette technique.

    Je m'explique. Pour vérifier, j'ai simplement démarrer notepad sous un débuggeur, menu Help > about Notepad.

    La boite de dialogue apparaît, je met le débuggeur en pause pendant que la boite est toujours visible, je remonte la pile d'appel (call stack) du programme et là je tombe sur :

    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    0100334F  PUSH EAX                                       ; /hIcon
    01003350  PUSH NOTEPAD.01001394                          ; |OtherStuff = ""
    01003355  PUSH DWORD PTR DS:[1009054]                    ; |Title = "Notepad"
    0100335B  PUSH DWORD PTR DS:[1009830]                    ; |hWnd = 0003035A ('Untitled - Notepad',class='Notepad')
    01003361  CALL DWORD PTR DS:[<&SHELL32.ShellAboutW>]     ; \ShellAboutW

    Je pose un BreakPoint sur l'API ShellAboutW(), redémarre notepad en monitorant cette fois-ci avec Procmon. Je vais dans le menu de notepad pour faire apparaître la boite, le débuggeur break, J'efface tout ce qu'a loggé Procmon et je "step over" sur le CALL de ShellAboutW(). A ce moment apparaissent les clés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11327	10:21:04,5186058	NOTEPAD.EXE	2700	RegOpenKey	HKLM\Software\Microsoft\Windows NT\CurrentVersion	SUCCESS	Desired Access: Read
    11328	10:21:04,5186533	NOTEPAD.EXE	2700	RegOpenKey	HKLM\Software\Microsoft\Windows NT\CurrentVersion	SUCCESS	Desired Access: Query Value
    11329	10:21:04,5186762	NOTEPAD.EXE	2700	RegQueryValue	HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\BuildLab	SUCCESS	Type: REG_SZ, Length: 60, Data: xxx
    11330	10:21:04,5187008	NOTEPAD.EXE	2700	RegCloseKey	HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion	SUCCESS	
    11331	10:21:04,5187215	NOTEPAD.EXE	2700	RegQueryValue	HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\RegisteredOwner	SUCCESS	Type: REG_SZ, Length: 8, Data: xxx
    11332	10:21:04,5187349	NOTEPAD.EXE	2700	RegQueryValue	HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\RegisteredOrganization	SUCCESS	Type: REG_SZ, Length: 10, Data: xxx
    11333	10:21:04,5187469	NOTEPAD.EXE	2700	RegQueryValue	HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\OEMID	NAME NOT FOUND	Length: 144
    11334	10:21:04,5187589	NOTEPAD.EXE	2700	RegQueryValue	HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID	SUCCESS	Type: REG_SZ, Length: 48, Data: xxx
    11335	10:21:04,5187754	NOTEPAD.EXE	2700	RegCloseKey	HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion	SUCCESS
    Donc, c'est bien l'API ShellAboutW() qui fait les appels au registre et non notepad lui-même. Dans le cas de l'IAT patching de notepad, tu ne log que les appels directs de notepad.

    Donc si on patch l'IAT de notepad, on passe à coté de ce type d'appel !

    Une solution pour tout logger (ou être sûr que, quoi qu'il arrive, on re-dirige bien une API) est de passer à l'étape supérieur et de faire du "function patching" (ou DLL patching ). Il ne s'agit surtout pas de modifier la DLL en dure, mais uniquement à l'exécution.

    La méthode est un peu plus complexe que l'IAT patching puisqu'il s'agit de patcher l'entrée d'une fonction pour rediriger sur du code personnel (nécessite une bonne connaissance de l'API et d'injecter du code assembleur, il faut aussi éviter les problèmes de pile, etc.).
    Le code personnel appel alors la "vraie fonction" et retourne au programme appelant.

    Exemple :

    Code original :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    NOTEPAD -> CALL [NOTEPAD IAT] (ShellAboutW) -> [Shell32.dll] ShellAboutW -> [... (plusieurs APIs internes)] -> RegOpenKey() -> Dépilement -> Notepad
    Code modifié (Function Patching) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    NOTEPAD -> CALL [NOTEPAD IAT] (ShellAboutW) -> [Shell32.dll] ShellAboutW -> [... (plusieurs APIs internes)] -> RegOpenKey() [ début de fonction] -> Procédure de remplacement (Log1*) -> CALL RegOpenKey() [Corps de fonction] -> Retour procédure de remplacement(Log2*) -> Dépilement -> Notepad.
    Log1* : possibilité de logger les paramètre passés à RegOpenKey, voir de les modifier.

    Log2* : possibilité de logger le retour de la "vraie" API RegOpenKey(). Possibilité aussi de modifier le retour de fonction de RegOpenKey().

    Voilà en gros le principe... Si cela t'intéresse je peux toujours coder un petit truc de démo.

  11. #11
    Candidat au Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    - Tu as atteint les limites de l'IAT patching D'ailleurs c'est un cas intéressant pour démontrer les limites de cette technique.
    Aïe aïe... j'ai bien été désabusé sur ce coup-là.. je ne m'étais pas rendu compte de ce concept d'appel direct/indirect.. merci de m'avoir ouvert les yeux.

    Une solution pour tout logger (ou être sûr que, quoi qu'il arrive, on re-dirige bien une API) est de passer à l'étape supérieur et de faire du "function patching" (ou DLL patching ). Il ne s'agit surtout pas de modifier la DLL en dure, mais uniquement à l'exécution.
    Donc si on veut bien, on va aller modifier les thunks mais directement à l'intérieur de la DLL chargée en mêmoire. Ce qui voudra dire que les redirections de fonctions seront "vues" par tous les processus(notepad.exe, firefox.exe, vlc.exe,...) qui feront appel à ces fonction "hooké", c'est cela?


    Code original :

    Code :

    NOTEPAD -> CALL [NOTEPAD IAT] (ShellAboutW) -> [Shell32.dll] ShellAboutW -> [... (plusieurs APIs internes)] -> RegOpenKey() -> Dépilement -> Notepad

    Code modifié (Function Patching) :

    Code :

    NOTEPAD -> CALL [NOTEPAD IAT] (ShellAboutW) -> [Shell32.dll] ShellAboutW -> [... (plusieurs APIs internes)] -> RegOpenKey() [ début de fonction] -> Procédure de remplacement (Log1*) -> CALL RegOpenKey() [Corps de fonction] -> Retour procédure de remplacement(Log2*) -> Dépilement -> Notepad.

    Log1* : possibilité de logger les paramètre passés à RegOpenKey, voir de les modifier.

    Log2* : possibilité de logger le retour de la "vraie" API RegOpenKey(). Possibilité aussi de modifier le retour de fonction de RegOpenKey().

    Voilà en gros le principe... Si cela t'intéresse je peux toujours coder un petit truc de démo.
    Oui ça m'intéresse beaucoup. Parce que je t'explique en quelques mots ce que je m'étais fixé..
    Le but serait de faire un "surveillant"(monitor) d'application qui regarde toutes les fonctions API appelées qu'une "application teste"(notepad, ...) utilise.

    Alors j'ai pensé qu'il fallait hooker toutes les fonctions API par rapport au processus que l'on teste=> donc modifier tous les thunks des fonctions.
    J'ai commencé avec ce concept de l'IAT patching. Et je pensais continuer en faisant toujours du patching, mais en assembleur pour directement faire jumper le call sur une fonction de hook "générale" pour toutes les fonctions API qui sont surveillée.
    Cette fonction pourrait logger, lire les paramètres de la fonctions,... donc ça revient à ce que tu me décrire là.

    Mais selon ce que tu as écrit, c'est tous les appels API d'une certaine DLL(par ex: kernel32.exe) que tu vas tracer? Est-ce que j'ai bien compris?

    @+

    InovaH

  12. #12
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    Citation Envoyé par inovah Voir le message
    Donc si on veut bien, on va aller modifier les thunks mais directement à l'intérieur de la DLL chargée en mêmoire.
    Non pas exactement. Dans le "function patching", on va plutôt rediriger une fonction d'une DLL vers notre propre fonction , traiter dans notre fonction et appeler la vraie fonction de la DLL.

    Il "suffit" de patcher le début de la fonction (i.e RegOpenKeyExW) pour sauter vers notre code, logger les paramètres passés (ou les modifier), appeler vers la vraie fonction RegOpenKeyExW, qui elle même retourne dans notre fonction de Log (ici on peut détourner / modifier le retour de fonction).

    On a ensuite plus qu'a retourner à l'appelant. C'est un peu plus complexe que l'api patching parce que ça nécessite un peu d'assembleur. (j'ai un bout de code qui traîne qque part concernant cette technique il faudrait que je le retrouve...)

    Ce qui voudra dire que les redirections de fonctions seront "vues" par tous les processus(notepad.exe, firefox.exe, vlc.exe,...) qui feront appel à ces fonction "hooké", c'est cela?
    Dans un cas "normal" (i.e : les DLLs ne sont pas modifiées) c'est bien le cas, une DLL est mappée dans tous les espaces d'adressage des processus mais n'existe en réalité qu'une seule fois.

    Seulement, Windows implémente un mécanisme appelé "Copy-on-write" (copie si écriture) qui fait que lorsque qu'une page - qui est mappée en temps normal dans tous les processus - est modifiée, la page devient privée au processus.

    En clair, si on modifie une DLL en y écrivant, la modification est recopiée dans l'espace d'adressage du processus avec sa modification, et n'est alors plus visible que depuis le processus ayant fait la modification. Ce type de hook n'est donc jamais "system-wide".

    Ce mécanisme est expliqué notamment ici : http://support.microsoft.com/kb/103858

    On trouve pas mal de littérature sur ce sujet, sur le net.

    Le but serait de faire un "surveillant"(monitor) d'application qui regarde toutes les fonctions API appelées qu'une "application teste"(notepad, ...) utilise.


    Alors j'ai pensé qu'il fallait hooker toutes les fonctions API par rapport au processus que l'on teste=> donc modifier tous les thunks des fonctions.
    J'ai commencé avec ce concept de l'IAT patching. Et je pensais continuer en faisant toujours du patching, mais en assembleur pour directement faire jumper le call sur une fonction de hook "générale" pour toutes les fonctions API qui sont surveillée.
    Cette fonction pourrait logger, lire les paramètres de la fonctions,... donc ça revient à ce que tu me décrire là.
    Ce que tu veux faire n'est pas réalisable avec "juste" du hooking, parce que ça reviendrait à vouloir hooker toutes les fonctions systèmes (puisqu'on ne sait pas à l'avance quelles fonctions va utiliser un programme).

    En fait on appelle cela un "tracer", c-a-d un programme qui trace l'exécution d'un programme et en relève chaque API traversée. C'est toutefois beaucoup plus complexe que du hooking mais pas irréalisable...

    - On peut soit le faire en statique (analyse du fichier PE sans exécution) en construisant un CFG (control flow graph) du programme. (dans ce cas on ne peut bien sûr pas logger les paramètres passés aux APIs).

    - Soit le faire en faisant un debugger amélioré, qui à l'exécution log chaque API traversée avec ses params. Dans ce cas on pourra implémenter par exemple un "stack walker" pour avoir exactement tout ce qui est traversé.

    Dans les deux cas c'est un sacré projet à mettre en place...

  13. #13
    Candidat au Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Hello Neitsa,

    désolé pour mon absence, j'ai été un peu trop absorbé par le boulot :o)

    Il "suffit" de patcher le début de la fonction (i.e RegOpenKeyExW) pour sauter vers notre code, logger les paramètres passés (ou les modifier), appeler vers la vraie fonction RegOpenKeyExW, qui elle même retourne dans notre fonction de Log (ici on peut détourner / modifier le retour de fonction).

    On a ensuite plus qu'a retourner à l'appelant. C'est un peu plus complexe que l'api patching parce que ça nécessite un peu d'assembleur. (j'ai un bout de code qui traîne qque part concernant cette technique il faudrait que je le retrouve...)
    J'ai cherché un peu de doc sur le web, et ça à l'air d'être la technique la plus adapté si on veut intercepter tous les appels API. Par contre je n'ai trouvé aucun exemple concret de code, donc si tu retrouves dans le fond d'un des tiroirs de ton disque dur ton exemple, il est le bienvenu

    Windows implémente un mécanisme appelé "Copy-on-write"
    Encore une fois, tu m'apprends un concept que je ne connaissait pas du tout. Maintenant en allant plus loin, en admettant RegOpenKeyEx() est "hookée", et ce que ShellAbout() va pointer et utiliser la version modifiée de RegOpenKeyEx() ou est-ce qu'il va aller pointer sur la version "non-modifié"?

    Ce que tu veux faire n'est pas réalisable avec "juste" du hooking, parce que ça reviendrait à vouloir hooker toutes les fonctions systèmes (puisqu'on ne sait pas à l'avance quelles fonctions va utiliser un programme).
    En fait, cette partie hooking serait un complément à une analyse statique. Avec la partie statique on obtient les dll utilisées par le programme, les fonctions et leur differentes "return address".
    Maintenant la partie hooking serait faite pour compléter ces infos en récupérant les valeurs des paramètres et les fonctions qui sont éventuellement "loadées" pendant l'exécution.
    Comme je n'ai pas encore trouvé de moyen de faire un hook général avec une fonction qui récupère de manière automatique les valeurs et nombre des paramètres de chaque fonction(très certainement en assembleur), je me dis que c'est déjà pas mal si j'ai un "proof of concept" avec cette méthode de "function patching" en définissant les fonctions que l'on veut hooker.

    Je sais que ça paraît ambitieux, mais comme tu dis, rien n'est irréalisable, ou sans vouloir faire de pub "impossible is nothing..."

  14. #14
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Hello,

    J'ai cherché un peu de doc sur le web, et ça à l'air d'être la technique la plus adapté si on veut intercepter tous les appels API. Par contre je n'ai trouvé aucun exemple concret de code, donc si tu retrouves dans le fond d'un des tiroirs de ton disque dur ton exemple, il est le bienvenu
    Solution VS2005 :

    http://neitsa.binary-reverser.org/z_...ookProject.rar

    Hooking de RegOpenKeyExW avec logging de params. Contient un injecteur et la DLL de Hook.

    J'ai essayé de commenter au maximum. La gestion d'erreur est "olé olé" dans certains cas... Pas de fonction de "UnHook" même si tout est présent pour le faire.

    Ne fonctionne a priori que sous XP SP2 32 bits. Il aurait été possible de le faire "multi-OS 32 bits" à coup sûr mais il fallait embarquer un LDE (Length Disasm Engine) et sur le coup, j'ai été un peu flemmard.

    La partie critique est la mise en place du hook qui fait appel à de l'arithmétique de pointeur et quelques passage "tricky" (transtypage de tableaux de BYTE en pointeur de fonction...mais on ne peut pas faire autrement dans des cas comme celui-là), pas forcément facile à comprendre.

    N'hésites pas si tu as des questions. Le log ressemble à ça (pris en hookant IE7) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    2007\10\12 - 14:32:53:777	hKey : 80000002 ; lpSubKey : 773D1CE8 ; ulOptions : 00000000; samDesired : 00020019, phkResult : 0179F068
    lpSubKey content : Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes
    
    2007\10\12 - 14:32:53:948	hKey : 80000001 ; lpSubKey : 42EF2D90 ; ulOptions : 00000000; samDesired : 00000001, phkResult : 0179F0E4
    lpSubKey content : Software\Microsoft\windows\CurrentVersion\Explorer\AutoComplete
    
    2007\10\12 - 14:32:53:948	hKey : 80000002 ; lpSubKey : 42EF2D90 ; ulOptions : 00000000; samDesired : 00000001, phkResult : 0179F0E4
    lpSubKey content : Software\Microsoft\windows\CurrentVersion\Explorer\AutoComplete
    
    2007\10\12 - 14:32:53:948	hKey : 80000002 ; lpSubKey : 42F5BB40 ; ulOptions : 00000000; samDesired : 00000001, phkResult : 0179F2AC
    lpSubKey content : Software\Microsoft\Internet Explorer\AutoComplete\Client\
    
    2007\10\12 - 14:32:53:948	hKey : 80000002 ; lpSubKey : 76FDEF24 ; ulOptions : 00000000; samDesired : 00020019, phkResult : 0179ECB4
    lpSubKey content : Software\Microsoft\COM3
    
    [...]
    Maintenant en allant plus loin, en admettant RegOpenKeyEx() est "hookée", et ce que ShellAbout() va pointer et utiliser la version modifiée de RegOpenKeyEx() ou est-ce qu'il va aller pointer sur la version "non-modifié"?
    ShellAbout pointe sur la vraie fonction RegOpenKey. Mais le début de celle ci est redirigé vers notre fonction de Hook (en termes clairs, le début de la fonction RegOpenKeyExW est un JMP vers notre fonction de HOOK).

    Original :

    Code ASM : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    77DD6A78 RegOpenKeyExW       8BFF          MOV EDI,EDI
    77DD6A7A                     55            PUSH EBP
    77DD6A7B                     8BEC          MOV EBP,ESP
    77DD6A7D                  .  83EC 0C       SUB ESP,0C
    77DD6A80                  .  53            PUSH EBX
    77DD6A81                  .  56            PUSH ESI
    77DD6A82                  .  8B75 08       MOV ESI,DWORD PTR SS:[EBP+8]
    77DD6A85                  .  33C9          XOR ECX,ECX
    77DD6A87                  .  81FE 04000080 CMP ESI,80000004
    [...]

    Modifié :

    Code ASM : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    77DD6A78 RegOpenKeyExW       E9 83952289   JMP MyRegOpenKeyExW ; fonction de logging dans la DLL de HOOK
    77DD6A7D                  .  83EC 0C       SUB ESP,0C
    77DD6A80                  .  53            PUSH EBX
    77DD6A81                  .  56            PUSH ESI
    77DD6A82                  .  8B75 08       MOV ESI,DWORD PTR SS:[EBP+8]
    77DD6A85                  .  33C9          XOR ECX,ECX
    77DD6A87                  .  81FE 04000080 CMP ESI,80000004

    Ensuite, La fonction de Logging log les paramètres passés à RegOpenKeyExW puis une fois tout loggé elle appelle (via un CALL) la suite de la fonction [*1], ici à l'adresse : 0x77DD6A7D (sous le JMP).

    Ensuite, une fois que la vraie fonction RegOpenKeyExW retourne, elle retourne dans la fonction de log (vu que l'on a fait un CALL). La fonction de Logging retourne, quant à elle, vers la fonction appellante (type ShellAbout()).

    [*1] En réalité c'est un peu plus complexe, on passe par une zone tampon
    chargé de faire la transition entre les deux... cf. code source pour tous les détails.
    En fait, cette partie hooking serait un complément à une analyse statique. Avec la partie statique on obtient les dll utilisées par le programme, les fonctions et leur differentes "return address".
    Maintenant la partie hooking serait faite pour compléter ces infos en récupérant les valeurs des paramètres et les fonctions qui sont éventuellement "loadées" pendant l'exécution.
    Ok, je comprend ce que tu veux faire.

    Comme je n'ai pas encore trouvé de moyen de faire un hook général avec une fonction qui récupère de manière automatique les valeurs et nombre des paramètres de chaque fonction(très certainement en assembleur)
    En théorie si tu peux trouver le nombre d'arguments d'une fonction (suffit de regarder sa signature en export), tu ne peux absolument pas savoir de quel type sont les params de fonction. (e.g : comment avoir si un des params est une valeur, un handle, un pointeur de char, un pointeur sur objet, etc...)

    Néanmoins, il reste la possibilité de charger les fichier de symboles d'une DLL (pourvu quelle soit système ou que l'on dispose de son fichier de symbole) et accéder aux types de paramètres via les symbols exportées... (ca demande vérification sur la possibilité de cette option).

    Je sais que ça paraît ambitieux, mais comme tu dis, rien n'est irréalisable, ou sans vouloir faire de pub "impossible is nothing..."
    Hihi, oui même si c'est un gros morceaux, avec un peu d'acharnement il y a de quoi tenir un bon outil d'analyse. Si jamais tu as besoin d'un coup de main...

    P.S : Jette un coup d'oeil à "Detours" de Microsoft, un bibliothèque qui fait du fonction patching (c'est son but), par contre je ne connais pas les détails de l'implémentation, je ne l'ai jamais analysé, mais je suis sur que l'analyse à elle seule du comportement de cette bibliothèque vaut le coup !

    https://research.microsoft.com/sn/detours/

Discussions similaires

  1. Connaitre le processus qui appelle une fonction API
    Par RazielReaver dans le forum API, COM et SDKs
    Réponses: 9
    Dernier message: 28/05/2006, 13h56
  2. MASM et XP : fonctions API inconnues
    Par naplot dans le forum x86 32-bits / 64-bits
    Réponses: 1
    Dernier message: 27/03/2006, 03h41
  3. Fonction API
    Par margilb dans le forum C++Builder
    Réponses: 2
    Dernier message: 08/07/2002, 11h11
  4. FOnction api specifiant la position de la souris
    Par florent dans le forum C++Builder
    Réponses: 4
    Dernier message: 15/05/2002, 20h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo