Подтвердить что ты не робот

Выключение компьютера с помощью сборки

Как отключить компьютер, используя только код сборки?

4b9b3361

Ответ 1

Вам нужно сказать, какое это семейство процессоров и какую ОС вы используете. Кроме того, с какими привилегиями работает ваш код - если это код ядра, то он имеет больше привилегий, чем пользовательский код.

Предполагая, что вы используете какой-то член семейства Windows NT (включая XP или Vista) на процессоре семейства Intel x86, и ваш код - это обычный (пользовательский) код, тогда... вам нужно вызвать встроенную функцию Windows, чтобы сделай это. Вы не можете просто выполнить магическую последовательность сборки.

Даже если бы вы могли просто выполнить некоторую магическую последовательность сборки, вы бы этого не хотели - вы почти наверняка хотите дать ОС возможность записывать данные из дискового кэша на диск и выполнять другие операции постепенного отключения.

Если вы пишете свою собственную ОС для x86, то вам нужно взглянуть на спецификации ACPI (или APM). Если с кодом GPL все в порядке, соответствующие подпрограммы ядра Linux находятся здесь (ACPI) и здесь (APM).

Ответ 2

Это 29-байтная программа, которую я использовал, чтобы отключить компьютер в режиме DOS в течение многих лет.

;Connect to APM API
MOV     AX,5301
XOR     BX,BX
INT     15

;Try to set APM version (to 1.2)
MOV     AX,530E
XOR     BX,BX
MOV     CX,0102
INT     15

;Turn off the system
MOV     AX,5307
MOV     BX,0001
MOV     CX,0003
INT     15

;Exit (for good measure and in case of failure)
RET

Вы можете искать больше функций с Список прерываний Ralf Browns at DJGPP.

Ответ 4

В Linux прочитайте перезагрузку (2).

источники, представляющие интерес:

kernel/sys.c kernel/exit.c и arch/x86/kernel/apm.c

не полный ответ, но я думаю, что это хороший старт. Мне нужно будет прочитать мой машинный код BIOS, чтобы посмотреть, что они делают. но эта часть специфична для машины. maby, если вы знаете, что IC contol power на вашей материнской плате вы можете определить, какой порт ввода-вывода, зарегистрировать и команду вам нужно. затем настройте правильные состояния платы/устройств и затем выполните команду для выключения питания.

BIOS управляет мощностью через INT 15h ah = 53h (так называемое Advanced Power Management aka APM) Функция al = 07, используемая в Linux, - это заданное состояние мощности cmd. Параметры bx = 0001h означают, что все устройства и cx = 0003k означают остановку.

Ответ 5

Преобразование ответа @larz на узел nasm выполняется следующим образом:

Предпосылки: Bochs, Nasm

Этот пример был запущен на debian wheezy со стандартными пакетами.

Код (имя_файла: shutdown.asm):

    org 0x7c00
    jmp main

Shutdown:
    mov ax, 0x1000
    mov ax, ss
    mov sp, 0xf000
    mov ax, 0x5307
    mov bx, 0x0001
    mov cx, 0x0003
    int 0x15

WaitForEnter:
    mov ah, 0
    int 0x16
    cmp al, 0x0D
    jne WaitForEnter
    ret

main:   
    call WaitForEnter
    call Shutdown

times 510-($-$$) db 0
dw 0xaa55

Сопротивление Nasm:

nasm -f bin -o boot_sect.img shutdown.asm

Файл конфигурации Bochs (имя файла:.bochsrc) в том же каталоге, что и код (shutdown.asm)

display_library: sdl
floppya: 1_44=boot_sect.img, status=inserted
boot: a

* Примечание. Я использую библиотеку sdl для bochs, которая представляет собой отдельный пакет из самих bochs

Запуск bochs (из того же каталога, что и раньше):

bochs

Нажмите, чтобы завершить работу

* Примечание. Я не уверен, что все строки между ярлыком Shutdown и ярлыком WaitForEnter необходимы

Ответ 6

Из arch/x86/kernel/amp.c:

/**
 * apm_power_off - ask the BIOS to power off
 *
 * Handle the power off sequence. This is the one piece of code we
 * will execute even on SMP machines. In order to deal with BIOS
 * bugs we support real mode APM BIOS power off calls. We also make
 * the SMP call on CPU0 as some systems will only honour this call
 * on their first cpu.
 */

static void apm_power_off(void)
{
 unsigned char po_bios_call[] = {
  0xb8, 0x00, 0x10, /* movw  $0x1000,ax  */
  0x8e, 0xd0,  /* movw  ax,ss       */
  0xbc, 0x00, 0xf0, /* movw  $0xf000,sp  */
  0xb8, 0x07, 0x53, /* movw  $0x5307,ax  */
  0xbb, 0x01, 0x00, /* movw  $0x0001,bx  */
  0xb9, 0x03, 0x00, /* movw  $0x0003,cx  */
  0xcd, 0x15  /* int   $0x15       */
 };

 /* Some bioses don't like being called from CPU != 0 */
 if (apm_info.realmode_power_off) {
  set_cpus_allowed_ptr(current, cpumask_of(0));
  machine_real_restart(po_bios_call, sizeof(po_bios_call));
 } else {
  (void)set_system_power_state(APM_STATE_OFF);
 }
}

