The usual practice is to make sure that every function and global variable that is for use only internal to some module is declared static in that module. That limits exposure of internal implementation details from a single module.
If you need internal implementation details that cross between modules, but which are not for public consumption, then declare one or more .h files that are kept private and not delivered to end users. The names of objects defined in that way will still be visible to the linker (and to tools such as objdump and nm) but their detailed signatures will not be.
If you have data structures that are delivered to the end user, but which are opaque, then consider having the API deliver them as pointers to a struct that is declared by not defined in the public API .h file. That will preserve type safety, while concealing the implementation details. Naturally, the complete struct definition is in a private .h file.
With care, you can keep a partially documented publicly known struct that is a type-pun for the real definition but which only exposes the public members. This is more difficult to keep up to date, and if you do it, I would make certain that there are some strong test cases to validate that the public version is in fact equivalent to the private version in all ways that matter.
Naturally, use strip to remove the debug segments so that the internal details are not leaked that way.
There are tools out there that can obfuscate all the names that are intended to be only internal use. If run as part of the build process, you can work with an internal debug build that has sensible names for everything, and ship a build that has named all the internal functions and global variables with names that only a linker can love.
Finally, get used to the fact that anyone that can use your library will be able to reverse engineer your library to some extent. There are anti-debugger measures that can be taken, but IMHO that way lies madness and frustration.
I don't have a quick answer other than to explore the use of "static" functions. I would recommend reading Miro Samek's work on something he calls "C+". Basically object oriented ANSI C. Great read. He owns Quantum leaps software.
发布评论
评论(3)
通常的做法是确保仅在某个模块内部使用的每个函数和全局变量都在该模块中声明为
static
。这限制了单个模块内部实现细节的暴露。如果您需要跨模块但不供公共使用的内部实现详细信息,请声明一个或多个保持私有且不交付给最终用户的
.h
文件。以这种方式定义的对象的名称对于链接器(以及诸如 objdump 和 nm 之类的工具)仍然可见,但它们的详细签名将不可见。如果您有交付给最终用户的数据结构,但这些数据结构是不透明的,请考虑让 API 将它们作为指向未在公共 API
中定义的
struct
的指针来交付.h 文件。这将保持类型安全,同时隐藏实现细节。当然,完整的 struct 定义位于私有 .h 文件中。小心地,您可以保留部分记录的公开已知的结构,它是真正定义的类型双关语,但仅公开公共成员。这更难保持最新状态,如果你这样做,我会确保有一些强大的测试用例来验证公共版本实际上在所有重要方面与私有版本相同。
当然,使用
strip
删除调试段,这样内部细节就不会泄露。有一些工具可以混淆所有仅供内部使用的名称。如果作为构建过程的一部分运行,您可以使用内部调试构建,该构建对所有内容都具有合理的名称,并发布一个构建,该构建已使用只有链接器可以喜欢的名称来命名所有内部函数和全局变量。
最后,要习惯这样一个事实:任何可以使用您的库的人都能够在某种程度上对您的库进行逆向工程。可以采取一些反调试措施,但恕我直言,这种方式会带来疯狂和挫败感。
The usual practice is to make sure that every function and global variable that is for use only internal to some module is declared
static
in that module. That limits exposure of internal implementation details from a single module.If you need internal implementation details that cross between modules, but which are not for public consumption, then declare one or more
.h
files that are kept private and not delivered to end users. The names of objects defined in that way will still be visible to the linker (and to tools such asobjdump
andnm
) but their detailed signatures will not be.If you have data structures that are delivered to the end user, but which are opaque, then consider having the API deliver them as pointers to a
struct
that is declared by not defined in the public API.h
file. That will preserve type safety, while concealing the implementation details. Naturally, the completestruct
definition is in a private.h
file.With care, you can keep a partially documented publicly known
struct
that is a type-pun for the real definition but which only exposes the public members. This is more difficult to keep up to date, and if you do it, I would make certain that there are some strong test cases to validate that the public version is in fact equivalent to the private version in all ways that matter.Naturally, use
strip
to remove the debug segments so that the internal details are not leaked that way.There are tools out there that can obfuscate all the names that are intended to be only internal use. If run as part of the build process, you can work with an internal debug build that has sensible names for everything, and ship a build that has named all the internal functions and global variables with names that only a linker can love.
Finally, get used to the fact that anyone that can use your library will be able to reverse engineer your library to some extent. There are anti-debugger measures that can be taken, but IMHO that way lies madness and frustration.
除了探索“静态”函数的使用之外,我没有快速的答案。我建议阅读 Miro Samek 的作品,他称之为“C+”。基本上是面向对象的 ANSI C。读得很好。他拥有量子跳跃软件。
I don't have a quick answer other than to explore the use of "static" functions. I would recommend reading Miro Samek's work on something he calls "C+". Basically object oriented ANSI C. Great read. He owns Quantum leaps software.
擦除此函数的标头,在导出表中进行一些混淆,然后打包代码并应用一些反调试器算法。
http://upx.sourceforge.net/
http://www.oreans.com/
Erase headers for this functions, do some obfuscation in exports table and get pack your code and apply some anti debugger algorithm.
http://upx.sourceforge.net/
http://www.oreans.com/