Exemplos de palavras-chave de um programa de gancho completo: gancho, bloqueio, serviço
Esta é a pergunta do teste para "Analista Sênior de Programas do Windows" da empresa xx que recebi quando estava me candidatando a um emprego. Os requisitos específicos (ou seja, a descrição do meu programa) são:
1. O programa cliente é denominado Cliente. Monitore o funcionamento do sistema. Se você descobrir que existe um processo "notepad" (notepad.exe) ou um processo "calculadora" (calc.exe) no sistema, elimine o processo imediatamente e grave o evento no banco de dados; periodicamente Verifique o banco de dados a cada 1 minuto e carregue os registros de eventos que ainda não foram carregados no servidor.
1. O ambiente operacional de destino é o sistema operacional Windows 2000.
2. Projete o programa para servir ao sistema.
3. O programa deve ter capacidades anti-ataque, incluindo funções como anti-exclusão e resistência ao encerramento forçado de processos.
(1) Manter o programa em execução contínua e evitar que outros programas interrompam à força a execução do programa atual;
(2) Proteger o banco de dados de eventos e o arquivo de execução principal contra exclusão;
(3) Se for encontrada uma anormalidade (o processo é encerrado, o arquivo é excluído, etc.), force imediatamente o recarregamento/execução do programa;
(4) Se uma anormalidade for detectada três vezes consecutivas, o processo daemon forçará a reinicialização do sistema operacional após reiniciar o sistema, garantindo que o programa carregue e execute normalmente;
(A) Para realizar as funções acima, o programa não se limita ao formato EXE, podendo a forma de implementação ser decidida por si de acordo com as necessidades.
(B) As funções acima são todas implementadas no ambiente operacional normal do Windows 2000 e sob permissões de administrador. Não há necessidade de considerar o modo de segurança ou permissões do Windows e outros problemas.
4. Use bancos de dados de desktop simples, como Access, xBase e outros bancos de dados de arquivos.
5. Cada evento gerado contém pelo menos duas informações: o horário da ocorrência do evento e o objeto de processamento do evento.
Os dados do evento são armazenados no banco de dados na tabela tEvent. A tabela tEvent contém pelo menos dois campos:
(1) Campo EventTime: tipo hora/data. Registre a hora em que o evento ocorreu.
(2) Campo EventTarget: tipo de caractere. Registra os objetos mortos no evento. Os objetos a serem considerados são o processo do Bloco de Notas e o processo da Calculadora.
Se precisar de outras tabelas ou campos, você poderá adicioná-los conforme necessário.
6. O formato de transmissão de dados da rede é personalizado. Decida o conteúdo específico e o formato de transmissão de acordo com suas necessidades, e não há requisitos específicos. A rede do cliente precisa funcionar em conjunto com a rede do servidor.
7. Não há limite para a linguagem de desenvolvimento e o ambiente de desenvolvimento integrado usado, você mesmo pode escolher.
8. Para o método de conexão do banco de dados, escolha de acordo com suas necessidades.
2. O programa do lado do servidor é denominado Servidor. Monitore a rede e, assim que um cliente fizer upload dos dados, as informações do evento serão imediatamente extraídas e exibidas em uma lista na interface do usuário.
1. O ambiente operacional de destino é o sistema operacional Windows 2000.
2. O programa deve ser projetado como um aplicativo GUI comum do Windows 2000. A interface do usuário deve conter pelo menos uma lista de informações de eventos, que contém pelo menos três informações: horário de ocorrência do evento, objeto de processamento de evento e origem do evento.
(1) Horário de ocorrência do evento: igual ao horário de ocorrência do evento do cliente.
(2) Objeto de processamento de eventos: igual ao objeto de processamento de eventos do cliente.
(3) Fonte do evento: endereço IP da máquina cliente que carregou o evento atual.
3. O formato de transmissão de dados da rede é customizado e funciona em conjunto com o cliente;
4. Não há limite para a linguagem de desenvolvimento e o ambiente de desenvolvimento integrado usado, você mesmo pode escolher.
Instruções para executar o programa:
client.ini deve ser colocado no diretório raiz da unidade C. Outros arquivos podem ser colocados em qualquer lugar, mas survival.exe e client.exe devem ser colocados na mesma pasta. Antes de iniciar survival.exe, configure o ip do servidor (interval_server. ) em client.ini) e, em seguida, inicie ADServer.exe.
Descrição do código fonte 1. Servidor ADServer.exe
Como o lado do servidor é simples, vamos falar primeiro sobre o lado do servidor :)
A tarefa do servidor é receber dados da rede e usar o bloqueio de transmissão TServerSocket. Cada vez que TServerSocket recebe uma solicitação de conexão de um cliente, ele gera um thread TServerClientThread. Você deve criar um novo TWinSocketStream neste thread para ler e gravar dados do cliente. O código principal está escrito na parte ClientExecute deste thread.
Não há problema com TWinSocketStream gravando dados no cliente, mas a leitura de dados do cliente (usando o método read) geralmente retorna antes de terminar a leitura, mesmo se você usar WaitForData. Então escrevi uma função waitDateComplete para aguardar a leitura dos dados.
2. Cliente O cliente é um pouco mais problemático. Client.exe é um serviço e survival.exe é um aplicativo. Os dois monitoram um ao outro. hookDll.dll é usado para ganchos. Os ganchos globais devem ser escritos em módulos DLL independentes (exceto alguns ganchos, consulte este artigo: http://www.pconline.com.cn/pcedu/empolder/gj/ vc/ 0403/340480.html).
Client.exe não possui algumas linhas de código. Ele usa principalmente CreateProcess para iniciar o processo. Observe que se o serviço quiser fazer coisas relacionadas ao shell do Windows, como ganchos usados em hookdll.dll iniciado por este programa, o ServiceType deve ser definido como stWin32 e a propriedade TService::Interactive deve ser definida como true.
survival.exe é usado para iniciar o serviço, carregar hookdll.dll e relatar eventos ao servidor.
1. Iniciar o serviço requer três processos. Primeiro, abra o controlador de serviço, que é o backend do "serviço" na ferramenta de gerenciamento. Use OpenSCManager para obter o identificador do gerenciador de serviço e, em seguida, use OpenService (identificador do gerenciador de serviço, nome do serviço. , SERVICE_START | SERVICE_QUERY_STATUS) para obter o identificador do serviço especificado e, finalmente, você pode usar StartService(...) para abrir o serviço. Observe que pelo menos as duas permissões, SERVICE_START e SERVICE_QUERY_STATUS, devem ser obtidas.
2. Em termos de carregamento do hookdll.dll, este programa utiliza vinculação implícita, ou seja, utiliza o projetoAdd to Project do BCB para importar o arquivo lib da dll. Após a importação, se a função da dll não for chamada no código, a dll não será carregada. Este programa chama a função beginTrace (host HWND) para passar o identificador da janela de survival.exe, e a dll envia algumas mensagens para survival.exe por meio desse identificador.
3. Em termos de reporte de eventos ao servidor, foi especialmente escrita uma classe TMSocketClient, que é a principal responsável pelo processo de envio de mensagens -> recebimento de recebimentos de mensagens. O código principal está em TMSocketClient::Command (….). o código em ADServer.exe, é muito simples de ler. Ao #define diferentes constantes de comando, este módulo pode completar muitos tipos de tarefas de transmissão. Na verdade, este módulo é uma classe que escrevi no passado para simular o TNMFTP. Ele foi simplificado pela exclusão de muitos #defines e usado para transferir arquivos em uma LAN virtual (o TNMFTP não pode funcionar em uma LAN virtual).
3. hookDll.dll
O código é muito simples, basta prestar atenção em uma coisa, ou seja, se N processos chamarem a mesma dll, essa dll será copiada N vezes. De modo geral, cópias diferentes dessas N dlls possuem cada uma seus próprios segmentos de dados. Ou seja, o valor da mesma variável em cada cópia é diferente e não interfere um no outro. Mas na verdade, o Windows deixou um mecanismo que nos permite declarar tal variável em uma dll e manter os dados consistentes entre N instâncias da dll, assim como se fosse um ponteiro que transcende o espaço do processo. Para declarar tal variável, primeiro crie um arquivo .def com o mesmo nome da dll e escreva no arquivo:
SEÇÕES
SHSEG LER ESCREVER COMPARTILHADO
Em seguida, declare as variáveis DLL que deseja compartilhar entre processos como variáveis globais e inicialize essas variáveis. Observe que a diferença entre compartilhar e não compartilhar é se ele foi inicializado!
Este programa refere-se a "Aplicação de Hooks: Monitoramento de Execução do Programa" no CCRun. Agradecimentos ao autor Victor Chen.
OK, parece que isso é basicamente tudo o que há para explicar. Além disso, existem algumas variáveis inúteis no programa que não tenho tempo para limpá-las. Por favor, perdoe-me :) Obrigado por assistir!
Expandir