AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79492746
Accepted
Alphin Thomas
Alphin Thomas
Asked: 2025-03-07 23:19:06 +0800 CST2025-03-07 23:19:06 +0800 CST 2025-03-07 23:19:06 +0800 CST

Um programa C pode detectar se seu próprio código-fonte foi modificado?

  • 772

Em muitos casos, compilamos um programa C e executamos o binário sem nos preocuparmos com mudanças no arquivo fonte original. No entanto, estou curioso:

É possível que um programa C em execução detecte se seu próprio .carquivo de origem foi modificado após a compilação?

Algumas restrições a considerar:

  • O programa deve verificar se há modificações em seu próprio arquivo de origem, não apenas no binário ( a.out)
  • Não deve depender de ferramentas externas como md5sumou statpor meio system()de chamadas.
  • A solução deve funcionar em sistemas operacionais comuns (Linux/Windows)
  • Isso deve ser feito puramente em C, usando bibliotecas de sistema padrão ou amplamente disponíveis.

Isso exigiria a leitura do arquivo de origem em tempo de execução e a comparação de registros de data e hora ou hashes, ou existe uma maneira mais elegante de fazer isso?

c
  • 2 2 respostas
  • 123 Views

2 respostas

  • Voted
  1. ikegami
    2025-03-07T23:26:50+08:002025-03-07T23:26:50+08:00

    Há grandes problemas para identificar quais arquivos são "seu código-fonte". Pode haver milhões de cópias na máquina, ou nenhuma. E talvez haja cópias, mas nenhuma delas foi usada para compilar o programa. O programa pode ter sido compilado em uma máquina diferente.

    Mas, fora isso, claro. Ver se um arquivo mudou é uma questão de lê-lo e compará-lo com uma cópia armazenada anteriormente. Ler arquivos e copiar blocos de memória são triviais de fazer em C.

    Para economizar espaço, você pode salvar um hash criptográfico dos arquivos de origem no binário em vez dos próprios arquivos de origem. Mais complicado, mas ainda fácil de fazer.

    Para economizar tempo, você também pode usar heurísticas relacionadas a tamanhos de arquivo e tempos de modificação de arquivo para pular a verificação dos arquivos byte por byte. Isso reduz a confiabilidade, no entanto. A verificação de tamanhos de arquivo e tempos de modificação de arquivo é feita facilmente com a statchamada da biblioteca (em oposição à ferramenta externa).

    • 2
  2. Best Answer
    John Bollinger
    2025-03-08T00:31:05+08:002025-03-08T00:31:05+08:00

    É possível que um programa C em execução detecte se seu próprio arquivo de origem .c foi modificado após a compilação?

    Não sem fazer suposições sobre quais arquivos são esses. Não há conexão duradoura entre binários compilados e os arquivos de origem C (e pode haver muitos contribuindo para um único programa) dos quais os binários foram construídos. Antes que o programa pudesse tentar tal verificação, ele precisaria de alguma forma determinar quais arquivos precisavam ser verificados.

    E não de forma confiável. Na melhor das hipóteses, o programa poderia verificar se os arquivos de origem selecionados para teste têm os mesmos atributos e conteúdos das fontes das quais foi construído, mas não poderia descartar que alguns deles tenham sido alterados e depois alterados de volta entre a construção e a execução.

    E mesmo que a informação possa ser determinada, ela não é muito útil, porque fica imediatamente obsoleta. O programa pode ser capaz de determinar se certos arquivos que ele pode observar em tempo de execução correspondem aos arquivos dos quais ele foi criado, mas então ele sabe apenas que eles corresponderam (ou não) no momento em que foram testados. Não é seguro assumir que eles continuam a corresponder por qualquer período de tempo após o teste, nem mesmo que o resultado do teste esteja correto no momento em que é inicialmente determinado. Por exemplo, talvez o arquivo esteja sendo modificado ao mesmo tempo em que está sendo testado, de modo que o estado lido pelo teste já seja diferente no momento em que o teste é concluído.

    Isso exigiria a leitura do arquivo de origem em tempo de execução e a comparação de registros de data e hora ou hashes, ou existe uma maneira mais elegante de fazer isso?

    Depois de identificar os arquivos a serem testados — o que não é nada trivial — surge a questão de quais informações você realmente quer saber.

    • Você pode testar o timestamp atual em relação a um registrado no binário, mas isso informa apenas se os timestamps correspondem. Esse pode ser seu critério, mas é muito fraco, porque timestamps são facilmente manipulados. Por outro lado, é rápido e fácil, pois requer a leitura apenas dos metadados dos arquivos, não de seus conteúdos.

    • Você pode calcular um hash ou checksum dos arquivos, individualmente ou coletivamente, e comparar isso a um valor esperado armazenado no binário. Isso requer a leitura de cada byte de cada um dos arquivos, e fornece um resultado probabilístico, não um certo. No entanto, requer apenas que um valor de hash ou checksum seja armazenado no executável. (Ou armazenado em um arquivo externo, mas isso apresenta outra maneira pela qual o teste pode ser confundido.)

    • Você pode ler cada byte de cada um dos arquivos e comparar com uma cópia armazenada em algum lugar. O C em si não fornece um meio para que esse "algum lugar" esteja dentro do binário, mas há maneiras de fazer os linkers fazerem esse tipo de coisa. Se o armazenamento for externo, essa abordagem será tão boa quanto as cópias de origem contra as quais o programa testa. Se for interno, as cópias ocuparão uma quantidade razoável de espaço no binário.

    Não tenho certeza de que tipo de solução "mais elegante" você imagina que possa haver. Se você quer aprender algo sobre o estado de certos arquivos em tempo de execução, então você tem que examinar esses arquivos em tempo de execução.

    • 2

relate perguntas

  • Multiplicação mais rápida que *

  • Usando uma macro para comprimento de string no especificador de formato scanf () em C

  • Como você pode definir o tipo de dados de #define para long double?

  • Ponteiros const incompatíveis

  • Mudança de cor não gradual no OpenGL

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve