Lorsque vous écrivez votre premier compilateur pour C, à vous de l'écrire dans une autre langue. Maintenant, vous avez un compilateur C, assembleur. Finalement, vous arriverez à l'endroit où vous avez à analyser des chaînes, plus précisément des séquences d'échappement. Vous allez écrire le code pour convertir \n
pour le personnage avec le code décimal 10 (et \r
- 13, etc).
Après que le compilateur est prêt, vous allez commencer à ré-écrire en C. Ce processus est appelé "l'amorçage".
La chaîne d'analyse de code sera le suivant:
...
if (c == 92) { // backslash
c = getc();
if (c == 110) { // n
return 10;
} else if (c == 92) { // another backslash
return 92;
} else {
...
}
}
...
Lors de cette compile, vous disposez d'un binaire qui comprend le '\n'. Cela signifie que vous pouvez modifier le code source:
...
if (c == '\\') {
c = getc();
if (c == 'n') {
return '\n';
} else if (c == '\\') {
return '\\';
} else {
...
}
}
...
Alors, où est l'information que "\n " est le code pour 13? C'est dans le binaire! C'est comme de l'ADN: la Compilation de code source C avec ce binaire hériteront de cette information. Si le compilateur compile lui-même, il va transmettre cette connaissance à sa progéniture. À partir de ce point, il n'y a pas moyen de voir à partir de la source de ce que le compilateur va faire.
Si vous voulez cacher un virus dans le source d'un programme, vous pouvez le faire comme ceci: Obtenir le code source d'un compilateur, trouver la fonction qui compile les fonctions et le remplacer par celui-ci:
void compileFunction(char * name, char * filename, char * code) {
if (strcmp("compileFunction", name) == 0 && strcmp("compile.c", filename) == 0) {
code = A;
} else if (strcmp("xxx", name) == 0 && strcmp("yyy.c", filename) == 0) {
code = B;
}
... code to compile the function body from the string in "code" ...
}
Les parties intéressantes sont A et B. A est le code source pour compileFunction
y compris les virus, probablement cryptée, d'une certaine façon il n'est donc pas évident de la recherche sur le binaire résultant. Cela permet de s'assurer que la compilation le compilateur avec lui-même permettra de préserver le virus de l'injection de code.
B est le même pour la fonction que nous voulons remplacer notre virus. Par exemple, il pourrait être la fonction "login" dans le source du fichier "login.c" est probablement à partir du noyau Linux. On pourrait le remplacer par une version qui accepte le mot de passe "joshua" pour le compte root en plus du mot de passe.
Si vous compiler et diffuser comme un fichier binaire, il n'y aura pas moyen de trouver le virus en regardant le source.
La source d'origine de l'idée: http://cm.bell-labs.com/who/ken/trust.html
0 votes
Duplicata possible de L'amorçage nécessite toujours un soutien extérieur
0 votes
C'est une très vieille question, mais disons que j'ai écrit un interpréteur pour le langage Foo en Java. Puis avec le langage foo, j'ai écrit son propre interpréteur. Foo aurait toujours besoin du JRE, non ?
0 votes
Vous pourrait écrire le premier
Foo
compilateur dansFoo
même. Votre code source serait unFoo
programme avecFoo
des instructions sur la manière de générer du code machine (ou, en termes plus modernes, un autre code de base) à partir d'un fichierFoo
entrée du code source. Maintenant, vous auriez besoin de quelque chose ou quelqu'un qui comprendFoo
La spécification du programme est suffisamment claire pour que l'on puisse tracer à la main la sortie correcte de ce programme, exécuté sur lui-même. Pour autant que je sache, cependant, ce que je décris n'a jamais été fait avec aucun langage, pour des raisons évidentes.