{"id":43007107,"url":"https://github.com/HamiltonianCycle/ClassNameDeobfuscator","last_synced_at":"2026-02-11T00:01:14.465Z","repository":{"id":28285022,"uuid":"31797354","full_name":"HamiltonianCycle/ClassNameDeobfuscator","owner":"HamiltonianCycle","description":"Simple script to parse through the .smali files produced by apktool and extract the .source annotation lines.","archived":false,"fork":false,"pushed_at":"2016-10-27T02:46:28.000Z","size":263,"stargazers_count":73,"open_issues_count":2,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2023-02-28T14:45:49.165Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HamiltonianCycle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-07T01:47:34.000Z","updated_at":"2023-02-04T00:52:41.000Z","dependencies_parsed_at":"2022-08-26T15:00:36.133Z","dependency_job_id":null,"html_url":"https://github.com/HamiltonianCycle/ClassNameDeobfuscator","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/HamiltonianCycle/ClassNameDeobfuscator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HamiltonianCycle%2FClassNameDeobfuscator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HamiltonianCycle%2FClassNameDeobfuscator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HamiltonianCycle%2FClassNameDeobfuscator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HamiltonianCycle%2FClassNameDeobfuscator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HamiltonianCycle","download_url":"https://codeload.github.com/HamiltonianCycle/ClassNameDeobfuscator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HamiltonianCycle%2FClassNameDeobfuscator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29322733,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-10T20:44:44.282Z","status":"ssl_error","status_checked_at":"2026-02-10T20:44:43.393Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-31T05:00:27.493Z","updated_at":"2026-02-11T00:01:14.456Z","avatar_url":"https://github.com/HamiltonianCycle.png","language":"Python","funding_links":[],"categories":["Awesome Mobile Application Penetration Testing  ![awesome](https://awesome.re/badge.svg)"],"sub_categories":["Android Application Penetration Testing"],"readme":"# ClassNameDeobfuscator\nThis is a simple script to parse through the .smali files produced by apktool and extract the .source annotation lines.\n\nObfuscation can be a pain to deal with when reversing an app. However, some apps do not have the `.source` annotation line removed/mangled druing the obfuscation process. This leaves the original Java class file name intact in the obfuscated code. We can abuse this to partially deobfuscate the class names.\n\nTo be clear, I am not claiming that I am the first to discover this, for lack of a better term let's call it, information leakage. However, I did stumble upon it independently while reversing an obfuscated app. Looking at a smali file, I noticed a `.source` line and a lightbulb went off. So, I threw together this script to show off the extent of what information can be revealed.  See the demo section below for some relevant Proguard details.\n\n## Requirements\n * This assumes you have run `apktool` (or some other smali producing tool) to create smali files for the target app\n * Python 3\n\n## Usage\nFull disclosure: Only tested this on Windows using Python 3.4.2\n\n```\nusage: ClassNameDeobfuscator.py [-h] [-o output.txt] namespace\n\nExecute in the smali directory of a disassembled APK\n\npositional arguments:\n  namespace      base namespace to begin deobfuscating classes\n\noptional arguments:\n  -h, --help     show this help message and exit\n  -o output.txt  output filename to save deobfusacted class mapping\n```\n\n## Example\n````\n# Prepwork. Yeah, it sucks that the script needs to be in the smali dir, but I'm lazy.\napktool d com.someapp.apk\ncd com.someapp/smali/\ncp /path/to/ClassNameDeobfuscator.py .\n\n# Print results to stdout:\npython ClassNameDeobfuscator.py com.someapp\n\n# Save results to file:\npython ClassNameDeobfuscator.py -o /path/to/your/out.txt com.someapp\n```\n\nUsing the namespace for the app as the namespace argument, in the example it's the `com.someapp` argument given to `ClassNameDeobfuscator.py`, is helpful to avoid going through thrid-party libraries and such that are included in the app. Unless, that is your goal. Use common sense and set the `namespace` according to your needs. The script will try to parse the given namespace argument into a directory structure. So, if nothing else, you can just `.`-delimit to the directory that you care about.\n\n## Demo, Cause, \u0026 Remediation\n\nFor all the following demo, I will be using a silly little sample app I put together, [CatPurrDay](https://github.com/HamiltonianCycle/CatPurrDay/tree/master/app/src/main/java/com/catpurrday).\n\nIt would appear that new-ish versions of Android Studio (I am on Beta 0.8.6) will remove `.source` annotations with a very minimal Proguard configuration:\n\n![Default Proguard configuration](/img/proguard-configuration.png?raw=true \"Default Proguard configuration\")\n\nThis was surprising, I was expecting the default configuration to illustrate the class name leaking described above.  That's great, that the default obfuscation of Proguard does remove `.source` lines.\n\n![Script output with default Proguard configuration](/img/output-with-proguard.png?raw=true \"Script output with default Proguard configuration\")\n\nLet's work backwards to see what Proguard rules could be enabled to leak class names.  The place to start this search is, of course, [the manual](https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/usage.html).\n\nSure enough, buried down in the usage is a rule called `-keepattributes`, whose description contains the following statements,\n\n\u003e For example, you should at least keep the Exceptions, InnerClasses, and Signature attributes when processing a library. You should also keep the SourceFile and LineNumberTable attributes for producing useful obfuscated stack traces.\n\nSeems logical enough. Let's oblige. Rebuilding the demo app with the Proguard rule `-keepattributes SourceFile LineNumberTable` yields the following:\n\n![Script output with -keepattributes Proguard rule enabled](/img/output-with-source-attribute.png?raw=true \"Script output with -keepattributes Proguard rule enabled\")\n\n## Conclusion\n\nIn summary, even if you're obfuscating your app, you may be inadvertently leaking the class names by leaving the original source file attribute (and possibly other information!) in your obfsucated app. As we can see from the above examples, leaving the source file attribute can help a reverse engineer tremendously because it gives them whatever contextual information is present in your class names.\n\nHowever, whether you want to strip these attributes out is a risk/reward trade-off you  need to consider for yourself. After all, the Proguard team isn't likely suggesting *keeping* these attributes without good reason. On the otherhand, how valuable is it to keep a reverse engineer in the dark on what your class names are? Like always, consider your situation, apply common sense, and do what's right for you.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHamiltonianCycle%2FClassNameDeobfuscator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHamiltonianCycle%2FClassNameDeobfuscator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHamiltonianCycle%2FClassNameDeobfuscator/lists"}