What does --keepattributes SourceFile in Proguard do? - proguard

I'm trying to figure out how Firebase will do the mapping from obfuscated code to real code and according to their docs, I need to add this line -
-keepattributes SourceFile,LineNumberTable
This is supposed to keep the file names and line numbers intact. However, despite using this configuration, I noticed that after decompiling my APK, it contains obfuscated file names like a.java, b.java etc. Additionally, I read in this answer that the SourceFile is just a String which can be renamed. I don't understand this.
My questions are
What is the SourceFile attribute?
Why does keeping the SourceFile attribute still obfuscate the files despite the documentation saying that file names are kept intact?
Why is the SourceFile attribute re-namable?

These options refer to the file names and line numbers that are part of a stack trace. The names for classes, methods, etc. are still obfuscated. Firebase can use your mapping file to translate these obfuscated names to their original names.
In case you need to preserve the names of the classes, methods, etc. you can set up -keep rules to do so as documented here under "Keep Options":
https://www.guardsquare.com/manual/configuration/usage
You can see the impact your configuration has on your source tree by using the ProGuard Playground.

Related

Canonical way to map SourceFile class attribute to actual file system path

The SourceFile attribute only contains the file name, not a full or relative path. This is not much information to go with because javac will place the .class file in a potentially unrelated directory (relative to the -d argument), based on the package in which the class is declared. While this is required for finding and loading the class at run time, it makes the .class file location only a hint to where the .java file might be located in the source tree.
The documentation of the
com.sun.jdi.ReferenceType.sourcePaths(String) method suggests a heuristics to obtain a file system path:
In the reference implementation, for strata which do not explicitly specify source path (the Java programming language stratum never does), the returned strings are the sourceNames(String) prefixed by the package name of this ReferenceType converted to a platform dependent path.
There is no obvious way to do better than that. Of course, if the file does not exist at the expected location, one could search the source tree and check if the file name happens to be unique, and use that as the location. But beyond that, there are not many options.
Are there any other, non-obvious ways to solve this?

using require in layer.conf in yocto

Considering all freedom that yocto gives to the developer, I have a question.
I would like to make this my_file.inc available only for recipes in one particular meta-layer. I know, that, for instance, using INHERIT keyword inside the local.conf will make my_class.bbclass file available globally for each recipe.
Is it a good practice to add this:
require my_file.inc
inside layer.conf? Or should I change my_file.inc to the my_file.bbclass, and, add INHERIT = "my_file.bbclass" to the layer.conf?
Any other possibilities?
Even if it seems to work, neither of your approaches is technically completely correct. The key point is that all .conf files are parsed first and everything they contain is globally visible throughout the whole build process. So if you add something through the layer.conf file, itis not being pulled in through an unexpected place, it also is not being limited that layer only and might therefore cause breakage at other places.
While I do not have a really good and clean solution, maybe the following can help you:
You can make your custom recipes react on certain keywords in DISTRO_FEATURES or MACHINE_FEATURES. Then you can create a two-staged approach:
Add the desired keyword in local.conf (or your MACHINE, or DISTRO, or whatever configuration)
Make the recipes react to it. If you need the mechanism in several places, then it might be useful to pour it into a .bbclass that your layer brings along and that you pull in for the respective recipes.
This way the effect is properly contained.
Maybe part 5.1.3.2 from the Yocto Project answers your question:
Avoid duplicating include files. Use append files (.bbappend) for each recipe that uses an include file. Or, if you are introducing a new recipe that requires the included file, use the path relative to the original layer directory to refer to the file. For example, use require recipes-core/package/file.inc instead of require file.inc. If you're finding you have to overlay the include file, it could indicate a deficiency in the include file in the layer to which it originally belongs. If this is the case, you should try to address that deficiency instead of overlaying the include file. For example, you could address this by getting the maintainer of the include file to add a variable or variables to make it easy to override the parts needing to be overridden.
So to avoid duplicate inclusion later, it would be better not to include your .inc file(s) this way.

