Não tenho certeza se esta pergunta deve ir aqui ou em reverseengineering.stackexchange.com
Citando da Wikipédia :
No processador 8086, a tabela de interrupção é chamada IVT (tabela de vetor de interrupção). O IVT sempre reside no mesmo local na memória, variando de 0x0000 a 0x03ff, e consiste em 256 ponteiros far de modo real de quatro bytes (256 × 4 = 1024 bytes de memória).
Isto é o que eu encontro no monitor qemu:
(qemu) xp/128xw 0
0000000000000000: 0xf000ff53 0xf000ff53 0xf000e2c3 0xf000ff53
0000000000000010: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000020: 0xf000fea5 0xf000e987 0xf000d62c 0xf000d62c
0000000000000030: 0xf000d62c 0xf000d62c 0xf000ef57 0xf000d62c
0000000000000040: 0xc0005526 0xf000f84d 0xf000f841 0xf000e3fe
0000000000000050: 0xf000e739 0xf000f859 0xf000e82e 0xf000efd2
0000000000000060: 0xf000d648 0xf000e6f2 0xf000fe6e 0xf000ff53
0000000000000070: 0xf000ff53 0xf000ff53 0xf0006aa4 0xc0008930
0000000000000080: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000090: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000c0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000d0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000e0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000100: 0xf000ec59 0xf000ff53 0xf000ff53 0xc0006730
0000000000000110: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000120: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000130: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000140: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000150: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000160: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000170: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000180: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000000190: 0x00000000 0x00000000 0x00000000 0xf000ff53
00000000000001a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001c0: 0xf000d611 0xf000ec4e 0xf000ec4e 0xf000ec4e
00000000000001d0: 0xf000d61a 0xf000d623 0xf000d608 0xf000ec4e
00000000000001e0: 0xf000ff53 0x00000000 0xf000ff53 0xf000ff53
00000000000001f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
Não tenho certeza do que fazer com esses valores. Não se parece com uma tabela de descritor de interrupção (desreferenciar esses valores fornece todos os nulos). Então, o que estou realmente olhando aqui?
Qualquer que seja o seu firmware deixou contendo.
Em um sistema moderno ideal, o processador nunca entra no modo real, como expliquei nesta seção de perguntas e respostas da SU intitulada: Em que modo os chips Intel modernos de 64 bits executam o setor de inicialização? , o primeiro KiB de memória física é tão irrelevante quanto Johan Myréen fez em outra resposta aqui. Mas muitos firmwares modernos (ainda) têm suporte à compatibilidade , o que significa que
Uma dessas estruturas de dados é o modo real IVT. As antigas APIs de firmware de modo real são baseadas em
int
instruções, e o IVT de modo real é preenchido pelo firmware como parte de sua inicialização com ponteiros para as várias rotinas de manipulação de firmware para essas instruções.Os softwares de sistema de modo protegido não precisam das antigas APIs de firmware de modo real e nunca executam o processador em modo real, portanto, o IVT de modo real nos primeiros 1KiB de memória física não é usado. (O modo protegido v8086 não endereça o endereço físico 00000000 e superior, lembre-se. Ele endereça os endereços lógicos 00000000 e superiores, que são traduzidos por tabelas de páginas.) Em sistemas EFI modernos, o firmware entrega um mapa de memória da memória física ao sistema operacional bootstrap, informando quais partes são reservadas ao firmware para seus próprios propósitos de API de modo protegido e quais partes o sistema operacional está livre para seguir em frente e usar para seu pool de memória física. Em teoria, a primeira página da memória física pode estar na última categoria.
Na prática, em primeiro lugar, os firmwares geralmente marcam a primeira página da memória física como "código de serviços de inicialização", o que significa que um sistema operacional pode reivindicá-lo e usá-lo como parte de seu pool de memória física, mas somente após a inicialização . os serviços de tempo do firmware EFI foram encerrados pelo sistema operacional e o firmware reduzido para fornecer apenas seus serviços de tempo de execução. Um exemplo disso pode ser visto no log do kernel Linux (com a
que xe decodifica com outro programa em uma forma mais legível como:add_efi_memmap
opção) mostrado por Finnbarr P. Murphy:Na prática, em segundo lugar, o Linux ignora explicitamente essa faixa de memória física, mesmo que o firmware diga que pode ir em frente e usá-la. Você descobrirá que em firmwares EFI e não EFI, uma vez que o Linux tenha o mapa de memória física, ele o corrige ( em uma função chamada
trim_bios_range
), resultando em mensagens de log do kernel, como:Isso não é tanto para lidar com firmwares EFI modernos, onde o modo real IVT não faz parte da API de firmware, mas sim para lidar com firmwares PC98 antigos, onde faz parte da API de firmware, mas os firmwares o relatam (via essa mesma API) como memória física disponível para ser sobrescrita pelo sistema operacional.
Assim, embora em teoria esse intervalo de memória física possa conter código ou dados arbitrários, dependendo das necessidades momentâneas dos alocadores de memória do kernel e da memória virtual paginada por demanda; na prática, o Linux simplesmente o deixa intocado como o firmware o configurou originalmente.
E em seu sistema, o firmware o preencheu com entradas IVT de modo real. As entradas IVT de modo real são apenas ponteiros far 16:16, é claro, e se você observar sua memória usando um hexdump de 2 bytes, poderá ver isso claramente. Alguns exemplos:
iret
.Leitura adicional
A arquitetura original do processador 8086 (implementada como Modo Real em processadores 80286+) não tem relevância para o Linux, que opera em Modo Protegido. Não há nenhuma tabela de vetores de interrupção no endereço físico 0, em vez disso é usada uma Tabela de Descritores de Interrupção contendo Descritores de Interrupção. O IDT pode ser localizado em qualquer lugar na memória.
O kernel do Linux obtém um mapa de memória física do firmware (BIOS ou EFI) que informa quais quadros de página de memória física podem ser usados e quais estão reservados ou não estão presentes. O intervalo de quadros de página utilizáveis não é contíguo, mas normalmente possui grandes buracos. Tradicionalmente, o kernel Linux x86 pulou o início da memória física, mesmo que esteja marcado como utilizável. Assim, o endereço físico 0 não é usado pelo kernel do Linux.
Despejando memória
Aqui está uma maneira alternativa de despejar o conteúdo da memória dentro do sistema em vez de fazer isso externamente:
Análise
A parte superior acima de 000c0000 pode estar relacionada ao bootloader. Por que eu suspeitaria disso? O código 55aah no local
Referência: Assinatura de inicialização - BIOS000c0000
normalmente pode ser uma marca na memória para coisas como um gatilho para o BIOS executar um carregador de inicialização secundário.No entanto, dado que este 55aah ocorre na faixa c0000h-effffh, é mais provável que esta parte seja o cabeçalho de expansão PNP:
Referência: Especificação de inicialização do BIOS53ss...
Quanto aos dados 53ffh que estão no início. Não está claro para mim o que isso realmente é. Pesquisando ainda mais, é provável que seja algo que o kernel do Linux escreveu lá depois que o bootloading do MBR do BIOS foi entregue ao kernel do Linux para inicializar.
Cavando mais, consegui encontrar este parágrafo de um trabalho de pesquisa intitulado: Injeção de código malicioso via /dev/mem :
Referências