<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Thomas Barabosch</title>
        <description>Systems security, reverse engineering, malware analysis, and threat research.</description>
        <link>https://tbarabosch.github.io/</link>
        <atom:link href="https://tbarabosch.github.io/feed.xml" rel="self" type="application/rss+xml"/>
        <pubDate>Wed, 15 Jul 2026 21:02:33 +0000</pubDate>
        <lastBuildDate>Wed, 15 Jul 2026 21:02:33 +0000</lastBuildDate>
        <generator>Jekyll v3.10.0</generator>
        
            <item>
                <title>Hello, world, again</title>
                <description>&lt;p&gt;Every now and then, a system deserves a clean boot.&lt;/p&gt;

&lt;p&gt;I have relaunched this blog with a new design: less ornamental, more direct, and closer to the kind of interface I keep coming back to anyway. Think manpage energy, but for notes on systems security, reverse engineering, malware analysis, threat research, and the occasional opinion that needed more room than a short post elsewhere.&lt;/p&gt;

&lt;p&gt;The old posts are still here. New ones should follow.&lt;/p&gt;

&lt;p&gt;If you want the updated map of who I am, what I work on, and what belongs on this site, start with the updated &lt;a href=&quot;/about/&quot;&gt;about page&lt;/a&gt;.&lt;/p&gt;
</description>
                <pubDate>Tue, 14 Jul 2026 22:00:00 +0000</pubDate>
                <link>https://tbarabosch.github.io/hello-world-again/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/hello-world-again/</guid>
                
                <category>blog</category>
                
                <category>about</category>
                
                
            </item>
        
            <item>
                <title>Detect API hashing with YARA</title>
                <description>&lt;p&gt;Malware utilizes obfuscation to complicate its analysis. There is one obfuscation technique that targets specifically static analysis: API hashing. In a nutshell, malware uses hashes of API names (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x0688eae1&lt;/code&gt;) instead of plain strings (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kernel32!Sleep&lt;/code&gt;) to obfuscate the API functionality it relies on. This is typically a pretty nasty obfuscation technique since it requires malware analysts to resolve this API hashing before they can conduct a meaningful analysis. There are many advanced malware families that utilize API hashing including &lt;a href=&quot;https://www.proofpoint.com/us/threat-insight/post/buer-new-loader-emerges-underground-marketplace&quot;&gt;Buer&lt;/a&gt;, &lt;a href=&quot;https://www.fireeye.com/blog/threat-research/2012/11/precalculated-string-hashes-reverse-engineering-shellcode.html&quot;&gt;PoisonIvy&lt;/a&gt;, &lt;a href=&quot;https://blogs.jpcert.or.jp/en/2017/02/plugx-poison-iv-919a.html&quot;&gt;PlugX&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/VK_Intel/status/981326743486185472?s=20&quot;&gt;UrlZone&lt;/a&gt;.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;As a first step in the triage phase, it is nice to have a first pointer whether or not a malware family could use API hashing and if so which algorithm it uses to hash API names. Therefore, I wrote a tiny project called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apihash_to_yara.py&lt;/code&gt; that generates YARA rules to detect this behavior fast and without too many false positives. The source code is on &lt;a href=&quot;https://github.com/tbarabosch/apihash_to_yara&quot;&gt;GitHub&lt;/a&gt; where you’ll also find two sets of precompiled YARA rules.&lt;/p&gt;

&lt;p&gt;API hashing is an obfuscation technique that you’ll typically encounter in advanced malware. Normally, the names of APIs are stored in plain text in a binary (e.g. as part of the Import Table of the PE header). Remember that strings and APIs are very important corner stones in the reverse engineering puzzle. Hence, malware authors try to obfuscate them so that malware analysts have to significantly invest more time.&lt;/p&gt;

&lt;p&gt;In API hashing, API names are not stored in plain text but rather their hashes are stored in the binary. Malware utilizes these hashes and resolves the addresses to APIs itself. To resolve an API hash &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;h&lt;/code&gt; to an API name, it typically hashes the exported APIs of DLL loaded into the process space with an embedded hashing algorithm. Then, it compares each computed hash to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;h&lt;/code&gt;. A good write-up on how malware achieves this by enumerating DLLs via the PEB &lt;a href=&quot;https://modexp.wordpress.com/2017/01/15/shellcode-resolving-api-addresses/&quot;&gt;can be found here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A common algorithm that you’ll encounter is &lt;a href=&quot;https://en.wikipedia.org/wiki/Cyclic_redundancy_check&quot;&gt;CRC32&lt;/a&gt;. The following Python snippet shows how we can compute the CRC32 hash of the API name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sleep&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;zlib&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;crc32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Sleep&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;s&quot;&gt;&apos;0xcef2eda8&apos;&lt;/span&gt;         
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that we do not have to come up with our own implementations for the many API hashing algorithms that exist in malware since there is already an implementation of many in &lt;a href=&quot;https://github.com/fireeye/flare-ida/blob/master/shellcode_hashes/make_sc_hash_db.py&quot;&gt;make_sc_hash_db from flare-ida&lt;/a&gt;, which we’ll use later.&lt;/p&gt;

&lt;p&gt;To detect this behavior fast with YARA, we do not have to know how the resolving works in detail. We won’t match the embedded algorithm either. Instead, we’ll match the API hashes that have to be stored in the malicious binary somewhere.&lt;/p&gt;

