IAT von delay loaded DLLs



  • Hi,

    ich versuche den ImportAddressTable von delay loaded DLLs zu finden. Im Beispielcode versuche ich den IAT der delay loaded WS2_32 DLL zu finden. Dependency Walker zeigt mir an das die Originalinstanz der WS2_32.DLL sich im Modul RPCRT4.DLL befindet.

    Ich finde zwar die DLL und den IAT aber die Addressen die sich im IAT befinden sind nicht die Selben die mir GetProcAddress(GetModuleHandle("WS2_32.DLL"), fnName) liefert. Woran liegt das?

    Wenn ich das selbe mit statisch geladenen DLLs mache (zb KERNEL32) funktioniert es.

    #include <delayimp.h>
    	#include <windows.h>
    	#include <stdio.h>
    	#include <shlwapi.h>
    
    	#pragma warning(disable:4200)
    
    	#define MakePtr(cast, ptr, addValue ) (cast)( (DWORD)(ptr)+(DWORD)(addValue))
    
          ....
    
    	HMODULE base_address = GetModuleHandle("RPCRT4.DLL");
    
     	PIMAGE_NT_HEADERS pNTHdr = PEHeaderFromHModule(base_address); //nt header der datei
    	if(!pNTHdr)
            return false;
    
    	DWORD delay_importRVA = pNTHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress;   
        if(!delay_importRVA)
            return false;
    
    	PCImgDelayDescr pImgDelayDescr  = MakePtr( PCImgDelayDescr, base_address, delay_importRVA );  
    
    	while(pImgDelayDescr->rvaDLLName)
    	{
    		PSTR pszImportModuleName = MakePtr(PSTR, base_address, pImgDelayDescr->rvaDLLName);  
    
     		if(lstrcmpi(pszImportModuleName, "WS2_32.DLL") == 0)  
    		{
    			break;   //dll gefunden
    		}
    
    		pImgDelayDescr++;   
    	}
    
    	PIMAGE_THUNK_DATA pIAT;     
        PIMAGE_THUNK_DATA pINT;    
        PIMAGE_THUNK_DATA pIteratingIAT; 
    
    	pIAT = MakePtr( PIMAGE_THUNK_DATA, (PVOID) base_address, (PVOID) pImgDelayDescr->rvaIAT); 
    	pINT = MakePtr( PIMAGE_THUNK_DATA, (PVOID) base_address, (PVOID) pImgDelayDescr->rvaINT); 
    
        pIteratingIAT = pIAT;
        unsigned cFuncs = 0;
        while ( pIteratingIAT->u1.Function )
        {
            cFuncs++;
            pIteratingIAT++;
        }
    
        if ( cFuncs == 0 )   
            return false;
    
        pIteratingIAT = pIAT;
    
    	while ( pIteratingIAT->u1.Function )
        {  
    		if ( !IMAGE_SNAP_BY_ORDINAL( pINT->u1.Ordinal ) )  // import by name
            {
    			PIMAGE_IMPORT_BY_NAME pImportName = MakePtr( PIMAGE_IMPORT_BY_NAME, (PVOID)base_address, pINT->u1.AddressOfData ); 
    
    			if(lstrcmpi("WSASend", (char*)pImportName->Name ) == 0  )  
    			{  
    				DWORD tst = (DWORD)GetProcAddress(GetModuleHandle("WS2_32.DLL"), "WSASend")
    
    				if(pIteratingIAT->u1.Function == tst)    
    					return true;                         //funktion gefunden
    			}
    		} 
    
            pIteratingIAT++;   
            pINT++;         
        }
    


  • Wie stellst du denn sicher, dass die Funktionen schon importiert sind? (delay-loaded DLL)



  • #include <WinSock2.h>
    #include <Windows.h>
    ...
    
    typedef int (__stdcall *WSASend_Type)(SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
    
     ...
    int main()
    {
    ...
    
    	WSASend_Type fn;
    
    	fn = (WSASend_Type)GetProcAddress(GetModuleHandle("Ws2_32.dll"), "WSASend");
    
    	WSABUF buf;
    	buf.buf = new char [20];
    	strcpy(buf.buf, "Test");
    	buf.len = 1;
    
    	fn(1, &buf, 1, (LPDWORD)sizeof(buf), 0, NULL, NULL);
    
    	getIAT();
    
     ...
    }
    


  • msdn schrieb:

    Imports of data cannot be supported. A workaround is to explicitly handle the data import yourself using LoadLibrary (or GetModuleHandle after you know the delay-load helper has loaded the DLL) and GetProcAddress

    Constraints of Delay Loading DLLs



  • macht leider auch keinen Unterschied

    (WSASend_Type)GetProcAddress(LoadLibrary("Ws2_32.dll"), "WSASend");
    

Anmelden zum Antworten