我有这个习惯,总是编译C ++项目并建立版本。我总是用十六进制编辑器(通常是HxD)打开.EXE并查看二进制信息。
我最讨厌并尝试找到解决方案的事实是,字符串表中的某个地方,相关(至少从我的观点来看)信息是提供的。也许对于其他人来说,这听起来像精神分裂症的困扰,但我只是不喜欢我的可执行文件包含,例如,应用程序中使用的所有Windows函数的名称。
我尝试了很多编译器,看看哪些编辑器发布的信息最少。例如,GCC将所有这些留在所有生成的最终exe中
libgcj_s.dll._Jv_RegisterClasses....\Data.ald.rb.Error.Data file is corrupt!
....Data for the application not found!.€.@.ř.@.0.@.€.@.°.@.p.@.p.@.p.@.p.@.
¸.@.$.@.€.@°.@.std::bad_alloc..__gnu_cxx::__concurrence_lock_error.__gnu_cxx
::__concurrence_unlock_error...std::exception.std::bad_exception...pure virt
ual method called..../../runtime/pseudo-reloc.c....VirtualQuery (addr, &b, s
ize of(b))............................/../../../gcc-4.4.1/libgcc/../gcc/conf
ig/i386/cygming-shared-data.c...0 && "Couldn't retrieve name of GCClib share
d data atom"....ret->size == sizeof(__cygming_shared) && "GCClib shared data
size mismatch".0 && "Couldn't add GCClib shared data atom".....-GCCLIBCYGMI
NG-EH-TDM1-SJLJ-GTHR-MINGW32........
在这里,您可以看到我使用的编译器以及版本。现在,您可以在下面几行看到我使用的每个Windows函数的列表,如CreateMainWindow,GetCurrentThreadId等。
我想知道是否有办法不显示或加密,混淆它。
使用Visual C ++,此信息不会发布。相反,它不像GCC那样跨平台,即使在两个Windows系统(如7和XP)之间,也不需要C ++运行时,框架或用VC ++编译的任何程序。此外,VC ++可执行文件还包含应用程序中使用的Windows函数的那些过程入口点。
我知道甚至NASM也会保存被调用的Windows函数的名称,因此它看起来像是一个Windows问题。但也许它们可以加密,或者有一些技巧不能显示它们。
我将查看GCC源代码,了解指定要保存在可执行文件中的字符串的位置 - 也许可以跳过该指令或其他内容。
嗯,这是我最后的一个偏执狂,也许可以用某种方式对待它。感谢您的意见和答案。
答案 0 :(得分:2)
如果使用-nostdlib
进行编译,那么GCC的内容应该会消失,但是你也会失去一些C ++支持和std :: *。
在Windows上,您可以创建仅链接到LoadLibrary
和GetProcAddress
的应用程序,并且在运行时它可以获得您需要的其他功能(功能名称可以加密形式存储)并且在将字符串传递给GetProcAddress之前解密该字符串。这样做很多工作,而且Windows加载器可能比你的代码更快,所以我混淆你调用简单函数的事实似乎毫无意义例如GetLastError
和CreateWindow
。
答案 1 :(得分:1)
Windows API函数从dll加载,如kernel32.dll。为了获取加载的API函数的内存地址,将搜索来自dll的导出函数名称表。因此存在这些名称。
您可以手动加载使用LoadLibrary引用的任何Windows API函数。您可以使用GetProcAddress查找函数的地址,并以一些模糊的形式存储函数名称。或者,您可以使用每个函数的“序数” - 一个标识dll中每个函数的数值。这样,您可以创建一组函数指针,用于调用API函数。
但是,要真正使其干净,您可能必须关闭默认库的链接并替换编译器隐式使用的C运行时库的组件。不过,这样做很麻烦。