Laden...

Wie rufe ich die Methode an, von deren ich Handle habe

Erstellt von spongebob vor 15 Jahren Letzter Beitrag vor 15 Jahren 5.594 Views
S
spongebob Themenstarter:in
37 Beiträge seit 2008
vor 15 Jahren
Wie rufe ich die Methode an, von deren ich Handle habe

Hallo, zusammen!
Weist jemand, ob Möglichkeit existiert.
Um in meiner .NET Anwendung eine Methode aufrufen, die zu anderem (nicht .NET) Anwendung gehört, und von deren ich Handle habe?
Danke im voraus
spongebob

Gelöschter Account
vor 15 Jahren

prinzipiell ist mir kein weg bekannt allein durch das handle einer applikation, dessen methoden aufzurufen.

915 Beiträge seit 2006
vor 15 Jahren

Hrm, fürchte da musst etwas genauer werden - du redest von einem Funktionszeiger ?
Also zum Beispiel in C++ ein void* ?

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

S
spongebob Themenstarter:in
37 Beiträge seit 2008
vor 15 Jahren

Also zum Beispiel in C++ ein void* ?

Genau!
Ich habe aus C++ Anwendung mit Hilfe SendMessage nach .NET Anwendung ein Funktionszeiger geschickt, und jetzt möchte ich die o.g. Funktion aus .NET aufrufen.
Es ist möglich?

915 Beiträge seit 2006
vor 15 Jahren

Also Prinzipiel schon...

Siehe dazu am besten MSDN Marshal.GetDelegateForFunctionPointer bzw. diesen Thread da gehts zwar um DLL's in Resourcen der Weg ist aber der selbe zumindets bei dem Codebeispiel von mir. Ansonsten, glaube dieser Thread könnte dir auch enorm weiter helfen.

Es ist nen bissel rumgefrimel dabei, da kommst nicht drum herum.

[Edit] Bin zu blöd die Links richtig reinzukopieren grummel

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

6.862 Beiträge seit 2003
vor 15 Jahren

Ich glaub nicht dass das so einfach ist, immerhin sind das getrennte Speicherräume zwischen verschiedenen Applikationen. Und du schickst ja nichts anderes als ne Adresse und die zeigt bei der Empfängerapplikation ja in den eigenen Adressraum irgendwo hin und net in den Adressraum der Senderapplikation.

Baka wa shinanakya naoranai.

Mein XING Profil.

915 Beiträge seit 2006
vor 15 Jahren

Hrm, sicher bin ich mir auch nicht aber via

     
            IntPtr hMod = LoadLibrary(@"C:\MyLib.dll");
            IntPtr hFunction = GetProcAddress(hMod, "MyFunction");

wie beim ersten Thread (wo es schlussendlich zwar um DLL's als Resourcen geht) wird ja der Funktionszeiger ebenso aus dem entsprechenden Adressraum geladen.

Aber du hast recht Talla die Rahmenbedingungen müssen stimmen, ich weis jetzt nicht wie spongebob an den Funktionszeiger kommt, wenn er aber nicht innerhalb seiner eigenen Prozedur ist so muss er sich über GetProcAddress zutritt verschaffen und kann dazu auch GetModuleHandle verwenden um z.B. von einem bestehenden Programm sich eine Funktion / Methode zu "erklauen".

Müsste um genauere Aussagen dazu machen zu können das ganze Testen, leider fehlt da etwas die Zeit.

Denk nur dran, für den ersten Test, das delegate muss via Invoke aufgerufen werden, genauso müssen die verwendeten Parameter und deren Datentypen genau die selben sie wie für die Funktion auf die der Funktionszeiger zeigt.

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

1.200 Beiträge seit 2007
vor 15 Jahren

Ich glaub nicht dass das so einfach ist, immerhin sind das getrennte Speicherräume zwischen verschiedenen Applikationen. Und du schickst ja nichts anderes als ne Adresse und die zeigt bei der Empfängerapplikation ja in den eigenen Adressraum irgendwo hin und net in den Adressraum der Senderapplikation.

Du kannst aber laut WinAPI mit WriteProcessMemory() und ReadProcessMemory() auf den Speicher anderer Applikationen zugreifen.

In wie weit das wirklich für welches OS und welche Applikation funktioniert, kann ich nicht sagen.

Shift to the left, shift to the right!
Pop up, push down, byte, byte, byte!

YARRRRRR!

Gelöschter Account
vor 15 Jahren

ja aber reinschreiben in irgendwelche speicherbereiche ist etwas anderes als eine funktion aufzurufen. oder irre ich mich hierbei?

S
spongebob Themenstarter:in
37 Beiträge seit 2008
vor 15 Jahren

Danke für die Hinweise.
Klappt noch aber nicht. Und zwar

Hier Codeabschnitt aus C++


void (*M12)();
void M1();
void M1()
{
	printf("TEST POINTER TO FUNCTION");
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// MFC initialisieren und drucken. Bei Fehlschlag Fehlermeldung aufrufen.
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: Den Fehlercode an Ihre Anforderungen anpassen.
		_tprintf(_T("Schwerwiegender Fehler bei der MFC-Initialisierung\n"));
		nRetCode = 1;
	}
	else
	{

		HWND hw = (HWND)atol(argv[1]);
		

		M12 = M1;
		int ii = (int)M12;
		//Hier schicke ich Message nach .NET Anwendung...
		SendMessageW(hw, 12345, (WPARAM)ii,1);
	}
	return nRetCode;
}

