Inspirado por uma pergunta StackOverflow agora excluída . Você pode encontrar uma maneira de executar um método específico, sem chamá-lo explicitamente? Quanto mais indireto, melhor.
Aqui está o que quero dizer exatamente (C usado apenas para exemplificação, todos os idiomas aceitos):
// Call this.
void the_function(void)
{
printf("Hi there!\n");
}
int main(int argc, char** argv)
{
the_function(); // NO! Bad! This is a direct call.
return 0;
}
Pergunta original:
popularity-contest
function
Comunidade
fonte
fonte
Respostas:
C
Quando compilado com o GCC, o compilador substitui
printf("Goodbye!\n")
porputs("Goodbye!")
, o que é mais simples e deve ser equivalente. Forneci sorrateiramente minhaputs
função personalizada , para que ela seja chamada.fonte
Bem, como o malware é capaz de executar funções que não são chamadas no código? Por buffers transbordantes!
No meu sistema, o endereço de retorno de
main
é armazenado 3 palavras acima da primeira variável local. Ao embaralhar esse endereço de retorno com o endereço de outra função,main
"retorna" para essa função. Se você deseja reproduzir esse comportamento em outro sistema, pode ser necessário ajustar 3 para outro valor.fonte
<!-- language: lang-c -->
duas linhas antes do seu código para destacá-lo.Bater
fonte
Python 2
Aqui estão algumas maneiras inspiradas nas outras respostas:
executando o código diretamente
Esta é a melhor maneira de realmente não chamar a função.
usando o destruidor
Usando a E / S std
usando pesquisas de atributo
O mecanismo de importação
Bem, acho que é tudo .. Não posso importar nada agora. Não espera ..
Usando os suportes de item de obtenção
[]
Usando variáveis globais. Meu favorito!
hello
é um acesso ad['hello']
. Depois disso, o mundo parece cinzento.Meta classes;)
Usando iteradores (você pode sobrecarregar qualquer operador e usá-lo)
Erros!
As estruturas ligam de volta. Quase toda GUI tem essa funcionalidade.
Execute a string de origem (func deve estar em um arquivo)
Decoradores
com desserialização de picles (menos favoritos chegando)
Usando serialização
Mais respostas em Python:
hasattr
globals()
e__call__
indiretamentereprlib
fonte
Javascript
Este usa o JSFuck para fazer o trabalho sujo.
fonte
""
é uma string e[]
avalia como 0, então""[[]]
é indefinido e""[[]]+""
é "indefinido". A partir daí, você pode extrair letras individuais:(""[[]]+"")[[]]
é "u". Portanto, é mais um hack chamar exec com código arbitrário. Eu acho que isso conta?function anonymous() { x() }
.Pitão
Isso define
the_function
como a função de criação de perfil, fazendo com que seja executada em cada chamada e retorno de função.fonte
C #
Podemos abusar do DLR para sempre executar algum código sempre que você tentar chamar qualquer método em uma classe. Isso é um pouco menos barato / óbvio do que soluções como delegados, reflexões, construtores estáticos etc., porque o método que está sendo executado não é apenas nunca invocado, mas nem mesmo referenciado , nem mesmo pelo nome.
Isso sempre imprime "Ha! Enganou você!" não importa o que você tenta invocar
a
. Assim, eu poderia escrever coma.SuperCaliFragilisticExpiAlidocious()
a mesma facilidade e faria a mesma coisa.fonte
GNU C
Isso é muito direto, mas certamente não é uma chamada para
hello_world
, mesmo que a função seja executada.fonte
Rubi
Inspirado por wat .
fonte
C
Você pode registrar uma função a ser chamada no final do programa em C, se isso atender às suas necessidades:
fonte
Java
Tentei isso com java:
O método
secretMethodNotCalledInMain
é chamado apenas por reflexão e não estou procurando por nada chamadosecretMethodNotCalledInMain
(em vez disso, estou procurando por algo não chamadomain
). Além disso, a parte reflexiva do código é chamada fora domain
método quando o manipulador de exceção não capturado do JDK entra em ação.Aqui estão as minhas informações da JVM:
Aqui está a saída do meu programa:
Eu não esperava que esses
NullPointerException
códigos fossem lançados do código nativo para lidar com a reflexão. Mas, como mencionado por @ johnchen902, é porque ele herda alguns métodosjava.lang.Object
e acabei chamando-os denull
s.fonte
NPE
s não são bug do JDK. Eles são lançados porque você tentou chamar métodos de instância declaradosjava.lang.Object
como, por exemplo,toString()
comnull
.C ++
Uma maneira em C ++ é no construtor e / ou destruidor de um objeto estático:
fonte
new
e, portanto, seria uma resposta interessante ter uma maneira de invocar um semnew
. Mas eu não sei, os construtores estáticos parecem uma trapaça.new (p) foo()
. E você pode destruir um objeto sem liberar a memória viap->~foo()
.C: Olá Mundo
Resultado:
Para vincular o método, precisamos que printf () seja compilado em algum lugar do programa, mas ele não precisa ser chamado. As funções printf () e main () estão localizadas 276 bytes uma da outra no segmento de código. Este valor será alterado com base no SO e no compilador. Você pode encontrar os endereços reais em seu sistema com este código e apenas subtraí-los:
fonte
*
antesmain
é realmente confuso e desnecessário.main
é uma função que você não pode desreferenciar; portanto, decai implicitamente em um ponteiro de função que é desreferenciado para produzir uma função novamente. Você não pode subtrair um int de uma função, portanto ele se deteriora para um ponteiro de função novamente. Você também pode escrever(*****main-276)
;) Você provavelmente quis escrever(&main-276)
ou, em(*(main-276))
vez disso.The * before main is really confusing and unnecessary.
- Isso geralmente não é uma coisa boa neste site?main
, mas não pode encontrá-lo agora ...C (com GCC em linha asm)
Isso fará com que algum código emitido pelo GCC termine em um segmento diferente do arquivo do objeto, fazendo com que o fluxo de controle "caia" na função. Observe que isso não funciona se o GCC decidir reordenar as funções, obviamente. Testado com o GCC 3.4.6 no MirBSD-current / i386, usando
-O2
. (Além disso, interrompe a depuração, compilando com-g
erros out)fonte
PHP ≥5.4.0
Esta solução é reconhecidamente uma bagunça horrível, mas executa a tarefa que lhe foi dada (não havia estipulação de quão bem ela deve ser executada).
A função para chamar sem chamar :
A solução :
Exemplo :
Saídas possíveis:
Explicação :
Quando chamado,
executeFunction()
lerá o conteúdo do arquivo em execução no momento (o que significa que isso só deve ser executado a partir da CLI, como ele usa$argv
), analisará os argumentos e o corpo da função especificada, cortará tudo novamente em um novo bloco de código,eval()
tudo e retorne o resultado. O resultado é quegetRandomString()
nunca é realmente chamado, direta ou indiretamente, mas o código no corpo da função ainda é executado.fonte
__construct()
método conta no PHP, pois você nunca chama a função diretamente, mas usanew Something()
?register_tick_function()
,register_shutdown_function()
ouspl_autoload_register()
semelhante à resposta Python do @ grc, mas sinto que isso é 'trapaça' e é o caminho mais fácil.Perl
Sim, é só isso. Nem todas as sub-rotinas são criadas iguais.
fonte
T-SQL
É um recurso incorporado. Gatilhos para a vitória!
Se você realmente quer se divertir com ele, crie um monte de gatilhos INSTEAD OF no dia da mentira.
Resultados:
Muito brincadeira. Que lulz. Uau.
O funileiro alarga -o no SQLFiddle.
fonte
Javascript
No console do Firefox:
Em seguida, comece a digitar qualquer coisa no console - o Firefox chama
.toString()
várias vezes quando você digita no console.Abordagem semelhante é:
fonte
C
A plataforma de escolha é o Linux. Não podemos chamar nossa função; portanto, nosso vinculador fará isso:
Como obter o endereço mágico?
Estamos contando com a especificação básica do Linux Standard Core, que diz:
Compile o código:
gcc but_for_what_reason_exactly.c -o but_for_what_reason_exactly
Examine o endereço de
.fini_array
:objdump -h -j .fini_array but_for_what_reason_exactly
Encontre o VMA:
e substitua esse valor por
ADDRESS
.fonte
VB6 e VBA
Não tenho certeza se isso se qualifica ou não, porque está chamando o método de uma classe:
Isso ocorre em um módulo de classe:
E este é o código "de chamada":
Isso funciona trocando a função vptr's pelos dois Subs na vtable pela classe.
fonte
Haskell
No haskell, se você fizer:
Ele será executado imediatamente sem chamar seu nome quando você o executar. Magia!
fonte
Javascript
Fácil, basta usar
on___
eventos em JS. Por exemplo:fonte
Java
Outra resposta java de mim. Como você vê no código, ele chama diretamente
theCalledMethod
, mas o métodonotCalledMethod
é executado.Então, no final, estou fazendo 2 coisas:
Executando:
fonte
getBytes()
método, ativando-ogetBytes("UTF-8")
. Como não tenho um OS X, você poderia testar se isso funciona?Pitão
fonte
Java
Yay, coleta de lixo!
Uma versão para quem inevitavelmente dirá que
System.gc()
não é confiável:fonte
Objetivo-C
(Provavelmente apenas se compilado com clang no Mac OS X)
Este código usa vários truques para acessar a função não utilizada. Primeiro é o valor 0x2A27. Este é um ponteiro marcado para o número inteiro 42, que codifica o valor no ponteiro para evitar a alocação de um objeto.
O próximo é
MyClass
. Ele nunca é usado, mas o tempo de execução chama o+load
método quando ele é carregado antesmain
. Isso cria e registra dinamicamente uma nova classe, usandoNSValue
como superclasse. Ele também adiciona um+load
método para essa classe, usandoMyClass
's-unusedMethod
como implementação. Após o registro, ele chama o método load na nova classe (por algum motivo, não é chamado automaticamente).Como o método de carregamento da nova classe usa a mesma implementação
unusedMethod
que é efetivamente chamada. Ele pega a superclasse e adicionaunusedFunction
como uma implementação para odoesNotRecognizeSelector:
método dessa classe . Esse método era originalmente um método de instânciaMyClass
, mas está sendo chamado como método de classe na nova classe, assimself
como o novo objeto de classe. Portanto, a superclasse éNSValue
, que também é a superclasseNSNumber
.Finalmente,
main
corre. Ele pega o valor do ponteiro e o cola em umaNSString *
variável (a__bridge
primeira conversão paravoid *
permitir que isso seja usado com ou sem ARC). Em seguida, ele tenta chamarstringByAppendingString:
essa variável. Como na verdade é um número, que não implementa esse método, odoesNotRecognizeSelector:
método é chamado, que viaja pela hierarquia de classes atéNSValue
onde é implementado usandounusedFunction
.Nota: a incompatibilidade com outros sistemas se deve ao uso do ponteiro marcado, que não acredito que tenha sido implementado por outras implementações. Se isso foi substituído por um número criado normalmente, o restante do código deve funcionar bem.
fonte
0x2A27
valor, então não sei se isso foi implementado em outro lugar. O ObjFW é definitivamente interessante.0x2A27
é etiquetado como ponteiroJavascript
Eu sinto que isso não parece explicitamente chamar a função
fonte
C # (via
using
)fonte
Java
Estou aproveitando um recurso especial da serialização Java. O
readObject
método é chamado quando um objeto é desserializado, mas não é chamado diretamente - nem pelo meu código nem pela biblioteca de desserialização. Se você se aprofundar na fonte, verá que, em um nível baixo, o método é chamado internamente via reflexão.fonte
Perl
Isto é tão fácil. O código abaixo executa automaticamente o código na sub-rotina, mesmo sem chamada explícita.
Mesmo se você descomentar a chamada, ela ainda será chamada apenas uma vez.
fonte