Comment masquer les symboles exportés nom dans une bibliothèque partagée
Pour le CR, je me permet d'écrire un fichier DEF et l'utilisation de la "NONAME" directive pour ne laissant que le numéro de séquence dans la dll à l'exportation du tableau.
Comment pourrais-je faire la même chose avec gcc et le format ELF bibliothèque partagée?
Ou, est-il quelque chose d'équivalent en ELFE de la bibliothèque partagée, comme le numéro de séquence dans un format PE DLL? Si non, comment pourrais-je cacher la exporté nom du symbole à l'intérieur d'une bibliothèque partagée?
======================================
Mise à JOUR: Certains des descriptions supplémentaires:
Dans Windows, vous pouvez exporter une fonction en un seul endroit ID de type entier (l'ordinal) avec un nom vide.
De le montrer, la mise en page d'une dll à l'exportation du tableau ressemble à ceci: http://home.hiwaay.net/~georgech/WhitePapers/Exporting/HowTo22.gif.
la "NONAME" on ressemble à ceci: http://home.hiwaay.net/~georgech/WhitePapers/Exporting/HowTo23.gif.
Avis les fonctions nom "N/A" dans la seconde image. Voici une explication: hxxp://home.hiwaay.net/~georgech/WhitePapers/Exporting/Exp.htm.
======================================
Mise à JOUR: beaucoup de grâce pour tous ceux qui me font des conseils. Finalement, je décide de garder l'utilisation d'une librairie statique sur linux/posix plates-formes. Mais l'extrait de la petite "partie spéciale" (qui est l'utilisation de certaines fonctionnalités ne convient pas pour la lib statique, e.g: TLS Logement, etc.) normal partagée de la bibliothèque de. Parce que les petites normal partagée de la bibliothèque de ne faire que peu de choses, et ces travaux sont totalement insensible à la casse, donc il n'est pas nécessaire à masquer/cacher ses Api.
Je pense que c'est la façon la plus simple de résoudre mon problème 😀
Le point est que la plupart Linux gens ne savent pas ce qu'est un
NONAME
directive dans le monde Windows (au moins je n'ai pas, puisque je n'ai jamais utilisé ou codée pour Windows). Vous devriez donc vous expliquer ce que cela signifie (et qu'est ce qu'un "numéro de séquence dans un PE"). Plus généralement, expliquer ce que vous voulez vraiment réaliser, sans référence à la façon dont Windows est en train de faire.Vos commentaires sur les différentes réponses de l'information plus détaillée de la question. Vous devriez envisager l'édition de votre question pour inclure cette information.
Ok, vous avez raison Basile, je vais ajouter des explications supplémentaires. Mais en quelques mots: je neet exporter une fonction mais de cacher son nom.
Mais l'exportation d'une fonction et de cacher son nom est, dans le monde de Linux, une contradiction en soi. Vous aurez un fichier d'en-tête pour votre bibliothèque, et que le fichier d'en-tête la mention des fonctions exportées par noms (sinon, cette fonction n'est pas exporté, même si certains trucs sales qui pourrait être accessible).
OriginalL'auteur ASBai | 2012-03-10
Vous devez vous connecter pour publier un commentaire.
Les réponses précédentes concernant attribut ((visibilité ("caché"))) est bon lorsque vous souhaitez conserver le code à long terme, mais si vous n'avez que quelques symboles que vous voulez visible et veulent une solution rapide... Sur les symboles que vous voulez à l'usage de l'exportation, ajouter
Ensuite, vous pouvez passer
-fvisibility=hidden
pour le compilateurIl y a une explication détaillée ici:
http://gcc.gnu.org/wiki/Visibility
Edit: Une autre solution serait de construire une bibliothèque statique/archive (en faire .une archive avec
ar -cru mylib.a *.o
) ou de combiner les objets dans un seul fichier de l'objet en fonction de ce combiner deux GCC compiler .o fichiers objets dans un troisième .o fichierSi vous posez la question "Pourquoi combiner les fichiers objets au lieu de simplement faire une bibliothèque statique?" ... parce que l'éditeur de liens traiter .o fichiers différemment .un des fichiers (je ne sais pas pourquoi, c'est juste que c'est le cas), plus précisément, il permet de relier un .o fichier dans une bibliothèque partagée ou binaire, même si tous des symboles cachés (même ceux que vous utilisez), Ce qui a l'avantage de réduire les temps de démarrage (un de moins ASM et beaucoup moins de symboles de regarder en haut) et de la taille du binaire (les symboles représentent généralement environ 20% de la taille et de décapage ne s'occupe que de la moitié environ de celle - juste à l'extérieur des parties visibles)
pour les fichiers binaires
strip --strip-all -R .note -R .comment mybinary
pour les bibliothèques
strip --strip-unneeded -R .note -R .comment mylib.so
Plus sur les avantages de la liaison statique ici: http://sta.li/faq mais ils n'ont pas de discuter des questions de licences, qui sont la principale raison pas à utiliser une bibliothèque statique et puisque vous êtes désireux de cacher votre API, qui peut être un problème de
Maintenant que nous savons qu'ils ont un objet qui est "symbole propre", il est possible d'utiliser la combinaison de notre objet de construire un libpublic.donc, en reliant privé.o et public.c (alias/exportations uniquement ce que vous voulez publique) dans une bibliothèque partagée.
Cette méthode se prête bien à trouver le "code" qui est inutile dans votre API publique. Si vous ajoutez
-fdata-sections -ffunction-sections
à votre objet construit, quand vous faites le lien avec-Wl,--gc-sections,--print-gc-sections
, il permettra d'éliminer les sections inutilisées et imprimer une sortie de ce qui a été retiré.Edit 2 - ou vous pouvez cacher l'ensemble de l'API et de l'alias uniquement les fonctions que vous souhaitez exporter
alias ("cible")
L'attribut alias les causes de la déclaration qui doit être émise que par un alias pour un autre symbole, qui doit être spécifiée. Par exemple,
définit
f' to be a weak alias for
__f'. En C++, la déformation du nom de la cible doit être utilisé. C'est une erreur si `__f' n'est pas définie dans la même unité de traduction.Pas tous les ordinateurs cibles à l'appui de cet attribut.
Si vous lisez le lien il y a un exemple précis.
Ceci ne répond pas à la question (voir la mise à jour des informations et de précisions). Aussi, le lien n'est pas de fournir un exemple que les exportations d'une fonction "par ordinal" ou par tout autre mécanisme que par son nom.
avez-vous souhaitez configurer un alias de symbole? de cette façon, vous pouvez l'exporter et de cacher la vraie(s)?
Oui, définissez un nom d'alias est également acceptable pour moi. 🙂 Pourrais-je utiliser la version de script pour configurer les alias? Et si l'éditeur de liens (ld) pourrait mappage automatique le vrai nom d'alias?
OriginalL'auteur technosaurus
Vous pourriez envisager d'utiliser GCC fonction d'attribut pour la visibilité et de la rendre cachés, c'est à dire l'ajout de
__attribute__((visibility ("hidden")))
à de nombreux endroits appropriés dans votre fichier d'en-tête.Vous aurez alors de le cacher ainsi votre inutile de symboles, et de garder la bonne.
C'est un GCC extension (peut-être pris en charge par d'autres compilateurs comme Clang ou Cpi).
addenda
Dans le monde de Linux, une bibliothèque partagée devrait fonctions d'exportation (ou peut-être les données globales) par leurs noms, tel que publié dans les fichiers d'en-tête. Sinon, ne pas appeler ces fonctions "exporté" -ils ne sont pas!
Si vous voulez absolument avoir un fonction dans une bibliothèque partagée qui est accessible mais pas exporté, vous pouvez enregistrer d'une certaine façon (par exemple, en mettant le pointeur de fonction dans certains fente d'une base de données mondiale, par exemple un tableau), ce qui signifie que vous avez (ou offrir) une fonction d'enregistrement des machines. Mais ce n'est pas une fonction exportée plus.
Être plus concret, vous pourriez avoir dans votre programme principal d'un réseau mondial de pointeurs de fonction
puis dans votre
main.c
fichier de votre programmePuis dans votre objet partagé (.e.g. dans
myshared.c
fichier compilé danslibmyshared.so
) une fonction constructeur:Plus tard sur votre programme principal (ou un autre objet partagé) pourrait appeler
mais je n'aurais jamais de telles choses "exporté" de fonctions, seulement accessible fonctions.
Un exemple de programme de faire de telles choses semblables est mon Faire FONDRE (qui n'utilisent pas des tableaux, mais plus complexe allouées sur la pile de valeurs). Un autre exemple de programme tableau de pointeurs de fonction astuces est J. Pitrat L'AICA/Malice programme. BTW, son livre sur Artificielle des Êtres (la conscience d'un être conscient de la machine) est très intéressant (et mentionne que l'astuce qui j'avais proposé de lui - dans une annexe).
__attribute__((visibility ("hidden")))
de façon appropriée dans les fichiers d'en-tête de votre API (vous pouvez utiliser une macro pour vous aider)? Ou "est d'avoir une API" signifie quelque chose d'autre pour vous?Non, je crois que vous devriez vous demander quel est votre réel problème et de le résoudre dans l'ordinaire Linux. Vous pensez qu'il est trop centrée sur Windows manière, et qui ne fonctionne pas bien sous Linux (et probablement, vice-versa). Le standard de Linux façon est d'avoir, à l'intérieur de vos objets partagés, des milliers de fonctions exportées (avec leur nom visible pour les applications de les lier ou de les charger dynamiquement avec
dlopen
votre bibliothèque partagée).la sécurité par l'obfuscation ne fonctionne pas.
Avez-vous pensé à la solution inverse: faire de votre bibliothèque un logiciel libre (par exemple, sous licence GPLv3)?
Mais votre truc, si mis en œuvre dans une bibliothèque, rend le débogage des programmes pour les utilisateurs légitimes de votre bibliothèque plus difficile...
OriginalL'auteur Basile Starynkevitch
De cacher le sens de l'fonctions exportées sur UNIX, vous pouvez simplement dissimuler leurs noms avec un simple renommage, en utilisant #définit. Comme ceci:
et ainsi de suite.
Dans une affaire de quelques fonctions, il peut être fait par les mains. Si vous avez besoin de milliers, vous devez utiliser la génération de code.
La seule question est de savoir comment vous pouvez obtenir le dictionnaire. Eh bien, je vois quelques options ici:
__lxstat -> lxstat__
c'est seulement limité par votre imagination.
OriginalL'auteur Alexander
Vous pouvez écrire une version de script et de le transmettre à l'éditeur de liens pour ce faire.
Un script simple qui ressemble à ceci:
testfile.exp:
Ensuite le lien de votre exécutable avec les options suivantes:
Lorsqu'il est appliqué à une bibliothèque partagée, ce sera encore de la liste des symboles dans la .si le fichier à des fins de débogage, mais il n'est pas possible d'accéder à partir de l'extérieur de la bibliothèque.
il n'y a pas des ordinaux dans ELF .donc les fichiers, seuls les noms de symbole.
OriginalL'auteur Nils Pipenbrinck
Je cherchais une solution pour le même problème. Donc, à présent, je ne pouvais pas trouver une solution robuste. Cependant, comme une preuve de concept, j'ai utilisé objcopy pour atteindre les résultats souhaités. En principe, après la compilation d'un fichier de l'objet-je redéfinir certaines de ses symboles. Ensuite, la traduction du fichier d'objet est utilisé pour construire la finale de l'objet partagé ou un exécutable. Comme un résultat de la classe des noms de méthode qui pourrait être utilisée comme un indice de désosser mon algorithme sont complètement rebaptisé par certains sens des noms de m1,m2,m3.
Voici le test que j'ai utilisé pour s'assurer que l'idée fonctionne:
Makefile:
interface.h
shared_object.cpp
executable.cpp
Comment jamais, je suis fatigué plus compliquer mais élégant"," moyen: lancement le code à l'aide de MapViewOfFileEx / mmap avec l'autorisation d'exécution et l'exécuter par moi-même. De cette façon, vous avez besoin d'init tout par vous-même, et de le résoudre dans l'attente de l'IAT entrée, etc. J'ai enfin trouvé c'est trop compliqué pour un portable multi-plate-forme d'application, et de l'absence de la portabilité de certains plate-forme (par exemple: chrome NaCL) 🙁
Masquage de la fonction à l'aide des tables virtuelles est ok.. Cependant, le point est de savoir quoi faire si le produit est déjà en place et vous ne pouvez pas le modifier. Tout simplement parce qu'il est trop grand. L'obscurcissement semble la seule alternative à la liaison de tout de façon statique. Je cherchais un outil qui permet de coder en C++ noms automatiquement, sans effort supplémentaire. Pourtant, je ne pouvais pas en trouver un. Donc, je suis venu avec une approche qui permettrait de le faire.
La beauté de cette méthode est que vous pouvez crypter les noms de méthode et d'utiliser le cryptage nom comme un symbole. Ce qui vous permettrait par exemple à déchiffrer une trace de la pile et le débogage des applications, tandis que vous gardez votre trace de la pile complètement illisible pour les autres.
J'attends un outil qui pourrait changer.si " module d'exportation de la table des symboles, les renommer pour certains ce qui signifie moins de chose, et d'ajuster l'importation de la table du "consommateur" (qui sont à l'aide de ce module) automatiquement. Nous avons seulement besoin de cet outil pourrait s'attaquer au format ELF, parce que sous windows, on peut utiliser la NONAME directive dans un .Fichier DEF.
OriginalL'auteur Vahagn