Код теперь находится в apm_32.c. Найдите "apm_power_off".

Ответ 7

Это довольно легко. Кроме того, ребята, OP могут работать над своим собственным менеджером. То же самое, что я делаю. Это пример, который позволит пользователю выключить машину. Довольно просто, просто дает пользователю сообщение с ОК и Отмена. Если пользователь нажимает "ОК", машина выключится, если пользователь наберет отмену, программа просто выйдет. Он протестирован на версиях Windows на базе NT и должен работать с более старыми версиями, такими как ME, 95 и 98.

Это мой собственный код, и каждый может использовать его. http://pastebin.com/ccw3mWtw

Ответ 8

Вызвать функцию ExitWindowsEx API в файле kernel32.dll

Ответ 10

для 32-битной операционной системы, использующей этот код:

BITS 32

global _start
section .text

_start:

; Local variables:
;
; [ebp-4] Address of ntdll.dll
; [ebp-8] Address of ntdll.dll export table
; [ebp-12] Space for RtlAdjustPrivilege output

push ebp
mov ebp,esp
sub esp,12

; Save registers

push ebx
push esi
push edi

jmp get_delta_offset ; Get the delta offset

get_delta_offset2:
    pop ebx
    jmp start ; Jump to main code

get_delta_offset:
    call get_delta_offset2

data:
    NtShutdownSystem_s db "NtShutdownSystem"
    NtShutdownSystem_len equ $-NtShutdownSystem_s

    RtlAdjustPrivilege_s db "RtlAdjustPrivilege"
    RtlAdjustPrivilege_len equ $-RtlAdjustPrivilege_s

get_function_address:

    ; Save registers

    push ebx
    push esi
    push edi

    mov eax,[ebp-8]
    mov ebx,[eax+0x20] ; ebx now points to the export names array

    add ebx,[ebp-4]
    xor eax,eax

    .get_function_address_loop:
        mov esi,edx ; esi now points to the function
        mov edi,[ebx+eax*4]
        add edi,[ebp-4] ; edi now points to the export name

        push ecx ; Save the function name length
        cld ; Clear the direction flag

        rep cmpsb ; Do the comparison
        pop ecx ; Restore the length

        je .get_function_address_end
        inc eax

        cmp eax,[ebx+0x14]
        jl .get_function_address_loop

    .get_function_address_fail:
        pop edi
        pop esi
        pop ebx

        xor eax,eax
        ret

    .get_function_address_end:
        mov ebx,[ebp-8]
        mov ecx,[ebx+0x1c]

        add ecx,[ebp-4] ; ecx now points to the function addresses array

        mov edx,[ebx+0x24]
        add edx,[ebp-4] ; edx now points to the ordinals array

        movzx eax,word [edx+eax*2] ; eax now holds the ordinal
        mov eax,[ecx+eax*4] ; eax now holds the RVA of the function

        add eax,[ebp-4] ; eax now holds the address of the function

        ; Restore registers

        pop edi
        pop esi
        pop ebx

        ret

start:

xor ecx,ecx
mov eax,[fs:ecx+0x30] ; eax now points to the PEB

mov eax,[eax+0xc] ; eax now points to loader data
mov eax,[eax+0x14]

mov eax,[eax+ecx]
mov eax,[eax+0x10] ; eax now holds the address of ntdll.dll

mov [ebp-4],eax ; Save the address of ntdll.dll

add eax,[eax+0x3c] ; eax now points to the PE header
mov eax,[eax+0x78] ; eax now points to the export directory
add eax,[ebp-4] ; eax now points to the export table

mov [ebp-8],eax
xor ecx,ecx

mov cl,NtShutdownSystem_len
mov edx,ebx

add ebx,ecx ; Move to next string
call get_function_address

test eax,eax
je exit

mov esi,eax
xor ecx,ecx

mov cl,RtlAdjustPrivilege_len
mov edx,ebx

call get_function_address

test eax,eax
je exit

mov edi,eax
xor eax,eax

; Enable SeShutdownPrivilege

lea ecx,[ebp-12]

push ecx
push eax ; CurrentThread = FALSE
push 1 ; Enable = TRUE
push 19 ; SeShutdownPrivilege

call edi ; Call RtlAdjustPrivilege
xor eax,eax

push eax ; ShutdownNoReboot
call esi ; Call NtShutdownSystem

exit:

pop edi
pop esi
pop ebx

mov esp,ebp
pop ebp
ret