NtOpenProcess und NtTerminateProcess direkt über SYSENTER aufrufen



  • Hi Zusammen,

    ich versuche gerade die Native API (also die Ntxxx-Funktionen) direkt in meinem Programm aufzurufen. Mich würde nämlich mal interessieren, ob ich das auch ohne kernel32.dll und die Sprung-Stubs in ntdll.dll schaffe.
    Sieht aber nicht so aus ...^^
    Liegt warscheinlich daran, dass ich das erste mal Inline Assembler in Verbindung mit C++ verwende, aber wer weiß - vielleicht liegt der Fehler auch woanders.

    Mein Code sieht folgendermaßen aus:

    int main(int argc, char *argv[])
    {    
    	PCLIENT_ID ClientId = (PCLIENT_ID) malloc (sizeof (CLIENT_ID));
    	POBJECT_ATTRIBUTES obj = (POBJECT_ATTRIBUTES) malloc (sizeof (OBJECT_ATTRIBUTES));
    	DWORD dwAccess = 0x01;
    	PHANDLE phProcess = (PHANDLE) malloc (sizeof (HANDLE));
    
    	ClientId->UniqueProcess = ID_OF_PROCESS;
    	ClientId->UniqueThread = 0;
    
    	obj->Length = sizeof (OBJECT_ATTRIBUTES);
    	obj->Attributes = 0;
    	obj->ObjectName = NULL;
    	obj->RootDirectory = 0;
    	obj->SecurityDescriptor = 0;
    	obj->SecurityQualityOfService = 0;
    
    	__asm 
    	{
    		push [ClientId];
    		push [obj];
    		push [dwAccess];
    		push [phProcess];
    
    		mov eax, 7Ah; //Index für NtOpenProcess in der SSDT
    		mov edx, esp; 
    
    		sysenter;     //Call NtOpenProcess via KiFastCallEntry
    	}     
    	DWORD dwExitStatus = 0;
    	HANDLE hTerminate = *phProcess;
    
    	__asm 
    	{
    		push [dwExitStatus];
    		push [hTerminate];
    
    		mov eax, 101h; //Index für NtTerminateProcess in der SSDT
    		mov edx, esp;
    
    		sysenter;    //Call NtTerminateProcess via KiFastCallEntry
    	}
    
        system("PAUSE");          
        return (0);         
    }
    

    Der Code kompiliert einwandfrei. Nur bei der Ausführung schmiert mir das Programm ab, aka. ich bekomme einen Fehlerbericht. Dieses Fenster mit 'Senden' und 'Nicht Senden'- ich denke ihr kennt das auch schon. XD

    By the way, sollte sich jemand wundern, warum der Befehl 'sysenter' in den beiden inline assembly bei mir kompiliert wurde (der inline Asssembler von VC++ kennt den Befehl normalerweise nicht)- das habe ich anfangs als int 2eh kompilieren lassen und später mit einem Disassembler nachträglich in ein sysenter umgeändert. Die Anweisungslängen sind ja auf Assemblerebene gleich (2 Byte).

    Es wäre sehr freundlich von euch, wenn ihr mir dabei weiterhelfen könntet.

    Greetings, Xzi-bit



  • Da die (meisten) Funktionen nicht dokumentiert sind kann ich Dir nur sagen:
    Da musst Du wohl noch etwas reverse Engineeren 😉

    PS: Das einfachste ist: Frag an Deiner Uni ob Du den Windows Source-Code Dir anschauen kannst... die meinsten Unis haben Zugriff drauf... wenn nicht, kannst Du auch mich fragen 😉



  • Naja, ich denke, dass ich mir dabei ziemlich sicher sein kann.
    Ich habe eine Dokumentation für die beiden Funktionen gefunden:

    http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/NtOpenProcess.html
    und
    [url]http://undocumented.ntinternals.net/UserMode/Undocumented Functions/NT Objects/Process/NtTerminateProcess.html [/url]

    Den Code von OpenProcess aus der kernel32.dll hab ich mir mit Windbg anzeigen lassen und habe außerdem den Sourcecode von Reactos 3.1 für OpenProcess da.
    Der ist in dieser Hinsicht identisch.
    Mein Code müsste folglich auch stimmig sein.

    Aber ich werde so schnell wie möglich versuchen an den Quelltext zu kommen 😛
    Vielleicht ist es das Beste. Hast ja Recht XD



  • (...)
     __asm {
    
       PUSH ....     
       PUSH ....
       PUSH ....
       PUSH ....
    
       LEA  EAX,@LAB01    // <- !!!
       PUSH EAX
    
       MOV  EAX, ....   
       MOV  EDX, ESP
    
       SYSENTER
    
     @LAB01:
    
       ADD ESP, ....      // <- !!!
    
     }
    (...)
    

Anmelden zum Antworten