Hide executable symbols from nm command - objective-c

The nm command lists all symbols in executable. this is good guidance for reverse engineering and crackers. I want to hide them. The gcc maybe has switches for this purpose but I do not use gcc. Is there an approach to hide them directy from binary file?
Thanks.

You can use the strip command.
But I won't bother that much removing symbols. Very probably, your program might not interest a lot of people (as most programs). And if there is a security issue, it could eventually be found (e.g. by using strace to understand the behavior) even on stripped binaries.

strip will "strip" (remove) symbols from a binary.

Related

What does the -specs argument do in arm-none-eabi-gcc?

I was having trouble with the linker for the embedded arm gcc compiler, and I found a tutorial somewhere online saying that I could fix my linker errors in arm-none-eabi-gcc by including the argument -specs=nosys.specs, which worked for me, and it was able to compile my code.
My chip is an ATSAM7SE256 microcontroller, which to my understanding is an arm7tdmi processor using the armv4t and thumb instruction sets, and I've been compiling my code using:
arm-none-eabi-gcc -march=armv4t -mtune=arm7tdmi -specs=nosys.specs -o <exe_name>.elf <input_files>
And the code compiles with no issue, but I have no idea if it's doing what I think it's doing.
What is the significance of a spec file? What other values can you set with -specs=, and in what situations would you want to? Is nosys.specs the value I want for a completely embedded arm microcontroller?
It is documented at: https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc/Overall-Options.html#Overall-Options
It is a file containing switches to override standard defaults for various build components such as the compiler, assembler and linker. For example it can be used to replace the default C library.
I have never seen it used; typically bare-metal embedded system builds explicitly specify --nostdlib then explicitly link the required library. It could be used for environment specific build environments to link other default code such as an RTOS I guess. Personally I'd rather make all that explicit on the command line that hiding it in a file somewhere.
Essentially it applies the switches specified in the file as if they were defaults, so can be used to define defaults for specific build and execution environments.
The format of the specs file is documented at https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc/Spec-Files.html#Spec-Files
Without seeing both the linker errors and the content of the nosys.specs file in this case it is difficult to say how or why it solved your linker problem. The alternative solution of course would be to apply whatever switches are in the specs file directly.

Portable whole-archive linking in CMake

If you want to link a static library into an shared library or executable while keeping all the symbols visible (e.g. so you can dlopen it later to find them), a non-portable way to do this on Linux/BSD is to use the flag -Wl,--whole-archive. On macOS, the equivalent flag is -Wl,-force_load,<library>; on Windows it's apparently /WHOLEARCHIVE.
Is there a portable way to do this in CMake?
I know I can add linker flags with target_link_libraries. I can detect the OS. However, since the macOS version of this includes the library name in the same string as the flag (no spaces), I think this messes with CMake's usual handling of link targets and so on. The more compatible I try to make this, the more I have to bend over backwards to make it happen.
And this is without even getting into more unusual compilers like Intel, PGI, Cray, IBM, etc. Those may not be compilers that people commonly deal with, but in some domains it's basically unavoidable to need to deal with these.
Are there any better options?
flink.cmake will help you.
target_force_link_libraries(<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...
)

How do I add a prefix to all symbols in an elf object file but so that debugging still works?

I want to add a prefix to every symbol in an elf object file, how do you do that using Linux (eg debian)?
I need the debug information to still work (ie, gdb can still debug effectively albeit using the new names for all the symbols).
The elf object is relocatable.
A solution for a non-relocatable object would also be welcome.
A solution for which code-coverage stats continues to work would also be welcome but is not necessary.
I don't know of any canned way to do this.
I think it could be done by rewriting the ELF symbol table and the DWARF information as well. This is not trivial, though perhaps you could implement it using the various libraries in elfutils.

Extract Objective-c binary

Is it possible to extract a binary, to get the code that is behind the binary? With Class-dump you can see the implementation addresses, but is it possible to also see the code thats IN the implementation addresses? Is there ANY way to do it?
All your code compiles to single instructions, placed in the text section of your executable. The compiler is responsible for translating your higher level language to the processor specific instructions, which are simpler. Reverting this process would be nearly impossible, unless the code is quite simple. Some problems are ambiguity of statements, and the overall readability: local variables, for instance, will be nothing but an offset address.
If you want to read the disassembled code (the instructions of which the higher level code was compiled to) use this command in an executable:
otool -tV file
You can decompile (more accurately, disassemble) a binary and get it's assembly, but there is no way to get back the original Objective-C.
My curiosity begs me to ask why you want to do this!?
otx http://otx.osxninja.com/ is a good tool for symbolicating the otool based disassembly
It will handle both x86_64 and i386 disassembly.
and
Mach-O-Scope https://github.com/smorr/Mach-O-Scope is a a tool built on top of otx to dump it all into a sqlite3 database for browsing and annotating.
It won't give you the original source -- but it will get you pretty close providing you with the messages that are being sent around in methods.

Static library symbols missing in linked executable

I am trying to link a statically created .a library with another piece of C code.
However, in the final executable several symbols (function names) are are found missing when seen with the nm command. This is due to the fact that the linker (gcc being called) is stripping the symbols which are not referenced in the other piece of C code that is being linked with the library. The function symbol that I am trying to find with the nm command is visible in the .a library.
How can I make the linker not strip the symbols omitted this way?
Compile in gcc with -dynamic to force the compiler to include all symbols. But make sure that's what you really want, since it's wasteful.
Might be useful for some static factory patterns.
Generally, the linker does strip out other symbols - mainly for
Reduce the final size of the executable
Speed up the execution of the program
There are two trains of thoughts here:
When you use the option -O as part of the gcc command line, that is optimizing the code and thus all debugging information gets stripped out, and hence the linker will automatically do the same.
When you use the option -g as part of the gcc command line, that includes all debugging information so that the executable can be loaded under the debugger with symbols intact.
In essence those two are mutually exclusive - you cannot have both combined.
So it depends on which switches did you use for this to happen. Usually, -g switch is for internal debugging and testing prior to public release. The opposite would be something like this -O2 which makes the compiler smart enough to generate a executable that would be considered optimized such as removing dead variables, unrolling loops and so on.
Hope this helps and gives you the hint
Normally you need to call some registration function in your application to generate such a reference. Of course if you don't have access to the code of the first library, you can only use the -g option as described by tommieb75.