Hier von .NET(C#)


private void button3_Click(object sender, EventArgs e)
        {
            Process.Start(@"C:\CA123A\debug\CA123A.exe", " " + this.Handle.ToString());
            
        }


IntPtr fp;
        public delegate void MD();

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == 12345)
            {
                fp = m.WParam;
                MD mMD = (MD)Marshal.GetDelegateForFunctionPointer(fp, typeof(MD));
                mMD.Invoke(); /////HIER IST EINE AUSNAHME
////Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist ////häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist.


            }
        }

Ich verstehe nict
Was stimmt nicht????

915 Beiträge seit 2006
vor 15 Jahren

ja aber reinschreiben in irgendwelche speicherbereiche ist etwas anderes als eine funktion aufzurufen. oder irre ich mich hierbei?

Hrm... sagen wir es so reinschreiben ist relativ - erinnere dich wie ein Trojaner Funktioniert. Da wird das ganze insofern ins absurdum geführt da man hier Code in den Speicherbereich eines fremden Prozesses schreibt. Das geht indem man ja eine DLL in einem fremden Adressraum reinfriemelt und diese dann eine z.B. eine angegebene Funktion ausführt. Der Wichtigste Punkt hierzu ist das Verständniss von Zeigern, diese sind Variablen und Variablen werden auf dem Stack gespeichert und sind somit also relativ.

Wie das geht steht naja fast schon in diesen Thread, nur mehr schreibe ich erstmal dazu nicht rein, nur soviel Trojaner sind nicht zwangsläufig etwas böses sondern eigentlich viel mehr Dirty-Trick Lösungen für vermurkste Programme - daher kenne ich zumindest die Grundlagen 😉

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

6.862 Beiträge seit 2003
vor 15 Jahren

Die Code Injection die du beschreibst ist trotzdem noch was anderes als das was der Threadersteller erreichen will. Du beschreibst dass man Code an festgelegten Stellen in einer Fremdapplikation einschleusen kann und diese Applikation führt den dann aus, weil sie irgendwann in ihrem Programmablauf an diese Stelle kommt.

Die Problemstellung hier ist doch aber ne ganz andere. Du willst ja nicht deinen eigenen Code ausführen in einer Fremdapplikation, sondern fremden Code in deiner eigenen Applikation ausführen, und das geht soweit ich weiß net wirklich.

Baka wa shinanakya naoranai.

Mein XING Profil.

915 Beiträge seit 2006
vor 15 Jahren

@talla

Das bezog sich auch nicht auf den Thread sondern nur auf das von JAck30lena gepostete 🙂

@spongebob

Okay, das hätte ich zu aller erst auch mal versucht klar wird aber durch die Fehlermeldung dass das nicht alles ist. Die reine übergabe des Funktionszeigers reicht ja nicht aus, nun kommt ja der Fehler den Talla und JAck30lena meinten.

Hrm, versuch mal folgendes hol dir den Funktioszeiger nicht über die WndProc sondern direkt aus dem Fremdmodul, das kannst du über die WIN API GetModuleHandle und den Funktionszeiger via GetProcAddress holen.

Wenn das nicht hinhaut kann man noch nen paar andere Schritte angehen.

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

S
spongebob Themenstarter:in
37 Beiträge seit 2008
vor 15 Jahren

Hrm, versuch mal folgendes hol dir den Funktioszeiger nicht über die WndProc sondern direkt aus dem Fremdmodul, das kannst du über die WIN API GetModuleHandle und den Funktionszeiger via GetProcAddress holen.

Wie genau?
Könntest mir zeigen?

Ich habe selber versucht - hat aber nicht geklappt

in C++



//Hier schicke ich Message nach .NET Anwendung...
		HMODULE hm = GetModuleHandle("CA123A.exe");

		int iiL = (int)hm;
		
		SendMessageW(hw, 12345, 1,(LPARAM)iiL);


in C#


[DllImport("kernel32.dll", EntryPoint = "GetProcAddress", CharSet = CharSet.Unicode)]
        public static extern IntPtr GetProcAddress(IntPtr h, string name);

////
////
protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == 12345)
            {
                fp = GetProcAddress(m.LParam, "M12");/// Hier bekomme ich fp=0

               
            }
        }

