PC Abschalten



  • Hallo,

    ich hoffe mir aknn hier jemand helfen. Ich würde mit einem Programm gerne zum Schluss den PC abschalten. Meine Frage wäre wie man das mit Assembler machen kann. Vom int15 hab ich schon gehört, auch ausprobiert, aber der läuft ja nur im RealMode und ich befind mich ja im PM. Wäre echt toll wenn jemand ne Idee hätte. Hab schon überlegt, dass das Netzteil ja irgendwie mit den Ports vom Prozessor angesprochen werden könnte. Naja, vielleicht hat hier ja jemand ne Idee.

    PS.: Windows muss auch nicht heruntergefahren werden. Nur der Strom muss weg. Den Rest sichert mein Programm.

    Gruß faragat



  • Hi.

    Wenn du unter Windows oder einem aehnlichen ProtectedMode-OS arbeitest (vor allem NT-Versionen von Windows - also 2K, XP etc.), bekommst du meistens so ohne weiteres keinen direkten Zugriff auf die Computerhardware mehr. In diesem Fall solltest du die Funktionsweise deines Programms nochmal ueberdenken und die entsprechenden Funktionen des OS verwenden (hier wohl WinAPI).



  • cdw_@freenet.de
    www.cdw.de/shutdown.zip

    ASM-winshutdown(auch NT/X2000/XP) mit Parameterübergabe

    für MASM32, müsste aber größtenteils auch TASM kompatiebel sein:
    Parameter:

    --------------------------------------------------------------------------------
    l - Logoff
    q - shutdown
    r - reboot
    p - poweroff
    a - about

    Beispiel:

    shutdown.exe r

    veranlasst einen Neustart...

    Optionale Parameter:
    shutdown.exe <parameter1>[,parameter2]

    e - normalerweise wird ja beim Herunterfahren an die Progs die
    WM_QUERYENDSESSION bzw. WM_ENDSESSION gesendet, bei
    dieser Option
    eben nicht :-D, hier wird sofort heruntergefahren, was zur folge
    hat, dass alle geöffneten Programme ihre Daten bis zum letzten
    Speicherzeitpunk verlieren

    k - kill, wenn ein Prog auf die WM_QUERYENDSESSION bzw.
    WM_ENDSESSION
    nicht reagiert, wirds gekillt, so einfach ist das...

    z.B
    shutdown.exe r,e
    Veranlasst einen sofortigen Neustart immer noch besser als Hard-reset, oder?

    --------------------------------------------------------------------------------

    code:----------------------------------------------------------------------------
    ;*****************************************************
    ;echter Code beginnt ab hier:

    .586
    .model flat, stdcall ;muss sein...
    option casemap :none
    include \masm32\include\windows.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\masm32.inc
    include \masm32\include\advapi32.inc
    includelib \masm32\lib\advapi32.lib
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

    .data

    aboutTitle db "CDW - Cult of the Dead Window",0
    aboutMsg db "Shutdown.exe",13,"Erstellt: 12-16.04.02",13,"Läuft auch unter NT/2000/XP :-D",13,13,"Parameter: shutdown.exe <parameter>:",13,"l logoff - Ausloggen",13,"q quit - Herunterfahren, nicht ausschalten!",13,"r Reboot - Neustart",13,"p Poweroff (wenn verfügbar)",13,"a das hier",13,13,"Optionale Parameter (werden angehängt)",13,"zB: schutdown.exe <parameter>[,parameter2] :",13,"e emergency exit",13,"k kill - nichtreagierende Programme,werden gekillt",13,13,"Details siehe 'Readme.txt'",0
    ;da der Compiler die Eigenart hat, bei längeren untereinander
    ;stehenden Zeilen zu meckern "line too long", schreibe ich
    ; alles in einer Zeile

    .data?
    dwCurrentProcess dd ?
    dwParam1 dd ? ;Variable zur Parameterübergabe
    .code

    start:
    ;////maindialog
    call MainAPIproc ;der Name ist frei wählbar, ich habe mich für diesen entschieden...

    Exitwin:
    push 0
    call ExitProcess

    ;///Ende!

    MainAPIproc proc

    LOCAL tkp:TOKEN_PRIVILEGES
    LOCAL hToken: HANDLE
    .data
    shutdown db "SeShutdownPrivilege",0 ; keine Ahnung wieso dieser Teil
    ; der API vom Compiler nicht so recht akzeptiert wird,
    ;deswegen übergebe ich das als Zeiger auf diese "Zeichenfolge"

    clArguments db ? ;zeigt auf Argumentenline

    .code
    push offset clArguments
    push 1
    call GetCL ;Argumente abfragen

    ;***************************************************
    ;reaktion auf Parameterübergabe
    cmp [clArguments],6ch ; logoff l =>ASCII code dafür
    mov dwParam1,0 ; wenn Argument = "l" dann setze Parameter1 auf 0 (EWX_LOGOFF ist 0)
    je CheckParameter2 ; springe zur Überprüfung des Arguments Nr 2

    cmp [clArguments],071h ; shutdown q
    mov dwParam1,1
    je CheckParameter2

    cmp [clArguments],072h ;reboot r
    mov dwParam1,2
    je CheckParameter2

    cmp [clArguments], 070h ;poweroff p
    mov dwParam1,8
    je CheckParameter2

    mov dwParam1,1 ; wenn nichts zutrifft, dann param=1=>Herunterfahren

    cmp [clArguments], 061h ; about, "a"
    jne CheckParameter2 ;wenn das nicht a ist, springe zu ....
    push MB_OK or MB_ICONQUESTION ;ansonsten
    push offset aboutTitle ;gib mal
    push offset aboutMsg ; den About Dialog aus
    push NULL
    call MessageBoxA
    jmp Exitwin ;und beende sofort das Programm!

    CheckParameter2:
    cmp [clArguments+2], 065h ; emergency, argument2 : e, +2 ist damit das komma übersprungen wird 😃
    jne CheckIfItNot_E ; wenn das nicht gleich e ist, springe zur "k" Überprüfung!
    add dwParam1,4 ;ansonsten addiere 4 zum jetztigen Parameter (unter C steht etwa: "EWX_LOGOFF or EWX_FORCE" und "or" ist eigentlich wie plus)
    je ShutItNow ; man könnte auch "jmp" schreiben

    CheckIfItNot_E:
    cmp [clArguments+2], 06bh ; kill hunged, arg 2 :k
    jne ShutItNow ; wenns auch nicht k ist dann mache weiter...
    add dwParam1,10h ; ansonsten +16 (steht in MSDN )
    jmp ShutItNow ; auch "je" würde gehen

    ;man kan sich darüber streiten, obs effizient war, ich wollte aber
    ; nicht so viele Labels anlegen, wenn man aber mehr hochsrapchenorientiert
    ; programmiert und dann disassembliert, sieht man, dass bei jeder IF abfrage
    ; Labels erzeugt werden etwa so: Label1:
    ; cmp x,y
    ; jne Label2
    ; mov z,q
    ; jmp Label2

    ;*********************************************

    ShutItNow:
    call GetCurrentProcess ;das bracuchen wir jetzt für NT/2000/XP
    mov dwCurrentProcess,eax ;die Process ID

    lea eax,hToken ;hToken adresse ins eax laden
    push eax ; argument auf Stack
    push 28h ; TOKEN_ADJUST_PRIVILEGES(0x0020) xor TOKEN_QUERY(0x008)=28 => siehe WINNT.h
    push dwCurrentProcess ; unsere ProcessID
    call OpenProcessToken

    lea eax,tkp.Privileges[0].Luid
    push eax
    push offset shutdown ; wir wollen einen shutdown machen
    push 0
    call LookupPrivilegeValue ;und wir kriegen die doch
    ;wer es hier nicht so ganz durchblickt, sollte
    ;in die winAPIdoku schauen...z.b MSDN

    mov tkp.PrivilegeCount,1
    mov tkp.Privileges[0].Attributes,SE_PRIVILEGE_ENABLED ;enable dies! (wenn der benutzer keine Berechtigung dazu hat
    ; wird trotzdem nix daraus!
    push 0
    push 0
    push 0
    lea eax,tkp
    push eax
    push 0 ;False
    push hToken

    call AdjustTokenPrivileges

    push 0 ;wird nicht beachtet, da noch reserviert
    push dwParam1 ; unseren Parameter
    call ExitWindowsEx
    ret

    MainAPIproc endp

    ; EWX_LOGOFF equ 0
    ; EWX_SHUTDOWN equ 1
    ; EWX_REBOOT equ 2
    ; EWX_FORCE equ 4
    ; EWX_POWEROFF equ 8

    END start
    ;***********************************************
    --------------------------------------------------------------------------------

    PS:
    am besten mit

    \masm32\bin\ml /c /coff /nologo shutdowncode.asm
    \masm32\bin\Link /SUBSYSTEM:WINDOWS /MERGE:.rdata=.text shutdowncode.obj > nul

    compilen (einfach mal ne Batch erstellen), dann wird die Exe noch kleiner,
    aber der Code ist auch so
    auf MASM32 laufähig...



  • @Peter III:
    API-Calls schreibt man besser in C/C++. Das ist übersichtlicher.
    Assembler bietet dabei keinen Vorteil.



  • cd9000 schrieb:

    @Peter III:
    API-Calls schreibt man besser in C/C++. Das ist übersichtlicher.
    Assembler bietet dabei keinen Vorteil.

    das file wird kleiner 😃 und es macht meiner meinung nach mehr spass 😉

    gruss reima




Anmelden zum Antworten