2010-09-10 18 views
5

J'ai écrit une bibliothèque C composée de quelques fichiers .h et de fichiers .c. Je le compile comme une bibliothèque statique.Meilleure pratique pour la distribution d'une API C masquant des fonctions internes

Je voudrais n'exposer que certaines fonctions à l'utilisateur et garder le reste aussi "obscur" que possible pour rendre l'ingénierie inverse raisonnablement difficile.

Idéalement ma bibliothèque comprendrait:

1- un fichier .h avec seulement les fonctions exposées à l'utilisateur

2- myLibrary.a: comme non reversengineerable possible

Qu'est-ce que sont les meilleures pratiques pour cela? Où dois-je regarder, y at-il un bon tutoriel/livre quelque part?

Plus précisément:

pour - 1

J'ai déjà tout mon .h et .c travail et je voudrais éviter les changer autour, les déclarations de fonction de déplacement .h à .c et aller en références circulaires pbs potentiels. Est-ce possible?

Par exemple, est-ce une bonne idée de créer un nouveau fichier .h que je n'utiliserais que pour distribuer avec mon. Ce .h contiendrait des copies des fonctions que je veux exposer et transmettre des déclarations de types que j'utilise. est-ce une bonne idée?

pour - 2

a) ce que les drapeaux gcc (ou Xcode) je serai au courant (pour le décapage, de ne pas avoir des symboles de débogage, etc.) b) un bon pointeur pour en savoir plus sur la façon de faire obscurcissement de code?

Toute pensée vous aidera,

Merci, baba

+0

Veuillez montrer du code que vous avez déjà écrit. Nous ne sommes pas votre service de codage personnel –

Répondre

7

La pratique habituelle consiste à s'assurer que toutes les fonctions et variables globales destinées à être utilisées uniquement à l'intérieur d'un module sont déclarées static dans ce module. Cela limite l'exposition des détails de mise en œuvre internes à partir d'un seul module.

Si vous avez besoin de détails d'implémentation internes qui se croisent entre les modules, mais qui ne sont pas destinés à la consommation publique, déclarez un ou plusieurs fichiers .h qui restent confidentiels et ne sont pas remis aux utilisateurs finaux. Les noms des objets définis de cette manière seront toujours visibles pour l'éditeur de liens (et pour les outils tels que objdump et nm) mais leurs signatures détaillées ne le seront pas.Si vous avez des structures de données qui sont livrées à l'utilisateur final, mais qui sont opaques, pensez alors à ce que l'API les livre comme des pointeurs vers un fichier struct déclaré non défini dans le fichier API public .h. Cela préservera la sécurité du type tout en dissimulant les détails de l'implémentation. Naturellement, la définition complète struct est dans un fichier privé .h.

Avec soin, vous pouvez garder un struct publiquement documenté connu qui est un jeu de mots pour la définition réelle mais qui expose uniquement les membres publics. C'est plus difficile à tenir à jour, et si vous le faites, je ferais en sorte qu'il y ait des cas de test solides pour valider que la version publique est en fait équivalente à la version privée de toutes les façons qui comptent.

Naturellement, utilisez strip pour supprimer les segments de débogage afin que les détails internes ne fuient pas de cette façon.

Il existe des outils qui peuvent masquer tous les noms destinés à un usage interne uniquement. Si elle est exécutée dans le cadre du processus de construction, vous pouvez utiliser une construction de débogage interne qui a des noms sensés pour tout, et expédier une construction qui a nommé toutes les fonctions internes et variables globales avec des noms que seul un éditeur de liens peut aimer.

Enfin, s'habituer au fait que toute personne qui peut utiliser votre bibliothèque sera en mesure de désosser votre bibliothèque dans une certaine mesure. Il existe des mesures anti-débugger qui peuvent être prises, mais à mon humble avis de cette façon se trouve la folie et la frustration.

+0

J'ai un doute. Que diriez-vous d'appliquer l'indicateur __attribute __ ((visibility ("default"))) uniquement aux fonctions qu'il veut exposer et de passer -fvisibility = caché dans les drapeaux de compilation pour la lib entière. Je ne suis pas sûr du processus d'ingénierie inverse ici. –

+0

Même sans symboles, l'ingénierie inverse est possible tant que le code peut être exécuté et que le matériel physique est disponible pour l'inspection. Ce n'est peut-être pas trivial, mais cela reste possible. La situation pour une bibliothèque est légèrement pire car vous devez autoriser un utilisateur légitime à référencer * certains * symboles. – RBerteig

1

Je n'ai pas une réponse rapide autre que d'explorer l'utilisation des fonctions « statiques ». Je recommande de lire le travail de Miro Samek sur quelque chose qu'il appelle "C +". Fondamentalement orienté objet ANSI C. Bonne lecture. Il possède un logiciel Quantum bonds.