{"id":9828,"date":"2025-01-25T01:22:29","date_gmt":"2025-01-25T01:22:29","guid":{"rendered":"https:\/\/www.hexacorn.com\/blog\/?p=9828"},"modified":"2025-01-25T16:36:55","modified_gmt":"2025-01-25T16:36:55","slug":"being-a-tool-while-using-a-tool","status":"publish","type":"post","link":"https:\/\/www.hexacorn.com\/blog\/2025\/01\/25\/being-a-tool-while-using-a-tool\/","title":{"rendered":"Being a tool while using a tool"},"content":{"rendered":"\n<p>This case is kinda DFIR-fascinating.<\/p>\n\n\n\n<p>There is an unwritten rule in the DFIR world that says &#8211; always check the results provided by one tool, with another tool, or manually&#8230;<\/p>\n\n\n\n<p>Well&#8230; it all sounds nice in theory, until we come across a case that will change it all.<\/p>\n\n\n\n<p>So&#8230;<\/p>\n\n\n\n<p>If you use many different tools, and on regular basis, be warned that this case will destroy your faith in them&#8230;<\/p>\n\n\n\n<p>Ready?<\/p>\n\n\n\n<p>Let&#8217;s go!<\/p>\n\n\n\n<p>I have been using Total Commander for over 2 decades. I absolutely love this tool, and can&#8217;t imagine working with gazillion of files and samples that I play with on regular basis, without using it.<\/p>\n\n\n\n<p>But recently, I got fooled by it.<\/p>\n\n\n\n<p>When you download the Signal desktop client installer for Windows (v7.39), you can browse its contents with Total Commander+its (various) archive plugins to see the following output:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal1.png\"><img decoding=\"async\" loading=\"lazy\" width=\"579\" height=\"366\" src=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal1.png\" alt=\"\" class=\"wp-image-9829\" srcset=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal1.png 579w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal1-300x190.png 300w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal1-475x300.png 475w\" sizes=\"(max-width: 579px) 100vw, 579px\" \/><\/a><\/figure>\n\n\n\n<p>I was specifically interested in the <code>Signal.exe<\/code> binary so I used TC to copy <code>Signal.exe<\/code>  to my temporary work folder.<\/p>\n\n\n\n<p>To my surprise, the sigcheck reported that this binary was compiled for&#8230; ARM processors!<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Verified:       Signed\nSigning date:   01:00 2025-01-23\nPublisher:      Signal Messenger, LLC\nCompany:        Signal Messenger, LLC\nDescription:    Signal\nProduct:        Signal\nProd version:   7.39.0.0\nFile version:   7.39.0\nMachineType:    64-bit ARM<\/pre>\n\n\n\n<p>Huh?<\/p>\n\n\n\n<p>I was puzzled. <\/p>\n\n\n\n<p>I literally downloaded what I believed to be an installer of Signal that was meant for Intel-based Windows, but now I am seeing the ARM binary inside it!<\/p>\n\n\n\n<p>&lt;Anxiety level intensifies&gt;<\/p>\n\n\n\n<p>I then tried the very same approach with the installer of the older version of Signal (7.38), but the result was the same&#8230;.<\/p>\n\n\n\n<p>What&#8217;s going on here? I wondered&#8230;<\/p>\n\n\n\n<p>I must make a note here that the Signal setup program is using the Nullsoft installer to deliver the software to users. And in the reverse engineering world, once you recognize the installer type, the natural step in analysis is to decompile the script used by the installer. <\/p>\n\n\n\n<p>Using the older version of 7z (7z_1505) that extracts the [NSIS].nsi script file I got the following output listing all the embedded files inside the most recent Signal installer:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$PLUGINSDIR\\app-64.7z\n$PLUGINSDIR\\app-arm64.7z\n$PLUGINSDIR\\nsExec.dll\n$PLUGINSDIR\\nsis7z.dll\n$PLUGINSDIR\\SpiderBanner.dll\n$PLUGINSDIR\\StdUtils.dll\n$PLUGINSDIR\\System.dll\n$PLUGINSDIR\\WinShell.dll\n$R0\\Uninstall Signal.exe\n$PLUGINSDIR\\installerHeaderico.ico\n[NSIS].nsi<\/pre>\n\n\n\n<p>Huh&#8230;<\/p>\n\n\n\n<p>As you can see, there are two embedded 7z files listed above:<\/p>\n\n\n\n<ul>\n<li>$PLUGINSDIR\\app-64.7z<\/li>\n\n\n\n<li>$PLUGINSDIR\\app-arm64.7z<\/li>\n<\/ul>\n\n\n\n<p>The first one is Intel-based, and the second one is ARM-based.<\/p>\n\n\n\n<p>The [NSIS].nsi script references them here (using the respective 7z file depending on the architecture):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">label_796:\n  StrCmp $_40_ ARM64 0 label_799\n  SetOverwrite on\n  AllowSkipFiles on\n  File $PLUGINSDIR\\<strong>app-arm64.7z<\/strong>\n  Goto label_802\nlabel_799:\n  StrCmp $_40_ 64 0 label_802\n  File $PLUGINSDIR\\<strong>app-64.7z<\/strong>\n  Goto label_802<\/pre>\n\n\n\n<p>Kinda surprisingly, we can actually locate these 2 7z files inside the main installer file at the following offsets:<\/p>\n\n\n\n<ul>\n<li>0x0003C57B &#8211; app-arm64.7z<\/li>\n\n\n\n<li>0x087904C4 &#8211; app-64.7z<\/li>\n<\/ul>\n\n\n\n<p>and after carving\/extraction, browsing them with Total Commander we can reveal their content as shown below:<\/p>\n\n\n\n<p><strong>ARM (app-arm64.7z):<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal2.png\"><img decoding=\"async\" loading=\"lazy\" width=\"577\" height=\"366\" src=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal2.png\" alt=\"\" class=\"wp-image-9830\" srcset=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal2.png 577w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal2-300x190.png 300w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal2-473x300.png 473w\" sizes=\"(max-width: 577px) 100vw, 577px\" \/><\/a><\/figure>\n\n\n\n<p><strong>INTEL (app-64.7z):<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal3.png\"><img decoding=\"async\" loading=\"lazy\" width=\"577\" height=\"343\" src=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal3.png\" alt=\"\" class=\"wp-image-9831\" srcset=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal3.png 577w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal3-300x178.png 300w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/01\/tc_signal3-500x297.png 500w\" sizes=\"(max-width: 577px) 100vw, 577px\" \/><\/a><\/figure>\n\n\n\n<p>Do you see where it is going?<\/p>\n\n\n\n<p>With files\/installers using many embedded files, the Total Commander&#8217;s (+its plugins&#8217;) visibility seems to be limited only to the first embedded archive, in this case it is the <em>app-arm64.7z<\/em> file! (in fact, it&#8217;s a bit more complicated in case TC or its plugins can parse PE file\/their sections of the sample, adding an additional layer in a game of nested dolls).<\/p>\n\n\n\n<p>When I look at that original Signal installer again now I can see the Total Commander (+its plug-ins) only see the first embedded archive. As a result, I see the Intel-targeting setup file embedding the ARM-targeting file shown in TC. The proper handling would include full file analysis of the installer and recognition of all embedded archives as virtual subfolders&#8230; at least. <\/p>\n\n\n\n<p>The bottom line is this:<\/p>\n\n\n\n<ul>\n<li>Let&#8217;s admit it, file formats are complicated, especially if they are mixed\/overlapping<\/li>\n\n\n\n<li>Trust, but verify &#8212; use multiple tools to extract\/parse installer scripts, analyze\/compare their outputs<\/li>\n\n\n\n<li>Don&#8217;t trust GUI-only programs<\/li>\n\n\n\n<li>Question what you see (in my case: the Intel-CPU targeting installer including ARM binaries as seen by TC in the installer&#8217;s body looked odd)<\/li>\n\n\n\n<li>Analyze as many properly formatted file types as possible on a file format level to spot anomalies and inconsistencies in the future<\/li>\n\n\n\n<li>Use carving and static analysis tools on samples: extracted sections, embedded media files, executables, configuration files, URLs, IPs. github repository addresses, PDB paths, etc. &#8211; this can add a lot of intelligence value long term<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This case is kinda DFIR-fascinating. There is an unwritten rule in the DFIR world that says &#8211; always check the results provided by one tool, with another tool, or manually&#8230; Well&#8230; it all sounds nice in theory, until we come &hellip; <a href=\"https:\/\/www.hexacorn.com\/blog\/2025\/01\/25\/being-a-tool-while-using-a-tool\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[53,28,21,19,9],"tags":[],"_links":{"self":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/9828"}],"collection":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/comments?post=9828"}],"version-history":[{"count":6,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/9828\/revisions"}],"predecessor-version":[{"id":9837,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/9828\/revisions\/9837"}],"wp:attachment":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/media?parent=9828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/categories?post=9828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/tags?post=9828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}