- Celular / tabletpareado por QR · HTTP + SSE
- FanPilotserviço · painel web · regras de segurança
- Gigabyte.Engine.EnvironmentControl.dllSDK cliente do GCC, carregado por reflection
- EasyTuneEngineService.NET Remoting · ipc://GigabyteEngine · SYSTEM, só administradores
- ITE IT8689E Super I/OSmartGuardian · a curva roda no hardware
O problema
Nas placas Gigabyte, o único jeito de mudar as curvas dos fans pelo Windows é o Gigabyte Control Center: um programa de desktop, no próprio PC. O FanPilot nasceu para fazer o mesmo pelo celular, na mesma rede Wi-Fi, sem substituir o serviço do fabricante e sem distribuir nenhum arquivo dele.
Achando a entrada
A análise partiu dos arquivos instalados: metadados e IL dos assemblies .NET, dumps de API só por reflection e
decompilação pontual, confirmados depois em execução com pequenos probes (tools/Probe*.cs). A máquina de referência
foi uma B760M GAMING X AX com um i5-13400.
A arquitetura se revelou um cliente e um serviço conversando por .NET Remoting:
- O
GCC.exeé só a interface. Ele carrega aGigabyte.Engine.EnvironmentControl.dll, um SDK cliente de classes*Module. - Esses módulos se conectam a
ipc://GigabyteEngine/EnvironmentControl/<Objeto>, publicados pelo EasyTuneEngineService, um serviço do Windows que roda como SYSTEM. - O serviço faz o trabalho de verdade, até a
Gigabyte.EnvironmentControl.LowPinCount.dll, que conversa com o chip Super I/O ITE IT8689E da placa pelas portas LPC.
Dois detalhes pesaram logo de cara:
- A ACL da porta IPC só admite Administradores: um processo sem elevação recebe “acesso negado”. Por isso o FanPilot pede elevação.
- A primeira chamada numa conexão nova falha com “o pipe está sendo fechado”; tentar de novo funciona. O FanPilot tenta de novo uma vez.
Lendo os sensores
HardwareMonitorControlModule.GetCurrentMonitoredData devolve cada leitura como {Type, Title, DeviceUUID, Value, Unit}: na placa de teste, 23 itens, das temperaturas da CPU e do VRM ao RPM dos fans, tensões, clocks e potência da
CPU. A GPU não está ali, então o FanPilot lê as placas NVIDIA pelo nvml.dll do próprio driver.
Gravando uma curva
O Control Center escolhe uma “geração” de controle de fans pelo número de grupo da placa. Nesta placa é a terceira, e o
módulo que funciona é o SmartGuardianFanControlCoordinateSystemModule: Get e Set de uma curva por header,
escolha do sensor que comanda cada um, temperaturas e RPM lado a lado.
Uma curva é um SmartFanDataPointSet: um modo e uma lista de pontos, X em °C e Y como PWM de 0 a 255. Dentro do
serviço, o Set passa por um conversor que a transforma nos parâmetros nativos SmartGuardian do chip. Isso tem
uma consequência grande: a curva roda no hardware, e continua valendo com o FanPilot, e até o Windows, fechado.
O ponto que precisava ser 255
O primeiro teste de escrita “não funcionou”: todos os fans foram para a velocidade máxima. O conversor, lido em
SmartGuardianFanConfigConverter, explicou o porquê. Ele mapeia os pontos assim:
| Ponto | Vira |
|---|---|
P[0].X |
a temperatura em que o fan desliga |
P[1] |
temperatura e PWM de partida |
P[2..n-2] |
“extra vectors”: início, PWM e inclinação de cada trecho |
P[n-1] |
a temperatura de velocidade máxima, e o Y precisa ser 255 |
Com menos de três pontos, ou com o último ponto abaixo de 255, a conversão aborta em silêncio e o serviço grava uma configuração zerada, que o chip trata como velocidade máxima. Por isso o editor do FanPilot sempre termina a curva em 100%, e a validação recusa tudo o que o chip leria errado.
A correção foi confirmada na placa real: o System 1, com 40% até 70 °C, foi de 2352 para 1573 RPM em 8 segundos, e voltou a subir quando a curva original foi restaurada.
Sem os arquivos do fabricante
O FanPilot não redistribui nem compila contra nenhum arquivo da Gigabyte. Uma camada fina, a GigabyteApi, resolve
por reflection os tipos e membros do Control Center já instalado no PC, confere o contrato inteiro na partida e guarda
as referências. Se uma atualização do Control Center mudar algo, o FanPilot diz no painel exatamente o que falta e
segue pelo LibreHardwareMonitor. Um único build atende todas as placas, e a CI consegue gerá-lo.
Todas as outras placas
Placas sem o Control Center passam pelo LibreHardwareMonitor e pelo driver PawnIO, que o FanPilot oferece instalar pelo winget. Nelas, o chip só aceita uma porcentagem e não guarda curva, então o FanPilot executa as curvas, uma vez por segundo. Cada curva tem uma resposta (Rápida, Equilibrada ou Suave): a temperatura é suavizada, o fan só desacelera depois de o PC esfriar alguns graus e a velocidade muda aos poucos. Fechar o FanPilot, um sensor sem leitura ou falhas seguidas devolvem todos os fans à BIOS.
No Linux (beta), o FanPilot chega à placa pelos drivers hwmon do kernel (nct6775, it87,
asus-ec-sensors…) e à GPU pelo NVML ou pelo amdgpu, como um serviço do systemd.
Os dois caminhos ficam atrás de uma interface só, a IBoard, e o resto do FanPilot não precisa saber com qual está
falando.
O programa em volta
- Um serviço, que sobe com o Windows antes do logon e é reiniciado pelo Windows se cair, mais um ícone na bandeja e uma interface no terminal.
- Um painel web servido pelo próprio FanPilot por HTTP, com as leituras ao vivo empurradas por Server-Sent Events.
- Pareamento por QR: um código de 144 bits, de uso único, mostrado no PC, e depois um cookie de sessão do qual só o hash fica guardado. O servidor só atende pedidos endereçados ao PC (contra DNS rebinding) e confere a origem e um cabeçalho próprio em toda escrita (contra CSRF).
- Regras de segurança num lugar só: pelo menos 20% em toda curva, 100% no último ponto até 90 °C, bombas a 100% ou num mínimo escolhido e um watchdog de 15 segundos que reaplica a sua curva se algo a sobrescrever.
Como é testado
- 308 casos de teste em C# (xUnit), sem hardware e sem Administrador, contra uma placa falsa com cenários: a placa de demonstração, um pior caso com oito fans e nomes longos, uma placa sem suporte, um serviço fora do ar, um lento.
- Testes de unidade do JavaScript do painel (o test runner do Node): matemática das curvas, i18n, sensores.
- 70 testes de ponta a ponta em 15 arquivos do Playwright, rodando no Edge: o editor de curvas por mouse, teclado e toque, pareamento, alertas, histórico, modo painel, a integração MQTT, reconexão depois de reiniciar, acessibilidade com o axe-core e screenshots em 320, 390 e 1024 px nos dois temas.
--hardware-testna placa real: velocidade fixa, uma curva vigiada, Turbo, o fan da GPU e um reinício, nunca abaixo de 40%, recusando o fan da CPU e as bombas, parando se a CPU ou a GPU passarem de 80 °C e devolvendo tudo como estava.- CI a cada push (GitHub Actions): build, tudo o que está acima como Administrador e um smoke test do zip da release.

Fontes: docs/REVERSE_ENGINEERING.md e as specs de design no repositório. REVERSE_ENGINEERING.md