915 Beiträge seit 2006
vor 15 Jahren

Das ganze sieht in etwa wie folgt aus.


        [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        [DllImport("kernel32.dll")]
        static extern IntPtr GetProcAddress(IntPtr IntPtr_Module, string csProcName);

        private delegate void myFunctionDelegate();
        private myFunctionDelegate Invoke = MyFunction();

        public void DoIt()
        {
       
            Invoke();
        }

        private static myFunctionDelegate MyFunction()
        {
            IntPtr hMod = GetModuleHandle("CA123A.exe"); // das module handle in der sich die M12 funktion befindet.
            IntPtr hFunction = GetProcAddress(hMod, "M12"); // M12 nach deinem code die void* Methode im C++ Code

            return Marshal.GetDelegateForFunctionPointer(hFunction, typeof(myFunctionDelegate)) as myFunctionDelegate;
        }

Wie gesagt bei deinem Problem kann ich nur via Try & Error an den Fall dran gehen eine "dieser Weg funktioniert garantiert" Lösung kann ich dir nicht geben. Wenn das nicht klappt geb bescheid, dann muss ein anderer Lösungsweg gefunden werden. Also keine übergabe via WndProc oder SendMessage - ich würde dir gerne den Unterschied erklären, leider fehlt mir dafür das KnowHow 😮)

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

S
spongebob Themenstarter:in
37 Beiträge seit 2008
vor 15 Jahren

IntPtr hMod = GetModuleHandle("CA123A.exe");

Ich hab das gestern auch probiert - bringt aber zurück 0

915 Beiträge seit 2006
vor 15 Jahren

Hrm, hol dir das Modulhandle mal wie folgt.



        [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetProcAddress(IntPtr IntPtr_Module, string csProcName);

        [DllImport("kernel32")]
        private static extern IntPtr LoadLibrary(string lpFileName);

        private delegate void myFunctionDelegate();
        private myFunctionDelegate Invoke = MyFunction();

        public void DoIt()
        {
             Invoke();
        }

        private static myFunctionDelegate MyFunction()
        {
            Process proc = Process.GetProcessesByName("CA123A")[0]; // process CA123A.exe
            IntPtr hMod = LoadLibrary(proc.MainModule.FileName); // das module handle in der sich die M12 funktion befindet.
            IntPtr hFunction = GetProcAddress(hMod, "M12"); // M12 nach deinem code die void* Methode im C++ Code

            return Marshal.GetDelegateForFunctionPointer(hFunction, typeof(myFunctionDelegate)) as myFunctionDelegate;
        }


Sorry, wie gesagt mehr als Try & Error kann ich da auch nicht vorschlagen - wenn das nicht geht, gib bescheid.

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

S
spongebob Themenstarter:in
37 Beiträge seit 2008
vor 15 Jahren

IntPtr hFunction = GetProcAddress(hMod, "M12"); // M12 nach deinem code die void* Methode im C++ Code

hFunction immer bekomme ich 0

915 Beiträge seit 2006
vor 15 Jahren

Hrm, das muss so klappen.. ich habe ja deine DLL bzw. Programm nicht, aber habe das z.B so getestet:


			private delegate bool DelegBeep(uint iFreq, uint iDuration);

			[MarshalAs(UnmanagedType.FunctionPtr)]
			private static DelegBeep Beep;

			[DllImport("kernel32.dll")]
			private static extern IntPtr LoadLibrary(String dllname);
			[DllImport("kernel32.dll")]
			private static extern IntPtr GetProcAddress(IntPtr hModule, String procName);

			static void Main()
			{
				IntPtr hInst = LoadLibrary("Kernel32.dll");
				IntPtr hFunc = GetProcAddress(hInst, "Beep");
				Beep = Marshal.GetDelegateForFunctionPointer(hFunc, typeof(DelegBeep)) as DelegBeep;
				Beep(250, 250);
			}

Bist dir daher sicher das M12 wirklich in deinem Header drinne steht unter public?



public:
    void (*M12)();


Ansonsten schau dir das Project mal genauer an, das sollte das ganze besser aufzeigen. Es muss gehen, irgendwas stimmt da noch nicht - kann auch sein das ich wiedermal blind bin und es einfach nicht sehe 🙂

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

6.862 Beiträge seit 2003
vor 15 Jahren

Du musst da aufpassen, mit LoadLibrary wird der Code in deinen eigenen Adressraum gemappt, klar dass du dann ne gültige Adresse bekommst. Aber bei einer externen Anwendung ist es ein anderer Adressraum und das kann imo nicht funktionieren.

Baka wa shinanakya naoranai.

Mein XING Profil.

S
spongebob Themenstarter:in
37 Beiträge seit 2008
vor 15 Jahren

public:
void (*M12)();

Viellecht ist dat Problem.

Ich versuche so machen und bekomme beim Compilierung Fehler error C2059: Syntaxfehler: 'public'