Preciso executar um aplicativo C++ proprietário no Linux e preciso entender se ele contém alguma função fora dos recursos anunciados.
Existe uma maneira de listar todas as chamadas de API que o aplicativo faz, desde que não use syscalls do Linux e use apenas funções padrão stdc++?
Uma pergunta semelhante foi feita há quase uma década e a resposta não é nada satisfatória para mim. Preciso de algo totalmente automatizado.
DR: você pode conectar chamadas de função regulares através dos limites de objetos compartilhados com
bpftrace
. No entanto, especialmente para o que consideramos biblioteca padrão C++, isso é apenas uma pequena parte da funcionalidade real da "biblioteca padrão" do C++. Mas, mesmo que você pudesse rastrear todas essas chamadas de função, isso não lhe daria nenhuma garantia.Não existe uma maneira geral de saber quais funções são chamadas: no final, você não pode saber qual parte da biblioteca padrão foi vinculada estaticamente ao programa; a maior parte estará em linha, por design! Em C++, uma enorme quantidade de funcionalidade padrão está em modelos C++, portanto, parte da unidade de compilação do seu programa, não libstdc++. Pior ainda, mesmo quando se usa apenas uma funcionalidade que é definitivamente de uma biblioteca compartilhada, uma "chamada de função" simplesmente não é algo "especial"; é apenas configurar os registros necessários para passar argumentos e pular para um endereço. Para objetos compartilhados, esse endereço geralmente é resolvido usando o vinculador dinâmico padrão no momento da inicialização, mas não há absolutamente nenhuma garantia de que isso seja a única coisa que acontece. Especialmente se um programa carrega bibliotecas em tempo de execução (qualquer coisa que faça plugins, por exemplo, ou linguagens de script, ou…), não é tão fácil quanto apenas listar a tabela de funções a serem importadas.
Você pode rastrear seu programa de usuário e inserir um gancho para cada função na biblioteca padrão C++ e registrá-lo.
bpftrace
provavelmente seria a ferramenta de escolha aqui. Instale o bpftrace e veja suas ferramentas de exemplo, normalmente em /usr/share/bpftrace/tools, especialmentebashreadline.bt
:Escreva um pequeno programa awk, Python, PERL ou PL1 que gere tal
uretprobe:executable name:function name
para cada entradaobjdump -T /lib64/libstdc++.so
(ou qualquer biblioteca que você acha que o programa pode estar usando; você pode descobrir isso por meio destrace
, procurando poropen
chamadas). Tudo isso é muito programável!Sim, isso não lhe dará nenhuma garantia. Na melhor das hipóteses, você vê quais endereços são chamados. Se o programa preparou um trampolim ROP para fazer a biblioteca externa fazer o que quiser na situação certa, não pode ser feito. Geralmente, você só pode observar o que seu programa faz durante uma execução normal. Mas, a menos que você leia toda a sua desmontagem, não saberá se ele faz algo diferente quando executado em uma sexta-feira, 13, ou quando UID=1234, ou o CPUID termina em 7, ou… E: Qualquer funcionalidade indesejável em qualquer biblioteca externa que você não deseja que o programa chame, os programadores poderiam simplesmente ter incluído no próprio programa (copiando a funcionalidade ou apenas por meio de link estático).
É por isso que os sistemas operacionais e os UNIXoids segmentam especialmente os privilégios através de um sistema operacional/limite de usuário: nenhuma garantia pode ser feita sobre o comportamento de qualquer programa, mas o Linux pode garantir (com uma quantidade satisfatória de certeza) que um programa que não é permitido para acessar um arquivo não é possível acessá-lo; e a permissão de acesso é impossível de ser alcançada pelo próprio programa.