&lt;p&gt;There are two ways how malware stores these hashes. Both ways correspond to one way how they are resolved. The first way is to resolve the API hashes during the initialization of the malware. Therefore, the malware comprises an array of API hashes and resolves one after another on startup. For instance, this is what the malware PoisonIvy does. The following screenshot shows the API hash array found in its binary. I’ve marked the hash &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xBA36C10A&lt;/code&gt;, which corresponds to the API function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Kernel32!Sleep&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/apihash-to-yara/apihashing_poison_ivy_table.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The second way is to resolve the API hashes just in time. This means that every time the malware calls an API function, it first resolves the hash. The following screenshot of the malware family VMZeus depicts this behavior. The function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resolve_api_hashing&lt;/code&gt; takes among other parameters an API hash as input. It resolves the API hash and returns the address to the API in the register &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax&lt;/code&gt;. This is subsequently called (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call eax&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/apihash-to-yara/apihashing_vmzeus_crc32.png&quot; alt=&quot;API hashing in VMZeus sample: red boxes contain API hashes, the hash 0xCEF2EDA8 is the CRC32 hash of Sleep&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The main idea is to generate one YARA rule for several API hashes that are generated with API hashing algorithm. I didn’t want to reinvent the wheel and therefore I adjusted the API hashing algorithms found in &lt;a href=&quot;https://github.com/fireeye/flare-ida/blob/master/shellcode_hashes/make_sc_hash_db.py&quot;&gt;make_sc_hash_db from flare-ida&lt;/a&gt;. &lt;a href=&quot;https://www.fireeye.com/blog/threat-research/2012/11/precalculated-string-hashes-reverse-engineering-shellcode.html&quot;&gt;This project &lt;/a&gt;comprises more than a dozen API hashing algorithms.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apihash_to_yara&lt;/code&gt; requires a list of DLL names and API names (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kernel32!Sleep&lt;/code&gt;) as input and generates based on them a YARA rule set. I recommend to include &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;W&lt;/code&gt; versions of an API (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SleepA&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SleepW&lt;/code&gt;) since their API hashes are likely different. If you create your own list using the script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generate_api_list.py&lt;/code&gt; then this script will handle this for you. Since some malware families store their hashes in little endian format and some in big endian format, both formats are always generated.&lt;/p&gt;

&lt;p&gt;There are already two API lists included in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; directory of the project. The first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;top100_winapi_malpedia.txt&lt;/code&gt; comprises the Top100 Windows API functions found in samples hosted on &lt;a href=&quot;https://malpedia.caad.fkie.fraunhofer.de/&quot;&gt;Malpedia&lt;/a&gt;. The second API list &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;custom_apis.txt&lt;/code&gt; comprises all API names found in common Windows DLLs such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kernel32.dll&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are two parameters that help you to tweak the detection performance. First, there is the parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--yara_condition_match_threshold&lt;/code&gt; that defines how many API hashes have to be matched in a binary. The default value is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10&lt;/code&gt; API hashes, which is just an educated guess. The value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5&lt;/code&gt; API hashes yielded too many false positives. The second parameter that you could tweak is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--yara_condition_filesize_threshold&lt;/code&gt; that ensures that only binaries with less than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt; kilobytes are considered. This is another way to reduce false positives. Feel free to adjust these parameters to your needs. In the following, I’ll list all command line options of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apihash_to_yara.py&lt;/code&gt; for your reference:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;usage: apihash_to_yara.py &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--yara_condition_match_threshold&lt;/span&gt; YARA_CONDITION_MATCH_THRESHOLD] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--yara_condition_filesize_threshold&lt;/span&gt; YARA_CONDITION_FILESIZE_THRESHOLD] path_api_names output
 positional arguments:
   path_api_names        Path to list of API names
   output                Path to output
 optional arguments:
   &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;            show this &lt;span class=&quot;nb&quot;&gt;help &lt;/span&gt;message and &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;--yara_condition_match_threshold&lt;/span&gt; YARA_CONDITION_MATCH_THRESHOLD
                         Threshold of required matches &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;YARA condition
   &lt;span class=&quot;nt&quot;&gt;--yara_condition_filesize_threshold&lt;/span&gt; YARA_CONDITION_FILESIZE_THRESHOLD
                         Filesize threshold of required matches &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;YARA condition
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The output of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apihash_to_yara.py&lt;/code&gt; looks similar to the following:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;api_hash_ror7AddHash32&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;nl&quot;&gt;meta:&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Thomas Barabosch&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;reference1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://tbarabosch.github.io/apihash-to-yara/&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;reference2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tbarabosch/apihash_to_yara&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;reference3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/fireeye/flare-ida/tree/master/shellcode_hashes&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;reference4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://malpedia.caad.fkie.fraunhofer.de/stats/api_usage&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;api_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;300&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;yara_condition_match_threshold&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;10&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;yara_condition_filesize_threshold&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1024&quot;&lt;/span&gt;
     &lt;span class=&quot;nl&quot;&gt;strings:&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_Sleep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cb&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_Sleep_little_endian&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cb&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_SleepA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_SleepA_little_endian&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_SleepW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_SleepW_little_endian&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_CloseHandle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;66&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;57&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_CloseHandle_little_endian&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;57&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;66&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_CloseHandleA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;af&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fe&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_CloseHandleA_little_endian&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;af&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_CloseHandleW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;af&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fe&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32_dll_CloseHandleW_little_endian&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;af&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
     &lt;span class=&quot;nl&quot;&gt;condition:&lt;/span&gt;
         &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;them&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filesize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KB&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are two precompiled sets of YARA rules in the &lt;a href=&quot;https://github.com/tbarabosch/apihash_to_yara&quot;&gt;repository&lt;/a&gt;. First, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;top100_apis_malpedia.yar&lt;/code&gt; (based on the Malpedia API names) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;custom_apis.yar.gz&lt;/code&gt; (based on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;custom_apis.txt&lt;/code&gt;, gzipped due to size restrictions).&lt;/p&gt;

&lt;h2 id=&quot;does-it-work--a-very-unscientific-evaluation&quot;&gt;Does it work? – A very unscientific evaluation&lt;/h2&gt;

&lt;p&gt;No real scientific evaluation here, just some random case studies. I ran &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;top100_apis_malpedia.yar&lt;/code&gt; on Malpedia. I had more than 450 matches but this included different versions of a malware family. From 68 families I had at least one match. Throughout the years I’ve analyzed some of these families and remember them to use API hashing (not exactly the algorithm but the fact that they do). While this is a very weak confirmation that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apihash_to_yara.py&lt;/code&gt; works, I had a look at a handful samples.&lt;/p&gt;

&lt;p&gt;I’ll refrain from posting the list of matches due to the TLP:AMBER nature of some of the families. If you’ve access to the Malpedia corpus, please run it yourself. Play a bit with the threshold parameters to avoid false positives. Let me know your results and suggest improvements! Some examples that I stumbled upon are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.proofpoint.com/us/threat-insight/post/buer-new-loader-emerges-underground-marketplace&quot;&gt;Buer&lt;/a&gt; (ror13AddHash32Sub20h)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.botconf.eu/wp-content/uploads/2018/12/2018-Dennis-Schwarz-everything_panda_banker.pdf&quot;&gt;Panda Banker&lt;/a&gt; (crc32)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blogs.jpcert.or.jp/en/2017/02/plugx-poison-iv-919a.html&quot;&gt;Poison Ivy and PlugX&lt;/a&gt; (PoisonIvyHash)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Furthermore, I scheduled a Retrohunt on VirusTotal’s Goodware corpus. Actually, I scheduled two Retrohunts since the maximal size is 1MB per rule set. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;top100_apis_malpedia.yar&lt;/code&gt; has a filesize of 1.3MB. Therefore, I split the rule set accordingly. In total, there were &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;7&lt;/code&gt; false positives, all of them matched the rule &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sll1AddHash32&lt;/code&gt;. In environments where you can not tolerate false positives, you should turn off this rule.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/apihash-to-yara/vt_retrohunt_api_hashing.png&quot; alt=&quot;VirusTotal Retrohunt on Goodware corpus with top100_apis_malpedia.yar&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let me quickly conclude what we’ve presented in this blog post. This blog post presented &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apihashing_to_yara.py&lt;/code&gt;, a tiny project to generate YARA rules to detect API hashing in malware fast and without too many false positives. The project can be &lt;a href=&quot;https://github.com/tbarabosch/apihash_to_yara&quot;&gt;found on GitHub&lt;/a&gt;. There are also two precompiled YARA rules already included. Shout out to the giants on whose shoulders I stand: &lt;a href=&quot;https://github.com/fireeye/flare-ida/blob/master/shellcode_hashes/make_sc_hash_db.py&quot;&gt;make_sc_hash_db from flare-ida&lt;/a&gt; and &lt;a href=&quot;https://malpedia.caad.fkie.fraunhofer.de/&quot;&gt;Malpedia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As always, there is always room for improvement. One path that could be followed is finding the perfect condition thresholds. Right now the default value is 10 API hash matches and 1024KB filesize, however these values may be too conservative. Quick tests with lower thresholds (e.g. 5 matches) yielded too many FPs. Another path is adding more API hashing algorithms. If time permits, I’ll port new algorithms from &lt;a href=&quot;https://github.com/fireeye/flare-ida/blob/master/shellcode_hashes/make_sc_hash_db.py&quot;&gt;make_sc_hash_db from flare-ida&lt;/a&gt;.&lt;/p&gt;
</description>
                <pubDate>Tue, 16 Mar 2021 16:42:31 +0000</pubDate>
                <link>https://tbarabosch.github.io/apihash-to-yara/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/apihash-to-yara/</guid>
                
                <category>malware-analysis</category>
                
                <category>api-hashing</category>
                
                <category>yara</category>
                
                <category>reverse-engineering</category>
                
                
            </item>
        
            <item>
                <title>Learn how to fix PE magic numbers with Malduck</title>
                <description>&lt;p&gt;Malware often corrupts the Portable Executable (PE) header to hinder its analysis. By overwriting parts of the PE header, malware evades simple memory dumpers and thwarts proper loading by analysis tools. If we’re lucky then malware only overwrites the magic numbers of the PE header (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MZ&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PE&lt;/code&gt;) and leaves the rest of the header intact. We can fix such corrupted PE headers with ease. All we need is a little bit of knowledge about the PE format and the right tool to manipulate memory dumps.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;First, we’ll learn how to identify such corrupted PE headers quickly with a hexeditor. Next, we’ll see how to manipulate memory dumps with &lt;a href=&quot;https://malduck.readthedocs.io/en/latest/&quot;&gt;Malduck&lt;/a&gt;. This section gives you a head start on how to use this great Python module effectively. Finally, we are putting it all together and write a script to fix PE magic numbers of a corrupted PE header.&lt;/p&gt;

&lt;p&gt;In the following, I assume that you’ve got a basic understanding of the PE format. If not, I can recommend the article on &lt;a href=&quot;https://wiki.osdev.org/PE&quot;&gt;osdev.org&lt;/a&gt; (check the overview graphic of the PE format) as an introduction.&lt;/p&gt;

&lt;p&gt;There are two magic numbers in the PE header that are frequently overwritten by malware. First, the magic number of the DOS header (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_DOS_HEADER&lt;/code&gt;), which is a two-byte or WORD constant (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MZ&lt;/code&gt;). Second, the magic number of the PE header, which is a four-byte or DWORD constant (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PE\x00\x00&lt;/code&gt;). This is illustrated in the following screenshot of a PE file opened in a hexeditor. Both magic numbers are colored in orange. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MZ&lt;/code&gt; magic is at offset &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x0&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PE\x00\x00&lt;/code&gt; is at offset &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x80&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/fix-pe-magic-numbers-with-malduck/magic_numbers_pe_color.png&quot; alt=&quot;Regular PE header with magic numbers (MZ + PE) highlighted.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that we’ve seen a perfectly fine PE header, let’s see how a slightly corrupted PE header looks like. The next screenshot shows a PE header with both (principal) magic numbers overwritten.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/fix-pe-magic-numbers-with-malduck/overwritten_magic_numbers_pe.png&quot; alt=&quot;PE header with overwritten magic numbers.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can still identify that this is likely a PE file since the famous string &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;This program cannot be run in DOS mode&lt;/code&gt; is still there. But we are missing these two magic numbers, which in turn hinders many analysis tools to properly load and analyze such a binary.&lt;/p&gt;

&lt;p&gt;So, fixing this kind of corrupted PE header is straightforward. First, we have to restore the magic number &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MZ&lt;/code&gt; at offset &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x0&lt;/code&gt;. Second, we have to determine the offset to the PE header. The DOS header holds this offset in its field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e_lfanew&lt;/code&gt; (see next code block with DOS header for reference). Therefore, we have to read the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e_lfanew&lt;/code&gt; from the DOS header. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e_lfanew&lt;/code&gt; resides at offset &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x3c&lt;/code&gt;. Third, we have to restore the PE header magic number &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PE\x00\x00&lt;/code&gt; at the offset pointed to by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e_lfanew&lt;/code&gt;. Finally, we should validate, if the file is now a valid PE file.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_IMAGE_DOS_HEADER&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;                
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_magic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;cm&quot;&gt;/* 00: MZ Header signature */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_cblp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;cm&quot;&gt;/* 02: Bytes on last page of file */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_cp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;cm&quot;&gt;/* 04: Pages in file */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_crlc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;cm&quot;&gt;/* 06: Relocations */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_cparhdr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;cm&quot;&gt;/* 08: Size of header in paragraphs */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_minalloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;cm&quot;&gt;/* 0a: Minimum extra paragraphs needed */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_maxalloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;cm&quot;&gt;/* 0c: Maximum extra paragraphs needed */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_ss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;cm&quot;&gt;/* 0e: Initial (relative) SS value */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_sp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;cm&quot;&gt;/* 10: Initial SP value */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_csum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;cm&quot;&gt;/* 12: Checksum */&lt;/span&gt;        
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;cm&quot;&gt;/* 14: Initial IP value */&lt;/span&gt;           
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;cm&quot;&gt;/* 16: Initial (relative) CS value */&lt;/span&gt;          
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_lfarlc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;cm&quot;&gt;/* 18: File address of relocation table */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_ovno&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;cm&quot;&gt;/* 1a: Overlay number */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;     &lt;span class=&quot;cm&quot;&gt;/* 1c: Reserved words */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_oemid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;cm&quot;&gt;/* 24: OEM identifier (for e_oeminfo) */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_oeminfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;cm&quot;&gt;/* 26: OEM information; e_oemid specific */&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;e_res2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;   &lt;span class=&quot;cm&quot;&gt;/* 28: Reserved words */&lt;/span&gt;        
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e_lfanew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;cm&quot;&gt;/* 3c: Offset to extended header */&lt;/span&gt;       
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMAGE_DOS_HEADER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PIMAGE_DOS_HEADER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that if you encounter a memory dump that starts with around 1000 / 0x400 zero bytes, followed by properly aligned code, then you are likely out of luck. What you are looking at is likely a completely overwritten PE header. Here I’ve encountered two scenarios throughout the years. First, the malware unpacks a perfectly fine PE file and overwrites the PE header, for instance, before injecting it into another process. If this is the case then go back to debugging and dump the PE file before the header is overwritten.&lt;/p&gt;

&lt;p&gt;Second, the malware unpacks a PE file with an already corrupted PE header. In this case, you have to restore the PE header. If it is really necessary then you can try to &lt;a href=&quot;https://lief.quarkslab.com//doc/latest/tutorials/02_pe_from_scratch.html&quot;&gt;build a PE file from scratch&lt;/a&gt; with &lt;a href=&quot;https://lief.quarkslab.com/doc/latest/index.html&quot;&gt;LIEF&lt;/a&gt;. However, this is out of the scope of this blog post.&lt;/p&gt;

&lt;h2 id=&quot;manipulating-memory-dumps-with-malduck&quot;&gt;Manipulating memory dumps with Malduck&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://malduck.readthedocs.io/en/latest/&quot;&gt;Malduck&lt;/a&gt; is a Python module that helps writing malware analysis scripts quickly. It is developed and maintained by &lt;a href=&quot;https://www.cert.pl/&quot;&gt;CERT.pl&lt;/a&gt;. &lt;a href=&quot;https://malduck.readthedocs.io/en/latest/&quot;&gt;Malduck’s documentation&lt;/a&gt; is very decent. It is my default go-to tool to write malware analysis scripts (e.g. &lt;a href=&quot;/malware-analysts-guide-to-aplib-decompression/&quot;&gt;for aPLib decompression&lt;/a&gt;).&lt;/p&gt;

&lt;h3 id=&quot;open-a-memory-dump-with-malduck&quot;&gt;Open a memory dump with Malduck&lt;/h3&gt;

&lt;p&gt;Before we can manipulate memory dumps (of PE files), we have to open them with Malduck. The basis for all memory representations is the class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;a class=&quot;rank-math-link&quot; href=&quot;https://malduck.readthedocs.io/en/latest/procmem.html&quot;&amp;gt;Malduck.procmem&amp;lt;/a&amp;gt;&lt;/code&gt; (alias for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malduck.procmem.procmem.ProcessMemory&lt;/code&gt;). The constructor takes three parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;buf&lt;/strong&gt;: a buffer of the memory contents (as among others Python bytes)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;base&lt;/strong&gt; (optional): the base address of the memory dump, which defaults to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x0&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;regions&lt;/strong&gt; (optional): a list of regions of the memory dump, defaults to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;None&lt;/code&gt; (not relevant in the following since we’ll work with PE dumps)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can get the length of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessMemory&lt;/code&gt; instance with the method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length&lt;/code&gt; and close it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;close&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Apart from methods for reading and writing (see next sections), there are methods for searching (&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findmz&lt;/code&gt;&lt;/strong&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findp&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findv&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;regexp&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;regexv&lt;/code&gt;), YARA scanning (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarap&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarav&lt;/code&gt;), and disassembling (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;disasmv&lt;/code&gt;). Note that methods may be suffixed with either &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; (virtual) or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt; (physical). Methods suffixed with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; work on virtual addresses and methods suffixed with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt; work on physical addresses (raw offsets in the memory dump). The methods &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p2v&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v2p&lt;/code&gt; translate from physical addresses to virtual and vice versa.&lt;/p&gt;

&lt;p&gt;Based on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malduck.procmem.procmem.ProcessMemory&lt;/code&gt;, there are four more memory representations in Malduck:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://malduck.readthedocs.io/en/latest/procmem.html#processmemorype-procmempe&quot;&gt;ProcessMemoryPE&lt;/a&gt; (alias &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;procmempe&lt;/code&gt;) for PE files&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://malduck.readthedocs.io/en/latest/procmem.html#processmemoryelf-procmemelf&quot;&gt;ProcessMemoryELF&lt;/a&gt; (alias &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malduck.procmemelf&lt;/code&gt;) for ELF files&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://malduck.readthedocs.io/en/latest/procmem.html#cuckooprocessmemory-cuckoomem&quot;&gt;CuckooProcessMemory&lt;/a&gt; (alias &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malduck.cuckoomem&lt;/code&gt;) for memory dumps in Cuckoo 2.x format&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://malduck.readthedocs.io/en/latest/procmem.html#idaprocessmemory-idamem&quot;&gt;IDAProcessMemory&lt;/a&gt; (alias &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malduck.idamem&lt;/code&gt;) for working with IDAPython&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since this blog post covers PE files, we will work with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessMemoryPE&lt;/code&gt; (alias &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;procmempe&lt;/code&gt;) in the following. The constructor differs slightly from the constructor of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessMemory&lt;/code&gt;. The first two parameters are still &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;buf&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base&lt;/code&gt;. However, it does not take the parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;regions&lt;/code&gt; but takes two more parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;image&lt;/code&gt; (optional): indicate that this is a dump of a &lt;a href=&quot;https://docs.microsoft.com/en-us/archive/msdn-magazine/2002/february/inside-windows-win32-portable-executable-file-format-in-detail&quot;&gt;memory-mapped&lt;/a&gt; PE file, which defaults to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;False&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;detect_image&lt;/code&gt; (optional): heuristically detects if is a &lt;a href=&quot;https://docs.microsoft.com/en-us/archive/msdn-magazine/2002/february/inside-windows-win32-portable-executable-file-format-in-detail&quot;&gt;memory-mapped&lt;/a&gt; PE file, which defaults to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;False&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A useful method of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessMemoryPE&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_valid&lt;/code&gt;, which checks if the imagebase of the memory dump points to a valid PE header.&lt;/p&gt;

&lt;p&gt;I encourage you to read the &lt;a href=&quot;https://malduck.readthedocs.io/en/latest/index.html&quot;&gt;documentation&lt;/a&gt; to find other hidden gems. There are further methods like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extract&lt;/code&gt; that tries to extract a malware configuration from the memory dump. See Malduck’s &lt;a href=&quot;https://malduck.readthedocs.io/en/latest/extractor.html&quot;&gt;static configuration extractor engine&lt;/a&gt; for more information.&lt;/p&gt;

&lt;h3 id=&quot;read-processmemorype&quot;&gt;Read ProcessMemoryPE&lt;/h3&gt;

&lt;p&gt;Malduck supports two ways to read from a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessMemory&lt;/code&gt; instance. First, it allows reading raw data chunks with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readp&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readv&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readv_until&lt;/code&gt;. While &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readp&lt;/code&gt; takes as input a raw &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offset&lt;/code&gt; and an optional &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readv&lt;/code&gt; takes as input a virtual &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addr&lt;/code&gt;. The method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readv_until&lt;/code&gt; is useful when you want to read until a certain stop marker (e.g. end of configuration).&lt;/p&gt;

&lt;p&gt;Second, Malduck supports reading various data types:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;strings: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asciiz&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;utf16z&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;signed integers: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int8p&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int8v&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int16p&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int16v&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int32p&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int32v&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64p&lt;/code&gt; /&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64v&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;unsigned integers: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint8p&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint8v&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint16p&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint16v&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint32p&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint32v&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint64p&lt;/code&gt; /&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint64v&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that there is always a physical (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt;) and virtual (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt;) version. Internally, all utilize either &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readp&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readv&lt;/code&gt; to read the data.&lt;/p&gt;

&lt;h3 id=&quot;write-processmemorype&quot;&gt;Write ProcessMemoryPE&lt;/h3&gt;

&lt;p&gt;The support for writing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessMemory&lt;/code&gt; instances is rudimentary when compared with the reading support. There are just two functions to know: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patchp&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patchv&lt;/code&gt;. Both accept a raw &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offset&lt;/code&gt; / virtual &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addr&lt;/code&gt; and a bytes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;buf&lt;/code&gt;. That’s it, pretty straightforward!&lt;/p&gt;

&lt;h2 id=&quot;putting-it-all-together-fix-pe-magic-numbers-with-malduck&quot;&gt;Putting it all together: fix PE magic numbers with Malduck&lt;/h2&gt;

&lt;p&gt;This section puts it all together: our theoretical knowledge about the PE format and our practical knowledge about memory dump manipulation with Malduck. The script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fix_pe_magic_numbers.py&lt;/code&gt; takes a path to a dump of PE file with a corrupted header as input and outputs a fixed dump.&lt;/p&gt;

&lt;p&gt;First, it loads the dump into a buffer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; and opens it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malduck.procmempe&lt;/code&gt; (alias of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malduck.procmem.procmempe.ProcessMemoryPE&lt;/code&gt;) in line 11. The method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_valid&lt;/code&gt; checks if a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessMemoryPE&lt;/code&gt; object is a valid PE file (line 13). Next, it patches the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MZ&lt;/code&gt; magic number with the method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patchp&lt;/code&gt; (line 17) and reads the DOS header field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e_lfanew&lt;/code&gt; with the method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint32p&lt;/code&gt;. Again, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e_lfanew&lt;/code&gt; resides at offset &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x3C&lt;/code&gt;. Afterwards, it patches the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PE\x00\x00&lt;/code&gt; magic number with the method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patchp&lt;/code&gt; (line 24). Finally, it validates the PE file with the method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_valid&lt;/code&gt; (line 26). If it is valid, then it writes all bytes of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessMemoryPE&lt;/code&gt; object to a file (line 29).&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;malduck&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
   &lt;span class=&quot;sb&quot;&gt;`if len(argv) != 2:`&lt;/span&gt;
&lt;span class=&quot;sb&quot;&gt;`   print(&apos;Usage: fix_pe_magic_numbers.py PATH_TO_DUMP&apos;)     `&lt;/span&gt;
        &lt;span class=&quot;sb&quot;&gt;`return`&lt;/span&gt;

    &lt;span class=&quot;sb&quot;&gt;`with open(argv[1], &apos;rb&apos;) as f:     `&lt;/span&gt;
        &lt;span class=&quot;sb&quot;&gt;`data = f.read()`&lt;/span&gt;
        &lt;span class=&quot;sb&quot;&gt;`pe = malduck.procmempe(buf=data)     `&lt;/span&gt;

        &lt;span class=&quot;sb&quot;&gt;`if pe.is_valid():         `&lt;/span&gt;
            &lt;span class=&quot;sb&quot;&gt;`print(&apos;This file is already a valid PE file. Skipping...&apos;)         `&lt;/span&gt;
            &lt;span class=&quot;sb&quot;&gt;`return     `&lt;/span&gt;

        &lt;span class=&quot;sb&quot;&gt;`pe.patchp(0, b&apos;MZ&apos;)     `&lt;/span&gt;
        &lt;span class=&quot;sb&quot;&gt;`lfanew = pe.uint32p(0x3c)     `&lt;/span&gt;
        &lt;span class=&quot;sb&quot;&gt;`if lfanew &amp;gt; len(data):         `&lt;/span&gt;
            &lt;span class=&quot;sb&quot;&gt;`print(&apos;Bogus lfanew value ({hex(lfanew)}). Bailing out...&apos;)         `&lt;/span&gt;
            &lt;span class=&quot;sb&quot;&gt;`return     `&lt;/span&gt;
        
        &lt;span class=&quot;sb&quot;&gt;`print(f&apos;lfanew: {hex(lfanew)}&apos;)     `&lt;/span&gt;
        &lt;span class=&quot;sb&quot;&gt;`pe.patchp(lfanew, b&apos;PE\x00\x00&apos;)     `&lt;/span&gt;
        
        &lt;span class=&quot;sb&quot;&gt;`if pe.is_valid():         `&lt;/span&gt;
            &lt;span class=&quot;sb&quot;&gt;`print(&apos;Fixed file successfully. Dumping to new file...&apos;)         `&lt;/span&gt;
            &lt;span class=&quot;sb&quot;&gt;`with open(argv[1].replace(&apos;bin&apos;, &apos;&apos;) + &apos;_fixed_header.bin&apos;, &apos;wb&apos;) as g:`&lt;/span&gt;
 &lt;span class=&quot;sb&quot;&gt;`    `&lt;/span&gt;    &lt;span class=&quot;sb&quot;&gt;`g.write(pe.readp(0))         `&lt;/span&gt;
                &lt;span class=&quot;sb&quot;&gt;`print(&apos;Done.&apos;)     `&lt;/span&gt;
        &lt;span class=&quot;sb&quot;&gt;`else:         `&lt;/span&gt;
            &lt;span class=&quot;sb&quot;&gt;`print(&apos;Could not fix file, still not a valid PE file.&apos;)     `&lt;/span&gt;
        
        &lt;span class=&quot;sb&quot;&gt;`pe.close()`&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;&amp;lt;strong&amp;gt;main&amp;lt;/strong&amp;gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s see how it works with our broken memory dump from the beginning:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; file memdump.bin
memdump.bin: data
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; python fix_pe_magic_numbers.py memdump.bin
 lfanew: 0x80
 Fixed file successfully. Dumping to new file…
 Done.
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; file memdump_fixed_header.bin
memdump_fixed_header.bin: PE32+ executable &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;console&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; x86-64, &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;MS Windows
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;et voilà! The script fixed the memory dump as we can see in the following screenshot:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/fix-pe-magic-numbers-with-malduck/fixed_pe.png&quot; alt=&quot;Fix PE magic numbers with malduck.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Both magic numbers are located at their correct offsets: the magic number of the DOS header &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MZ&lt;/code&gt; resides at offset zero and the magic number of the File header resides at offset 0x80 (as indicated by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e_lfanew&lt;/code&gt;). Now you can load the PE file with other analysis tools and continue your analysis.&lt;/p&gt;
</description>
                <pubDate>Thu, 28 Jan 2021 07:00:00 +0000</pubDate>
                <link>https://tbarabosch.github.io/fix-pe-magic-numbers-with-malduck/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/fix-pe-magic-numbers-with-malduck/</guid>
                
                <category>malware-analysis</category>
                
                <category>pe-files</category>
                
                <category>memory-forensics</category>
                
                <category>tooling</category>
                
                
            </item>
        
            <item>
                <title>The malware analyst&apos;s guide to PE timestamps</title>
                <description>&lt;p&gt;This blog post is all about time. More exactly, timestamps found in Portable Executable (PE) files that describe a (possible) compilation date. These PE timestamps may even reveal details about a threat actor. For instance, it is possible to deduce a threat actor’s working hours and use this information – hopefully together with other artifacts – for attribution purposes. But be aware: even though PE timestamps can be a valuable forensic artifact, they can be forged with ease. While the COFF header field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; is the most-known place to look for a compilation timestamp, there are more places where we can find timestamps in a PE file.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;But there are also special cases where PE timestamps are not correct due to new build features, linker bugs, or simply forging. We’ll look into these cases and see how we can still get some information about the compilation date. Afterward, we’ll learn how to read PE timestamps with a wide range of tools and how to automate this work in order to deal with larger datasets. Of course, there are several real-world applications for malware / cyber threat intelligence analysts of what we’ll learn in this blog post. Finally, I’ll give you some ideas how you can utilize PE timestamps to reveal certain behaviors or characteristics of threat actors.&lt;/p&gt;

&lt;p&gt;This article assumes a basic understanding of the PE format. Good beginner write-ups are “&lt;a href=&quot;https://docs.microsoft.com/en-us/archive/msdn-magazine/2002/february/inside-windows-win32-portable-executable-file-format-in-detail&quot;&gt;An In-Depth Look into the Win32 Portable Executable File Format&lt;/a&gt;” and “&lt;a href=&quot;https://blog.kowalczyk.info/articles/pefileformat.html&quot;&gt;Portable Executable File Format&lt;/a&gt;“. As a follow-up, &lt;a href=&quot;https://github.com/corkami/docs/blob/master/PE/PE.md&quot;&gt;Ange Albertini wrote&lt;/a&gt; a much more detailed technical article on the PE format.&lt;/p&gt;

&lt;p&gt;This work wouldn’t have been possible without many great blog posts and papers published by the infosec community. I am standing on the shoulders of giants! I refer to these posts and papers in the following whenever possible.&lt;/p&gt;

&lt;p&gt;The probably most cited field of the PE format that holds a compilation timestamp is the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; of the &lt;a href=&quot;https://wiki.osdev.org/COFF#Microsoft_PE.2FCOFF&quot;&gt;COFF File Header&lt;/a&gt;. It is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DWORD&lt;/code&gt; (32 bit / 4 bytes) member of the struct &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_FILE_HEADER&lt;/code&gt; / &lt;a href=&quot;https://wiki.osdev.org/COFF#Microsoft_PE.2FCOFF&quot;&gt;COFF File Header&lt;/a&gt;. This struct is defined as follows:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_IMAGE_FILE_HEADER&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;Machine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;NumberOfSections&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TimeDateStamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PointerToSymbolTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NumberOfSymbols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;SizeOfOptionalHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;Characteristics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMAGE_FILE_HEADER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PIMAGE_FILE_HEADER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; is in &lt;a href=&quot;https://en.wikipedia.org/wiki/Epoch_(computing)&quot;&gt;epoch&lt;/a&gt;, which measures the seconds that have passed since January 1, 1970 UTC. Since it is a DWORD value, its range is quite limited. This will lead – if not fixed before – to an &lt;a href=&quot;https://en.wikipedia.org/wiki/Year_2038_problem&quot;&gt;integer overflow in the year 2038&lt;/a&gt;. Furthermore, epoch &lt;strong&gt;should not be&lt;/strong&gt; confused with &lt;em&gt;Win32 epoch&lt;/em&gt;, which &lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20090306-00/?p=18913&quot;&gt;starts in the year 1601&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As part of the linking process of the final PE binary, the linker sets the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; in the COFF File Header. However, its purpose today is mainly supporting the module loader as Raymond Chen lays out in “&lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705&quot;&gt;Why are the module timestamps in Windows 10 so nonsensical?&lt;/a&gt;“:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Remember what the timestamp is used for: It’s used by the module loader to determine whether bound imports should be trusted. We’ve already seen cases where the timestamp is inaccurate. For example, if you rebind a DLL, then the rebound DLL has the same timestamp as the original, rather than the timestamp of the rebind, because you don’t want to break the bindings of other DLLs that bound to your DLL.&lt;/p&gt;

  &lt;p&gt;So the timestamp is already unreliable.&lt;/p&gt;

  &lt;p&gt;The timestamp is really a unique ID that tells the loader, “The exports of this DLL have not changed since the last time anybody bound to it.” […]&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;Raymond Chen – Why are the module timestamps in Windows 10 so nonsensical?&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Bottom line&lt;/strong&gt;: even though nobody had the intention to tamper with a timestamp, it &lt;em&gt;may already be unreliable&lt;/em&gt; in certain cases.&lt;/p&gt;

&lt;h2 id=&quot;additional-timestamps-found-in-the-pe-file-format&quot;&gt;Additional timestamps found in the PE file format&lt;/h2&gt;

&lt;p&gt;In addition to the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; of the COFF File Header, there are further places where we can find possible compilation timestamps in PE files.&lt;/p&gt;

&lt;p&gt;I think the most complete listing was &lt;a href=&quot;http://waleedassar.blogspot.com/2014/02/pe-timedatestamp-viewer.html&quot;&gt;compiled by Walied Assar&lt;/a&gt;. He lists additional places in the PE format where we can find possible compilation timestamps. I’ll refer only to the ones that can be used in order to determine the compilation time in the following sections.&lt;/p&gt;

&lt;p&gt;Nevertheless, you should have a look at the other possible fields that &lt;a href=&quot;http://waleedassar.blogspot.com/2014/02/pe-timedatestamp-viewer.html&quot;&gt;Walied Assar’s aforementioned article&lt;/a&gt; mentions. Just for completeness, I’ll list the directories that I &lt;strong&gt;do not include&lt;/strong&gt; in the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; in &lt;strong&gt;&lt;em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_IMPORT_DESCRIPTOR&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt; (see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_EXPORT_DIRECTORY&lt;/code&gt;; used in bound imports)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_BOUND_IMPORT_DESCRIPTOR&lt;/code&gt; (see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_EXPORT_DIRECTORY&lt;/code&gt;; used in bound imports)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_LOAD_CONFIG_DIRECTORY&lt;/code&gt; (&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/debug/pe-format&quot;&gt;obsolete since Windows XP&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;_image_export_directory&quot;&gt;&lt;strong&gt;&lt;em&gt;_IMAGE_EXPORT_DIRECTORY&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;https://blog.kowalczyk.info/articles/pefileformat.html&quot;&gt;export directory&lt;/a&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_EXPORT_DIRECTORY&lt;/code&gt;) of the PE format contains also a field called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt;. Not all linkers seem to fill this field but &lt;a href=&quot;http://waleedassar.blogspot.com/2014/02/pe-timedatestamp-viewer.html&quot;&gt;Microsoft Visual Studio linkers fill it&lt;/a&gt; for both DLL and EXE PE files. For reference, the export directory structure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_EXPORT_DIRECTORY&lt;/code&gt; is defined as follows:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_IMAGE_EXPORT_DIRECTORY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Characteristics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TimeDateStamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MajorVersion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MinorVersion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NumberOfFunctions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NumberOfNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AddressOfFunctions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AddressOfNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AddressOfNameOrdinals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMAGE_EXPORT_DIRECTORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PIMAGE_EXPORT_DIRECTORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; is relevant for bound imports as other PE files that use &lt;a href=&quot;https://en.wikibooks.org/wiki/X86_Disassembly/Windows_Executable_Files&quot;&gt;bound imports&lt;/a&gt; (see &lt;a href=&quot;https://en.wikibooks.org/wiki/X86_Disassembly/Windows_Executable_Files&quot;&gt;Import Binding&lt;/a&gt;) refer to the value of this field in their own field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IMAGE_IMPORT_DESCRIPTOR&lt;/code&gt;. Or in other words: the linker fills the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IMAGE_IMPORT_DESCRIPTOR&lt;/code&gt; with the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_EXPORT_DIRECTORY&lt;/code&gt; of the PE file that they bind their import to. This is the reason why the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IMAGE_IMPORT_DESCRIPTOR&lt;/code&gt; are unusable to determine a possible compilation date.&lt;/p&gt;

&lt;p&gt;The value of this field describes the time &lt;a href=&quot;https://en.wikibooks.org/wiki/X86_Disassembly/Windows_Executable_Files&quot;&gt;when the export directory was created&lt;/a&gt;. Therefore, it doesn’t have to be equal to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; from the COFF File Header. But it is often equal &lt;a href=&quot;http://waleedassar.blogspot.com/2014/02/pe-timedatestamp-viewer.html&quot;&gt;or very close&lt;/a&gt; to it.&lt;/p&gt;

&lt;h3 id=&quot;_image_resource_directory&quot;&gt;&lt;strong&gt;&lt;em&gt;_IMAGE_RESOURCE_DIRECTORY&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; field resides in the &lt;a href=&quot;https://blog.kowalczyk.info/articles/pefileformat.html&quot;&gt;resource directory&lt;/a&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_RESOURCE_DIRECTORY&lt;/code&gt;). The corresponding structure is defined as follows:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_IMAGE_RESOURCE_DIRECTORY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;Characteristics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;TimeDateStamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;MajorVersion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;MinorVersion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;NumberOfNamedEntries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;NumberOfIdEntries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMAGE_RESOURCE_DIRECTORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PIMAGE_RESOURCE_DIRECTORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While &lt;a href=&quot;http://waleedassar.blogspot.com/2014/02/pe-timedatestamp-viewer.html&quot;&gt;Microsoft Visual Studio linkers seem not to set this field&lt;/a&gt;, (old) Borland linkers set it. This is especially relevant for malware that is compiled with a Delphi version between Delphi 4 and Delphi 2006. As we later see, there is a known bug so that these versions do not correctly set the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; of the COFF File Header. However, they set it – if the PE file comprises resources – in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IMAGE_RESOURCE_DIRECTORY&lt;/code&gt; and &lt;a href=&quot;http://waleedassar.blogspot.com/2014/02/pe-timedatestamp-viewer.html&quot;&gt;its subdirectories&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;_image_debug_directory&quot;&gt;&lt;strong&gt;&lt;em&gt;_IMAGE_DEBUG_DIRECTORY&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;If the linker emits debug information (&lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/build/reference/debug-generate-debug-info?view=msvc-160&quot;&gt;/DEBUG&lt;/a&gt;), then the PE file contains an &lt;a href=&quot;https://blog.kowalczyk.info/articles/pefileformat.html&quot;&gt;array of debug directories&lt;/a&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_DEBUG_DIRECTORY&lt;/code&gt;). The corresponding structure contains a field called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; and is defined as follows:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_IMAGE_DEBUG_DIRECTORY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;Characteristics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;TimeDateStamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;MajorVersion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;WORD&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;MinorVersion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;SizeOfData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;AddressOfRawData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;PointerToRawData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMAGE_DEBUG_DIRECTORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PIMAGE_DEBUG_DIRECTORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As a PE file can contain several &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_DEBUG_DIRECTORY&lt;/code&gt;s (&lt;a href=&quot;https://blog.kowalczyk.info/articles/pefileformat.html&quot;&gt;stored in an array&lt;/a&gt;), it is &lt;a href=&quot;http://waleedassar.blogspot.com/2014/02/pe-timedatestamp-viewer.html&quot;&gt;worth to check&lt;/a&gt; all of them, in case the timestamp of the first seems to be forged.&lt;/p&gt;

&lt;p&gt;Furthermore, one type of debugging information contains a timestamp. The field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Type&lt;/code&gt; holds several constants (range &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x0&lt;/code&gt; – &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x9&lt;/code&gt;) that i&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_debug_directory&quot;&gt;ndicate the format &lt;/a&gt;of the debugging information. If the field is set to &lt;strong&gt;&lt;em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IMAGE_DEBUG_TYPE_CODEVIEW&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2&lt;/code&gt;), then we can follow &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PointerToRawData&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_DEBUG_DIRECTORY&lt;/code&gt; and we’ll find the CodeView information.&lt;/p&gt;

