{"id":5088,"date":"2026-03-11T13:13:15","date_gmt":"2026-03-11T21:13:15","guid":{"rendered":"https:\/\/www.pnfsoftware.com\/blog\/?p=5088"},"modified":"2026-03-11T13:13:16","modified_gmt":"2026-03-11T21:13:16","slug":"mutation-resistant-library-code-matching","status":"publish","type":"post","link":"https:\/\/www.pnfsoftware.com\/blog\/mutation-resistant-library-code-matching\/","title":{"rendered":"Mutation-Resistant Library Code Matching"},"content":{"rendered":"\n<p>Our March 2026 release (JEB 5.38) ships with a transparent, flexible and fast code matching facility:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Transparent: as you reverse engineer your project, library code may be detected and reported.<\/li>\n\n\n\n<li>Flexible: matching is designed to resist recompilation, obfuscation, and method inlining to some degree.<\/li>\n\n\n\n<li>Fast: matching is almost instantaneous.<\/li>\n<\/ul>\n\n\n\n<p>This initial implementation is enabled for dex only. It will be made available for native code in a future release. The initial database is relatively compact. Mostly, it contains signatures for the latest JAR and AAR libraries commonly used in APKs, such as Androidx.<\/p>\n\n\n\n<p>Keep in mind code matching cannot guarantee accurate results in all cases! To ensure a low false-positive rate, the code matching module reports top-score matches only. Thresholds can be changed in the options.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-scaled.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"611\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1024x611.png\" alt=\"\" class=\"wp-image-5090\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1024x611.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-300x179.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-768x458.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1536x917.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-2048x1222.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">In this example screenshot, you may see an obfuscated version of androidx&#8217;s ProfileTranscoder.createCompressibleBody method (which inlines additional sub-routine calls) detected with a high score.<\/figcaption><\/figure>\n\n\n\n<p>So, how to best-use this feature in your workflow?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project-wide global analysis<\/h2>\n\n\n\n<p>When you start a new project, we recommend running a Global Analysis, with the code matching option enabled.<\/p>\n\n\n\n<p>When this toggle is enabled, after the analysis completes, high-score matches will be applied:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Methods will be renamed.<\/li>\n\n\n\n<li>Classes and types will be renamed and refactored (moved to newly-created packages).<\/li>\n\n\n\n<li>A special color is used in disassembly listing and code hierarchies to indicate library code.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Auto-matching when decompiling<\/h2>\n\n\n\n<p>By default, code matching also happens transparently when you decompile code via the GUI.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"245\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1-1024x245.png\" alt=\"\" class=\"wp-image-5092\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1-1024x245.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1-300x72.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1-768x184.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1-1536x368.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2026\/02\/image-1-2048x491.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">This option can be set at the engines level or on-demand, when decompiling (Ctrl+TAB, or Cmd+TAB)<\/figcaption><\/figure>\n\n\n\n<p>Detected matches will be placed as method comments in the decompiled Java code.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>To disable that behavior, set the <code>.parsers.dcmp_dex.CodeMatchSetting <\/code>option to <em>Disabled<\/em> (0).<\/li>\n\n\n\n<li>To apply detected matches (rename and refactor code), set that option to <em>Match and Apply<\/em> (2).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">API for scripting<\/h2>\n\n\n\n<p>In scripts and plugins, the code matching facility can be accessed via methods of <code><a href=\"https:\/\/www.pnfsoftware.com\/jeb\/apidoc\/com\/pnfsoftware\/jeb\/core\/units\/code\/android\/IDexDecompilerUnit.html\">IDexDecompilerUnit<\/a><\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>setCodeMatchingOverride<\/li>\n\n\n\n<li>getCodeMatchingOverride<\/li>\n\n\n\n<li>applyCodeMatches<\/li>\n\n\n\n<li>getUnappliedCodeMatches<\/li>\n\n\n\n<li>clearCodeMatches<br>etc.<\/li>\n<\/ul>\n\n\n\n<p>Match objects may also be set and retrieved through <code><a href=\"https:\/\/www.pnfsoftware.com\/jeb\/apidoc\/com\/pnfsoftware\/jeb\/core\/units\/code\/android\/IDexUnit.html\">IDexUnit<\/a><\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>setMethodMatch<\/li>\n\n\n\n<li>getMethodMatch<br>etc.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Future updates<\/h2>\n\n\n\n<p>We intend to tweak the code matching system over the next few releases, to ensure a low rate of false positives while maintaining a decent amount of true positive detections.<\/p>\n\n\n\n<p>The code signing process may also evolve and require adjustments. <sup class='footnote'><a href='#fn-5088-1' id='fnref-5088-1' onclick='return fdfootnote_show(5088)'>1<\/a><\/sup> Once it has stabilized, likely in the next couple of releases, we will consider the inclusion of transparent auto-signing for all code being analyzed. It will allow users to better leverage their reverse-engineering efforts across different projects, e.g. receive hints about code they&#8217;ve already worked on, at what time, etc.<\/p>\n\n\n\n<p>The code matching system will also be made available to the native code analysis pipeline via gendec shortly. We will keep you posted. Consider following us on <a href=\"https:\/\/x.com\/jebdec\">X<\/a> or join our <a href=\"https:\/\/pnfsoftware.com\/chat\">Slack<\/a> channel if you haven&#8217;t done so.<\/p>\n\n\n\n<p>&#8212;<\/p>\n\n\n\n<p>Until next time &amp; thanks again for your support &#8211; Nicolas \ud83d\ude42<\/p>\n\n\n<div class='footnotes' id='footnotes-5088'><div class='footnotedivider'><\/div><ol><li id='fn-5088-1'> We currently use low-dimensionality vector embeddings to represent code routines. The embeddings may be tweaked, however they will remain compact to ensure a low-disk footprint, low-memory and fast matching. <span class='footnotereverse'><a href='#fnref-5088-1'>&#8617;<\/a><\/span><\/li><\/ol><\/div>","protected":false},"excerpt":{"rendered":"<p>Our March 2026 release (JEB 5.38) ships with a transparent, flexible and fast code matching facility: This initial implementation is enabled for dex only. It will be made available for native code in a future release. The initial database is relatively compact. Mostly, it contains signatures for the latest JAR and AAR libraries commonly used &hellip; <a href=\"https:\/\/www.pnfsoftware.com\/blog\/mutation-resistant-library-code-matching\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Mutation-Resistant Library Code Matching<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[30],"tags":[],"class_list":["post-5088","post","type-post","status-publish","format-standard","hentry","category-jeb5"],"_links":{"self":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/5088","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/comments?post=5088"}],"version-history":[{"count":27,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/5088\/revisions"}],"predecessor-version":[{"id":5118,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/5088\/revisions\/5118"}],"wp:attachment":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=5088"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=5088"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=5088"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}