Perfis de doador e o espaço de configuração sombra
O que é uma identidade de doador no nível dos registradores: vendor ID e device ID, subsystem IDs, tamanhos de BAR e lista de capabilities. E por que um doador plausível ganha de um genérico.
Resposta curta
Um perfil de doador é a identidade de um dispositivo PCIe real. Sua placa escreve essa identidade no espaço de configuração sombra e é isso que ela mostra ao host. O perfil guarda o vendor ID, o device ID, os subsystem IDs, o layout das BARs e a lista de capabilities. Um doador plausível se lê como hardware normal. Um doador genérico, ou um que muitas placas dividem, é um padrão que qualquer um consegue enumerar.
Nesta página10
- O espaço de configuração é a primeira coisa que perguntam
- O espaço de configuração sombra e por que dá para escrever nele
- Os campos, e o que cada um conta a quem observa
- Por que plausível ganha de exótico
- O que torna um doador plausível
- Por que duas pessoas num mesmo doador é pior do que cada uma com um doador comum
- O que um perfil de doador não faz
- Perguntas que valem a pena antes de comprar um perfil
- Perguntas sobre doadores
- Fontes
O espaço de configuração é a primeira coisa que perguntam
Todo dispositivo PCIe carrega um pequeno bloco de registradores chamado espaço de configuração. O host lê esse bloco durante a enumeração para responder três perguntas. Quem é você, que classe de dispositivo você é e quanto espaço de endereçamento você quer. O Windows usa as respostas para escolher um driver. Qualquer outra coisa rodando naquela máquina consegue ler os mesmos registradores. É o firmware da sua placa que fornece essas respostas. Ou seja, o espaço de configuração é a identidade pública da placa, tendo você escolhido o conteúdo dele de propósito ou não.
O espaço de configuração sombra e por que dá para escrever nele
Num projeto de FPGA de fábrica, o bloco PCIe responde às leituras de configuração com valores fixados na síntese. O firmware DMA coloca na frente dele uma camada gravável de 4 KB em block RAM — o espaço de configuração sombra — e responde a partir dela. Na linhagem pública do pcileech-fpga, isso vive num arquivo de coeficientes compilado dentro do bitstream. Então a identidade da placa é dado, e não silício. É exatamente por isso que dá para recompilar o firmware em torno de outro doador sem trocar de hardware.
Os campos, e o que cada um conta a quem observa
Os offsets são contados a partir do início do espaço de configuração do dispositivo. A última coluna é a que importa. Ela não diz para que serve o campo, e sim o que alguém descobre ao lê-lo.
| Offset | Campo | O que guarda | O que conta a quem observa |
|---|---|---|---|
| 0x00 | Vendor ID | Um código de 16 bits que o PCI-SIG atribui ao fabricante | Qual empresa supostamente fez isto. Um valor não atribuído, ou um fabricante de FPGA conhecido numa placa que se diz uma NIC, é uma contradição imediata |
| 0x02 | Device ID | Um código de 16 bits que o fabricante atribui a um produto específico | Exatamente qual produto isto afirma ser. Junto com o vendor ID, identifica uma peça real que existe ou não existe |
| 0x08 | Revision ID | A revisão de silício daquela peça | Se aquela revisão chegou a ser vendida com este device ID. Uma revisão que nenhum produto usou já é uma incoerência por si só |
| 0x09-0x0B | Class code | Classe base, subclasse e interface de programação | Que categoria de dispositivo é este. Um class code que discorda do device ID é uma das verificações mais baratas que alguém pode rodar |
| 0x10-0x27 | BAR0 a BAR5 | Registradores de endereço base: quantas regiões o dispositivo quer, de que tamanho, memória ou I/O, prefetchable ou não | A pegada de memória que a peça real pediria. Um doador com BAR0 de 4 KB e um firmware que pede outra coisa deixou de combinar com a peça que diz ser |
| 0x2C | Subsystem Vendor ID | Quem montou a placa em que o chip está | Se a placa é uma peça de referência ou a montagem de um OEM específico. Costuma ser idêntico ao vendor ID em hardware do próprio fabricante |
| 0x2E | Subsystem ID | Qual variante de placa daquele integrador | O campo menos copiado em firmware ruim. Um chip real com um par de subsystem em branco ou sem sentido já é um sinal forte |
| 0x34 | Capabilities pointer | O offset da primeira entrada da lista encadeada de capabilities | Que o dispositivo tem capabilities. Um ponteiro que aponta para o nada é malformado de um jeito que hardware normal não é |
| 0x40+ | Lista de capabilities | Lista encadeada: gerenciamento de energia, MSI ou MSI-X, a própria capability PCI Express, entradas específicas do fabricante | Quais recursos a peça suporta. A lista do dispositivo real tem um conjunto específico numa ordem específica, e uma lista curta ou reordenada não bate |
| 0x100+ | Capabilities estendidas | Espaço estendido do PCIe: relatório avançado de erros, subestados de energia L1, número de série do dispositivo | Uma segunda superfície, maior, que quase ninguém preenche. Silêncio onde a peça real reporta entradas já é uma diferença |
| Ext cap 0x0003 | Device Serial Number | Um serial de 64 bits, somente leitura, que identifica de forma única um dispositivo físico | Um único valor que dá impressão digital à placa. Se duas placas reportam o mesmo, está provado que são o mesmo perfil |
Nenhuma dessas linhas é, sozinha, um método de detecção. São os campos que um observador consegue ler de graça. Um perfil vale o que vale o seu campo menos coerente.
Por que plausível ganha de exótico
Quem vai comprar firmware costuma pedir o doador mais raro possível, na teoria de que ninguém nunca viu aquilo. O raciocínio é o inverso do certo. Um dispositivo que ninguém viu é interessante, e interessante é o oposto do que você quer. O objetivo é uma peça que não chamaria atenção na sua máquina específica. Uma placa de captura combina com uma máquina que faz live. Uma NIC combina com uma máquina que tem uma segunda rede. Armazenamento combina com uma máquina com slot livre. Um doador é plausível quando quem lê a lista de dispositivos não tem motivo para olhar duas vezes.
O que torna um doador plausível
Cinco coisas, mais ou menos na ordem de quantas vezes cada uma é feita errado. As cinco vêm de o doador ser uma peça real, copiada por inteiro.
- Coerente por dentro
- Vendor, device, revisão, class code e o par de subsystem descrevem todos o mesmo produto que chegou às lojas
- Completo
- Os tamanhos de BAR e a lista de capabilities batem com a peça real, e não com um padrão de template
- Comum no contexto
- O tipo de placa que cabe numa máquina desse tipo, num slot desse tipo
- Não compartilhado
- O perfil não está rodando também num monte de outras placas
- Ainda em linha
- Uma peça que ainda existe por aí, e não uma aposentada anos atrás
Atenção
Por que duas pessoas num mesmo doador é pior do que cada uma com um doador comum
Um perfil de doador só vira impressão digital se ele se destaca. Um perfil compartilhado por muitas placas se destaca com muita facilidade. Não porque algum campo pareça errado, mas porque a combinação exata de campos se repete. Assim que uma combinação é ligada a alguma coisa, toda placa que a carrega herda essa ligação. Inclusive as placas que não fizeram nada. Um perfil comum, bem copiado e único é um alvo pior do que um perfil raro compartilhado por um lote. O primeiro é um entre milhares de dispositivos reais. O segundo é um conjunto com membros conhecidos.
Atenção
O que um perfil de doador não faz
Ele muda como a identidade da placa é lida na camada PCIe. O resto da sua exposição continua intocado. Isso inclui como o software se comporta e como o dispositivo de entrada move o cursor. Inclui também o caminho de vídeo, o histórico da própria conta e o que um humano revisando uma denúncia enxerga. Qualidade de firmware elimina uma forma específica de ser notado. Não é segurança. Ninguém consegue te oferecer segurança aqui, e qualquer vendedor que diga o contrário está te dizendo o que você quer ouvir.
Perguntas que valem a pena antes de comprar um perfil
As respostas a estas perguntas dizem mais do que qualquer nome de nível.
- O doador é uma peça real que chegou às lojas, ou um conjunto de valores editado à mão?
- Quantas outras placas rodam este mesmo perfil agora?
- Os tamanhos de BAR e a lista de capabilities foram copiados do doador, ou ficaram no padrão do template?
- O par de subsystem está preenchido, ou zerado?
- O perfil combina com a máquina em que ele vai ficar, ou ele é só incomum?
- O que acontece com o perfil se ele passar a ser associado a alguma coisa — existe caminho de recompilação?
Perguntas sobre doadores
Posso fornecer o meu próprio dispositivo doador?
Pergunte ao suporte antes de assumir qualquer coisa. Ler o espaço de configuração de um doador exige a placa física e uma máquina para lê-la. O que serve é um dump completo e exato, não três valores tirados de um anúncio.
O doador precisa ser um hardware que eu tenha de verdade?
Não, e normalmente não é. Ele precisa ser uma peça que não surpreenderia numa máquina como a sua. Ter o dispositivo real não muda nada em como a placa é lida.
Um doador raro é melhor que um comum?
Não por si só. Raro e compartilhado é a pior combinação. Comum e bem copiado é uma combinação razoável. Único é o que os níveis com doador por pedido existem para entregar.
Dá para mudar o espaço de configuração sem regravar?
Não. O espaço sombra é compilado dentro do bitstream, então outro perfil é outra imagem e uma nova gravação. É também por isso que trocar de perfil é um pedido de recompilação, e não um botão de configuração.
Um bom perfil de doador quer dizer que o meu setup está seguro?
Não. Ele trata um vetor de exposição — a identidade da placa na camada PCIe. Comportamento do software, entrada, caminho de vídeo e histórico da conta continuam intocados por ele.
Fontes
O que torna um doador plausível é julgamento nosso. O mesmo vale para o argumento de que um perfil compartilhado é pior que um perfil comum.
- 01PCI configuration space (overview)
o layout do cabeçalho e os offsets de vendor ID, device ID, BARs, subsystem IDs e da lista de capabilities
en.wikipedia.org
- 02pcileech-fpga (Ulf Frisk)
a linhagem pública de gateware que a página cita, em que o espaço de configuração sombra é compilado dentro do bitstream
github.com
Leia em seguida
Ainda travado? Abra um ticket no Discord
Todos os guias