Funktion eines gekaperten Prozesses aufrufen.



  • Hi Leute,

    ich möchte über Dll Injection eine Funktion in einem anderen Prozess aufrufen.
    Die Funktion sieht so aus:

    void Test(wstring const & message) {
    	MessageBox(NULL, message.c_str(), L"", MB_OK);
    }
    

    Die Funktion möchte ich jetzt (in der bereits injizierten) Dll aufrufen:

    typedef void (*__Test)(wstring const &);
    __Test Test = reinterpret_cast<__Test>(0x004013C1);
    Test(L"hello world");
    

    Leider stürzt der Wirtprozess dabei ab.
    Könnte es daran liegen, dass der auf den Speicherbereich des "hello world" in der Dll nicht vom Hauptprozess zugegriffen werden kann?

    Ich hoffe ihr könnt mir helfen 🙂



  • Was sagt der Debugger ?
    Die Adresse hardzucoden ist jedenfalls böse, vermutlich ändert die sich.



  • DerCoder schrieb:

    Könnte es daran liegen, dass der auf den Speicherbereich des "hello world" in der Dll nicht vom Hauptprozess zugegriffen werden kann?

    Ne.

    Ermittle die Adresse aus base + offset. Und Debugger benutzen (ich empfehle OllyDbg).

    Achja, check mal deine Mails 😛



  • Danke erstmal für die Antworten.
    Das Wirtprogramm zeigt mir in der Console die Adresse der Funktion an und zu Testzwecken ist es erstmal bequemer die Adresse hardzucoden, als dafür komplexe Funktionen zu schreiben.

    Jedenfalls habe ich es gerade nochmal getestet und merkwürdiger Weise funktioniert es jetzt! (Wahrscheinlich habe ich heute morgen die Adresse falsch eingetippt oder wie auch immer.)

    Ich stehe jetzt vor einem zweiten Problem:
    Ein bestimmtest Computerspiel setzt sich zusammen aus der PE und 3 Dlls die in den Ram geladen werden. Die Dlls exportieren allerhand Funktionen (das sieht man ganz gut mit IDA). Es sind alles Klassenfunktionen (Stichwort: thiscall) und es gibt globale Variablen: z.B.

    CClass & ClassObject 159316FF
    

    .

    Damit ist es schon recht einfach an das Objekt zu kommen:

    class CClass;
    CClass* obj = reinterpret_cast<CClass*>(0x159316FF);
    

    Die besagte Dll (aus der auch die obige Adresse kommt) beinhaltet noch weitere Funktionen, zum Beispiel die hier:

    .text:152BA0AB ; public: bool __thiscall CClass::MakeDir(class std::basic_string<wchar_t, struct std::char_traits<wchar_t>, class StringAllocator<wchar_t>> const &)
    

    Leider bin ich bei dem Prototypen schon mehr als überfordert 😕
    Bei dem Parameter handelt es sich doch um einen wstring (oder etwa nicht?).

    Mein Programm müsste daher so aussehen:

    typedef bool (__thiscall *__CClass_MakeDir)(CClass*, wstring const &);
    __CClass_MakeDir MakeDir = reinterpret_cast<__CClass_MakeDir>(0x152BA0AB);
    MakeDir(obj, L"Test");
    

    Leider bringt der Code den Hostprozess zum abstürzen und ich bin mir sicher, dass es am zweiten Parameter liegt.

    @Gregson Welche mails?



  • Bei dem Parameter handelt es sich doch um einen wstring (oder etwa nicht?).

    Ja, das sollte ein std::wstring sein.

    Sicher dass die Addressen richtig sind ?

    Kleines Testprogramm zum Rumprobieren:

    #include <windows.h>
    #include <string>
    
    class CTest1
    {
    public:
    	void CallTest(const std::wstring& stringw)
    	{
    		MessageBoxW(0,stringw.c_str(),L"",0);
    	}
    };
    
    int main()
    {
    	CTest1 c1 = CTest1();
    
    	typedef void (CTest1::*CTest1_Pointer)(std::wstring const &);
    	CTest1_Pointer ptr = &CTest1::CallTest;
    
    	void* adress= *(char**)&ptr;
    
    	typedef void (__thiscall *__CClass_MakeDir)(CTest1*, std::wstring const &);
    	__CClass_MakeDir MakeDir = reinterpret_cast<__CClass_MakeDir>(adress); 
    	MakeDir(&c1, L"Test");
    	return 0;
    }
    

    Der Rest ist dann Sache es Debuggers. 😉



  • DarkShadow44 schrieb:

    Bei dem Parameter handelt es sich doch um einen wstring (oder etwa nicht?).

    Ja, das sollte ein std::wstring sein.

    Was hat es dann mit dem StringAllocator<wchar_t> auf sich?

    Bei den Adressen bin ich mir absolut sicher, weil sie ja eben aus der Dll kommen und daher konstant sein müssen.

    Debuggen ist leider nicht möglich, weil OllyDbg ewig braucht, den Prozess zu laden (die meiste Zeit sagt OllyDbg: "Debug string ....").



  • DerCoder schrieb:

    @Gregson Welche mails?

    Na ich hab dir ne Mail geschrieben, per Profil->E-Mail senden.



  • Bei den Adressen bin ich mir absolut sicher, weil sie ja eben aus der Dll kommen und daher konstant sein müssen.

    Der Logik kann ich nicht folgen. Auch Addressen in DLLs können randomisiert werden, das weißt du ?

    xstring.h von VS 2010 schrieb:

    typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
    

    Das ist eine Definition, das ist nur ein Parameter, keine zwei!
    Was genau ein Allokator ist kann ich dir allerdings nicth erklären, ist aber ja auch nicht relevant.

    Und warum sollte sich der Prozess nicht Debuggen lassen ? 😕
    Hast du die neueste Version von Olly ?



  • Gregson schrieb:

    DerCoder schrieb:

    @Gregson Welche mails?

    Na ich hab dir ne Mail geschrieben, per Profil->E-Mail senden.

    Habe leider keine bekommen 😞 Wird wahrscheinlich herausgefiltert bei web.de
    Probier es doch nochmal: dercoder{at}web{at}de

    DarkShadow44 schrieb:

    Bei den Adressen bin ich mir absolut sicher, weil sie ja eben aus der Dll kommen und daher konstant sein müssen.

    Der Logik kann ich nicht folgen. Auch Addressen in DLLs können randomisiert werden, das weißt du ?

    xstring.h von VS 2010 schrieb:

    typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
    

    Das ist eine Definition, das ist nur ein Parameter, keine zwei!
    Was genau ein Allokator ist kann ich dir allerdings nicth erklären, ist aber ja auch nicht relevant.

    Laut cplusplus.com ist ein basic string folgendes:

    template < class charT,
               class traits = char_traits<charT>,    // basic_string::traits_type
               class Alloc = allocator<charT>        // basic_string::allocator_type
               > class basic_string;
    

    EDIT: Ich meine die Parameter in den spitzen Klammern (< >).

    DarkShadow44 schrieb:

    Und warum sollte sich der Prozess nicht Debuggen lassen ? 😕
    Hast du die neueste Version von Olly ?

    Jo, 2.0.1 oder so.
    Es ist möglich zu debuggen, aber es dauert ewig lange 😃
    Allein bis ich im Spiel eingeloggt bin, dauert es 5 Minuten (dadurch, dass der Olly mit dem "Debug String: " mist solange braucht).



  • Laut cplusplus.com ist ein basic string folgendes:
    Code:
    template < class charT,
    class traits = char_traits<charT>, // basic_string::traits_type
    class Alloc = allocator<charT> // basic_string::allocator_type
    > class basic_string;

    EDIT: Ich meine die Parameter in den spitzen Klammern (< >).

    Wen interessiert denn was genau ein "basic string" ist ? Es geht doch um "wstring". Und wstring ist halt als "basic string" mit bestimmten Parametern definiert.
    Nochmal zur Klarstellung, das ist in der DLL:

    public: bool __thiscall CClass::MakeDir(class std::basic_string<wchar_t, struct std::char_traits<wchar_t>, class StringAllocator<wchar_t>> const &)
    

    Das ist ein std::wstring:

    typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
    

    Ergo ist das in der DLL:

    public: bool __thiscall CClass::MakeDir(std::wstring const &)
    

    Allein bis ich im Spiel eingeloggt bin, dauert es 5 Minuten (dadurch, dass der Olly mit dem "Debug String: " mist solange braucht).

    "OutputDebugString" noppen ?



  • DarkShadow44 schrieb:

    Laut cplusplus.com ist ein basic string folgendes:
    Code:
    template < class charT,
    class traits = char_traits<charT>, // basic_string::traits_type
    class Alloc = allocator<charT> // basic_string::allocator_type
    > class basic_string;

    EDIT: Ich meine die Parameter in den spitzen Klammern (< >).

    Wen interessiert denn was genau ein "basic string" ist ? Es geht doch um "wstring". Und wstring ist halt als "basic string" mit bestimmten Parametern definiert.
    Nochmal zur Klarstellung, das ist in der DLL:

    public: bool __thiscall CClass::MakeDir(class std::basic_string<wchar_t, struct std::char_traits<wchar_t>, class StringAllocator<wchar_t>> const &)
    

    Das ist ein std::wstring:

    typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
    

    Ergo ist das in der DLL:

    public: bool __thiscall CClass::MakeDir(std::wstring const &)
    

    Allein bis ich im Spiel eingeloggt bin, dauert es 5 Minuten (dadurch, dass der Olly mit dem "Debug String: " mist solange braucht).

    "OutputDebugString" noppen ?

    Okay danke erstmal. Mein Ansatz ist also richtig. Ich werde jetzt erstmal versuchen mit dem debugger weiter zu experimentieren.
    Wonach muss ich suchen, wenn ich "OutputDebugString" noppen möchte? Soll ich bei den referenced strings nach "OutputDebugString" suchen? Sorry für meine blöden Fragen.

    Wenn ich mit dem Debugger im Prozess bin, wie kann ich dann herausfinden, woran mein Funktionsaufruf (in der Dll) scheitert? Ich würde ja gerne googlen, weiß aber überhaupt nicht wonach 😃

    Danke für deine Hilfe bis hier her 👍



  • Soll ich bei den referenced strings nach "OutputDebugString" suchen

    Das bringt nichts, außerdem wird "OutputDebugString" netterweise auch nicht von Olly als "Intermodular call" gefunden.
    Gehe ich recht in der Annahme dass sich bei "OutputDebugString" einfach ne MessageBox öffnet ? Dann kannst du einfach über "Search->All Intermodular calls" zur MessageBox gehen, Breakpoint setzen und dann wenn es zurück in "OutputDebguString" die Funktion umschreiben.
    Bei mir macht "OutputDebugString" interessanterweise gar nichts.

    Wenn ich mit dem Debugger im Prozess bin, wie kann ich dann herausfinden, woran mein Funktionsaufruf (in der Dll) scheitert? Ich würde ja gerne googlen, weiß aber überhaupt nicht wonach

    Du injektest ja eine DLL. Kannst du inline-Assembly nutzen ?
    Unter VS könntest du das einfach so machen:

    typedef void (__thiscall *__CClass_MakeDir)(CTest1*, std::wstring const &);
        __CClass_MakeDir MakeDir = reinterpret_cast<__CClass_MakeDir>(adress); 
        __asm int 3
        MakeDir(&c1, L"Test");
    

    Dann hält der Debugger direkt vor dem Aufruf an und du kannst ganz einfach durchsteppen. 🙂
    Alernativ kannst du natürlich das Programm auch einfach Crashen lassen und dann den Debugger attachen, aber ich setzte ihn gerne schon vor dem Problem selber an.



  • Ich würde nach der Injection nur noch mit Inline Assembler arbeiten!



  • 🙄



  • www.organner.pl schrieb:

    Ich würde nach der Injection nur noch mit Inline Assembler arbeiten!

    lol organner h4x0r


Log in to reply