&lt;p&gt;The relevant structures &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_CV_HEADER&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_CV_INFO_PDB20&lt;/code&gt; &lt;a href=&quot;https://github.com/tishion/PdbInfo/blob/master/PdbInfo/PEHelper.h&quot;&gt;are defined as follows&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define CV_SIGNATURE_NB10 &apos;01BN&apos;       
#define CV_SIGNATURE_NB09 &apos;90BN&apos;       
&lt;/span&gt;                
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_CV_HEADER&lt;/span&gt;               
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;       
 &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dwSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       
 &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dwOffset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CV_HEADER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PCV_HEADER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       
                
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_CV_INFO_PDB20&lt;/span&gt;       
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;       
 &lt;span class=&quot;n&quot;&gt;CV_HEADER&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CvHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       
 &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dwSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       
 &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dwAge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       
 &lt;span class=&quot;n&quot;&gt;BYTE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PdbFileName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;       
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CV_INFO_PDB20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PCV_INFO_PDB20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_CV_HEADER&lt;/code&gt;‘s signature in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dwSignature&lt;/code&gt; equals &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CV_SIGNATURE_NB10&lt;/code&gt;, then the PDB format is 2.0. In this case, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dwSignature&lt;/code&gt; contains an epoch value describing when the debug information was created. If it is not in PDB format, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dwSignature&lt;/code&gt; &lt;a href=&quot;https://github.com/tishion/PdbInfo/blob/master/PdbInfo/PEHelper.h&quot;&gt;may comprises an unique identifier&lt;/a&gt; for each build. Note that the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dwAge&lt;/code&gt; is not a timestamp in epoch but rather an ever-increasing value that indicates an update to the PDB information.&lt;/p&gt;

&lt;h2 id=&quot;special-cases&quot;&gt;Special cases&lt;/h2&gt;

&lt;p&gt;There are several noteworthy special cases where the timestamps are either not reliable or other timestamps should be preferred. The following sections will look into three of these cases and show possible ways to circumvent this limitation.&lt;/p&gt;

&lt;h3 id=&quot;delphi-timestamps&quot;&gt;Delphi timestamps&lt;/h3&gt;

&lt;p&gt;Do you know what happened on 1992-06-19? I googled it and found out that this was the day &lt;a href=&quot;https://en.wikipedia.org/wiki/Batman_Returns&quot;&gt;Batman Returns&lt;/a&gt; was released in the USA. But that’s only relevant for Batman fans and not really related to timestamps. Something different happened, at least, if you believe the PE timestamps of likely thousands or even millions of Delphi binaries. They all were built on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1992-06-19 22:22:17&lt;/code&gt;. The timestamp value is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A425E19&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;708992537&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;What sounds like a very productive programmer evening is actually a bug in many Delphi compiler versions. Delphi versions &lt;a href=&quot;https://stackoverflow.com/questions/1781443/how-can-i-get-the-compile-date-and-time-in-delphi&quot;&gt;before Delphi 2007&lt;/a&gt; (likely &lt;a href=&quot;https://www.hexacorn.com/blog/2014/12/05/the-not-so-boring-land-of-borland-executables-part-1/&quot;&gt;Delphi 4 – Delphi 2006&lt;/a&gt;) did not set the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; at all. It seems that they just used a preconfigured value for this field. Maybe they used a PE stub that they filled out accordingly. However, there &lt;a href=&quot;https://www.hexacorn.com/blog/2014/12/05/the-not-so-boring-land-of-borland-executables-part-1/&quot;&gt;is a way&lt;/a&gt; to determine the real compilation timestamp of these binaries. If the sample comprises a resources directory (&lt;strong&gt;&lt;em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_RESOURCE_DIRECTORY&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt;), we can read its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; field instead. But be aware that the value is not an epoch timestamp but a &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-dosdatetimetofiletime?redirectedfrom=MSDN&quot;&gt;MS DOS timestamp&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottom line&lt;/strong&gt;: if you see a binary with a timestamp value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1992-06-19 22:22:17&lt;/code&gt;, then you are likely dealing with a Delphi binary that was compiled with a Delphi version before Delphi 2007. If there are resources, then you may get at least a compilation estimate from the timestamp found in &lt;strong&gt;&lt;em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_RESOURCE_DIRECTORY&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;windows-10-reproducible-builds-timestamps&quot;&gt;Windows 10 reproducible builds timestamps&lt;/h3&gt;

&lt;p&gt;Windows 10 timestamps &lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705&quot;&gt;are nonsensical&lt;/a&gt; since Microsoft moved towards reproducible builds. In a nutshell, a reproducible build means starting a build from the exact same source code yields the exact same binary code. Obviously, timestamps are one obstacle in the way to reproducible builds. Therefore, timestamps are set to the hash of the resulting binary, which preserves reproducibility.&lt;/p&gt;