YGuard obfuscate single class, package and exclude libraries

I'm trying to use YGuard to obfuscate some parts of my program which contain encryption methods and other sensitive information (which I'll further protect in other ways once I figure this out).
Because the program is quite complex and contains quite many libraries it obviously gives a series of warning and finally fails with:
WARNING: Method initialize_ffi_type is native but com/sun/jna/Native is not kept/exposed.
WARNING: Method getAPIChecksum is native but com/sun/jna/Native is not kept/exposed.
[...]
yGuard was unable to resolve a class (java.lang.ClassNotFoundException: com.sun.tools.javac.parser.Parser$Factory)
Now whatever that means I'd like to
exclude libraries which being all open source have nothing to hide so far
obfuscate just the methods and variables of some Class or some package and leave the rest untouched.
So far in YGuard it seems I have to specify what I don't want to be obfuscated, however I have far too many classes, I'd like instead to do the opposite: Specify what I'd like to obfuscate and proceed increasing the number of Classes and packages I want obfuscated.
Thanks
It is the normal practice for obfuscators to specify what should be kept and not the other way around.
However, you can define library classpaths with the externalclasses rule (link). Classes that are defined in this path are neither obfuscated nor shrinked. The second error you are getting (ClassNotFoundException) indicates that you have not specified all libraries that your project depends on.
In order to obfuscate your code now, what you could do is:
Pack the code that you want to be obfuscated in one jar and define everything else as a library
use a patternset in your keep rule (link) to define everything to be kept except the classes that you want to have obfuscated.

Generating "user" and "developer" documentation from the same codebase using Doxygen

I'm new to Doxygen and I'm trying to document an API I am planning to open source. I'd really like to build two sets of documentation, one for end users of the API and one for those who intend to modify it. Is there a way to tag Doxygen comment blocks in a way such that I can generate "user" and "dev" documentation trees? Is there a better solution to my problem? Thanks!
Depending on how your code is structured, you might be able to get away with using two Doxygen config files each including separate source files. The "user" config file would only list the source files containing the public interface to the API, while the "dev" config file would list all source files for the whole project.
This does mean that all your interfaces (e.g. abstract base classes) will need to be documented with the user in mind, but that is usually not a problem as by definition there is unlikely to be any implementation details in an abstract base class.
All your "dev" documentation then sits in the actual classes implementing the interfaces, which are never seen by the API and can be safely omitted by the "user" Doxygen config file.
Of course if your code isn't structured this way it's not going to work, so the only solution I can think of is to fill your comments with a bunch of conditional statements.
In addition to what Malvineous already said, there is the \internal doxygen command.
\internal lets you hide or show part of the documentation by changing INTERNAL_DOCS in the Doxyfile
More information here: http://www.doxygen.nl/manual/commands.html#cmdinternal

Stopping doxygen searching for (and assuming) non-existant variables in source code

Im using doxygen outside of its design, but well within its capability. I have a bunch of essentially text files, appended with some doxygen tags. I am successfully generating doxygen output. However, somehow doxygen occasionally discovers what it assumes to be a variable, and proceeds to document it using surrounding text, causing a lot of confusing documentation. I cant see any direct relationship between these anomalies, only that they're reproducing the same output on each run, and what I can see is at least some are next to a ';' or a '='.
I only want doxygen to document what I've manually tagged. I am hoping to remove any occurrence of these anomalies, however I cannot alter existing text. I can only add doxygen tags, or alter the configuration file. Any ideas?
Many thanks.
Because in my particular case, I do not need any automatically generated documentation, only that which I have tagged with doxygen tags, setting
EXCLUDE_SYMBOLS = *
removes any instance of doxygen "finding" and documenting variables. This however may remove any ability to find any class declarations, namespaces or functions, however this is acceptable for me.