C++ Klasse aus unbekannter DLL importieren



  • Ich möchte aus einer DLL für die ich weder LIB noch Header Datei habe eine Klasse in mein Programm importieren. Ist dies möglich?

    Ich weiß, dass man sich durch Verwendung der Tools lib und dumpbin eine lib Datei erzeugen lassen kann. Aber ein Header Datei benötige ich doch auch? Oder nicht?

    Weiß vielleicht jemand Rat?



  • Mit anderen Worten: Du weißt nichts über diese Klasse?
    Woher weißt du dann überhaupt dass diese Klasse existiert, was diese Klasse ist und dass sie sich in dieser DLL befindet!?



  • Doch ich weiß relativ viel über die Klasse. Es sind mehrere Klassen in der DLL. Ich weiß die Methoden, public, protected, private, Rückgabetypen, Parameter, Vererbung. Dies habe ich alles mit IDA Disassembler ausgelesen und mir eine Header Datei daraus gestrickt. Nun weiß ich aber nicht wie ich die Klasse einlade und Instanziere. Mit LoadLibrary und GetProcAdress? Wie kann ich das machen? Den Konstructor aufrufen wird wohl nicht funktionieren, oder?



  • in dem er es mit der lib und dumpbin exe ausliest das was über den consolenbildschirm läuft kannst du dir via pipe's in ein externes programm ausesen lassen mittels der function UnDecorateSymbolName kannst du aus dem kauderwelsch der wieder lesbare functionen inclusieve klassenverweis machen

    aus

    GAcquireInterface@@UAE@XZ
    

    wird dann zb

    virtual __thiscall	 ~GAcquireInterface	(void);
    


  • @rT!f@Ct schrieb:

    ... mittels der function UnDecorateSymbolName kannst du aus dem kauderwelsch der wieder lesbare functionen inclusieve klassenverweis machen

    Das ist nicht mehr nötig, denn IDA zeigt mir diese Funktionen schon "undekoriert" an.

    Muss nur wissen wie ich nun die Klasse einlade aus der Dll. Was genau muss ich mit GetProcadress Laden wenn ich die ganze Klasse laden will?



  • Evtl ist das hier die möglichkeit?

    http://members.inode.at/anton.zechner/az/Dll.htm#CLASS



  • ich nehme mal an das es um einen cheat geht...

    wenn mittels einer dll auf eine ander dll zugreifen willst, die beide in ein und dem selben process laufen must du gar nix laden. du must die header in deine dll einbinden und die lib dazu.
    wenn beides compilert ist solltest du auf die functionen der anderen dll wie dort beschrieben zugriff haben.



  • Nicht um einen Cheat. Eher ein Hack um ein altes Spiel kompatibel zu machen.

    Also es funktioniert nun.

    So bin ich vorgegangen.

    1. Header File geschrieben mit allen Funktionen und Klassen die ich per IDA ausgelesen habe.
    2. Mit dem tool dumpbin die funktionsnamen und ordinalzahlen nochmal exportiert (dekoriert)
    3. Eine Def datei nach diesem schema:

    LIBRARY		"FUBAR.DLL"
    
    EXPORTS
    GetFooBar @101
    SetFooBar @102
    

    erstellt.

    4. mit em tool lib.exe aus der def datei eine lib datei erzeugt.
    5. die definition der klassen im header file so angepasst:

    class __declspec(dllexport)
    


  • Hier noch eine weitere Möglichkeit die DLL dynamisch zu laden (PDLL class):

    http://msdn.microsoft.com/en-us/library/ms810279.aspx

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    //	Class:  PDll																								    //
    //  Authors: MicHael Galkovsky                                                                           //
    //  Date:    April 14, 1998                                                                                  //
    //  Company:  Pervasive Software                                                                    //
    //  Purpose:    Base class to wrap dynamic use of dll                                          //
    //////////////////////////////////////////////////////////////////////////////////////////////
    
    #if !defined (_PDLL_H_)
    #define _PDLL_H_
    
    #include <windows.h>
    #include <winbase.h>
    
    #define FUNC_LOADED 3456
    
    //function declarations according to the number of parameters
    //define the type
    //declare a variable of that type
    //declare a member function by the same name as the dll function
    //check for dll handle
    //if this is the first call to the function then try to load it
    //if not then if the function was loaded successfully make a call to it
    //otherwise return a NULL cast to the return parameter.
    
    #define DECLARE_FUNCTION0(CallType, retVal, FuncName) \
    	typedef  retVal (CallType* TYPE_##FuncName)(); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName; \
    	retVal FuncName() \
    	{ \
    		if (m_dllHandle) \
    		{ \
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(); \
    			else \
    				return (retVal)NULL; \
    		} \
    		else \
    			return (retVal)NULL; \
    	}   	
    
    #define DECLARE_FUNCTION1(CallType,retVal, FuncName, Param1) \
    	typedef  retVal (CallType* TYPE_##FuncName)(Param1); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName;\
    	retVal FuncName(Param1 p1) \
    	{ \
    		if (m_dllHandle) \
    		{ \
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1); \
    			else \
    				return (retVal)NULL; \
    		} \
    		else \
    			return (retVal)NULL; \
    	}
    
    #define DECLARE_FUNCTION2(CallType,retVal, FuncName, Param1, Param2) \
    	typedef  retVal (CallType* TYPE_##FuncName)(Param1, Param2); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName;\
    	retVal FuncName (Param1 p1, Param2 p2) \
    	{\
    		if (m_dllHandle)\
    		{\
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1, p2); \
    			else \
    				return (retVal)NULL; \
    		} \
    		else\
    			return (retVal)NULL; \
    	}
    
    #define DECLARE_FUNCTION3(CallType,retVal, FuncName, Param1, Param2, Param3) \
    	typedef  retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName;\
    	retVal FuncName (Param1 p1, Param2 p2, Param3 p3) \
    	{\
    		if (m_dllHandle)\
    		{\
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED; \
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1, p2, p3);\
    			else \
    				return (retVal)NULL; \
    		} \
    		else\
    			return (retVal)NULL; \
    	}
    
    #define DECLARE_FUNCTION4(CallType,retVal, FuncName, Param1, Param2, Param3, Param4) \
    	typedef  retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName;\
    	retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4) \
    	{\
    		if (m_dllHandle)\
    		{\
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1, p2, p3, p4);\
    			else \
    				return (retVal)NULL; \
    		} \
    		else\
    			return (retVal)NULL; \
    	}
    
    #define DECLARE_FUNCTION5(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5) \
    	typedef  retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName; \
    	retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) \
    	{\
    		if (m_dllHandle)\
    		{\
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1, p2, p3, p4, p5);\
    			else \
    				return (retVal)NULL; \
    		} \
    		else\
    			return (retVal)NULL; \
    	}
    
    #define DECLARE_FUNCTION6(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6) \
    	typedef  retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5, Param6); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName;\
    	retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) \
    	{\
    		if (m_dllHandle)\
    		{\
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1, p2, p3, p4, p5, p6);\
    			else \
    				return (retVal)NULL; \
    		} \
    		else\
    			return (retVal)NULL; \
    	}
    
    #define DECLARE_FUNCTION7(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7) \
    	typedef  retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5, Param6, Param7); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName;\
    	retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) \
    	{\
    		if (m_dllHandle)\
    		{\
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1, p2, p3, p4, p5, p6, p7);\
    			else \
    				return (retVal)NULL; \
    		} \
    		else\
    			return (retVal)NULL; \
    	}
    
    #define DECLARE_FUNCTION8(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) \
    	typedef  retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName;\
    	retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) \
    	{\
    		if (m_dllHandle)\
    		{\
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1, p2, p3, p4, p5, p6, p7, p8);\
    			else \
    				return (retVal)NULL; \
    		}\
    		else\
    			return (retVal)NULL; \
    	}
    
    #define DECLARE_FUNCTION9(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) \
    	typedef  retVal (CallType* TYPE_##FuncName)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName; \
    	retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) \
    	{\
    		if (m_dllHandle)\
    		{\
    			if (FUNC_NAME != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1, p2, p3, p4, p5, p6, p7, p8, p9);\
    			else \
    				return (retVal)NULL; \
    		}\
    		else\
    			return (retVal)NULL; \
    	}
    
    #define DECLARE_FUNCTION10(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) \
    	typedef  retVal (CallType* TYPE_##FuncName)FuncName(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10); \
    	TYPE_##FuncName m_##FuncName; \
    	short m_is##FuncName;\
    	retVal FuncName (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) \
    	{\
    		if (m_dllHandle)\
    		{\
    			if (FUNC_LOADED != m_is##FuncName) \
    			{\
    				m_##FuncName = NULL; \
    				m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \
    				m_is##FuncName = FUNC_LOADED;\
    			}\
    			if (NULL != m_##FuncName) \
    				return m_##FuncName(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);\
    			else \
    				return (retVal)NULL; \
    		}\
    		else					\
    			return (retVal)NULL;\
    	}
    
    //declare constructors and LoadFunctions
    #define DECLARE_CLASS(ClassName) \
    	public:	\
    	ClassName (const char* name){LoadDll(name);} \
    	ClassName () {PDLL();}
    
    class PDLL
    {
    
    protected:
    	HINSTANCE m_dllHandle;
    	char* m_dllName;
    	int m_refCount;
    
    public:
    
    	PDLL()
    	{
    		m_dllHandle = NULL;
    		m_dllName = NULL;
    		m_refCount = 0;
    	}
    
    	//A NULL here means the name has already been set
    	void LoadDll(const char* name, short showMsg = 1)
    	{
    		if (name)
    			SetDllName(name);
    
    		//try to load
    		m_dllHandle = LoadLibrary(m_dllName);
    
    		if (m_dllHandle == NULL && showMsg)
    		{
    			//show warning here if needed
    			char dll[1000];
    			sprintf(dll, "¼ÓÔض¯Ì¬Á¬½Ó¿â%sʧ°Ü£¬Çë¼ì²éÊÇ·ñ´æÔÚÎļþ", name);
    			MessageBox(NULL, dll, "´íÎó", MB_OK);
    			ExitProcess(1);
    		}		
    	}
    
    	bool SetDllName(const char* newName)
    	{
    		bool retVal = false;
    
    		//we allow name resets only if the current DLL handle is invalid
    		//once they've hooked into a DLL, the  name cannot be changed
    		if (!m_dllHandle)
    		{
    			if (m_dllName)
    			{
    				delete []m_dllName;
    				m_dllName = NULL;
    			}
    
    			//They may be setting this null (e.g., uninitialize)
    			if (newName)
    			{
    				m_dllName = new char[strlen(newName) + 1];
    				//make sure memory was allocated
    				if (m_dllName)
    					strcpy(m_dllName, newName);
    				else
    					retVal = false;
    			}
    			retVal = true;
    		}
    		return retVal;
    	}
    
    	virtual bool Initialize(short showMsg = 1)
    	{
    
    		bool retVal = false;
    
    		//Add one to our internal reference counter
    		m_refCount++;
    
    		if (m_refCount == 1 && m_dllName) //if this is first time, load the DLL
    		{
    			//we are assuming the name is already set
        		LoadDll(NULL, showMsg);
    			retVal = (m_dllHandle != NULL);
    		}
    		return retVal;
    	}
    
    	virtual void Uninitialize(void)
    	{
    		//If we're already completely unintialized, early exit
    		if (!m_refCount)
    			return;
    
    		//if this is the last time this instance has been unitialized, 
    		//then do a full uninitialization
    		m_refCount--;
    
    		if (m_refCount < 1)
    		{
    			if (m_dllHandle)
        		{
    	    		FreeLibrary(m_dllHandle);
        			m_dllHandle = NULL;
    			}
    
    			SetDllName(NULL); //clear out the name & free memory
    		}
    	}
    
    	~PDLL()
    	{
    		//force this to be a true uninitialize
    		m_refCount = 1; 
    		Uninitialize();
    
    		//free name
    		if (m_dllName)
    		{
    			delete [] m_dllName;
    			m_dllName = NULL;
    		}
    	}
    
    };
    #endif
    

Anmelden zum Antworten