&lt;p&gt;Let’s have a look at a Windows 10 binary to verify this behavior. For instance, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;regedit.exe&lt;/code&gt; comprises a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xBB9B6911&lt;/code&gt; as can be seen in the following screenshot (using the tool &lt;a href=&quot;https://www.winitor.com/&quot;&gt;pestudio&lt;/a&gt;). If we translate this value to UTC time, then this date would be way in the future. As expected, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; value of Windows 10 binaries is unreliable.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analyst-guide-to-pe-timestamps/ts_regedit_pestudio.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Even though I am not aware of a way to get a compilation timestamp directly from these binaries, there are two possible ways to get at least an approximation. First, if the file was scanned at VirusTotal, then it must be older than the first submission date. This may be a very inaccurate approximation but a good starting point.&lt;/p&gt;

&lt;p&gt;Second, a better way to approximate the age of the binary would be to use a binary index like &lt;a href=&quot;https://winbindex.m417z.com&quot;&gt;Winbindex&lt;/a&gt;. For instance, here we can check if &lt;a href=&quot;https://winbindex.m417z.com/?file=regedit.exe&quot;&gt;it indexes&lt;/a&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;regedit.exe&lt;/code&gt; file from the previous example. And indeed: Winbindex lists this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;regedit.exe&lt;/code&gt; file with sha256 hash &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d5de45decfd0fa08ac12f5725dfc7e5af1e3ed0325559101990fdcf02c439441&lt;/code&gt; and states that it is part of Windows 10 1903 and 1909. So the earliest we can get is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2019-05-21&lt;/code&gt;, which is the release date of Windows 10 1903.&lt;/p&gt;

&lt;h3 id=&quot;gozi2--isfb-timestamps&quot;&gt;Gozi2 / ISFB timestamps&lt;/h3&gt;

&lt;p&gt;Gozi2 / ISFB and &lt;a href=&quot;https://research.checkpoint.com/2020/gozi-the-malware-with-a-thousand-faces/&quot;&gt;its forks &lt;/a&gt;are wide-spread malware strains. Malware analysts are likely to stumble upon one or more of them during their career. Even though the timestamps of a Gozi / ISFB sample may be forged, there is a “feature” of this malware family and many of its forks that is likely more reliable. As stated by Maciej Kotowicz in his &lt;a href=&quot;https://lokalhost.pl/txt/isfb_still.live.and.licking.Botconf2016.pdf&quot;&gt;report on ISFB&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;One of first operations of all ISFB’ variants is to decode strings that are stored in .bss section, section that is normally used to keep non-initialized global variables. The algorithm used for string encoding is quite simple, it is a rolling xor with a compilation date as a key.&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;ISFB: Still Live and Kicking by Maciej Kotowicz&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again, the old rule of thumb holds here: threat actors are often as lazy as we are. Therefore, they will not touch this “feature”. We can see this in an ISFB fork called &lt;a href=&quot;https://www.telekom.com/en/blog/group/article/lolsnif-tracking-another-ursnif-based-targeted-campaign-600062&quot;&gt;LOLSnif&lt;/a&gt;. The sample that was observed in campaigns in April 2020 loaded the plaintext key “Apr 1 2020” to decrypt its strings.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analyst-guide-to-pe-timestamps/ts_ursnif.png&quot; alt=&quot;ISFB fork LOLSnif loads compilation date as plaintext string for string decryption.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Threat actors who compile their malicious binaries can easily tamper with any of the aforementioned timestamp values. I would say that forging timestamps is a low-hanging fruit and not doing so shows a lack of or disinterest in Operational Security (OPSEC), respectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As a rule of thumb&lt;/strong&gt;: you should never blindly trust the timestamp found in any of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; fields as they can easily be forged! However, you can increase the confidence that you have in the correctness of this value by, for instance, correlating this with intrusion dates obtained from incident response engagements or metadata obtained from sources like &lt;a href=&quot;https://www.virustotal.com/&quot;&gt;VirusTotal&lt;/a&gt; (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;First Submission&lt;/code&gt;). Furthermore, you should never trust the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; value of packed binaries as this is one of the PE header fields that packers tamper with in the first place. However, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; values of unpacked binaries are in many cases (but certainly not all!) correct as threat actors often do not care about tampering with it.&lt;/p&gt;

&lt;h3 id=&quot;case-study-custom-loader-dlls-used-in-sunburst-attacks&quot;&gt;Case study: custom loader DLLs used in SUNBURST attacks&lt;/h3&gt;

&lt;p&gt;For instance, the threat actor who is responsible for the sophisticated supply chain attack known as &lt;a href=&quot;https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html&quot;&gt;SUNBURST&lt;/a&gt; forged timestamps as stated in Microsoft’s report “&lt;a href=&quot;https://www.microsoft.com/security/blog/2021/01/20/deep-dive-into-the-solorigate-second-stage-activation-from-sunburst-to-teardrop-and-raindrop/&quot;&gt;Deep dive into the Solorigate second-stage activation: From SUNBURST to TEARDROP and Raindrop&lt;/a&gt;“:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The custom loader DLLs dropped on disk carried compile timestamps ranging from July 2020 to October 2020, while the embedded Reflective DLLs carried compile timestamps ranging from March 2016 to November 2017. The presence of 2016-2017 compile timestamps is likely due to attackers’ usage of custom &lt;a href=&quot;https://www.cobaltstrike.com/help-malleable-c2&quot;&gt;Malleable C2 profiles&lt;/a&gt; with synthetic compile timestamp (&lt;em&gt;compile_time&lt;/em&gt;) values. At first glance it would appear as if the actor did not timestamp the compile time of the custom loader DLLs (2020 compile timestamps). However, forensic analysis of compromised systems revealed that in a few cases, the timestamp of the custom loader DLLs’ introduction to systems predated the compile timestamps of the custom loader DLLs (i.e., the DLLs appear to have been compiled at a future date).&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;Microsoft Security – Deep dive into the Solorigate second-stage activation: From SUNBURST to TEARDROP and Raindrop&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The interesting point here is that both the loader DLLs as well as the CobaltStrike Beacons have forged timestamps. The timestamps of the CobaltStrike Beacons were likely forged as part of the CobaltStrike framework and carried timestamps way in the past. However, the interesting thing here is that the outer layer – the custom loader DLLs – carried timestamps that laid in the future.&lt;/p&gt;

&lt;p&gt;Even though it might be wild speculation why these timestamps predated the actual intrusion dates, one possible explanation is that the threat actor wanted the intrusion to appear to last less time than it actually lasted, in case the loader DLLs would have been found by the local network defenders.&lt;/p&gt;

&lt;h2 id=&quot;read-pe-timestamps&quot;&gt;Read PE timestamps&lt;/h2&gt;

&lt;p&gt;Numerous tools and (Python) modules allow us to read (and modify) several fields of the PE header that can hold (compilation) timestamps. The following sections will show how these timestamps can be read with tools that I deem important. The first tools serve for manual inspection of individual PE files. But the later sections will show how to use two well-known Python modules in order to automate the PE timestamp extraction as a means of analyzing several PE files of a campaign / a threat actor.&lt;/p&gt;

&lt;p&gt;Note that there is also &lt;a href=&quot;https://www.hexacorn.com/blog/2019/03/11/pe-compilation-timestamps-vs-forensics/&quot;&gt;an issue with several tools&lt;/a&gt;. While some display the TimeDateStamp as UTC time, some localize the TimeDateStamp and display incorrect information. IMHO the correct way is to display timestamps as UTC time and additionally indicate the shift that is required so that it’s in the supposedly correct time zone.&lt;/p&gt;

&lt;h3 id=&quot;read-pe-timestamps-with-a-pe-file-viewer&quot;&gt;Read PE timestamps with a PE file viewer&lt;/h3&gt;

&lt;p&gt;This one is a no-brainer. Every PE file viewer like, for instance, &lt;a href=&quot;https://github.com/blackberry/pe_tree&quot;&gt;PE Tree&lt;/a&gt;, &lt;a href=&quot;https://www.winitor.com/&quot;&gt;pestudio&lt;/a&gt;, or &lt;a href=&quot;https://github.com/hasherezade/pe-bear-releases&quot;&gt;PE-bear&lt;/a&gt; displays the aforementioned &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; fields as seen in the following screenshot using PE Tree. Note how PE Tree correctly displays the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; field as UTC time.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analyst-guide-to-pe-timestamps/ts_pe_tree.png&quot; alt=&quot;Reading PE timestamps with PE viewer pe-tree&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Walied Assar &lt;a href=&quot;http://waleedassar.blogspot.com/2014/02/pe-timedatestamp-viewer.html&quot;&gt;wrote a tiny command line program &lt;/a&gt;called &lt;a href=&quot;https://github.com/waleedassar/TimeDateStamp/&quot;&gt;TimeDateStamp&lt;/a&gt;. This command line program inspects half of a dozen timestamps that are defined in the PE format. Use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-f&lt;/code&gt; flag with a path to a PE file as follows:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:&lt;span class=&quot;se&quot;&gt;\U&lt;/span&gt;sers&lt;span class=&quot;se&quot;&gt;\U&lt;/span&gt;SER&lt;span class=&quot;se&quot;&gt;\D&lt;/span&gt;esktop&amp;gt;TimeDateStamp.exe &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; yara64.exe
     TimeDateStamp from _IMAGE_FILE_HEADER        &lt;span class=&quot;nt&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; Fri Jun 26 08:37:17 2020
     TimeDateStamp from _IMAGE_EXPORT_DIRECTORY   &lt;span class=&quot;nt&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; Empty
     TimeDateStamp from _IMAGE_DEBUG_DIRECTORY    &lt;span class=&quot;nt&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
     TimeDateStamp from _IMAGE_LOAD_CONFIG_DIRECTORY &lt;span class=&quot;nt&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; Empty    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Another neat feature is that we can input a hex value (with or without leading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x&lt;/code&gt;) and the tool spits out the corresponding date. For instance, if we input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A425E19&lt;/code&gt; (do you still remember what that was?), then it spits out &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fri Jun 19 22:22:17 1992&lt;/code&gt; correctly:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:&lt;span class=&quot;se&quot;&gt;\U&lt;/span&gt;sers&lt;span class=&quot;se&quot;&gt;\U&lt;/span&gt;SER&lt;span class=&quot;se&quot;&gt;\D&lt;/span&gt;esktop&amp;gt;TimeDateStamp.exe 2A425E19
 Fri Jun 19 22:22:17 1992
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;read-pe-timestamps-with-an-hex-editor&quot;&gt;Read PE timestamps with an hex editor&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/push_pnx/status/1164900331098128385?s=20&quot;&gt;Daniel Plohmann’s tweet &lt;/a&gt;with a list of DWORDs with only the most significant byte set and their corresponding dates is particularly interesting. For those who work frequently with HexEditors inspecting binary formats (not necessarily the PE format), this table is very helpful. Based on the most significant byte of the timestamp DWORD, we can quickly estimate the date.&lt;/p&gt;

&lt;p&gt;For instance, the Delphi timestamp &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A425E19&lt;/code&gt; falls in the bin &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A000000&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2B000000&lt;/code&gt;, or for humans &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1992-04-30 14:11:12&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1992-11-10 17:31:28&lt;/code&gt;. Note that each bin covers more or less six months.&lt;/p&gt;

&lt;p&gt;I’ve generated the bins for 2015 – 2025, which should be the most relevant as of 2021:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;U -&amp;gt; 0x55000000 - 2015-03-11T09:42:40
 V -&amp;gt; 0x56000000 - 2015-09-21T15:02:56
 W -&amp;gt; 0x57000000 - 2016-04-02T19:23:12
 X -&amp;gt; 0x58000000 - 2016-10-13T23:43:28
 Y -&amp;gt; 0x59000000 - 2017-04-26T04:03:44
 Z -&amp;gt; 0x5a000000 - 2017-11-06T07:24:00
 [ -&amp;gt; 0x5b000000 - 2018-05-19T12:44:16
 \ -&amp;gt; 0x5c000000 - 2018-11-29T16:04:32
 ] -&amp;gt; 0x5d000000 - 2019-06-11T21:24:48
 ^ -&amp;gt; 0x5e000000 - 2019-12-23T00:45:04
 _ -&amp;gt; 0x5f000000 - 2020-07-04T06:05:20
 ` -&amp;gt; 0x60000000 - 2021-01-14T09:25:36
 a -&amp;gt; 0x61000000 - 2021-07-27T14:45:52
 b -&amp;gt; 0x62000000 - 2022-02-06T18:06:08
 c -&amp;gt; 0x63000000 - 2022-08-19T23:26:24
 d -&amp;gt; 0x64000000 - 2023-03-02T02:46:40
 e -&amp;gt; 0x65000000 - 2023-09-12T08:06:56
 f -&amp;gt; 0x66000000 - 2024-03-24T11:27:12
 g -&amp;gt; 0x67000000 - 2024-10-04T16:47:28
 h -&amp;gt; 0x68000000 - 2025-04-16T21:07:44
 i -&amp;gt; 0x69000000 - 2025-10-28T00:28:00
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;read-pe-timestamps-from-the-command-line&quot;&gt;Read PE timestamps from the command line&lt;/h3&gt;

&lt;p&gt;There are many command line tools that can read the PE header. One tool I like to use is &lt;a href=&quot;https://manpages.debian.org/testing/pev/readpe.1.en.html&quot;&gt;readpe&lt;/a&gt; from the &lt;a href=&quot;https://github.com/merces/pev&quot;&gt;pev&lt;/a&gt; toolkit. pev is open source, works on several platforms, and comes with many handy tools when dealing with PE files from the command line. Let’s just use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readpe&lt;/code&gt; to read the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; of the COFF File Header from a packed &lt;a href=&quot;https://sysopfb.github.io/malware,/icedid/2020/04/28/IcedIDs-updated-photoloader.html&quot;&gt;IcedId PhotoLoader&lt;/a&gt; sample (&lt;a href=&quot;https://www.virustotal.com/gui/file/4e7161be03f206c1b086bb15b47470ec1c9381302eb34d0e76915496aec77193/details&quot;&gt;4e7161be03f206c1b086bb15b47470ec1c9381302eb34d0e76915496aec77193&lt;/a&gt;, first submission to VT: 2020-05-27 23:31:27).&lt;/p&gt;

&lt;p&gt;We call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readpe&lt;/code&gt; with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-h&lt;/code&gt; flag, which allows us to specify a header that we would like to inspect. For our purpose, this is the COFF header (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;coff&lt;/code&gt;). As a result, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readpe&lt;/code&gt; dumps all fields from this header.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;readpe &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt; coff 4e7161be03f206c1b086bb15b47470ec1c9381302eb34d0e76915496aec77193
COFF/File header
     Machine:                         0x14c IMAGE_FILE_MACHINE_I386
     Number of sections:              4
     Date/time stamp:                 1432567928 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Mon, 25 May 2015 15:32:08 UTC&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
     Symbol Table offset:             0
     Number of symbols:               0
     Size of optional header:         0xe0
     Characteristics:                 0x103
     Characteristics names
                                          IMAGE_FILE_RELOCS_STRIPPED
                                          IMAGE_FILE_EXECUTABLE_IMAGE
                                          IMAGE_FILE_32BIT_MACHINE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, the timestamp is forged since the first submission of this sample was in Spring 2020 but the timestamp says that the sample is from Spring 2015. Let’s unpack the sample with &lt;a href=&quot;https://www.unpac.me/results/c5c293b9-4951-4c2a-ad5e-312e599483db#/&quot;&gt;unpac.me&lt;/a&gt; and we receive one unpacked child (70fe6ccca21ce51800c7b998e8fc06997eac07e086f1dcdd87765b2dcea72395):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;readpe -h coff 70fe6ccca21ce51800c7b998e8fc06997eac07e086f1dcdd87765b2dcea72395
COFF/File header
     Machine:                         0x14c IMAGE_FILE_MACHINE_I386
     Number of sections:              5
     Date/time stamp:                 1586956141 (Wed, 15 Apr 2020 13:09:01 UTC)
     Symbol Table offset:             0
     Number of symbols:               0
     Size of optional header:         0xe0
     Characteristics:                 0x102
     Characteristics names
                                          IMAGE_FILE_EXECUTABLE_IMAGE
                                          IMAGE_FILE_32BIT_MACHINE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, this timestamp looks much better. It is likely to be the correct compilation timestamp of this sample due to the first submission to VT differs just one month. Furthermore, there is a &lt;a href=&quot;https://sysopfb.github.io/malware,/icedid/2020/04/28/IcedIDs-updated-photoloader.html&quot;&gt;blog post&lt;/a&gt; published at the end of April 2020 that described this new variant of IcedId’s PhotoLoader.&lt;/p&gt;

&lt;h3 id=&quot;read-pe-timestamps-with-pefile&quot;&gt;Read PE timestamps with pefile&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/erocarrera/pefile&quot;&gt;pefile&lt;/a&gt; is a Python module to parse and modify PE files. The following script (based on &lt;a href=&quot;https://bufferoverflows.net/exploring-pe-files-with-python/&quot;&gt;this blog post&lt;/a&gt;) shows how to read the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; from the COFF File Header and convert it to UTC time. In addition, it prints out how old the PE file is. Note that accessing other &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; fields as described in Section “Additional timestamps found in PE files” works similarly. Please refer to the &lt;a href=&quot;https://github.com/erocarrera/pefile/blob/wiki/UsageExamples.md&quot;&gt;usage examples of pefile&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pefile&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pefile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FILE_HEADER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;TimeDateStamp&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Value&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;utc_time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;utcfromtimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;t_delta&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utc_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;days&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;utc_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strftime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%Y-%m-%d %H:%M:%S +00:00 (UTC)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; (&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t_delta&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; days old)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we run this simple script on a Delphi sample (Wabot, &lt;a href=&quot;https://www.virustotal.com/gui/file/ebf6d5d12f4d18cef9456a363991ba028329cd25ee3908101c6c5aa624f21265/detection&quot;&gt;ebf6d5d12f4d18cef9456a363991ba028329cd25ee3908101c6c5aa624f21265&lt;/a&gt;), then we get a somewhat surprising result:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python get_timestamp_pefile.py ebf6d5d12f4d18cef9456a363991ba028329cd25ee3908101c6c5aa624f21265
1992-06-19 22:40:53 +00:00 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;UTC&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;10436 days old&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The value is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A426275&lt;/code&gt;, which translates to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1992-06-19 22:40:53&lt;/code&gt;. This is not the expected Delphi timestamp &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A425E19&lt;/code&gt;. The most significant two bytes are equal (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A42&lt;/code&gt;), but the least significant two bytes / WORD is different. A possible explanation is that the timestamp was modified.&lt;/p&gt;

&lt;h3 id=&quot;read-pe-timestamps-with-lief&quot;&gt;Read PE timestamps with lief&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://lief.quarkslab.com/doc/latest/&quot;&gt;lief&lt;/a&gt; is another project to parse and modify PE files. Its core is written in C++ but there is a Python module as well. In contrast to pefile, lief can parse various executable formats such as &lt;a href=&quot;https://lief.quarkslab.com/doc/latest/tutorials/03_elf_change_symbols.html&quot;&gt;ELF&lt;/a&gt; and &lt;a href=&quot;https://lief.quarkslab.com/doc/latest/tutorials/11_macho_modification.html&quot;&gt;MachO&lt;/a&gt; while offering the same interface. Therefore, lief works well in projects that do not only target one platform. Furthermore, lief added several advanced features not yet implemented in pefile like working with &lt;a href=&quot;https://lief.quarkslab.com/doc/latest/tutorials/13_pe_authenticode.html&quot;&gt;PE Authenticode&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;read-coff-file-header-timestamps&quot;&gt;Read COFF File Header timestamps&lt;/h4&gt;

&lt;p&gt;The following code snippet shows the script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get_timestamp_lief.py&lt;/code&gt; that reads the PE Header field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; (called by lief &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;time_date_stamps&lt;/code&gt;) and converts it to UTC time (analogous to the pefile script of the previous section). Just import the module &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lief&lt;/code&gt; and open the binary with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parse&lt;/code&gt; method. The COFF File Header is accessible via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;header&lt;/code&gt; and the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; is called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;time_date_stamps&lt;/code&gt; in lief.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt;
 &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;lief&lt;/span&gt;
 &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lief&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time_date_stamps&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;utc_time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;utcfromtimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;t_delta&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utc_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;days&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;utc_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strftime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%Y-%m-%d %H:%M:%S +00:00 (UTC)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; (&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t_delta&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; days old)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;read-delphi-timestamps&quot;&gt;Read Delphi timestamps&lt;/h4&gt;

&lt;p&gt;Again, Delphi binaries that were compiled with Delphi 4 – Delphi 2006 had a bug: all of them had the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; value in the COFF File Header. However, there is a way (as described by &lt;a href=&quot;https://www.hexacorn.com/blog/2014/12/05/the-not-so-boring-land-of-borland-executables-part-1/&quot;&gt;Hexacorn&lt;/a&gt;) to get the compilation timestamp via the field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; in the resource directory (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_RESOURCE_DIRECTORY&lt;/code&gt;). Be aware that in Delphi binaries this field does not hold an epoch timestamp but rather a MS DOS timestamp.&lt;/p&gt;

&lt;p&gt;The following script reads a possible compilation timestamp for Delphi binaries. It borrows the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from_msdos&lt;/code&gt; from the project &lt;a href=&quot;https://github.com/digitalsleuth/time_decode&quot;&gt;Time Decode&lt;/a&gt; to convert the MS DOS timestamp to a readable string. First, it checks if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeDateStamp&lt;/code&gt; field of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IMAGE_FILE_HEADER&lt;/code&gt; equals the expected Delphi timestamp (seen in Delphi 4 – Delphi 2006 binaries) in lines 26 – 27. In this case, it checks if there are resources with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;binary.has_resources&lt;/code&gt; in line 29 and then gets resource directory with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;binary.resources&lt;/code&gt; in line 30. Finally, it gets the timestamp and converts it from MS DOS format to a readable string.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt;
 &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;lief&lt;/span&gt;
 &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

 &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;from_msdos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msdos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
     &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;taken from https://github.com/digitalsleuth/time_decode&quot;&quot;&quot;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;msdos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msdos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;{0:032b}&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msdos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:]:&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;dos_year&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1980&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;dos_month&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;dos_day&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;dos_hour&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;dos_min&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;dos_sec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dos_year&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1970&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dos_month&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dos_day&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dos_hour&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dos_min&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dos_sec&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;dt_obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dos_year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dos_month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dos_day&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dos_hour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dos_min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dos_sec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dt_obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strftime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;%Y-%m-%d %H:%M:%S&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Not a valid MS DOS timestamp&quot;&lt;/span&gt;

 &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lief&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time_date_stamps&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x2a425e19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Found binary compiled with Delphi 4 - Delphi 2006&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_resources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time_date_stamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
             &lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time_date_stamp&lt;/span&gt;
             &lt;span class=&quot;n&quot;&gt;dos_time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from_msdos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;_IMAGE_RESOURCE_DIRECTORY: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; -&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dos_time&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
             &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Timestamp of _IMAGE_RESOURCE_DIRECTORY is set to zero&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Binary has no resources.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;utc_time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;utcfromtimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Likely not a binary compiled with Delphi 4 - Delphi 2006&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos; -&amp;gt; &apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utc_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strftime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%Y-%m-%d %H:%M:%S +00:00 (UTC)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I tested it with an older Azorult (version 3.1) sample:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; python lief_delphi_ts.py azor3.1_patched_fixed.pe32                                                 
Found binary compiled with Delphi 4 - Delphi 2006
 _IMAGE_RESOURCE_DIRECTORY: 0x4cbe1371 -&amp;gt; 2018-05-30 02:27:34
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This looks a lot better. First, it matches the Delphi timestamp in the COFF File Header as expected. Luckily, there are resources and hence a &lt;strong&gt;&lt;em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_IMAGE_RESOURCE_DIRECTORY&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt; struct. The date &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2018-05-30&lt;/code&gt; seems to be a reasonable compilation timestamp for an Azorult version 3.1 sample.&lt;/p&gt;

&lt;h2 id=&quot;what-can-we-do-with-pe-timestamps&quot;&gt;What can we do with PE timestamps?&lt;/h2&gt;

&lt;p&gt;Now that we know where we can find PE timestamps and how we can read them using a wide range of tools, this section answers the final question: what can we do with PE timestamps? The following sections should inspire what we can do with them but also warn you once more that relying solely on this feature alone can certainly be very misleading.&lt;/p&gt;

&lt;h3 id=&quot;use-case-determine-probable-intrusion-date&quot;&gt;Use case: Determine probable intrusion date&lt;/h3&gt;

&lt;p&gt;If timestamps found in PE files were always reliable, they could be used to determine probable intrusion dates, &lt;strong&gt;especially if you are an observer on the outside&lt;/strong&gt;. For instance, it is &lt;a href=&quot;/never-upload-ransomware-samples-to-the-internet/&quot;&gt;common to hunt for ransomware&lt;/a&gt; samples on online cloud services like VirusTotal as these samples contain information that can identify the possible victim.&lt;/p&gt;

&lt;p&gt;For instance, CL0P ransomware &lt;a href=&quot;https://www.telekom.com/en/blog/group/article/inside-of-cl0p-s-ransomware-operation-615824&quot;&gt;timestamps are reliable&lt;/a&gt;. Firstly, &lt;a href=&quot;https://www.telekom.com/en/blog/group/article/inside-of-cl0p-s-ransomware-operation-615824&quot;&gt;incident response engagements&lt;/a&gt; suggest this. Secondly, the temporal correlation between the sample timestamps, the first submission to VirusTotal, and the publication of the victim’s data &lt;a href=&quot;https://www.telekom.com/en/blog/group/article/inside-of-cl0p-s-ransomware-operation-615824&quot;&gt;on their leak portal&lt;/a&gt; seem to be in line. If you combine these factors then you can likely estimate the deployment date of the ransomware from the outside.&lt;/p&gt;

&lt;p&gt;Nevertheless, this is in theory not limited to ransomware deployments. PE timestamps of samples that were used in a certain intrusion (possible one in the interest of the public domain) can be utilized to estimate the intrusion dates of nation-state actors like &lt;a href=&quot;https://malpedia.caad.fkie.fraunhofer.de/details/win.winnti&quot;&gt;Winnti&lt;/a&gt;. Samples of Winnti typically contain information such as a &lt;a href=&quot;https://www.welivesecurity.com/wp-content/uploads/2019/10/ESET_Winnti.pdf&quot;&gt;C&amp;amp;C domain and a campaign ID&lt;/a&gt; that can be used to guess possible victims. In addition, PE timestamps seem to be &lt;a href=&quot;https://quointelligence.eu/2020/04/winnti-group-insights-from-the-past/&quot;&gt;reliable to a certain degree&lt;/a&gt; to estimate at least the year of the intrusion.&lt;/p&gt;

&lt;h3 id=&quot;use-case-timeline-of-threat-actors-campaigns-and-threat-actors-working-hours&quot;&gt;Use case: Timeline of threat actor’s campaigns and threat actor’s working hours&lt;/h3&gt;

&lt;p&gt;As stated by Bartholomew &amp;amp; Guerrero-Saade in their exceptional paper “&lt;a href=&quot;https://media.kasperskycontenthub.com/wp-content/uploads/sites/43/2017/10/20114955/Bartholomew-GuerreroSaade-VB2016.pdf&quot;&gt;Wave your false flags!&lt;/a&gt;“, timestamps allow for creating a timeline of a threat actor’s campaigns or deduce their working hours:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A great benefit of the Portable Executable file format is the inclusion of compilation times. Though these can be altered with ease, many samples include original timestamps. Beyond an obvious indication of an actor’s longevity, timestamps allow for an understanding of specific campaigns as well as the evolution of an actor’s toolkit throughout the years. With a large enough collection of related samples, it’s also possible to create a timeline of the campaign operators’ workday. Where these operate in any professional setting or with any semblance of discipline, it’s possible to match the normal peaks and troughs of a workday and pinpoint a general timezone for their operations.&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;Bartholomew &amp;amp; Guerrero-Saade – Wave your false flags!&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are at least two commonly plot types possible based on the PE timestamps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;timeline of the malware samples/families (see Page 32 of &lt;a href=&quot;https://www.fireeye.com/content/dam/fireeye-www/services/pdfs/mandiant-apt1-report.pdf&quot;&gt;Mandiant’s APT1 report&lt;/a&gt; for a great example)&lt;/li&gt;
  &lt;li&gt;heatmap by day of week and hour of day (similar to the &lt;a href=&quot;https://blog.exploratory.io/google-analytics-visualize-sessions-by-day-hour-with-heatmap-ed767f9386a8?gi=808c905fe174&quot;&gt;ones typically found in web traffic analysis&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bartholomew &amp;amp; Guerrero-Saade stated “&lt;em&gt;With a large enough collection of related samples&lt;/em&gt;” all these cool things can be done. Honestly, I don’t have a large number of samples for this blog post at hand. Nevertheless, I’ve plotted a tiny timeline of the different SDBBot versions published (based on the PE timestamps) in Summer 2020. The samples are on &lt;a href=&quot;https://bazaar.abuse.ch/browse.php?search=tag%3Asdbbot&quot;&gt;MalwareBazaar&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analyst-guide-to-pe-timestamps/ts_sdbbot_summer_2020.png&quot; alt=&quot;Timeline of PE timestamps vs versions of SDBBot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Of course, the is room for improvement, and not speaking of the horrible design. For instance, we could plot tiny red dots on the X-axis for every day the threat actor was active. In this case, this should give us a workday / weekend pattern.&lt;/p&gt;

&lt;h3 id=&quot;use-case-pinpoint-a-threat-actor-to-a-timezone&quot;&gt;Use case: Pinpoint a threat actor to a timezone&lt;/h3&gt;

&lt;p&gt;The previous section mentions that the timezone of a threat actor can be pinpointed based on PE timestamps. In order for this to work out, there are two requirements:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“&lt;em&gt;large enough collection of related samples&lt;/em&gt;” that we can attribute to the threat actor without a doubt&lt;/li&gt;
  &lt;li&gt;certain confidence that the threat actor did not tamper with the PE timestamps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is likely that the PE timestamps fall into a certain range if the threat actor works in a professional environment with regular office hours. Likely, most samples will be compiled within an 8 to 12 hours range, which maps to a 9 to 5 pattern plus/minus two hours. Furthermore, there are likely one or two days off like Saturday or Sunday. But this might depend on the cultural origin of the threat actor. For instance, &lt;a href=&quot;https://en.wikipedia.org/wiki/996_working_hour_system&quot;&gt;996 working hour system&lt;/a&gt; is common in the People’s Republic of China. In addition, there could also be thirty minutes and up to two hours of lunch breaks.&lt;/p&gt;

&lt;p&gt;If you can identify such a pattern, then you add/subtract the difference of hours so that this maps to the 9 AM to 5 PM range of a timezone. In case your plot does not reveal a 9 to 5 pattern, then there are still possible explanations. In case you can see two possible 9 to 5 patterns then this could indicate shift work.&lt;/p&gt;

&lt;p&gt;Finally, another warning example of why you should not blindly trust PE timestamps. Imagine that you’ve dozens of samples of a threat actor. You are pretty confident that this threat actor works normal working hours from 9 AM to 5 PM (GMT+0). You could assume that this threat actor may work in the United Kingdom or in Portugal if you blindly and solely rely on these timestamps.&lt;/p&gt;

&lt;p&gt;Suppose that later on, you’ve got additional information from incident response engagements. Now, it seems that the threat actor works from 12 PM to 8 PM (GMT+0). This would map from 9 AM to 5 PM (GMT+3). Possible countries would now be, for instance, Russia or Turkey. How can you really be sure that the threat actor did not manipulate the PE timestamps and subtracted three hours from each and every timestamp found in the PE files?&lt;/p&gt;
</description>
                <pubDate>Fri, 22 Jan 2021 06:00:00 +0000</pubDate>
                <link>https://tbarabosch.github.io/malware-analyst-guide-to-pe-timestamps/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/malware-analyst-guide-to-pe-timestamps/</guid>
                
                <category>malware-analysis</category>
                
                <category>pe-files</category>
                
                <category>forensics</category>
                
                <category>threat-intelligence</category>
                
                
            </item>
        
            <item>
                <title>Where to start tracking adversary infrastructure?</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Reviewed July 2026:&lt;/strong&gt; This resource list is kept for historical and conceptual value. Individual services, links, and company names may have changed since publication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Adversaries require infrastructure to support their operations and to ultimately achieve their goals like intelligence collection. Therefore, infrastructure is one of the four core features of the famous &lt;a href=&quot;https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf&quot;&gt;Diamond Model of Intrusion Analysis&lt;/a&gt;. The proactive detection of adversary infrastructure can help cyber threat intelligence (CTI) teams detect this infrastructure even before the adversary has utilized it.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The quintessence here is that we are all lazy humans with our personal preferences and tendencies. Therefore, operational security (OpSec) is sometimes neglected for greater comfort. Tracking adversary infrastructure is based on the idea that we take data from past intrusions, identify patterns, which we then search for in the future. This initial data from past intrusions may be primary source data from incident response engagements or secondary source data from CTI blogs. Today, there are numerous sources that we can leverage to detect future adversary infrastructure: either we rely on third-party services like &lt;a href=&quot;https://www.shodan.io/&quot;&gt;Shodan&lt;/a&gt; or &lt;a href=&quot;https://censys.io/&quot;&gt;Censys&lt;/a&gt;, to name a few, or we can run our own scanning infrastructure using, for instance, &lt;a href=&quot;https://github.com/robertdavidgraham/masscan&quot;&gt;MASSCAN&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This blog post lists curated resources for tracking adversary infrastructure. The first section &lt;em&gt;Infrastructure tracking basics&lt;/em&gt; lists introductory resources to get started. The next section &lt;em&gt;Examples of infrastructure tracking&lt;/em&gt; comprises a list of read-worthy resources that showcase how to use the techniques described in the previous section. The third section &lt;em&gt;Infrastructure tracking automation&lt;/em&gt; gives an overview of resources for those who wish to automate parts of the tracking process. Finally, I’ll present a list of (open source) tools and online services that are essential for this endeavor.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://censys.io/advanced-persistent-infrastructure-tracking/&quot;&gt;Advanced Persistent Infrastructure Tracking&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/0x3c7&quot;&gt;Nils Kuhnert&lt;/a&gt; @ &lt;a href=&quot;https://censys.io/resources/&quot;&gt;Censys Blog&lt;/a&gt;: This should be the first introductory article you read before you start tracking adversary infrastructure. It gives you the background on &lt;strong&gt;why&lt;/strong&gt; this actually works, e.g. different teams with different skillsets set up the infrastructure and operate it. Using the online service Censys as an example, it shows how to use HTTP headers to track CobaltStrike infrastructure in general and certificate data to track APT29’s infrastructure. The blog post concludes with a bunch of useful tips for beginners.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.domaintools.com/resources/blog/analyzing-network-infrastructure-as-composite-objects&quot;&gt;Analyzing Network Infrastructure as Composite Objects&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/jfslowik&quot;&gt;Joe Slowik&lt;/a&gt; / &lt;a href=&quot;https://www.domaintools.com/resources/blog/&quot;&gt;Domains Tools Blog&lt;/a&gt;: Good introductory post on malicious network infrastructure, mostly focusing on domain names, IP addresses, and SSL/TLS certificates. It encourages analysts not to treat these types of IoCs as atomic objects but rather as composite objects. CTI analysts should see the identification of new IoCs as an intermediate objective and leverage them for their long-term objective of understanding an adversary’s behavior and tendencies.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.domaintools.com/resources/blog/extrapolating-adversary-intent-through-infrastructure&quot;&gt;Extrapolating Adversary Intent Through Infrastructure&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/jfslowik&quot;&gt;Joe Slowik&lt;/a&gt; / &lt;a href=&quot;https://www.domaintools.com/resources/blog/&quot;&gt;Domains Tools Blog&lt;/a&gt;: Often adversaries leverage themes in domain creation. For instance, this may help them to blend in with expected traffic on their victims’ networks (e.g. Microsoft-themed domain names). In this blog post, three case studies show how important the themes of domain names are. By studying them, we can infer the intentions and purposes of the adversary.&lt;/li&gt;
  &lt;li&gt;Attribution of Advanced Persistent Threats: How to Identify the Actors Behind Cyber-Espionage (ISBN: 978-3662613122) by &lt;a href=&quot;https://twitter.com/Timo_Steffens&quot;&gt;Timo Steffens&lt;/a&gt;: This book is the most comprehensive resource on threat actor attribution. Of course, infrastructure plays an important role in attribution. Therefore, a whole chapter is dedicated to this topic (Chapter 4). Personally, I would recommend this book to every CTI analyst.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;examples-of-infrastructure-tracking&quot;&gt;Examples of infrastructure tracking&lt;/h2&gt;

&lt;p&gt;There are several blog posts that prove that tracking adversary infrastructure works. It doesn’t matter if it’s APT or cybercrime infrastructure. The following are read-worthy articles that show how to apply the acquired knowledge to real-world data.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.fireeye.com/content/dam/fireeye-www/services/pdfs/mandiant-apt1-report.pdf&quot;&gt;APT1- Exposing One of China’s Cyber Espionage Units&lt;/a&gt; by Mandiant: This report originally published in 2013 was unprecedented. It showed that a private-sector entity can deliver a very precise attribution of a nation-state actor. Furthermore, it introduced the three magical letters A-P-T to a wider audience. I believe that every CTI analyst should read this report, alone due to its historical value. The infrastructure tracking part starts on page 39 and comprises 11 pages.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.randhome.io/blog/2020/12/20/analyzing-cobalt-strike-for-fun-and-profit/&quot;&gt;Analyzing Cobalt Strike for Fun and Profit&lt;/a&gt; by Etienne Maynier @ &lt;a href=&quot;https://www.randhome.io/&quot;&gt;randhome.io&lt;/a&gt;: This article shows how the fingerprinting tools JARM and Shodan can be combined in order to unearth a significant part of live CobaltStrike CC servers. The servers are then contacted, Beacons are downloaded, and configuration information is extracted.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.domaintools.com/resources/blog/identifying-critical-infrastructure-targeting-through-network-creation&quot;&gt;Identifying Critical Infrastructure Targeting through Network Creation&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/jfslowik&quot;&gt;Joe Slowik&lt;/a&gt; / &lt;a href=&quot;https://www.domaintools.com/resources/blog/&quot;&gt;Domains Tools Blog&lt;/a&gt;: This blog post shows how to use previous findings from other researchers in order to pivot on them to find further infrastructure. They focus on the infrastructure of APT34 / OilRig. At first, they pivot on email addresses that this actor utilized to register domains. One of the email addresses registered several domains that follow certain patterns, e.g. mimicking corporate/executive themes or referring to the People’s Republic of China (PRC). Pivoting on these domains allowed them to find further emails sent from this aforementioned infrastructure in several malware repositories. Subsequently, they unveiled a previously unknown phishing campaign. Even though there is no final conclusion on whether this is a related or completely separated phishing campaign, this finding may help other researchers in their future investigations.&lt;/li&gt;
  &lt;li&gt;Sandworm: A New Era of Cyberwar and the Hunt for the Kremlin’s Most Dangerous Hackers (ISBN: 978-0525564638) by Andy Greenberg: Even though this is a nonfiction but also nontechnical book, it is a good read for long and cold winter evenings with some tracking of adversary infrastructure. This book tells the story of the hunt for the nation-state actor Sandworm, who is responsible for many high-profile cyber operations in recent history. Many reputable CTI analysts tell their part of their story.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;infrastructure-tracking-automation&quot;&gt;Infrastructure tracking automation&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.fireeye.com/blog/threat-research/2020/07/scandalous-external-detection-using-network-scan-data-and-automation.html&quot;&gt;SCANdalous&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/x04steve&quot;&gt;Aaron Stephens&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/anthomsec&quot;&gt;Andrew Thompson&lt;/a&gt; / &lt;a href=&quot;https://www.fireeye.com/blog/threat-research.html&quot;&gt;FireEye Threat Research Blog&lt;/a&gt;: SCANdalous is an in-house system of FireEye that proactively detects adversary infrastructure. However, the analyst is still in the loop. It is a very interesting example for those who wish to automate infrastructure tracking. Its main idea is to observe and collect data on adversaries (e.g. via incident response engagements), to identify patterns and characteristics (e.g. regarding the HTTP headers), to craft queries (e.g. for Shodan), and to monitor new results over time. There are also a &lt;a href=&quot;https://www.youtube.com/watch?v=x1tEOkY-7JE&quot;&gt;video presentation&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/aaronst/talks/master/scanttouchthis.pdf&quot;&gt;slides&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;tools&quot;&gt;Tools&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://nmap.org/&quot;&gt;Nmap&lt;/a&gt;: Nmap is a network scanner that discovers hosts, scans ports, and detects service versions as well as operating systems. It comprises a scripting engine called Nmap Scritping Engine (NSE). There are already many NSE scripts available, for instance, to detect &lt;a href=&quot;https://github.com/TKCERT/winnti-nmap-script&quot;&gt;Winnti infections&lt;/a&gt; or grab &lt;a href=&quot;https://github.com/whickey-r7/grab_beacon_config/blob/main/grab_beacon_config.nse&quot;&gt;CobaltStrike Beacon configurations&lt;/a&gt;. While versatile and well supported, it is not a solution to conduct mass scans. It is rather useful to, for example, scan suspicious hosts obtained from services like &lt;a href=&quot;https://www.shodan.io/&quot;&gt;Shodan&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/robertdavidgraham/masscan&quot;&gt;MASSCAN&lt;/a&gt;: MASSCAN is an Internet-scale port scanner. It is blazing fast so that it can transmit up to 10 million packets per second. Under the hood, MASSCAN transmits packets asynchronously and comes with its own TCP/IP stack. While it is great to conduct superficial scans of many machines, it is not suited for in-depth scans like Nmap.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/salesforce/jarm&quot;&gt;JARM&lt;/a&gt;: JARM is a tool for active fingerprinting of Transport Layer Security (TLS) server. There is a blog post that goes&lt;a href=&quot;http://Easily Identify Malicious Servers on the Internet with JARM&quot;&gt; into the details of JARM’s&lt;/a&gt; inner workings. Several online services like Shodan have added support for JARM. A great example of how to combine JARM and Shodan is &lt;a href=&quot;https://www.randhome.io/blog/2020/12/20/analyzing-cobalt-strike-for-fun-and-profit/&quot;&gt;Analyzing Cobalt Strike for Fun and Profit&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;online-services&quot;&gt;Online services&lt;/h2&gt;

&lt;p&gt;The following online services are essential tools for tracking adversary infrastructure. It is very unlikely that you have these capabilities in-house. Most of them offer free researcher accounts that usually come with a (very) limited daily quota. Nevertheless, this is sufficient for starters or for those who track only one or two adversaries very closely. Especially if you are planning to automate the tracking process, you require paid accounts with larger daily quotas.&lt;/p&gt;

&lt;h3 id=&quot;search-engines&quot;&gt;Search engines&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.shodan.io/&quot;&gt;Shodan&lt;/a&gt;: Shodan crawls the Internet for publicly accessible devices and lets its users search within this data. &lt;a href=&quot;https://help.shodan.io/the-basics/search-query-fundamentals&quot;&gt;Search queries&lt;/a&gt; over the web interface allow many modifiers, but their real power lies in its &lt;a href=&quot;https://developer.shodan.io/api&quot;&gt;REST API&lt;/a&gt;. There is also a &lt;a href=&quot;https://shodan.readthedocs.io/en/latest/&quot;&gt;Python library&lt;/a&gt; for this search engine.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://censys.io/&quot;&gt;Censys&lt;/a&gt;: Censys offers a quite comprehensive view of the current state of the Internet. It allows searching for &lt;a href=&quot;https://censys.io/ipv4&quot;&gt;IPv4 hosts&lt;/a&gt;, &lt;a href=&quot;https://censys.io/domain&quot;&gt;domains&lt;/a&gt;, and &lt;a href=&quot;https://censys.io/certificates&quot;&gt;certificates&lt;/a&gt;. There is of course a REST API to automate searches.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.binaryedge.io/&quot;&gt;BinaryEdge&lt;/a&gt;: BinaryEdge is another service that offers a vast amount of Internet-wide data to search in. Naturally, they offer a &lt;a href=&quot;https://docs.binaryedge.io/api-v2/&quot;&gt;REST API &lt;/a&gt;for automation purposes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;passive-databases&quot;&gt;Passive Databases&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.riskiq.com/&quot;&gt;RiskIQ PassiveTotal&lt;/a&gt;: PassiveTotal aggregates web data from different sources (e.g. passive DNS, WHOIS, SSL/TLS certificates). This (historical) data allows us to quickly pivot on these sources and identify further adversary infrastructure.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.circl.lu/services/passive-ssl/&quot;&gt;CIRCL Passive SSL&lt;/a&gt;: Passive SSL is a historical database with historical X.509 certificates seen per IP address. It is only accessible via its REST API but they offer also a Python library called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pypssl&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
                <pubDate>Fri, 15 Jan 2021 22:18:33 +0000</pubDate>
                <link>https://tbarabosch.github.io/resources-tracking-adversary-infrastructure/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/resources-tracking-adversary-infrastructure/</guid>
                
                <category>threat-intelligence</category>
                
                <category>infrastructure-tracking</category>
                
                <category>osint</category>
                
                <category>cti</category>
                
                
            </item>
        
            <item>
                <title>The malware analyst&apos;s guide to aPLib decompression</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Reviewed July 2026:&lt;/strong&gt; This post is kept for the analysis workflow and file-format notes. External project links and tool versions may have changed since publication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://ibsensoftware.com/products_aPLib.html&quot;&gt;aPLib&lt;/a&gt; is a compression library that is very easy to use and integrate with C/C++ projects. It is a pure &lt;a href=&quot;https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch&quot;&gt;LZ-based&lt;/a&gt; compression library. There is also an executable packer based on it called &lt;a href=&quot;http://ibsensoftware.com/products_aPACK.html&quot;&gt;aPACK.&lt;/a&gt; Due to its ease of use and tiny footprint, it’s a very popular library utilized by many malware families like &lt;a href=&quot;https://labs.sentinelone.com/writing-malware-configuration-extractors-isfb-ursnif/&quot;&gt;ISFB/Ursnif&lt;/a&gt;, &lt;a href=&quot;https://github.com/bowlofstew/rovnix/blob/master/bootkit/Inc/aplib.h&quot;&gt;Rovnix&lt;/a&gt;, and many more. Knowledge about aPLib detection and aPLib decompression is crucial for every malware analyst.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;This blog post dives into many internals of aPlib, explains how to detect aPLib compression with your bare eyes as well as YARA, and finally shows you how to decompress aPLib compressed blobs with several tools.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ibsensoftware.com/products_aPLib.html&quot;&gt;aPLib&lt;/a&gt; is a library implementing the compression algorithm found in the executable compressor &lt;a href=&quot;http://ibsensoftware.com/products_aPACK.html&quot;&gt;aPACK&lt;/a&gt;. It is a pure &lt;a href=&quot;https://en.wikipedia.org/wiki/LZ77_and_LZ78&quot;&gt;LZ compression&lt;/a&gt; implementation. The library aPLib is known for its fast decompression speed and tiny footprint of the decompression code. At the time of writing, the current version was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v1.1.1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The objective of this section is not to explain how the actual compression algorithm at aPLib’s core works, but rather to give a quick overview of the library itself (project structure, relevant functions, relevant structs).&lt;/p&gt;

&lt;p&gt;Since you’ll likely encounter aPLib decompression during malware analysis, I’ll focus on the decompression portion of aPLib in the following. Nevertheless, this blog post should be also valuable for those who look into aPLib compression.&lt;/p&gt;

&lt;h3 id=&quot;the-aplib-library&quot;&gt;The aPLib library&lt;/h3&gt;

&lt;p&gt;The library can be found at the &lt;a href=&quot;http://ibsensoftware.com/files/aPLib-1.1.1.zip&quot;&gt;author’s website&lt;/a&gt;. It comprises a lot of valuable information. First and foremost, there is the source code for decompression (but not compression!):&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;└── src
     ├── 32bit
     │   ├── crc32.asm
     │   ├── depack.asm
     │   ├── depackf.asm
     │   ├── depacks.asm
     │   ├── scheck.asm
     │   ├── sdepack.asm
     │   ├── sgetsize.asm
     │   └── spack.asm
     ├── 64bit
     │   ├── crc32.asm
     │   ├── depack.asm
     │   ├── depackf.asm
     │   ├── depacks.asm
     │   ├── scheck.asm
     │   ├── sdepack.asm
     │   ├── sgetsize.asm
     │   └── spack.asm
     ├── depack.c
     ├── depack.h
     ├── depacks.c
     └── depacks.h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Second, there is some additional user documentation (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;html&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chm&lt;/code&gt;). Third, there are libraries to statically or dynamically link against. Several platforms are supported including Windows:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;├── lib
 │   ├── dll
 │   │   ├── aplib.dll
 │   │   ├── aplib.h
 │   │   └── aplib.lib
 │   ├── dll64
 │   │   ├── aplib.dll
 │   │   ├── aplib.h
 │   │   └── aplib.lib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The library offers several decompression functions that fall in three classes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack_asm&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack_asm_fast&lt;/code&gt; assume valid input data and may crash if the input is invalid&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack_safe&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack_asm_safe&lt;/code&gt; catch decompression errors and do not crash on invalid input data&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aPsafe_depack&lt;/code&gt; is a function wrapper adding a header to the compressed data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At their core, they all utilize the LZ-based compression algorithm. In the following sections, I’ll have a look at each of the three classes.&lt;/p&gt;

&lt;h3 id=&quot;ap_depack&quot;&gt;aP_depack*&lt;/h3&gt;

&lt;p&gt;The decompression function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack&lt;/code&gt; decompresses a compressed binary blob. The counterpart of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack_safe&lt;/code&gt; is the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aPsafe_pack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The following function signature is defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;depack.h&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;aP_depack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The functions of this class assume that the compressed data is valid. This saves some sanity checks, which in turn results in faster decompression and a smaller footprint of the decompression code. However, it is likely that they crash if an error is encountered.&lt;/p&gt;

&lt;h3 id=&quot;ap_depack_safe&quot;&gt;aP_depack_safe*&lt;/h3&gt;

&lt;p&gt;The functions of this class solely add additional sanity checks. If they encounter an error condition, they return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;APLIB_ERROR&lt;/code&gt; (defined as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xFFFFFFFF&lt;/code&gt;). Furthermore, they require the length of the input (compressed data) and the size of the output (decompressed data) as seen in the signature of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack_safe&lt;/code&gt; function:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;aP_depack_safe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                             &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;srclen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                             &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                             &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dstlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Otherwise, they are equivalent to the functions from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack*&lt;/code&gt; class.&lt;/p&gt;

&lt;h3 id=&quot;apsafe_depack&quot;&gt;aPsafe_depack&lt;/h3&gt;

&lt;p&gt;The decompression function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aPsafe_depack&lt;/code&gt; decompresses a compressed binary blob safely. It is a wrapper around the functions of the class. The counterpart of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aPsafe_depack&lt;/code&gt; is the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aPsafe_pack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The function signature of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aPsafe_depack&lt;/code&gt; resembles the signature of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aP_depack_safe&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;aPsafe_depack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                             &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;srclen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                             &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                             &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dstlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aPsafe_depack&lt;/code&gt; requires that the compressed blob starts with a header. This header comprises additional information regarding the blob. This is for example very useful if we want to send an aPLib compressed blob over the network. The header structure looks like the following struct:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aPLib_header&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packed_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packed_crc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;orig_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;orig_crc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The struct &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aPLib_header&lt;/code&gt; has a size of 24 bytes. This holds on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x64&lt;/code&gt; systems. But there are several checks in the library that ensure that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;header_size&lt;/code&gt; is at least 24 bytes. The following screenshot shows a PE executable packed with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appack&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analysts-guide-to-aplib-decompression/ap32_example_exe.png&quot; alt=&quot;aPLib compressed PE executable: 24 bytes header (magic highlighted), followed by compressed payload&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can see the magic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AP32&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x32335041&lt;/code&gt;), directly followed by the header size of 0x18 / 24 bytes. The next four DWORDs are the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packed_size&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packed_crc&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orig_size&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orig_crc&lt;/code&gt;. After the header comes the payload, which starts in this case with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M8Z&lt;/code&gt; since we compressed a PE executable. We will use this fact later on for detection.&lt;/p&gt;

&lt;h2 id=&quot;detect-if-a-binary-statically-links-against-aplib&quot;&gt;Detect if a binary statically links against aPLib&lt;/h2&gt;

&lt;p&gt;Detecting if a binary comprises the capability of aPLib compression/decompression is straightforward in the case it dynamically links against aPLib and it comprises a valid IAT (Import Address Table). However, in the case of custom/malicious binaries, it typically statically links against aPLib.&lt;/p&gt;

&lt;p&gt;Still, there are many ways how we can detect this. First, we’ve already seen constants like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AP32&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x32335041&lt;/code&gt;), which we could leverage to detect aPLib. But there are also several strings present that refer to aPLib itself or its author (Jørgen Ibsen) as seen in the following screenshot:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analysts-guide-to-aplib-decompression/aplib_statically_linked.png&quot; alt=&quot;Strings that refer to aPLib decompression / compression capabilities in a binary.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These ASCII strings are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“aPLib v1.1.1 – the smaller the better :)”&lt;/li&gt;
  &lt;li&gt;“Copyright (c) 1998-2014 Joergen Ibsen, All Rights Reserved.”&lt;/li&gt;
  &lt;li&gt;More information: http://www.ibsensoftware.com/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another way would be detection via matching the assembly code. Tools like &lt;a href=&quot;https://github.com/fox-it/mkYARA&quot;&gt;mkYARA&lt;/a&gt; can help you to generate (strict/relaxed) YARA rules for assembly functions/algorithms.&lt;/p&gt;

&lt;p&gt;However, at this point, I do not want to reinvent the wheel and I just refer to one of the freely available YARA rules like the &lt;a href=&quot;https://github.com/x64dbg/yarasigs/blob/master/packer.yara&quot;&gt;one from “_pusher_”&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aPLib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Jorgen&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Ibsen&lt;/span&gt;               
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;             
 &lt;span class=&quot;nl&quot;&gt;meta:&lt;/span&gt;        
 &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;_pusher_&quot;&lt;/span&gt;          
 &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;2016-09&quot;&lt;/span&gt;            
 &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;www.ibsensoftware.com/products_aPLib.html&quot;&lt;/span&gt;              
 &lt;span class=&quot;nl&quot;&gt;strings:&lt;/span&gt;            
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;44&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;39&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B3&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;         
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B3&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B3&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B3&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;61&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;94&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F9&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FA&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D9&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;04&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;04&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;43&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;         
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F9&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FA&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D9&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;04&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;04&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;        
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a6&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B3&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B3&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D9&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D3&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D3&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D3&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FA&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D9&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B3&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F9&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;43&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a9&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FA&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D9&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;04&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;04&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;43&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B3&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B3&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AC&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
 &lt;span class=&quot;c1&quot;&gt;//taken from r!sc aspr unpacker,       &lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a11&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;88&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;07&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;47&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EF&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D6&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;57&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;07&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;88&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;07&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;47&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B8&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C0&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EA&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B9&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EA&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;56&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F5&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E9&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;58&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B9&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EA&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;56&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E9&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C1&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;56&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E9&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;06&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D1&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;56&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F0&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A4&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FF&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;89&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;61&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
 &lt;span class=&quot;nl&quot;&gt;condition:&lt;/span&gt;           
 &lt;span class=&quot;n&quot;&gt;any&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;them&lt;/span&gt;       
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Nevertheless, there is still the possibility that all strings are overwritten, constants like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AP32&lt;/code&gt; are changed or are dynamically computed. Just remember that having not a match does not rule out aPLib usage completely but it makes it very unlikely.&lt;/p&gt;

&lt;h2 id=&quot;detect-aplib-compression-with-your-bare-eyes-and-yara&quot;&gt;Detect aPLib compression with your bare eyes and YARA&lt;/h2&gt;

&lt;p&gt;The following three sections shows you how to detect aPLib compression with your bare eyes and suggest several YARA rules to automate detection.&lt;/p&gt;

&lt;h3 id=&quot;aplib-header&quot;&gt;aPLib header&lt;/h3&gt;

&lt;p&gt;If the compressed blob is safely packed, then it is quite easy to find them within larger blobs. All we need to do is looking for the aPLib magic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AP32&lt;/code&gt; and the default header size of 0x18:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analysts-guide-to-aplib-decompression/ap32_example_exe.png&quot; alt=&quot;aPLib compressed PE executable: 24 bytes header (magic highlighted), followed by compressed payload&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This boils down to searching for the byte sequence &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4150333218000000&lt;/code&gt;. We can write a quick and dirty YARA signature:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aplib_compressed_blob_with_header&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;nl&quot;&gt;meta:&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Thomas Barabosch&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;20200109&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Detects aPLib compressed blobs that comprise an aPLib header.&quot;&lt;/span&gt;
     &lt;span class=&quot;nl&quot;&gt;strings:&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aplib_compressed_with_header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;nl&quot;&gt;condition:&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aplib_compressed_with_header&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;compressed-pe-executables-without-aplib-header&quot;&gt;Compressed PE executables without aPLib header&lt;/h3&gt;

&lt;p&gt;However, as a malware analyst, you will stumble upon aPLib compressed blobs that do not comprise an aPLib header very frequently. At least, the good news is that the trained eye can easily spot aPLib compressed PE files. These blobs of compressed PE files do not start with the classic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MZ&lt;/code&gt; magic but with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M8Z&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analysts-guide-to-aplib-decompression/aplib_compressed.png&quot; alt=&quot;detect aPLib compression by searching for M8Z in ascii.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you know that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M8Z&lt;/code&gt; means aPLib compression, it makes sense to write a small YARA signature to detect this in the future. Here I assume that we dumped a blob from, for instance, the heap, and the magic is at the beginning of the file:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aplib_compressed_pe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;nl&quot;&gt;meta:&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Thomas Barabosch&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;20201226&quot;&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Detects aPLib compressed PE files, e.g. from memory dumps.&quot;&lt;/span&gt;
     &lt;span class=&quot;nl&quot;&gt;strings:&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mz_compressed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;M8Z&quot;&lt;/span&gt;
     &lt;span class=&quot;nl&quot;&gt;condition:&lt;/span&gt;
         &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mz_compressed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;compressed-elf-executables-without-aplib-header&quot;&gt;Compressed ELF executables without aPLib header&lt;/h3&gt;

&lt;p&gt;Furthermore, I compressed a couple of ELF x64 files with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appack&lt;/code&gt;. I wanted to see if there is also a pattern that gives aPLib compression away. If we byte-compare the output of two compressed files, then we will see the following:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analysts-guide-to-aplib-decompression/elf_aplib_compare.png&quot; alt=&quot;Two ELF files compressed with aPLib in comparison.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Both compressed blobs start with the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AP32&lt;/code&gt; magic and the default header size of 0x18. Of course, the next four DWORDs are the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packed_size&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packed_crc&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orig_size&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orig_crc&lt;/code&gt; are completely different. But then there are 10 bytes that are equal: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x7F07454C4602011E1501&lt;/code&gt;. These bytes include the ELF magic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ELF&lt;/code&gt;, which is not at the beginning but does not get disfigured like the PE magic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MZ&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M8Z&lt;/code&gt;. Right now, I am not sure if this is a consistent behavior across all ELF files or just for ELF x64 files.&lt;/p&gt;

&lt;p&gt;Again, we can write a YARA rule for this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rule aplib_compressed_elf_executable {
     meta:
         author = &quot;Thomas Barabosch&quot;
         version = &quot;20200109&quot;
         description = &quot;Detects aPLib compressed ELF executables. Note that there may be a aPLib header starting 24 bytes BEFORE the match!&quot;
     strings:
         $aplib_compressed_elf = { 7F 07 45 4C 46 02 01 1E }
     condition:
         $aplib_compressed_elf
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The YARA rules that I’ve presented here leave room for improvement. For example, we can check for cases where we have an aPLib header followed by a compressed PE executable, and so on. Be creative and let me know what you’ve found out!&lt;/p&gt;

&lt;h2 id=&quot;aplib-decompression&quot;&gt;aPLib decompression&lt;/h2&gt;

&lt;p&gt;Finally, we’ve learned so much about aPLib compression, how to spot it with our bare eyes and detect it with YARA. But there is one final piece missing: we need to talk about aPLib decompression. The following sections show you how to achieve aPLib decompression with three different tools.&lt;/p&gt;

&lt;h3 id=&quot;aplib-decompression-with-apack&quot;&gt;aPLib decompression with apack&lt;/h3&gt;

&lt;p&gt;Before looking at more complex scenarios, we can always resort to the tools that come with &lt;a href=&quot;http://ibsensoftware.com/products_aPLib.html&quot;&gt;aPLib&lt;/a&gt;. The library comes with an example tool called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appack&lt;/code&gt;. The source of this tool is stored under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;examples/appack.c&lt;/code&gt; and there are several &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make&lt;/code&gt; files for various platforms. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appack&lt;/code&gt; offers two commands &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;appack, aPLib compression library example
 Copyright 1998-2014 Joergen Ibsen &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;www.ibsensoftware.com&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 Syntax:
 &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;Compress    :  appack c &amp;lt;file&amp;gt; &amp;lt;packed_file&amp;gt; &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
 &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;Decompress  :  appack d &amp;lt;packed_file&amp;gt; &amp;lt;depacked_file&amp;gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For instance, we can decompress an aPLib compressed blob with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d&lt;/code&gt; command as in the following snippet illustrated:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; appack d bin_ls.bin bin_ls
 appack, aPLib compression library example
 Copyright 1998-2014 Joergen Ibsen &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;www.ibsensoftware.com&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 Decompressed 66101 -&amp;gt; 151352 bytes &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0.01 seconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it, pretty simple. But this is not suitable for more complex scenarios, e.g. automation. Here, we have two options. First, we can use the aPLib library itself and write C programs. Second, we can automate aPLib decompression using Python.&lt;/p&gt;

&lt;h3 id=&quot;aplib-decompression-with-malduck&quot;&gt;aPLib decompression with malduck&lt;/h3&gt;

&lt;p&gt;Lately, I utilize &lt;a href=&quot;https://malduck.readthedocs.io/en/latest/&quot;&gt;Malduck&lt;/a&gt; a lot. So, let’s see how we can decompress an aPLib compressed blob with it. We can decompress these files with the following script based on &lt;a href=&quot;https://malduck.readthedocs.io/en/latest/&quot;&gt;Malduck&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;malduck&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sb&quot;&gt;`if len(argv) != 2:`&lt;/span&gt;
&lt;span class=&quot;sb&quot;&gt;`        print(&apos;Usage: aplib.py PATH_TO_APLIB_COMPRESSED_BUFFER&apos;)`&lt;/span&gt;
   &lt;span class=&quot;sb&quot;&gt;` `&lt;/span&gt;
    &lt;span class=&quot;sb&quot;&gt;`with open(argv[1], &apos;rb&apos;) as f:     `&lt;/span&gt;
        &lt;span class=&quot;sb&quot;&gt;`data = f.read()     `&lt;/span&gt;
        &lt;span class=&quot;sb&quot;&gt;`try:         `&lt;/span&gt;
            &lt;span class=&quot;sb&quot;&gt;`res = malduck.aplib(data)`&lt;/span&gt;
   &lt;span class=&quot;sb&quot;&gt;`         if res:`&lt;/span&gt;
&lt;span class=&quot;sb&quot;&gt;`                with open(argv[1] + &apos;_aplib_decompressed&apos;, &apos;wb&apos;) as g:`&lt;/span&gt;
&lt;span class=&quot;sb&quot;&gt;`                    g.write(res)`&lt;/span&gt;
&lt;span class=&quot;sb&quot;&gt;`            else:`&lt;/span&gt;
   &lt;span class=&quot;sb&quot;&gt;`             print(f&apos;Malduck did not decompress the buffer.&apos;)`&lt;/span&gt;
   &lt;span class=&quot;sb&quot;&gt;`     except Exception as e:`&lt;/span&gt;
&lt;span class=&quot;sb&quot;&gt;`            print(f&apos;Could not aplib decompress: {e}&apos;)`&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;&amp;lt;strong&amp;gt;main&amp;lt;/strong&amp;gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malduck.aplib&lt;/code&gt; &lt;a href=&quot;https://malduck.readthedocs.io/en/latest/compression.html&quot;&gt;may take a flag&lt;/a&gt; called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;headerless&lt;/code&gt;. This flag forces headerless compression and does not check for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AP32&lt;/code&gt; magic. It defaults to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Even though this script seems to be trivial, it is a perfect skeleton for more complex tasks that resolve around aPLib compression. For instance, if you’ve to write a script for extracting the malware configuration of a specific family, which happens to use aPLib as part of the way how it stores its configuration.&lt;/p&gt;

&lt;h3 id=&quot;aplib-decompression-with-aplib-ripper&quot;&gt;aPLib decompression with aplib-ripper&lt;/h3&gt;

&lt;p&gt;Another great tool is &lt;a href=&quot;https://github.com/herrcore/aplib-ripper&quot;&gt;aplib-ripper&lt;/a&gt; by &lt;a href=&quot;https://github.com/herrcore&quot;&gt;herrcore&lt;/a&gt;. It rips one or several aPLib compressed PE executables from a blob. It searches for the string &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M8Z&lt;/code&gt;, forces a headerless decompression, and finally verifies and trims the output with &lt;a href=&quot;https://github.com/erocarrera/pefile&quot;&gt;pefile&lt;/a&gt;.&lt;/p&gt;
</description>
                <pubDate>Fri, 08 Jan 2021 06:00:00 +0000</pubDate>
                <link>https://tbarabosch.github.io/malware-analysts-guide-to-aplib-decompression/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/malware-analysts-guide-to-aplib-decompression/</guid>
                
                <category>malware-analysis</category>
                
                <category>compression</category>
                
                <category>reverse-engineering</category>
                
                <category>yara</category>
                
                
            </item>
        
            <item>
                <title>The malware analyst&apos;s guide to zlib compression</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Reviewed July 2026:&lt;/strong&gt; This post is kept for the detection and analysis workflow. Version-specific tool output may have changed since publication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Malware often utilizes data compression like zlib or &lt;a href=&quot;/malware-analysts-guide-to-aplib-decompression/&quot;&gt;aPLib&lt;/a&gt;. There are several reasons for this behavior: first, it saves space and makes binaries smaller and network transfers faster. Second, it adds another layer of obfuscation as the malware analyst needs to detect the compression algorithm first. One of the widely adopted data compression libraries in malware is &lt;em&gt;zlib&lt;/em&gt;. For instance, malware families like &lt;a href=&quot;https://blogs.blackberry.com/en/2016/04/the-ghost-dragon&quot;&gt;GhostRat&lt;/a&gt; utilize zlib compression.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;a href=&quot;https://www.ietf.org/rfc/rfc1950.txt&quot;&gt;RFC1950&lt;/a&gt; defines the &lt;em&gt;ZLIB Compressed Data Format&lt;/em&gt;. &lt;a href=&quot;http://www.zlib.net/&quot;&gt;zlib&lt;/a&gt; is an open-source platform-independent compression library. At the time of writing, the current version was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.2.11&lt;/code&gt;. It uses the &lt;a href=&quot;https://en.wikipedia.org/wiki/DEFLATE&quot;&gt;deflate&lt;/a&gt; compression algorithm. Since the Deflate algorithm is out of the scope of this article, I can really recommend reading the &lt;a href=&quot;https://en.wikipedia.org/wiki/Deflate&quot;&gt;Wikipedia article&lt;/a&gt; about this compression algorithm.&lt;/p&gt;

&lt;h2 id=&quot;detect-if-a-binary-statically-links-against-zlib&quot;&gt;Detect if a binary statically links against zlib&lt;/h2&gt;

&lt;p&gt;Spotting zlib in malicious code is often times very easy. Since many malware authors do not remove strings, the name of &lt;em&gt;zlib&lt;/em&gt;‘s author (Marc Adler) and several error messages can be found in the binary:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler”&lt;/li&gt;
  &lt;li&gt;“inflate 1.2.8 Copyright 1995-2013 Mark Adler”&lt;/li&gt;
  &lt;li&gt;“incorrect header check”&lt;/li&gt;
  &lt;li&gt;“too many length or distance symbols”&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;detect-aplib-compression-with-your-bare-eyes&quot;&gt;Detect aPLib compression with your bare eyes&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.ietf.org/rfc/rfc1950.txt&quot;&gt;RFC1950&lt;/a&gt; states that a zlib stream has the following structure:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  0   1          
+---+---+          
|CMF|FLG|   (more--&amp;gt;)          
+---+---+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMF&lt;/code&gt; stands for &lt;em&gt;Compression Method&lt;/em&gt; and flags and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FLG&lt;/code&gt; stands for &lt;em&gt;FLaGs&lt;/em&gt;. These two fields can have the following values:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x7801&lt;/code&gt;, which stands for no compression or low compression&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x789C&lt;/code&gt;, which stands for default compression&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x78DA&lt;/code&gt;, which stand for best compression&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, if you spot these values at the beginning of a data stream, then chances are high that you are dealing with zlib compression.&lt;/p&gt;

&lt;p&gt;For instance, the following screenshot shows a &lt;em&gt;zlib&lt;/em&gt; compressed PE file using best compression (level 9). Note the marked first two bytes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x78DA&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/malware-analysts-guide-to-zlib-compression/pe_zlib_best.png&quot; alt=&quot;zlib compression of PE file with best compression level 9&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the following sections, I’ll review several ways how zlib compressed blobs can be uncompressed. First, I’ll show how to decompress them on the command line. Next, I’ll show you how to do zlib decompression with Python.&lt;/p&gt;

&lt;h3 id=&quot;zlib-decompression-on-the-command-line&quot;&gt;zlib decompression on the command line&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.openssl.org/&quot;&gt;OpenSSL&lt;/a&gt; can decompress &lt;em&gt;zlib&lt;/em&gt; compressed blobs. One of its &lt;em&gt;Cipher commands&lt;/em&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zlib&lt;/code&gt;. Using the flag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-d&lt;/code&gt; allows us to decompress blobs. The following example decompresses a zlib compressed PE file with &lt;em&gt;OpenSSL&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; file compressed.bin   
 compressed.bin: zlib compressed data
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; hexdump compressed.bin | &lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; 5
 0000000 da78 bdec 7809 c55b 30d5 f73c b16a d96c
 0000010 ec96 8e48 d89c 9289 c4d8 9b21 2ced 9024
 0000020 cb50 6c96 c889 9096 38e4 5366 5964 45b6
 0000030 4964 c968 5bc2 c04a d684 4375 8503 94be
 0000040 96d2 2db7 b42d 05b4 d65a 38b2 2584 2dd0
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; openssl zlib &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &amp;lt; compressed.bin &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; decompressed.bin 
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; file decompressed.bin 
 decompressed.bin: PE32+ executable &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;console&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; x86-64, &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;MS Windows
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; hexdump decompressed.bin | &lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; 5
 0000000 5a4d 0090 0003 0000 0004 0000 ffff 0000
 0000010 00b8 0000 0000 0000 0040 0000 0000 0000
 0000020 0000 0000 0000 0000 0000 0000 0000 0000
 0000030 0000 0000 0000 0000 0000 0000 0080 0000
 0000040 1f0e 0eba b400 cd09 b821 4c01 21cd 6854
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openssl zlib &amp;lt; INPUT &amp;gt; OUTPUT&lt;/code&gt; on the other hand allows us to compress binary files on the command line.&lt;/p&gt;

&lt;h3 id=&quot;zlib-decompression-with-python&quot;&gt;zlib decompression with Python&lt;/h3&gt;

&lt;p&gt;First, there is an entire &lt;a href=&quot;https://docs.python.org/2/library/zlib.html&quot;&gt;zlib module in the Python standard lib.&lt;/a&gt; That’s wonderful news since we can deal with all zlib compression/decompression issues in Python.&lt;/p&gt;

&lt;p&gt;The following code snippet shows how to decompress in case a &lt;em&gt;zlib&lt;/em&gt; header is present.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# https://docs.python.org/2/library/zlib.html
# if blob has a zlib header then the BLOB can be decompressed simply by calling
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;zlib&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;zlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decompress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BLOB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, a common obfuscation technique in malware is not using a &lt;em&gt;zlib&lt;/em&gt; header. The following code snippet shows how to deal with such blobs.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Source: http://stackoverflow.com/questions/561607/identifying-algorithms-in-binaries
# &quot;From my experience, most of the times the files are compressed using plain old Deflate.
# You can try using zlib to open them, starting from different offset to compensate for custom headers.
# Problem is, zlib itself adds its own header. In python (and I guess other implementations has that feature as well),
# you can pass to zlib.decompress -15 as the history buffer size (i.e. zlib.decompress(data,-15)),
# which cause it to decompress raw deflated data, without zlib&apos;s headers.&quot;
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;zlib&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;zlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decompress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BLOB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
                <pubDate>Sat, 02 Jan 2021 17:50:54 +0000</pubDate>
                <link>https://tbarabosch.github.io/malware-analysts-guide-to-zlib-compression/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/malware-analysts-guide-to-zlib-compression/</guid>
                
                <category>malware-analysis</category>
                
                <category>compression</category>
                
                <category>reverse-engineering</category>
                
                <category>yara</category>
                
                
            </item>
        
            <item>
                <title>Never upload ransomware samples to the Internet</title>
                <description>&lt;p&gt;Ransomware is our contemporary plague. It is a thriving business that attracts more and more cybercriminals every month. New ransomware gangs &lt;a href=&quot;https://www.zdnet.com/article/the-ransomware-landscape-is-more-crowded-than-you-think/&quot;&gt;sprout like mushrooms&lt;/a&gt;. These self-proclaimed “security teams” test the security of many small to large enterprises. But their unsolicited penetration tests are not that cheap. What they leave behind is pure mayhem and a huge bill for the victims. Furthermore, some attacks are really disgusting since ransomware gangs have targeted non-profit organizations, schools, and even hospitals on various occasions.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;There are hundreds of articles on the Internet about ransomware. For instance, the &lt;a href=&quot;https://www.nomoreransom.org/&quot;&gt;No More Ransom&lt;/a&gt; project educates on ransomware and offers help for victims. There are technical approaches to stop ransomware. Of course, the cyber security industry offers many products to protect against or mitigate ransomware. There are also community approaches like &lt;a href=&quot;https://github.com/Neo23x0/Raccine&quot;&gt;Raccine&lt;/a&gt; that help to stop ransomware.&lt;/p&gt;

&lt;p&gt;But once ransomware has been deployed on your network and you are in a ransomware incident, the headless chicken mode is very common. Unfortunately, there is one golden rule that I often see getting broken due to headless chicken mode:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;NEVER EVER upload ransomware samples to the Internet!&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;Some random incident responder&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even though I thought that this would be common knowledge, I’ve been proven wrong many times. Therefore, this is my take at explaining what information a ransomware sample contains, why you should never upload them to the Internet, and what actually happens if you upload them after all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audience&lt;/strong&gt;: This is definitively not an article for the seasoned Cyber Threat Intelligence analyst or the alike. This is an article dedicated to the ones in many smaller to medium businesses, schools, hospitals, and so on that do not have a dedicated security team: the non-security IT staff including system administrators that are typically the firsts to encounter the mess ransomware gangs leave behind. But also entry-level cyber security professionals can benefit from reading this article and understand how analysts hunt for ransomware samples.&lt;/p&gt;

&lt;h2 id=&quot;what-kind-of-information-does-a-ransomware-sample-contain&quot;&gt;What kind of information does a ransomware sample contain?&lt;/h2&gt;

&lt;p&gt;Ransomware is only the last step of a network intrusion. It may have started with a spear-phishing mail, later on, some undetected lateral movement, and subsequently the take over of your Windows Domain Controller. At this point in time, the attacker may deploy the ransomware on the network on a lonely Friday night.&lt;/p&gt;

&lt;p&gt;These ransomware samples are often compiled for the victim at hand. They are therefore &lt;em&gt;unique&lt;/em&gt;. Hence, they contain a lot of information related to the victim that should not be made public. This information includes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a ransom note with
    &lt;ul&gt;
      &lt;li&gt;the name of the victim&lt;/li&gt;
      &lt;li&gt;names of network shares&lt;/li&gt;
      &lt;li&gt;names of computers in the network&lt;/li&gt;
      &lt;li&gt;names of employees (as part of network share paths)&lt;/li&gt;
      &lt;li&gt;names of clients&lt;/li&gt;
      &lt;li&gt;type of stolen data (e.g. accounting data, executive data, …)&lt;/li&gt;
      &lt;li&gt;links to screenshots as proof (e.g. data listings, bank account balances, …)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;meta-information
    &lt;ul&gt;
      &lt;li&gt;the timestamp of the ransomware sample that can be used to estimate the date of the attack&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following ransom note that I’ve extracted from a ransomware sample uploaded to the Internet illustrates my point:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/never-upload-ransomware-samples-to-the-internet/ransom_note_example.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example ransom note containing a lot of information about the victim.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Needless to say that this information should not turn up on the Internet. I know that some will argue that this information will be public soon anyway if the victim does not pay the ransom. Because modern ransomware gangs use the &lt;a href=&quot;https://www.infosecurity-magazine.com/blogs/double-extortion-ransomware/&quot;&gt;double extortion tactic&lt;/a&gt;. In a nutshell, before deploying the ransomware, these gangs steal (sometimes) terabytes of data from a network and threaten to publish this information on the Darknet or sell/auction it off.&lt;/p&gt;

&lt;p&gt;By the way, paying the ransom is something that is &lt;a href=&quot;https://www.nomoreransom.org/en/ransomware-qa.html&quot;&gt;never recommended&lt;/a&gt;. Above all, because this proves to cybercriminals that this is an effective way of making money. Furthermore, this may have severe consequences for a business, if it pays cybercriminals residing somewhere in an embargoed region.&lt;/p&gt;

&lt;h2 id=&quot;why-shouldnt-i-upload-ransomware-samples-to-the-internet&quot;&gt;Why shouldn’t I upload ransomware samples to the Internet?&lt;/h2&gt;

&lt;p&gt;As you’ve seen, there is a lot of information related to the victim that a ransomware sample contains. Once IT staff is confronted with a ransomware incident, they may start their own investigation, trying to find the root of all evil. One of these steps is typically uploading many of the suspicious files found on the network to online services like VirusTotal. Consequently, these samples are public on the Internet.&lt;/p&gt;

&lt;p&gt;Unfortunately, this is a common mistake that IT staff unaware of cyber security subtleties commits. What do you gain by uploading ransomware samples? You probably know already that the sample at hand is malware because it encrypted most of your network. Often the classification of the malware, if that really matters at this particular moment, is often proudly presented by the malware itself. Either as a file extension of all the encrypted files or in the ransom note. Therefore, you are not gaining anything, but possibly losing a lot.&lt;/p&gt;

&lt;p&gt;Services like &lt;a href=&quot;https://www.virustotal.com&quot;&gt;VirusTotal&lt;/a&gt; are very good to check if a file is malicious and you suspect that it is commodity malware. Therefore, the first step is never to upload a file but rather check its file hash, e.g. sha256. Somebody else usually has uploaded the sample for us anyway. There are great tools like &lt;a href=&quot;https://github.com/alexandreborges/malwoverview&quot;&gt;malwoverview&lt;/a&gt; that help you with this task.&lt;/p&gt;

&lt;p&gt;If a hash does not yield a result then there are several explications. First, the sample is too fresh that somebody has uploaded it yet, check back a couple of minutes later. Second, the threat actor uses hash busting and changes the hash of each sample. Third, this sample is unique because it was utilized in a targeted attack.&lt;/p&gt;

&lt;p&gt;The third point is the point that applies to ransomware. The sample is &lt;em&gt;unique&lt;/em&gt;. Ransomware threat actors compile their samples typically for each victim just before the deployment. Even though this is not a nation-state actor that attacked your network, you should treat the sample as if it were from one due to the information leakage that would occur on upload.&lt;/p&gt;

&lt;p&gt;Even though not uploading ransomware samples to the Internet won’t fix the core problem you may have, i.e. an encrypted network, this will likely make your (at this point in time miserable) life a little bit brighter.&lt;/p&gt;

&lt;p&gt;Because you have much more time to focus on the actual incident and you do not have to deal with a media disaster right from the beginning! Perhaps this gives your press relations officer some time to prepare a proper statement.&lt;/p&gt;

&lt;p&gt;Furthermore, note that this is a way to identify ransomware victims that paid the ransom and never showed up on any ransomware portal. The proof that they fall victim and paid will be out there forever. Mind the possible consequences I’ve stated above.&lt;/p&gt;

&lt;h2 id=&quot;what-happens-if-i-upload-a-ransomware-sample-to-the-internet&quot;&gt;What happens if I upload a ransomware sample to the Internet?&lt;/h2&gt;

&lt;p&gt;There are many analysts out there that hunt for these samples for several reasons. One of them is not that noble but very common: public discussion of who got ransomwared by whom. This is then picked up by the press and it is something that you do not need when already in a ransomware incident, possibly in headless chicken mode anyway.&lt;/p&gt;

&lt;p&gt;Let me illustrate by the example of VirusTotal what happens. The following applies to similar services on the Internet. I choose VirusTotal because it probably the most common choice of IT staff to upload malicious samples. It is not that I am blaming anything on this very useful service. Actually, VirusTotal tells you this in their &lt;a href=&quot;https://support.virustotal.com/hc/en-us/articles/115002145529-Terms-of-Service&quot;&gt;Terms of Service&lt;/a&gt;, their &lt;a href=&quot;https://support.virustotal.com/hc/en-us/articles/115002168385-Privacy-Policy&quot;&gt;Privacy Policy&lt;/a&gt;, and again right about the time you click on “Submit”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;By submitting data below, you are agreeing to our &lt;a href=&quot;https://support.virustotal.com/hc/en-us/articles/115002145529-Terms-of-Service&quot;&gt;Terms of Service&lt;/a&gt; and &lt;a href=&quot;https://support.virustotal.com/hc/en-us/articles/115002168385-Privacy-Policy&quot;&gt;Privacy Policy&lt;/a&gt;, and to the &lt;strong&gt;sharing of your Sample submission with the security community.&lt;/strong&gt; Please do not submit any personal information; VirusTotal is not responsible for the contents of your submission.&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;VirusTotal&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, you’ve been warned a lot!&lt;/p&gt;

&lt;p&gt;But you may ask: how do analysts find my sample in the endless stream of files uploaded to VirusTotal? This is where &lt;a href=&quot;https://support.virustotal.com/hc/en-us/articles/360001315437-Livehunt&quot;&gt;LiveHunt&lt;/a&gt; comes into play. This is a service that is offered to customers and researchers to hook into the never-ending stream of files uploaded. Each file is checked against custom signatures (&lt;a href=&quot;http://virustotal.github.io/yara/&quot;&gt;YARA&lt;/a&gt; rules). Furthermore, these samples are shared with AV companies who will likely have other ways to find the needle in the haystack.&lt;/p&gt;

&lt;p&gt;If you know exactly what you are looking then it is quite easy to find the needle in the haystack. This means once you have analyzed one sample of a certain ransomware family, written a YARA rule for it, then you will likely detect it in the future again. Actually, you do not have to write many rules on your own because there are plenty on &lt;a href=&quot;https://github.com/advanced-threat-research/Yara-Rules/tree/master/ransomware&quot;&gt;GitHub&lt;/a&gt;. For instance, the following is a &lt;a href=&quot;https://github.com/advanced-threat-research/Yara-Rules/blob/master/ransomware/RANSOM_Ryuk.yar&quot;&gt;YARA rule&lt;/a&gt; for the ransomware family &lt;a href=&quot;https://malpedia.caad.fkie.fraunhofer.de/details/win.ryuk&quot;&gt;Ryuk&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Ransom_Ryuk_sept2020&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;                 
   &lt;span class=&quot;nl&quot;&gt;meta:&lt;/span&gt;       
      &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Detecting latest Ryuk samples&quot;&lt;/span&gt;         
      &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;McAfe ATR&quot;&lt;/span&gt;          
      &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;2020-10-13&quot;&lt;/span&gt;           
      &lt;span class=&quot;n&quot;&gt;malware_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ransomware&quot;&lt;/span&gt;       
      &lt;span class=&quot;n&quot;&gt;malware_family&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Ransom:W32/Ryuk&quot;&lt;/span&gt;           
      &lt;span class=&quot;n&quot;&gt;actor_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Cybercrime&quot;&lt;/span&gt;          
      &lt;span class=&quot;n&quot;&gt;actor_group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Unknown&quot;&lt;/span&gt;           
      &lt;span class=&quot;n&quot;&gt;hash1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cfdc2cb47ef3d2396307c487fc3c9fe55b3802b2e570bee9aea4ab1e4ed2ec28&quot;&lt;/span&gt;       
                
   &lt;span class=&quot;nl&quot;&gt;strings:&lt;/span&gt;           
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /TR &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;C:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Windows&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;System32&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;cmd.exe /c for /l %x in (1,1,50) do start wordpad.exe /p &quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;         
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cmd.exe /c &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;bcdedit /set {default} recoveryenabled No &amp;amp; bcdedit /set {default}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;          
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cmd.exe /c &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;bootstatuspolicy ignoreallfailures&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;        
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cmd.exe /c &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vssadmin.exe Delete Shadows /all /quiet&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;           
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;C:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Windows&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;System32&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;cmd.exe&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;            
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x6&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cmd.exe /c &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;WMIC.exe shadowcopy delete&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;            
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/C REG ADD &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;HKEY_CURRENT_USER&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;SOFTWARE&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Microsoft&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Windows&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CurrentVersion&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /v &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;EV&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /t REG_SZ /d &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;          
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;W/C REG DELETE &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;HKEY_CURRENT_USER&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;SOFTWARE&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Microsoft&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Windows&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CurrentVersion&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /v &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;EV&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /f&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;             
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x9&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;System32&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;cmd.exe&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;            
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Ncsrss.exe&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;               
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s11&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;lsaas.exe&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;              
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s12&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;lan.exe&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;              
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s13&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;$WGetCurrentProcess&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;            
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s14&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Documents and Settings&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Default User&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;sys&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;            
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s15&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Ws2_32.dll&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;            
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s16&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; explorer.exe&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;            
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s17&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;e&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Documents and Settings&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Default User&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;             
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s18&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Public&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;             
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s19&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Public&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;sys&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wide&lt;/span&gt;              
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s20&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SOFTWARE&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Microsoft&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Windows&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CurrentVersion&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Policies&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt;       
        
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e8&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fc&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;89&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;            
      &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fc&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;89&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c7&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;       
                
   &lt;span class=&quot;nl&quot;&gt;condition:&lt;/span&gt;            
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x5a4d&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;and&lt;/span&gt;              
      &lt;span class=&quot;n&quot;&gt;filesize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;and&lt;/span&gt;                
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;them&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;and&lt;/span&gt;                 
      &lt;span class=&quot;n&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;them&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;       
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This rule comprises several strings and a condition that is checked against each file. The condition matches, roughly speaking, Windows binaries that are less than 400 kilobytes in size and comprise a certain number of the aforementioned strings.&lt;/p&gt;

&lt;p&gt;Let’s say you uploaded a ransomware sample to VirusTotal, which belongs to one of the heavily tracked ransomware families then there are likely several YARA rules going off, and researchers notified. Notifications are either seen in the &lt;a href=&quot;https://support.virustotal.com/hc/en-us/articles/360001315437-Livehunt#h_cfdf3cbc-ec4f-4076-82bf-f3a0dadf6da8&quot;&gt;VirusTotal WebGUI&lt;/a&gt; or via email notification as shown in the following screenshot.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/never-upload-ransomware-samples-to-the-internet/vt_hunting_ransomware.png&quot; alt=&quot;VT notification received due to upload ransomware sample&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sample notification received for a ransomware sample.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now even further meta information is attached to the ransomware sample. For instance, the country from where the sample was uploaded, which might be used to track down the exact location of the victim if it is a branch of an enterprise operating in many countries.&lt;/p&gt;

&lt;p&gt;And finally, at some point, you will contract an incident responder because it is very likely that your in-house capabilities won’t be enough. If you tell them that you’ve just uploaded the sample to some online service, chances are that they will not be amused. I’ve never come along an incident responder that was happy when their client uploaded a ransomware sample to the Internet…&lt;/p&gt;
</description>
                <pubDate>Mon, 28 Dec 2020 22:51:09 +0000</pubDate>
                <link>https://tbarabosch.github.io/never-upload-ransomware-samples-to-the-internet/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/never-upload-ransomware-samples-to-the-internet/</guid>
                
                <category>ransomware</category>
                
                <category>malware-analysis</category>
                
                <category>incident-response</category>
                
                <category>opsec</category>
                
                
            </item>
        
            <item>
                <title>Linux from Scratch - Is it worth it?</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Reviewed July 2026:&lt;/strong&gt; This post is kept as a historical reflection on Linux from Scratch 8.0. Version-specific links and package versions may no longer match the current LFS book.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One thing on my ever-growing ToDo list was to build my own Linux system since I stumbled upon &lt;a href=&quot;http://www.linuxfromscratch.org&quot;&gt;Linux from Scratch&lt;/a&gt; (LFS) a couple of years ago. LFS is an online book that guides you through the whole process of building your own minimal Linux system. It consists of several phases: initially, you create partitions for your new system and download all the packages you need to build it. Then, you add an initial user LFS and set up a temporary system with a clean toolchain (assembler, compiler, linker) as well as other system tools. Next, you chroot into your temporary system, create essential files and folders, mount virtual filesystems like &lt;em&gt;/dev&lt;/em&gt; and &lt;em&gt;/sys&lt;/em&gt; and start to compile essential packages with your new toolchain. Finally, you install boot scripts, compile the Linux kernel, install Grub, and reboot. And wait, don’t forget to pray before booting into your system!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The book’s chapters are well-structured. They present you command lines commands to execute in order to, for instance, to build one piece of the puzzle and reasons why this piece is required, e.g. see the chapter on &lt;a href=&quot;http://www.linuxfromscratch.org/lfs/view/stable/chapter06/bzip2.html&quot;&gt;Bzip2&lt;/a&gt;. Even though the LFS book suggests that the system you build is fully usable and could be used as the primary system, it is more an educational project. For instance, do not expect to end up with a comfortable package manager like &lt;em&gt;apt-get&lt;/em&gt;. Hence, many LFSers are likely to build their system in a virtual machine. One clear advantage is that you can create snapshots during the build process, which is assumed to take place in one pass without turning off your machine. Otherwise, you have to set up your chroot again.&lt;/p&gt;

&lt;p&gt;Based on a such minimal system, further guides can be followed to get something more usable. These guides include &lt;a href=&quot;http://www.linuxfromscratch.org/blfs/&quot;&gt;Beyond Linux From Scratch&lt;/a&gt;, which also introduces security measures to the system, and &lt;a href=&quot;http://www.linuxfromscratch.org/alfs/&quot;&gt;Cross Linux From Scratch&lt;/a&gt;, which teaches how to cross-compile and how to build multilib environments.&lt;/p&gt;

&lt;p&gt;I followed &lt;a href=&quot;http://www.linuxfromscratch.org/lfs/view/stable/&quot;&gt;Linux from Scratch 8.0&lt;/a&gt;, which was the stable version I used at the time. It built a Linux system based on the Linux Kernel in version 4.9.9. There are three major points, making LFS a great project for a couple of evenings, which I discuss in the following. Finally, I wrap up my lines of thoughts in a quick conclusion.&lt;/p&gt;

&lt;p&gt;What is really needed to end up with a bash shell? Which package depends on which one? What are all these libraries in my &lt;em&gt;libs&lt;/em&gt; directories good for? There are many questions you could pose here. LFS makes you realize what it takes to build a minimal Linux system. For instance, it made me realize what forms &lt;em&gt;binutils&lt;/em&gt;, &lt;em&gt;coreutils&lt;/em&gt; and &lt;em&gt;util-linux&lt;/em&gt;. Tools that I use on a daily basis, I took them for granted but never knew where they came from.&lt;/p&gt;

&lt;h2 id=&quot;learning-by-doing&quot;&gt;Learning by Doing&lt;/h2&gt;

&lt;p&gt;LFS is Learning by doing, no beating around the bush here. You build a Linux system from scratch with your bare hands! After theory comes implementation. The stuff you learn here should be applicable to a wide range of Linux-related problems. Be it building your own cross-compiling toolchain as you actually do in LFS, be it building your custom Linux system for an embedded platform.&lt;/p&gt;

&lt;p&gt;Furthermore, for those that would like to get into OS development, Linux from Scratch allows them to review certain key concepts like the toolchain of linker, compiler, assembler, which are &lt;a href=&quot;http://wiki.osdev.org/Required_Knowledge&quot;&gt;critical to OS development&lt;/a&gt;. Before diving into OS development, I would certainly recommend going through LFS to see how to glue components together to an OS.&lt;/p&gt;

&lt;p&gt;However, you won’t code anything. For instance, the LFS guys provide you with a set of init scripts so that you don’t need to write custom ones. They serve as a fully-working template: study them and extend them, if needed.&lt;br /&gt;
But IMHO it would be too much to extend these scripts in a first LFS iteration. A rough understanding of the boot process is sufficient.&lt;/p&gt;

&lt;h2 id=&quot;take-your-time--it-is-well-spent-and-worth-it&quot;&gt;Take your time – It is well spent and worth it!&lt;/h2&gt;

&lt;p&gt;Take your time! I repeat slowly: take your time! I guess many just rush through the chapters, blindly executing commands, and end up with a working Linux system, without ever having understood what has happened. If you do this, it just boils to many &lt;em&gt;./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install&lt;/em&gt; calls. And actually there are tools to &lt;a href=&quot;http://www.linuxfromscratch.org/alfs/&quot;&gt;automate the whole LFS process&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Linux from Scratch should be rather seen as a marathon than as a quick sprint. There will be so many questions popping up in your mind. Try to follow them, search for answers on Google or Wikipedia while your computer is heating your room. Most of the time, I started by reading the project’s Wikipedia page and in case there were still open questions I consulted the project’s website. This made me read up on the project’s history, the people, and the organizations behind and it enabled me to see connections between various projects. Then, I started to poke around in the project’s folder structure and opened some source files. After compilation and installation, I checked the files produced and the locations where they were put.&lt;/p&gt;

&lt;p&gt;Doing this, for example, made me realize what kind of a monster &lt;a href=&quot;https://en.wikipedia.org/wiki/GNU_Compiler_Collection&quot;&gt;gcc&lt;/a&gt; really is. … It made me think about the pros and cons of gcc and why llvm is a brilliant compiler. So I continued to read up more on the &lt;a href=&quot;https://clang.llvm.org/comparison.html&quot;&gt;pros and cons&lt;/a&gt; of clang/llvm and gcc. I knew that llvm is the default compiler on macOS, where I already enjoy it. However, the fact that &lt;a href=&quot;https://www.freebsd.org/&quot;&gt;FreeBSD&lt;/a&gt; and &lt;a href=&quot;http://llvm.org/devmtg/2013-11/slides/Robinson-PS4Toolchain.pdf&quot;&gt;Sony’s PS4 system software&lt;/a&gt; also use clang/llvm was new to me. Actually, there is a &lt;a href=&quot;https://github.com/ramosian-glider/clang-kernel-build&quot;&gt;project&lt;/a&gt; that provides patches for the Linux kernel in order to make it compilable with clang. As you can see, you can start with one thing and end up on the PS4. Nevertheless, it is very educational and many new ideas will come to your mind.&lt;/p&gt;

&lt;h2 id=&quot;final-thoughts-on-linux-from-scratch&quot;&gt;Final thoughts on Linux from Scratch&lt;/h2&gt;

&lt;p&gt;First, of it all, it is a nice feeling to boot into your own Linux system, built with your bare hands. You end up with run level 3, a simple bash shell, nothing fancy at all. You see the cursor blinking and think: “Puh, I did not mess anything up”, since there are so many pitfalls. Then, you relax and toy around with your system. Totally worth it!&lt;/p&gt;

&lt;p&gt;Of course, I did register my Linux from Scratch system at the &lt;a href=&quot;http://www.linuxfromscratch.org/cgi-bin/lfscounter.php&quot;&gt;lfscounter&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;You have successfully registered!
ID: 26656
Name: Thomas Barabosch
First LFS Version: 8.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Even though 26656 seems to be a huge number, it isn’t if you take into account that LFS will turn 20 next year. On the other side, not everybody registers his system.&lt;/p&gt;

&lt;p&gt;There is so much future work still left. As mentioned earlier, no package manager is installed. Actually, the current strategy is &lt;a href=&quot;http://www.linuxfromscratch.org/lfs/view/stable/chapter06/pkgmgt.html&quot;&gt;It is All in My Head!&lt;/a&gt;, which only works for a very exclusive group of Linux users:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Yes, this is a package management technique. Some folks do not find the need for a package manager because they know the packages intimately and know what files are installed by each package. Some users also do not need any package management because they plan on rebuilding the entire system when a package is changed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the end, I invested several evenings to build the whole system, even though my initial SBU was less than five minutes. In retrospect, time was invested well. Can I now compile my custom Linux distribution and ditch my Ubuntu installation? Probably not, but it is a start and some may dive deeper into this topic because of Linux from Scratch. For me, the next thing to do is &lt;a href=&quot;http://www.linuxfromscratch.org/blfs/&quot;&gt;Beyond Linux From Scratch&lt;/a&gt; and to have a look at how exactly &lt;a href=&quot;http://www.linuxfromscratch.org/blfs/view/stable-systemd/postlfs/security.html&quot;&gt;security features&lt;/a&gt; like PAM are incorporated in a Linux system.&lt;/p&gt;
</description>
                <pubDate>Fri, 25 Dec 2020 16:30:11 +0000</pubDate>
                <link>https://tbarabosch.github.io/linux-from-scratch-is-it-worth-it/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/linux-from-scratch-is-it-worth-it/</guid>
                
                <category>linux</category>
                
                <category>systems</category>
                
                <category>operating-systems</category>
                
                <category>learning</category>
                
                
            </item>
        
            <item>
                <title>How to patch a Windows API in x64dbg</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Reviewed July 2026:&lt;/strong&gt; This post is kept as a historical debugging note. The x64dbg and Python plugin APIs may have changed since publication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some months ago, I analyzed a banking Trojan that employed a chain of injections. First, it hollowed an instance of &lt;em&gt;svchost.exe&lt;/em&gt;. From there, it injected its code into several processes (especially browsers). My goal was to analyze the network protocol. Unfortunately, all processes could communicate with the CC and there was a mutual exclusion scheme that ensured only one network communicator at a time. This resulted in my process never contacting the CC and in me not seeing the network protocol.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;My quick hack was to prevent others instances to communicate via the network by preventing further code injections. The malware at hand utilized &lt;em&gt;ZwOpenProcess&lt;/em&gt; during its code injections. The solution: patch a Windows API in &lt;em&gt;x64dbg&lt;/em&gt; to always return zero yielded no more injections. And finally, I was able to tamper with the network protocol.&lt;/p&gt;

&lt;p&gt;Most of the time I utilize &lt;a href=&quot;http://x64dbg.com/&quot;&gt;x64dbg&lt;/a&gt;, an open source debugger. Since a couple of months &lt;a href=&quot;https://github.com/x64dbg/x64dbgpy&quot;&gt;python bindings exist&lt;/a&gt;. They work fine, though there is no documentation. The following gist does the trick: patching ZwOpenProcess to always return zero. This should yield no more code injections in many malware families. Furthermore, you can use it as a blueprint for patching other APIs in &lt;em&gt;x64dbg&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;x64dbgpy.pluginsdk&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;       
                         
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;patchZwOpenProcess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;       
    &lt;span class=&quot;c1&quot;&gt;# This function patches the function ZwOpenProcess in such way that the XXX fails to open and infect more processes       
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# The good thing about that is that there won&apos;t be any concurrency issues and you can be sure that the networking       
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# will be done in the current process.       
&lt;/span&gt;                
    &lt;span class=&quot;c1&quot;&gt;# patches mov eax, 0; jmp TO_RETURN (should be +3)       
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;PATCH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xB8&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x00&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xEB\x03&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x90&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;addrZwOpenProcess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RemoteGetProcAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;ntdll&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;ZwOpenProcess&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addrZwOpenProcess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PATCH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;       
                
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;       
    &lt;span class=&quot;n&quot;&gt;patchZwOpenProcess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;       
                
&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The gist just assembles some shellcode (&lt;em&gt;mov eax, 0; jmp TO_RETURN&lt;/em&gt;) to force the API to return zero, resolves the target API with &lt;em&gt;RemoteGetProcAddress&lt;/em&gt; and overwrites the original code of the api with &lt;em&gt;memory.Write&lt;/em&gt;. As I said, there is no documentation of &lt;em&gt;x64dbgpy&lt;/em&gt;. You can refer to &lt;a href=&quot;https://github.com/x64dbg/x64dbgpy/tree/v25/swig/x64dbgpy/pluginsdk/_scriptapi&quot;&gt;this folder of x64dbgpy’s repo&lt;/a&gt;.&lt;/p&gt;
</description>
                <pubDate>Thu, 24 Dec 2020 12:00:00 +0000</pubDate>
                <link>https://tbarabosch.github.io/patch-a-windows-api-in-x64dbg/</link>
                <guid isPermaLink="true">https://tbarabosch.github.io/patch-a-windows-api-in-x64dbg/</guid>
                
                <category>malware-analysis</category>
                
                <category>debugging</category>
                
                <category>reverse-engineering</category>
                
                <category>windows</category>
                
                
            </item>
        
    </channel>
</rss>