<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>lopqto&apos;s adventures</title>
    <description>Personal blog of Hamidreza Babaee. Reverse engineering, malware analysis, and vulnerability researching.
</description>
    <link>https://lopqto.me/</link>
    <atom:link href="https://lopqto.me/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 16 Feb 2026 09:17:12 +0330</pubDate>
    <lastBuildDate>Mon, 16 Feb 2026 09:17:12 +0330</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Punched In: Extracting Firmware from an ESP8266 RFID Terminal</title>
        <description>&lt;p&gt;I was looking to buy a time tracker device for the office. In my searching process I found a very cheap device that immediately triggered my curiosity. As you may already know by reading my older posts, I love dissecting this kind of hardware (unknown &amp;amp; random manufacturer), so I decided to purchase one just to reverse it.&lt;/p&gt;

&lt;h3 id=&quot;the-device&quot;&gt;The Device&lt;/h3&gt;

&lt;p&gt;This device is a time tracking device. After you turn it on for the first time, it starts a wireless access point. You can connect to it and open the control panel to configure your office’s WiFi credentials. After the reboot it will act as a WiFi client and connect to the AP.&lt;/p&gt;

&lt;p&gt;Each user has a unique RFID card, and they will scan it using the terminal. The terminal will send the RFID tag number plus the timestamp to a remote API.&lt;/p&gt;

&lt;h3 id=&quot;hardware-parts&quot;&gt;Hardware Parts&lt;/h3&gt;

&lt;p&gt;After I configured the WiFi credentials and restarted the device, I headed to the DHCP page of my router to find the IP address of the device so I can open the control panel. In that list of entries, I found something very interesting:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-1.jpg&quot; alt=&quot;DHCP page enteries&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That was the AHA moment!&lt;/p&gt;

&lt;p&gt;As per &lt;a href=&quot;https://en.wikipedia.org/wiki/ESP8266&quot;&gt;Wikipedia’s description&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The ESP8266 is a low-cost Wi-Fi microchip, with built-in TCP/IP networking software, and microcontroller capability, produced by Espressif Systems&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It makes sense. To keep the hardware cost very low, they used a very cheap microcontroller with WiFi connectivity and to compensate for that, they delegated all the main functionalities like leave tracker, timesheet, etc. to a remote API.&lt;/p&gt;

&lt;p&gt;I decided to open the device and take a look at it:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-2.jpg&quot; alt=&quot;The inside&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To be honest, I felt down a bit. The hardware is far from an intricate device and more like a hobby project.&lt;/p&gt;

&lt;p&gt;Let’s review:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Microcontroller&lt;/strong&gt;: Wemos D1 Mini -&amp;gt; an ESP8266-based development board.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Display&lt;/strong&gt;: 1602 LCD with I2C Backpack&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;RFID Reader&lt;/strong&gt;: RC522 (MFRC522) - &lt;a href=&quot;https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf&quot;&gt;datasheet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Base Board&lt;/strong&gt;: Custom “Shield” / Carrier PCB -&amp;gt; Acts as a “motherboard” to fix the messy jumper wires issue. It breaks out the pins from Wemos D1 Mini to the specific headers for the RFID and LCD.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;LED Indicators&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I decided to focus on the firmware instead of hardware and go as deep as possible.&lt;/p&gt;

&lt;h3 id=&quot;getting-the-firmware&quot;&gt;Getting the Firmware&lt;/h3&gt;

&lt;p&gt;We can easily see the mini USB port that’s connected to an AC socket to act as the power source.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-3.jpg&quot; alt=&quot;mini USB port&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can connect the Wemos to our PC using a simple mini USB cable, and the dumping part would be a piece of cake for these reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Hardware Disabling:&lt;/strong&gt; You cannot disable the port via software. You must physically destroy the UART traces (TX/RX lines) or remove the USB-to-Serial IC (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CH340&lt;/code&gt;) after flashing.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Flash Encryption:&lt;/strong&gt; The ESP8266 does not support hardware flash encryption. If someone has physical access, they can bypass the USB port and wire directly to the SPI flash chip pins to dump data.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;eFuse Limitations:&lt;/strong&gt; Unlike the ESP32, the ESP8266 lacks the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flash_crypt_cnt&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JTAG_DISABLE&lt;/code&gt;  eFuses.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Physical Protection:&lt;/strong&gt; The only real protection is potting the board in epoxy to prevent physical probing of the flash memory chip. Which in this case, they didn’t!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To verify my guess, I connected the microcontroller to my PC and checked the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flash-id&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;esptool &lt;span class=&quot;nt&quot;&gt;--port&lt;/span&gt; /dev/cu.usbserial-A5069RR4 flash-id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-4.jpg&quot; alt=&quot;flash-id details&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To Dump it:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;esptool &lt;span class=&quot;nt&quot;&gt;--port&lt;/span&gt; /dev/cu.usbserial-A5069RR4 read-flash 0 0x400000 wemos_firmware_dump.bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: Wemos D1 Mini has exactly 4MB of memory, so we read it all.&lt;/p&gt;

&lt;p&gt;And finally to verify the dump:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;esptool &lt;span class=&quot;nt&quot;&gt;--chip&lt;/span&gt; esp8266 image-info wemos_firmware_dump.bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-5.jpg&quot; alt=&quot;image-info details&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Cool, we got the entire (probably) unencrypted firmware. Let’s move to the next part!&lt;/p&gt;

&lt;h3 id=&quot;reading-the-binary&quot;&gt;Reading the Binary&lt;/h3&gt;

&lt;p&gt;I found &lt;a href=&quot;http://cholla.mmto.org/esp8266/xtensa.html&quot;&gt;this guide&lt;/a&gt; that describes ESP8266’s processor architecture like this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The ESP8266 has an Xtensa lx106 processor at its core. This is a 32 bit RISC processor with 16 registers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the previous step we used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;esptool&lt;/code&gt; to analyze the image info. So obviously, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;esptool&lt;/code&gt; knows how to parse the image.&lt;/p&gt;

&lt;p&gt;I digged a little bit deeper in the esptool source code and found this &lt;a href=&quot;https://github.com/espressif/esptool/blob/master/esptool/bin_image.py&quot;&gt;bin_image.py&lt;/a&gt; file which is responsible to parse the headers.&lt;/p&gt;

&lt;p&gt;By looking at the file I found these headers:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Common Header:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&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;n&quot;&gt;magic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;segments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flash_mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flash_size_freq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entrypoint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;BBBBI&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&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;Which is equivalent to:&lt;/p&gt;

&lt;div class=&quot;language-rust 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;header&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;magic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;segments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// count&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;flash_mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;flash_size_freq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entrypoint&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;ol&gt;
  &lt;li&gt;&lt;strong&gt;Segment Header:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&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;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;II&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&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;Which is equivalent to:&lt;/p&gt;

&lt;div class=&quot;language-rust 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;segment_header&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// load address&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&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;And for the segments, data comes right after the segment header so we can write it like:&lt;/p&gt;

&lt;div class=&quot;language-rust 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;segment_header&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&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;I dug way deeper and wrote a pattern file for the entire image with some helper variables for &lt;a href=&quot;https://imhex.werwolv.net/&quot;&gt;ImHex&lt;/a&gt; and sent a pull request (&lt;a href=&quot;https://github.com/WerWolv/ImHex-Patterns/pull/492&quot;&gt;PR #492&lt;/a&gt;) for it. At this moment the PR is still open.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/lopqto/ImHex-Patterns/blob/esp8266/patterns/esp8266.hexpat&quot;&gt;Pattern file&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-6.jpg&quot; alt=&quot;Example firmware in ImHex&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After verifying everything about the legitimacy of the firmware and writing a pattern file for it, we are ready to load it in Ghidra for further analysis.&lt;/p&gt;

&lt;h3 id=&quot;into-ghidra&quot;&gt;Into Ghidra&lt;/h3&gt;

&lt;p&gt;Ghidra already supports Xtensa pretty well (added in version 11.0) and can disassemble and generate pseudocode for these processors easily. The issue resides with the custom proprietary firmware format of ESP8266. Ghidra must know where to look, where to disassemble as code, and where to look for data. For these kinds of situations, Ghidra uses loaders.&lt;/p&gt;

&lt;p&gt;Ghidra doesn’t have a native loader that understands ESP8266 firmware. Unlike standard formats like ELF or Mach-O, ESP8266 uses a proprietary binary format with a custom header structure featuring:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;An 8-byte header with magic byte (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xe9&lt;/code&gt;) for identification&lt;/li&gt;
  &lt;li&gt;Segment-based layout where each section has its own offset and size&lt;/li&gt;
  &lt;li&gt;Multiple headers including a user ROM header at offset &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x1000&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Specific memory mappings for IROM, user code, and data segments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without a proper loader, Ghidra would need you to manually extract and position each binary segment into the correct memory regions. The loader handles all this automatically by parsing the firmware structure and creating properly mapped memory blocks with correct permissions.&lt;/p&gt;

&lt;p&gt;I found an older ESP8266 loader &lt;a href=&quot;https://github.com/hank/ghidra-esp8266&quot;&gt;here!&lt;/a&gt;, but the codebase was outdated and needed updates. So I decided to send a pull request (&lt;a href=&quot;https://github.com/hank/ghidra-esp8266/pull/6&quot;&gt;PR #6&lt;/a&gt;) to contribute the fixes back to the community.&lt;/p&gt;

&lt;p&gt;After installing and enabling the custom loader, we can easily import the dumped firmware into Ghidra:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-7.jpg&quot; alt=&quot;Ghidra&apos;s open file dialog&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Loader parses the firmware headers like what we did in the previous sections, then creates memory layouts and fixes the permissions:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Address&lt;/th&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Loader Section Name –&lt;/th&gt;
      &lt;th&gt;Size&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;0x3FFE8000&lt;/td&gt;
      &lt;td&gt;dram0&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.user_data&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;14000h&lt;/td&gt;
      &lt;td&gt;User data RAM. Available to applications&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;0x40100000&lt;/td&gt;
      &lt;td&gt;iram1&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.user_code&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;8000h&lt;/td&gt;
      &lt;td&gt;Instruction RAM. Used by bootloader&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;0x40200000&lt;/td&gt;
      &lt;td&gt;SPI Flash&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;code&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;-&lt;/td&gt;
      &lt;td&gt;SPI Flash is mapped here&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;After loading the firmware into Ghidra, we can see that it was able to analyze the firmware. One of the simplest ways to verify this is by looking at the strings. Seeing meaningful strings usually means that the loader did its job and was able to map the data sections to the correct memory addresses.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-8.jpg&quot; alt=&quot;String view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If we head to the function lists, we can spot the other issue. Ghidra was unable to find function signatures using their signature db and all of the functions are labeled like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FUN_*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-11.jpg&quot; alt=&quot;Function Table&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To solve this issue we can use a &lt;strong&gt;FidDb&lt;/strong&gt;. It’s a database file used by &lt;strong&gt;Ghidra’s Function ID (FID)&lt;/strong&gt; analyzer to identify and match functions across different binaries.&lt;/p&gt;

&lt;p&gt;Because we are in microcontroller land, usually we are limited in terms of public FidDbs. For that reason, we need to create one ourselves.&lt;/p&gt;

&lt;p&gt;To do that, we need to compile another firmware that uses same SDK and libraries with debug symbols on. To build a firmware for an ESP8266, there are two viable options:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Arduino IDE + ESP8266 SDK&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PlatformIO + ESP8266 SDK&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can have an educated guess and based on the hardware design, guess that they used Arduino IDE to develop the firmware because it is much easier and user friendly.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You can read about installing ESP8266 SDK for Arduino IDE &lt;a href=&quot;https://randomnerdtutorials.com/how-to-install-esp8266-board-arduino-ide/&quot;&gt;here!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generating function signatures heavily depends on the SDK and library version. Even minor version differences can affect function signatures due to compiler optimizations or code changes. While ESP8266 SDKs share core functionality across versions, you shouldn’t assume signature compatibility. To be honest, you cannot expect 100% function signature coverage. FidDb is a helper utility to make the reversing process easier, not an ultimate solution. That’s why I decided not to play the cat-and-mouse game. of hunting down the exact SDK version to match the FidDb perfectly. The reality is that even with a perfectly matched FidDb, there will always be functions that need manual analysis. Since ESP8266 firmware is relatively small and the FidDb provides useful partial matches even across versions, I chose to just use what’s available and move forward with the actual reverse engineering. The time spent hunting for the exact SDK version is better spent on the analysis itself.&lt;/p&gt;

&lt;p&gt;I created this simple sketch:&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;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;ESP8266WiFi.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;ESP8266WebServer.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;ESP8266HTTPClient.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;ESP8266mDNS.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;WiFiClient.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;WiFiUdp.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;DNSServer.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mega_stub&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;c1&quot;&gt;// Never execute&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;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mega_stub&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;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&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;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loop&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;Exporting it generates two files: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bin&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.elf&lt;/code&gt;. We need to load the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.elf&lt;/code&gt; one because it has the debug symbols.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-9.jpg&quot; alt=&quot;Debug symbols&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I then loaded it in Ghidra, let Ghidra analyze it, and generated a FidDb out of it.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Create an empty FidDb&lt;/strong&gt;: Tools -&amp;gt; Function ID -&amp;gt; Create new empty FidDb&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Populate the FidDb&lt;/strong&gt;: Tools -&amp;gt; Function ID -&amp;gt; Populate Fid Database (Use Xtensa Little Endian for the language field)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After that, we can head to the dumped firmware and attached the created FidDb (Tools -&amp;gt; Function ID -&amp;gt; Attach existing FidDb). Make sure to let the Ghidra to analyze it again!&lt;/p&gt;

&lt;p&gt;Tadaaa!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/punched-in-series-part1-10.jpg&quot; alt=&quot;Fixed Function Table&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With meaningful function names now identified, Ghidra can show us the actual structure of the firmware. Instead of cryptic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FUN_40200000&lt;/code&gt; addresses, we now see recognizable functions like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loop()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WiFi_init()&lt;/code&gt;, and others.&lt;/p&gt;

&lt;p&gt;Everything is ready for our adventure.&lt;/p&gt;

&lt;h3 id=&quot;whats-next&quot;&gt;What’s Next&lt;/h3&gt;

&lt;p&gt;In Part 1, we identified the hardware, successfully dumped the firmware and made some helper utilities along the way. We created a pattern for ImHex, and were able to load the firmware in Ghidra and adjust it so we can reverse it later with more ease.&lt;/p&gt;

&lt;p&gt;I think we are at a good point now and ready to take the next step. In the next post (that hopefully I can allocate some time to write soon), we will take a look at the actual firmware to see how it actually works, if there are any vulnerabilities with it and what hidden functionalities exist. We will talk about ESP8266 firmware much deeper.&lt;/p&gt;

&lt;p&gt;Feel free to ping me if you had any questions!
Peace!&lt;/p&gt;

&lt;h3 id=&quot;references--tools&quot;&gt;References &amp;amp; Tools&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://cholla.mmto.org/esp8266/xtensa.html&quot;&gt;Xtensa cheat sheet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map&quot;&gt;ESP8266 memory map (and wiki)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/espressif/esptool/blob/master/esptool/bin_image.py&quot;&gt;esptool bin_image.py&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/lopqto/ImHex-Patterns/blob/esp8266/patterns/esp8266.hexpat&quot;&gt;ESP8266 pattern&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/lopqto/ghidra-esp8266/tree/patch-12.x&quot;&gt;ESP826 loader (patched for Ghidra 12.x)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 12 Feb 2026 03:30:00 +0330</pubDate>
        <link>https://lopqto.me/posts/punched-in-series-part1</link>
        <guid isPermaLink="true">https://lopqto.me/posts/punched-in-series-part1</guid>
        
        
        <category>reverse-engineering</category>
        
        <category>hardware</category>
        
      </item>
    
      <item>
        <title>Via Negativa: On Reducing Entropy in Systems</title>
        <description>&lt;p&gt;On the way home after a short vacation, the peace of a bus ride sparked a reflection. Opening my notebook, one thought stood out: stability, both in my role as a DevSecOps engineer and in personal life, had come simply by subtraction rather than addition.&lt;/p&gt;

&lt;h3 id=&quot;what-is-via-negativa&quot;&gt;What is &lt;em&gt;Via Negativa&lt;/em&gt;?&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Via Negativa&lt;/em&gt;, “the negative way”, is a philosophical and theological idea. Leaving theology aside, I like the philosophy behind it: a way of thinking that removes what is false or unnecessary.&lt;/p&gt;

&lt;p&gt;As Taleb put it:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Progress is often made by removing harmful things, not adding more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whether we call it &lt;em&gt;Via Negativa&lt;/em&gt;, minimalism, essentialism, or the Pareto principle (80/20), the message is the same: &lt;strong&gt;remove the unnecessary, and what remains is what truly matters.&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;subtraction-vs-addition&quot;&gt;Subtraction vs. Addition&lt;/h3&gt;

&lt;p&gt;Addition is seductive. It is measurable, tangible, visible.&lt;/p&gt;

&lt;p&gt;Add another CI/CD pipeline. One more security scanner. Another policy, rule, habit-tracking app, supplement, or note-taking tool.&lt;/p&gt;

&lt;p&gt;The world rewards addition:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Stack more.&lt;/li&gt;
  &lt;li&gt;Optimize more.&lt;/li&gt;
  &lt;li&gt;Buy more.&lt;/li&gt;
  &lt;li&gt;Squeeze every last drop of time and energy to do more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Addition feels productive because the results are visible.&lt;/p&gt;

&lt;p&gt;Subtraction, on the other hand, feels empty. You remove something, and it looks like loss. It feels like doing less, being less. It goes against what the world advertises.&lt;/p&gt;

&lt;p&gt;But subtraction has one thing addition lacks: &lt;strong&gt;it reduces entropy&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Less moving parts.&lt;/li&gt;
  &lt;li&gt;Less bugs.&lt;/li&gt;
  &lt;li&gt;Less crashes.&lt;/li&gt;
  &lt;li&gt;Less alerts.&lt;/li&gt;
  &lt;li&gt;Less noise.&lt;/li&gt;
  &lt;li&gt;Less distraction.&lt;/li&gt;
  &lt;li&gt;Less wasted energy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And with that reduction comes stability.&lt;/p&gt;

&lt;h3 id=&quot;subtracting-as-an-engineer&quot;&gt;Subtracting as an Engineer&lt;/h3&gt;

&lt;p&gt;In the world of technology, the desire to add surrounds us. I have seen it, and I have done it. We get a new security tool, and it feels like progress. We add a new dashboard with dozens of graphs, and we feel more in control. For a while, this works. We are catching more things, we have more “visibility.” It feels like a win for the whole team.&lt;/p&gt;

&lt;p&gt;Then the noise begins. The new tool sends a message for every little thing that occurs. The dashboard is so cluttered that nobody ever looks at it anymore. The CI/CD pipeline is now a muddle of scripts that only one person fully comprehends. The important signals are drowned out by the constant noise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The bravest engineering decision is often not to add a new feature, but to delete a redundant one.&lt;/strong&gt; It’s the courage to say, “We don’t need this alert,” or “Let’s simplify this pipeline.” When we eliminate the noise, we can now listen to the signal. The result is a less noisy, more focused team that can respond to &lt;em&gt;actual&lt;/em&gt; problems faster. We design systems that are not only robust but also simple to understand. Simplicity provides us strength.&lt;/p&gt;

&lt;h3 id=&quot;enjoying-the-sunset&quot;&gt;Enjoying the Sunset&lt;/h3&gt;

&lt;p&gt;This philosophy of subtraction is not just limited to our systems at work; it’s extended to our lives.&lt;/p&gt;

&lt;p&gt;It starts by removing the unneeded, the applications that don’t assist you, the alerts that get in the way of the here and now. The quiet at first feels awkward. The absence of the continuous hum of input is frightening. Our brains, trained for distraction, don’t know what to do with quiet.&lt;/p&gt;

&lt;p&gt;But soon that emptiness manifests as empty space. Time itself becomes open. A gap of five minutes is no longer just time to glance at a phone, but time to complete a whole page in a notebook. A simple meal, untouching of a screen, is a whole experience.&lt;/p&gt;

&lt;p&gt;The purpose of this idea, this subtraction exercise, is not to be an machine of maximum efficiency. It’s the opposite. It is to be a space quiet enough to finally hear your own mind. To be the author of your own day, not a reactor to the demands of a thousand notices. &lt;strong&gt;It is to understand that by removing the things that consumed your time, you finally have time to live.&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I experienced it myself, resting on a bench as the sun set, music in the background, a tree’s shadow dancing on the wall, nothing urgent, just the quiet fullness of the moment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Life is simple. Living is even simpler.&lt;/strong&gt; The hard part was trusting that &lt;em&gt;less could be enough&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;closing-toughts&quot;&gt;Closing Toughts&lt;/h3&gt;

&lt;p&gt;Subtraction isn’t glamorous. It doesn’t win you quick applause. It seems to be like doing less, being less.&lt;/p&gt;

&lt;p&gt;But it is subtraction that reduces entropy, in systems, and in life.
And clarity appears expensive when entropy is low.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And occasionally the most heroic act of design, as an engineer or in life, is not what we add, but what we have the courage to subtract.&lt;/strong&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 22 Sep 2025 00:30:00 +0330</pubDate>
        <link>https://lopqto.me/posts/via-negativa</link>
        <guid isPermaLink="true">https://lopqto.me/posts/via-negativa</guid>
        
        
        <category>philosophy</category>
        
      </item>
    
      <item>
        <title>Reversing a Remote Controller: A Case Study in RF Engineering</title>
        <description>&lt;p&gt;Feeling bored, I decided to take on a personal challenge: reverse-engineer a toy’s remote controller. My goal was to gain practical experience with radio communication and create a custom controller with new features, like controlling it remotely over Wi-Fi. It’s a classic hands-on project that starts with a simple question: what makes this thing tick?&lt;/p&gt;

&lt;h3 id=&quot;exploring-the-target-device&quot;&gt;Exploring the Target Device&lt;/h3&gt;

&lt;p&gt;I had a toy with a remote controller laying around. The remote controller has 3 buttons for 3 different functions: power, change the rhythm of the bottom part, change the rhythm of the top part. I was suspecting that the remote controller uses radio waves to communicate with the toy like other similar remote controllers.&lt;/p&gt;

&lt;p&gt;After opening the remote controller, My suspicion was confirmed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/reversing-a-remote-controller1.png&quot; alt=&quot;Inside the remote controller&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A few things immediately jumped out that pointed toward a specific frequency. The board is labeled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AYKJ006-TX&lt;/code&gt;, with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TX&lt;/code&gt; being the standard abbreviation for a transmitter. More importantly, the distinct, curvy copper line labeled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ANT&lt;/code&gt; is clearly a PCB trace antenna. Simple, short-range remotes like this almost always operate in the unlicensed ISM bands, with 433 MHz being one of the most common frequencies worldwide. This made 433 MHz my primary suspect.&lt;/p&gt;

&lt;p&gt;Let’s look at the components.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;The Encoder and Transmitter IC (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U1&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;The most important component on this board is the large black chip labeled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U1&lt;/code&gt;. It has 2 primary functions:&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Encoder:&lt;/strong&gt; When user presses a button, it converts that action into a command.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Transmitter:&lt;/strong&gt; After generating the command, the chip modulates it onto a 433 MHz radio frequency carrier wave.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;The Crystal Oscillator (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y1&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;The shiny, metallic component labeled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y1&lt;/code&gt; is a crystal oscillator. It generates a stable clock signal that is used by the main chip (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U1&lt;/code&gt;).&lt;/p&gt;

    &lt;p&gt;If you look closely, you will notice it’s marked “13.560,” which means it vibrates at 13.560 MHz and not 433 MHz. This is a common engineering trick. The main chip (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U1&lt;/code&gt;) contains a circuit called a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Phase-Locked Loop (PLL)&lt;/code&gt;, which acts as a frequency multiplier. It takes the stable 13.560 MHz signal and multiplies it by 32 to generate the final transmission frequency:&lt;/p&gt;

    &lt;pre&gt;&lt;code class=&quot;language-math&quot;&gt;13.560MHz × 32 = 433.92 MHz
&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;It’s often cheaper and more stable to use a lower-frequency crystal and multiply it up.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;The User Interface Components&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;There are 3 buttons for 3 different functions: power, change the rhythm of the bottom part, change the rhythm of the top part labeled as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S1&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S2&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S3&lt;/code&gt;. Also there are 4 different LEDs labeled as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D1&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D2&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D3&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D4&lt;/code&gt;. They provide a visual feedback when the button is pressed.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Power Management Components&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Battery Terminals (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BAT+&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BAT-&lt;/code&gt;):&lt;/strong&gt; These are the metal contacts where the battery (CR2032) is connected to power the entire circuit.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Voltage Regulator (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U2&lt;/code&gt;):&lt;/strong&gt; Its job is to take the variable battery voltage and provide a constant, clean voltage (3.3V) that the main chip (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U1&lt;/code&gt;) needs to operate on.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;planning-the-next-steps&quot;&gt;Planning the Next Steps&lt;/h3&gt;

&lt;p&gt;My goal was to reverse engineer the remote controller and create a custom one that can control the device. I needed to understand the communication protocol used by the remote controller to be able to replicate those signals. To achieve this, I had 2 options:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Using a Logic Analyzer:&lt;/strong&gt; A logic analyzer is a tool that captures and displays digital signals within an electronic circuit. To use this method, I would have had to solder tiny wires directly to the pins of the encoder chip (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U1&lt;/code&gt;). This would let me “eavesdrop” on the exact digital commands the chip generates when a button is pressed, before they are turned into a radio wave.
    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; It provides a very clean, noise-free look at the digital data.&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; It requires delicate soldering skills, risks damaging the board, and tells you nothing about the radio transmission part of the signal (the modulation).&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Using a Software Defined Radio (SDR):&lt;/strong&gt; An SDR is essentially a radio scanner for a computer. It’s a device that can be tuned to almost any frequency to receive raw radio signals directly from the air. I could use it to capture the exact 433 MHz signal the remote sends out, just as the toy’s receiver would hear it.
    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; It requires no physical modification to the remote. It captures the complete, final signal as it’s transmitted.&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; The captured signal can have noise from other radio sources, and it requires software on a computer to process and decode the raw radio data back into a digital command.&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since I had an SDR device lying around and wanted a practical project to learn more about radio hacking, I decided to go with option 2.&lt;/p&gt;

&lt;h3 id=&quot;capturing-the-radio-waves&quot;&gt;Capturing the Radio Waves&lt;/h3&gt;

&lt;p&gt;To capture the radio waves, I plugged my RTL-SDR device into my computer and used a software suite called Universal Radio Hacker (&lt;a href=&quot;https://github.com/jopohl/urh&quot;&gt;URH&lt;/a&gt;).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The Universal Radio Hacker (URH) is a complete suite for wireless protocol investigation with native support for many common Software Defined Radios.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the software running, I configured my setup to get the cleanest signal possible:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;I tuned the SDR to the frequency of the remote (433 MHz).&lt;/li&gt;
  &lt;li&gt;Next, I adjusted the gain. Since the remote was right next to the SDR’s antenna, the signal was very strong. A high gain would only amplify unnecessary background noise, so I lowered it significantly.&lt;/li&gt;
  &lt;li&gt;Then, I created a ground plane to improve reception. For the simple monopole antenna that comes with most SDRs, placing it on a metal plate (or any large metal surface) acts as a ground plane, which helps stabilize the signal and reduce interference.&lt;/li&gt;
  &lt;li&gt;Finally, I hit the record button in URH to start capturing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/img/reversing-a-remote-controller4.png&quot; alt=&quot;URH configuration&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Voila! I had a clean, noise-free sample of the transmission. Now I could jump into the next part.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/reversing-a-remote-controller5.png&quot; alt=&quot;Captured signals&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;probing-for-a-rolling-code&quot;&gt;Probing for a Rolling Code&lt;/h3&gt;

&lt;p&gt;With everything ready, I began transmitting. The button for the toy’s top part (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S1&lt;/code&gt;) cycles through four different rhythm modes. To capture the full sequence and check for consistency, I pressed the button eight times, ensuring I recorded two full cycles of all four modes.&lt;/p&gt;

&lt;p&gt;There was a critical reason for this repetition. &lt;strong&gt;I needed to check if the protocol had any “moving parts,” like a rolling code or a timestamp.&lt;/strong&gt; More secure systems, like car key fobs, change the code with every press to make replay attacks impossible. By capturing two sets of signals for each of the four modes, I could compare them. If the first signal for “mode 1” was identical to the second signal for “mode 1,” it would mean the code is static, and a simple replay attack would likely work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This was a make-or-break step.&lt;/strong&gt; If the code wasn’t static, I’d have to figure out how to generate the new code for each transmission. That would likely mean reverse-engineering the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U1&lt;/code&gt; chip itself, and an SDR isn’t the right tool for that kind of task.&lt;/p&gt;

&lt;p&gt;URH attempts to automatically analyze the signal and show the bits. In my case, its interpretation wasn’t perfect, but it didn’t need to be. It was clear enough to see that the payload was static. After each cycle, it sent the exact same payload for that mode.&lt;/p&gt;

&lt;p&gt;As you can see, in the following image, searching for the single pattern resulted in 2 different groups of matches.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/reversing-a-remote-controller3.png&quot; alt=&quot;bits&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That was the confirmation I needed. &lt;strong&gt;The device uses a static code, which means it’s completely vulnerable to a replay attack.&lt;/strong&gt; Game on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Quick Note on Security:&lt;/strong&gt; It’s worth pointing out that finding a “vulnerability” like this in a simple toy isn’t an indictment of the manufacturer. Implementing secure rolling codes (cryptography) adds complexity and cost. For low-cost consumer electronics, manufacturers make a deliberate trade-off, opting for simple, static codes that are cheap and reliable over robust security. This is expected and perfectly normal for this class of device.&lt;/p&gt;

&lt;h3 id=&quot;demodulating-the-signal&quot;&gt;Demodulating the Signal&lt;/h3&gt;

&lt;p&gt;In simple terms, modulation is the process of encoding digital data (our ones and zeros) onto a radio wave, and demodulation is getting that data back off the wave at the other end.&lt;/p&gt;

&lt;p&gt;Figuring out the modulation type was straightforward once I looked at the captured signal. The pattern was a dead giveaway for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Amplitude Shift Keying (ASK)&lt;/code&gt;, one of the simplest forms of digital modulation.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/reversing-a-remote-controller9.png&quot; alt=&quot;ASK modulation&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The key thing to look for with ASK is the “on-off” nature of the transmission. When I viewed the signal in URH, I didn’t see a continuous wave that changed its shape. Instead, I saw a series of clean, distinct bursts of radio energy separated by total silence. This is the classic signature of ASK, meaning the transmitter sends a 1 by turning the 433 MHz carrier wave ON (high amplitude) and sends a 0 by turning it OFF (low amplitude, or silence).&lt;/p&gt;

&lt;p&gt;But how does it know how long each 1 or 0 should be? That’s where the encoding scheme comes in.&lt;/p&gt;

&lt;h4 id=&quot;what-is-a-pwm&quot;&gt;What is a PWM?&lt;/h4&gt;

&lt;p&gt;The specific method this remote uses to structure its ones and zeros is a form of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pulse Width Modulation (PWM)&lt;/code&gt;. Don’t let the name intimidate you; the concept is really simple. It uses pulses of different lengths (or widths) to represent different data.&lt;/p&gt;

&lt;p&gt;Think of it like sending a message with a flashlight in the dark:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;To send a 1&lt;/strong&gt;, you might do a long flash followed by a short pause.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/img/reversing-a-remote-controller6.png&quot; alt=&quot;One&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;To send a 0&lt;/strong&gt;, you’d do a short flash followed by a long pause.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/img/reversing-a-remote-controller7.png&quot; alt=&quot;Zero&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The receiver on the other end just has to measure the duration of each flash and each pause to reconstruct the original message. My remote does the exact same thing, just with radio waves instead of light and with timings measured in microseconds. By analyzing the captured signal, I could see two distinct pulse lengths, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;short&lt;/code&gt; one and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;long&lt;/code&gt; one, confirming that this was the method being used.&lt;/p&gt;

&lt;h3 id=&quot;dissecting-a-command&quot;&gt;Dissecting a Command&lt;/h3&gt;

&lt;p&gt;With the encoding method figured out, I could finally dissect a complete command. My first step was to lean on URH’s built-in analysis tools, which gave me a bird’s-eye view of the entire transmission structure.&lt;/p&gt;

&lt;p&gt;A single press of a button wasn’t just one command; it was a whole conversation. The remote was clearly designed for reliability, sending its message multiple times to make sure the toy heard it correctly. The structure for every button press was identical:&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;1001111111111111111111 [Pause: 1898 samples]
111110111110111110111000000011100000001111101110000000111110111000000011100000001110000000111110111110111000000011111011100000001010001111111111111111111 [Pause: 1897 samples]
111110111110111110111000000011100000001111101110000000111110111000000011100000001110000000111110111110111000000011111011100000001010001111111111111111111 [Pause: 1897 samples]
111110111110111110111000000011100000001111101110000000111110111000000011100000001110000000111110111110111000000011111011100000001010001111111111111111111 [Pause: 1898 samples]
111110111110111110111000000011100000001111101110000000111110111000000011100000001110000000111110111110111000000011111011100000001010001111111111111111111 [Pause: 1895 samples]
11111011111011111011100000001110000000111110111000000011111011100000001110000000111000000011111011111011100000001111101110000000101 [Pause: 490234 samples]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;The Preamble:&lt;/strong&gt; A short, distinct initial pulse. &lt;strong&gt;This acts like a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wake-up&lt;/code&gt; call&lt;/strong&gt; for the receiver, letting it know a real command is about to follow and allowing it to synchronize its clock.&lt;/li&gt;
&lt;/ul&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;1001111111111111111111 [Pause: 1898 samples]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;The Command Repeats:&lt;/strong&gt; The main data payload was sent back-to-back four times. This is a common strategy in simple RF devices. If the first transmission is garbled by interference, the receiver has more chances to get a clean copy.&lt;/li&gt;
&lt;/ul&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;111110111110111110111000000011100000001111101110000000111110111000000011100000001110000000111110111110111000000011111011100000001010001111111111111111111 [Pause: 1897 samples]
111110111110111110111000000011100000001111101110000000111110111000000011100000001110000000111110111110111000000011111011100000001010001111111111111111111 [Pause: 1897 samples]
111110111110111110111000000011100000001111101110000000111110111000000011100000001110000000111110111110111000000011111011100000001010001111111111111111111 [Pause: 1898 samples]
111110111110111110111000000011100000001111101110000000111110111000000011100000001110000000111110111110111000000011111011100000001010001111111111111111111 [Pause: 1895 samples]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;The Trimmed Packet:&lt;/strong&gt; The transmission ended with a final, shorter burst of data. This was a truncated version of the main command, likely &lt;strong&gt;acting as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;message over&lt;/code&gt; signal&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&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;11111011111011111011100000001110000000111110111000000011111011100000001110000000111000000011111011111011100000001111101110000000101 [Pause: 490234 samples]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With the overall structure understood, I could focus on one of those identical, repeated blocks. By analyzing the repeating patterns of high (1) and low (0) samples, I could deduce the encoding “alphabet” for a single bit of data:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Logical 1:&lt;/strong&gt; A long high pulse followed by a short low pulse. In the sampled data, this corresponds to the pattern &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;111110&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Logical 0:&lt;/strong&gt; A short high pulse followed by a long low pulse. In the sampled data, this corresponds to the pattern &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1110000000&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these rules, I could now decode the full data payload. For example, applying these rules to one of the captured packets for the “top part” function gave me the 16-bit binary message:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-binary&quot;&gt;1110 0101 0001 1010
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By doing this for all the captured modes, a clear pattern emerged.&lt;/p&gt;

&lt;h4 id=&quot;the-final-command-format&quot;&gt;The Final Command Format&lt;/h4&gt;

&lt;p&gt;The command is a 16-bit (2-byte) packet with a clear and simple 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;[ Address Nibble (4 bits) | Command Nibble (4 bits) | Checksum (8 bits) ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Address Nibble:&lt;/strong&gt; A 4-bit chunk that acts as a group identifier. For example, all commands for the “top part” used the address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1110 (Hex: 0xE)&lt;/code&gt;. This tells the receiver which function to modify.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Command Nibble:&lt;/strong&gt; The next 4-bit chunk is the actual instruction. For the “top part,” this value changed for each of the four rhythm modes, telling the receiver which specific pattern to activate.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Checksum:&lt;/strong&gt; The final 8 bits are a simple checksum. It’s a bitwise NOT of the first 8 bits (the address and command combined). Every 1 is flipped to a 0, and every 0 is flipped to a 1. This is a computationally cheap way for the receiver to verify that it received the message without errors.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a breakdown of the example command we decoded (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1110010100011010&lt;/code&gt;):&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Part&lt;/th&gt;
      &lt;th&gt;Binary&lt;/th&gt;
      &lt;th&gt;Hex&lt;/th&gt;
      &lt;th&gt;Meaning&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Address Nibble&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1110&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xE&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Address for the “top part” function&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Command Nibble&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0101&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x5&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Instruction for a specific rhythm mode&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Full Byte 1&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;11100101&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xE5&lt;/code&gt; The complete command byte&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Checksum&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00011010&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x1A&lt;/code&gt; The bitwise NOT of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xE5&lt;/code&gt;, used to verify the message&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;timing-is-everything&quot;&gt;Timing is Everything!&lt;/h4&gt;

&lt;p&gt;Knowing the sequence of ones and zeros is only half the job. To build a perfect clone, I had to replicate the signal’s timing with microsecond precision. &lt;strong&gt;A radio receiver is incredibly picky; if your pulses are too long or too short, it will reject the command as noise.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While a logic analyzer is the ideal tool for getting perfect, noise-free timing measurements directly from the hardware, it’s possible to get a very good estimate from a clean radio capture in URH. By zooming in on the demodulated signal, you can measure the number of “samples” for each pulse and pause. By establishing a base time unit (e.g., one sample equals ~5µs at a sample rate of 200k), you can calculate the approximate duration of each part of the signal.&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;Time per sample = 1 / Sample Rate
1 / 200,000 = 0.000005s or 5µs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/img/reversing-a-remote-controller8.png&quot; alt=&quot;Timing&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This method requires some trial and error. I started with the calculated estimates and then “hand-tuned” the microsecond values in my code, testing each time until the device responded reliably.&lt;/p&gt;

&lt;h3 id=&quot;creating-a-custom-remote-controller&quot;&gt;Creating a Custom Remote Controller&lt;/h3&gt;

&lt;p&gt;With the protocol fully reverse-engineered, the next step was to build the hardware. The goal was to create a new remote from scratch that could replicate the toy’s signals.&lt;/p&gt;

&lt;p&gt;For the main controller, I chose a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NodeMCU ESP8266&lt;/code&gt; board. It’s inexpensiveyet powerful (and also has a built-in WiFi module), which is great for this kind of hardware project. For the transmitter, I used a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;standard 433 MHz ASK module&lt;/code&gt;, the same type found in the original remote.&lt;/p&gt;

&lt;p&gt;Finally, a crucial component was a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;decoupling capacitor&lt;/code&gt;. During early tests, I discovered the transmitter’s power draw was causing signal instability. Adding a capacitor directly across the transmitter’s power pins provides the instant current needed for clean, strong pulses.&lt;/p&gt;

&lt;p&gt;I soldered all components onto a piece of perfboard to create a compact and sturdy device. The NodeMCU is the main board, with the transmitter and its supporting capacitor placed nearby.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/reversing-a-remote-controller2.png&quot; alt=&quot;The custom remote controller&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The final step was to translate our findings into C++ code for the NodeMCU. This involved creating functions to precisely replicate the signal’s unique structure.&lt;/p&gt;

&lt;h4 id=&quot;the-building-blocks-timing-is-key&quot;&gt;The Building Blocks: Timing is Key&lt;/h4&gt;

&lt;p&gt;The foundation of the code is built on generating pulses with microsecond accuracy. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delayMicroseconds()&lt;/code&gt; function is perfect for this, but to ensure perfect stability and prevent timing jitter from the microcontroller’s background tasks, each pulse is sent inside a “critical section” by temporarily disabling interrupts.&lt;/p&gt;

&lt;p&gt;The core of the signal is the PWM “alphabet” we discovered, which defines a logical 1 and a 0. The timings were hardcoded directly from our analysis:&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;c1&quot;&gt;// Timings in microseconds&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PULSE_SHORT_US&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;250&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;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PULSE_LONG_US&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;520&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;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PAUSE_SHORT_US&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&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;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PAUSE_LONG_US&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;680&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;nf&quot;&gt;send_logical_1&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;c1&quot;&gt;// A long HIGH pulse followed by a short LOW pause&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_high_pulse_critical&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PULSE_LONG_US&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;delayMicroseconds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PAUSE_SHORT_US&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;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;send_logical_0&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;c1&quot;&gt;// A short HIGH pulse followed by a long LOW pause&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_high_pulse_critical&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PULSE_SHORT_US&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;delayMicroseconds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PAUSE_LONG_US&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;h4 id=&quot;assembling-the-full-command&quot;&gt;Assembling the Full Command&lt;/h4&gt;

&lt;p&gt;With the functions for sending a 1 and a 0 defined, the full command structure could be built. Each transmission starts with a unique preamble, which acts as a “wake-up” call for the receiver.&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;c1&quot;&gt;// Preamble timings in microseconds&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PREAMBLE_PULSE_1_US&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&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;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PREAMBLE_PAUSE_US&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;160&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;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PREAMBLE_PULSE_2_US&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1860&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;nf&quot;&gt;send_preamble&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;send_high_pulse_critical&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PREAMBLE_PULSE_1_US&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;delayMicroseconds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PREAMBLE_PAUSE_US&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_high_pulse_critical&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PREAMBLE_PULSE_2_US&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;Finally, the main function assembles the full 16-bit packet. It takes the 4-bit address and the 4-bit command, combines them into a single byte, and calculates the checksum by performing a bitwise NOT. It then sends the full sequence: the preamble, four full repetitions of the data packet with its trailer, and a final trimmed packet.&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;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;send_command&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;c1&quot;&gt;// Hardcoded for one of the &quot;top part&quot; rhythm modes&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address_nibble&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mb&quot;&gt;0b1110&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Address for the &quot;top part&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command_nibble&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mb&quot;&gt;0b0110&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Command for a specific mode&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Construct the full 8-bit command&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte1&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;address_nibble&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&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;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command_nibble&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Calculate the checksum&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;checksum&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;n&quot;&gt;byte1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Send the preamble once&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_preamble&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;delayMicroseconds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PAUSE_INTER_PACKET_US&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Send the command + checksum + trailer 4 times&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;REPETITIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;send_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;send_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;checksum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;send_trailer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;delayMicroseconds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PAUSE_INTER_PACKET_US&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;c1&quot;&gt;// Send the final trimmed packet (command + checksum only)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;checksum&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;After uploading the code and powering it on, it worked flawlessly. The custom-built remote could control the toy’s functions just like the original, now functioning as a platform for future expansion.&lt;/p&gt;

&lt;p&gt;I did the same thing for the other 2 buttons as well and created a fully functional replica.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This project was more than just building a new remote; it was a deep dive into the practical side of reverse-engineering. I started with a simple problem and a basic tool—an SDR—and worked step-by-step to a complete solution. By looking closely at the signals, I uncovered the device’s secrets: a static protocol, ASK modulation, and a simple PWM encoding scheme. From there, I was able to build the same logic into a new device.&lt;/p&gt;

&lt;p&gt;The main takeaway is that even with simple tools, you can figure out how complex systems work. The static code made the project much easier to tackle, and the bit-flipping checksum was a great example of a simple but effective way to check for errors. This hands-on process strengthened my understanding of radio communication and embedded systems, giving me a solid base for more complex projects in the future. Especially with radio communications!&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Amplitude-shift_keying&quot;&gt;Amplitude-shift keying&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Pulse-width_modulation&quot;&gt;Pulse-width modulation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Signal_modulation&quot;&gt;Signal modulation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/jopohl/urh&quot;&gt;Universal Radio Hacker&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/merbanan/rtl_433&quot;&gt;rtl_433&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 16 Aug 2025 03:30:00 +0330</pubDate>
        <link>https://lopqto.me/posts/reversing-a-remote-controller</link>
        <guid isPermaLink="true">https://lopqto.me/posts/reversing-a-remote-controller</guid>
        
        
        <category>reverse-engineering</category>
        
        <category>hardware</category>
        
        <category>radio</category>
        
      </item>
    
      <item>
        <title>From Laziness to Control: Reversing an IoT device using Frida</title>
        <description>&lt;p&gt;Have you ever had that irresistible urge to take apart a cheap IoT device you bought from a random store? You know, that feeling that says, “Let’s dive into the mystery and figure out how this thing actually works!” But then you stop and ask yourself, “Why am I even doing this?” and struggle to come up with a good reason. Well, let me tell you, if there was a Ph.D. for taking apart useless things, I’d probably have earned it!&lt;/p&gt;

&lt;p&gt;Today, we’re going to explore the exciting world of reverse engineering, with a focus on understanding the device’s communication protocol. And here’s my little secret: this is my go-to trick when I’m feeling a bit lazy. Get ready for some tech magic, my friends!&lt;/p&gt;

&lt;h3 id=&quot;exploring-the-target-device&quot;&gt;Exploring the Target Device&lt;/h3&gt;

&lt;p&gt;Alright, let’s kick off our journey by addressing the question: What are we going to reverse engineer? Last week, I purchased an LED strip stand (as shown in the image), which came with a controller and a questionable phone app. From my experience, these types of apps usually communicate through Bluetooth. However, I’m not entirely certain about the controller itself. It could be using infrared, Bluetooth, or maybe even something entirely different (but probably not)?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/from-laziness-to-control1.jpg&quot; alt=&quot;LED strip stand&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/from-laziness-to-control2.jpg&quot; alt=&quot;Mobile app&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now, here’s the deal: I want to ditch the app because it’s been tickeling me crazy. To achieve this, I need to uncover the commands that are being sent from the app to the LED strip. Once I have a clear understanding of these commands, I can rewrite them in a programming language that I’m comfortable with. So, our goal is set: let’s crack the code.&lt;/p&gt;

&lt;h3 id=&quot;choosing-the-right-approach&quot;&gt;Choosing the Right Approach&lt;/h3&gt;

&lt;p&gt;In order to achieve our goal of taking down the app and gaining control over our LED strip, we have several options available. Let’s explore each one:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Dump the LED strip’s firmware and reverse it: This approach involves extracting and analyzing the firmware of the LED strip itself. However, it requires extensive knowledge of hardware and may consume a significant amount of time and effort. Considering the complexity and potential challenges, this approach may not be the most convenient choice for a simple strip light.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Dump the controller’s firmware: This method involves extracting and examining the firmware of the controller. Similar to the previous approach, it requires hardware knowledge and can be time-consuming. While it provides valuable insights, it may not be the most suitable option for our scenario.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Use a magical device to sniff Bluetooth communication: This option involves employing a specialized device to intercept and analyze the Bluetooth communication between the app and the LED strip. Unfortunately, obtaining such a device might be difficult or costly, making it less reliable for our purposes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Dissect the mobile app and reverse engineer it: This is the approach I have chosen, and let me tell you why. Tackling the mobile app allows us to dive into its inner workings, understand the commands it sends to the LED strip, and ultimately rewrite those commands according to our preferences. It’s a more accessible option, requiring reverse engineering skills but without the hardware-intensive aspects of the other methods.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Considering my inclination toward efficiency and laziness, focusing on dissecting and reverse engineering the mobile app appears to be the most favorable path forward. Let’s dive into the app’s code and unveil its secrets!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/from-laziness-to-control3.png&quot; alt=&quot;Byte code viewer&apos;s output&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When we’re faced with a big challenge like reading lots of messy code written in Java or Kotlin, it can be really tiring to go through it all by hand. But don’t worry, I’ve got a solution that’s both efficient and effective. Our main goal is still clear: we want to figure out how the app communicates and extract the important commands, without getting too caught up in the app’s inner workings.&lt;/p&gt;

&lt;p&gt;Here’s where dynamic analysis comes in. It’s a smart technique that lets us skip the hard work of reading all that code manually. Instead, we can focus on the most important parts. And to make things even easier, we’ll use Frida, a handy tool that can help us with our analysis.&lt;/p&gt;

&lt;p&gt;By using dynamic analysis and Frida, we’ll be able to work smarter, not harder (I made up this excuse to cover up my laziness :d ). We’ll be able to find the key details of the communication protocol without getting lost in all the other stuff. Get ready to see how this combination of analysis and Frida can make our job much simpler and more efficient.&lt;/p&gt;

&lt;h3 id=&quot;environment-setup&quot;&gt;Environment Setup&lt;/h3&gt;

&lt;p&gt;Let’s set up the environment for our project. Here are the steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Rooted Android device: We’ll need a real Android device that has been rooted for this project. Emulators won’t work because they don’t support the Bluetooth stack. Some emulators might have a simulated Bluetooth connection, but we need to connect to a real device. Also, install the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HappyLighting&lt;/code&gt; app.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;ADB (Android Debug Bridge): We’ll use ADB to communicate with the Android device. You can install ADB on Debian-based Linux distributions by running the following command:&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&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;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;adb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: Make sure you have enabled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Developer Options&lt;/code&gt; on your Android device.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Frida: We also need to install Frida (You need Python) on both the computer and the Android device.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On your computer, run the following command to install the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frida-tools&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;pip &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;frida-tools
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the Android device, first download the appropriate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frida-server&lt;/code&gt; binary for your device’s CPU architecture from &lt;a href=&quot;https://github.com/frida/frida/releases&quot;&gt;here!&lt;/a&gt;. Then, push the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frida-server&lt;/code&gt; to the device by running these commands:&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;adb push /path/to/frida-server /data/local/tmp/
adb shell &lt;span class=&quot;nb&quot;&gt;chmod &lt;/span&gt;755 /data/local/tmp/frida-server
adb shell /data/local/tmp/frida-server &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To verify that everything is working correctly and that you can communicate with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frida-server&lt;/code&gt;, run the following command on your computer:&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;frida-ps &lt;span class=&quot;nt&quot;&gt;-U&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You should see a list of running processes on your Android device.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/from-laziness-to-control4.png&quot; alt=&quot;frida-ps&apos;s output&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With these steps completed, we have our environment set up and ready to go.&lt;/p&gt;

&lt;h3 id=&quot;reversing-the-communication-protocol&quot;&gt;Reversing the Communication Protocol&lt;/h3&gt;

&lt;p&gt;Finally, we’ve reached the exciting part where we dive into reversing and getting our hands dirty. But before we begin, let’s discuss our approach. If you’re already familiar with Frida and how it works, great! If not, take a quick look &lt;a href=&quot;https://learnfrida.info/&quot;&gt;here!&lt;/a&gt; to get acquainted.&lt;/p&gt;

&lt;p&gt;In simple terms, our goal is to find the specific function responsible for sending commands to the LED strip device, hook it using Frida, and log those commands. This way, we can reimplement a basic Bluetooth client and send the commands ourselves.&lt;/p&gt;

&lt;p&gt;Now, you might be wondering how we can achieve this without delving into the complexities of reversing the Android application. Well, let’s take a step back and think outside the box for a moment. Do we really need to locate specific functions? In fact, what is the “right” function we want to hook?&lt;/p&gt;

&lt;p&gt;To answer that, we need to consider a different perspective. We’re interested in the last function in the chain of the functions that handles and sends the commands to the device. Why the last one? Because we want to capture the raw payload being sent to the device, including any checksums, encodings, or padding applied. We need the raw payload as our starting point. We can capture that payload, send it to the device, and see if it works. If it does, great! If not, we can backtrack and analyze the chain further.&lt;/p&gt;

&lt;p&gt;So, what is this last function responsible for sending the Bluetooth payload? Well, you guessed it! It’s the Java Bluetooth function from the Android SDK. Ultimately, Java and the Android SDK are responsible for delivering the payload to Android’s Bluetooth stack. Therefore, we can conveniently ignore all the code and simply hook the Java Bluetooth function. That’s all there is to it. We can reverse the communication protocol without actually having to reverse the entire application (if we’re fortunate enough that capturing and emulating the raw payload works for us).&lt;/p&gt;

&lt;p&gt;With this approach, we’re ready to uncover the secrets of the communication protocol and create our own Bluetooth client. It’s time to embark on this reverse engineering journey and see where it takes us!&lt;/p&gt;

&lt;p&gt;To implement hooking with Frida, we need to find the Bluetooth function’s signature. After some searching, we come across the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android.bluetooth.BluetoothGattCharacteristic&lt;/code&gt; class, which has a function called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setValue&lt;/code&gt; responsible for sending payloads through Bluetooth. The function signature is as follows:&lt;/p&gt;

&lt;div class=&quot;language-java 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;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&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;Take your time and look at the examples provided by Frida docs &lt;a href=&quot;https://frida.re/docs/examples/android/&quot;&gt;here!&lt;/a&gt;. Now, let’s write a proper hook for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setValue&lt;/code&gt; function using Frida:&lt;/p&gt;

&lt;div class=&quot;language-javascript 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;nx&quot;&gt;Java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;perform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BluetoothGattCharacteristic&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;android.bluetooth.BluetoothGattCharacteristic&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
    &lt;span class=&quot;c1&quot;&gt;// setValue(String)&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;BluetoothGattCharacteristic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;overload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;java.lang.String&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;implementation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&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;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;[BluetoothGattCharacteristic.setValue] Value (String): &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
      &lt;span class=&quot;c1&quot;&gt;// Call the original method and return the result&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&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;nx&quot;&gt;result&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;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code sets up a hook on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android.bluetooth.BluetoothGattCharacteristic.setValue()&lt;/code&gt; function. Whenever this function is called, it will log the inputs (hopefully the commands we’re looking for) to the console.&lt;/p&gt;

&lt;p&gt;However, we notice that there are three more &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;overloads&lt;/code&gt; for this function, as mentioned in the Android Developer documentation &lt;a href=&quot;https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic#setValue(java.lang.String)&quot;&gt;here!&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In Java, method overloading is the ability to define more than one method with the same name in a class. The compiler is able to distinguish between the methods because of their method signatures1. This means that multiple methods can have the same name as long as the number and/or type of parameters are different. Method overloading is mainly used to increase the readability of the program; to make it look better. For example, instead of defining two methods that should do the same thing, it is better to overload one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To ensure we don’t miss anything, let’s implement hooks for these overloads as well:&lt;/p&gt;

&lt;div class=&quot;language-javascript 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;nx&quot;&gt;Java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;perform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BluetoothGattCharacteristic&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;android.bluetooth.BluetoothGattCharacteristic&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
    &lt;span class=&quot;c1&quot;&gt;// Overload 1: setValue(String)&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;BluetoothGattCharacteristic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;overload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;java.lang.String&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;implementation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&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;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;[BluetoothGattCharacteristic.setValue] Value (String): &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
      &lt;span class=&quot;c1&quot;&gt;// Call the original method and return the result&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&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;nx&quot;&gt;result&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;c1&quot;&gt;// Overload 2: setValue(byte[])&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;BluetoothGattCharacteristic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;overload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;[B&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;implementation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&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;c1&quot;&gt;// Convert byte array to hex string&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;hexValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bytesToHex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
      &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;[BluetoothGattCharacteristic.setValue] Value (byte[]): &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;hexValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
      &lt;span class=&quot;c1&quot;&gt;// Call the original method and return the result&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&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;nx&quot;&gt;result&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;c1&quot;&gt;// Overload 3: setValue(int, int, int)&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;BluetoothGattCharacteristic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;overload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;implementation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value3&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;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;[BluetoothGattCharacteristic.setValue] Values (int, int, int): &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
      &lt;span class=&quot;c1&quot;&gt;// Call the original method and return the result&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value3&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;nx&quot;&gt;result&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;c1&quot;&gt;// Overload 4: setValue(int, int, int, int)&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;BluetoothGattCharacteristic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;overload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;implementation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value4&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;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;[BluetoothGattCharacteristic.setValue] Values (int, int, int, int): &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
      &lt;span class=&quot;c1&quot;&gt;// Call the original method and return the result&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value4&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;nx&quot;&gt;result&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;c1&quot;&gt;// Helper function to convert a byte array to a hex string&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bytesToHex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bytes&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;hexArray&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&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;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&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;nx&quot;&gt;i&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;byteString&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;nx&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toString&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;nx&quot;&gt;hexArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byteString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&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;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;byteString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;byteString&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;hexArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&apos;&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;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With this code, we have implemented hooks for all the overloads of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setValue&lt;/code&gt; function. Each hook will log the inputs to the console, allowing us to capture the commands we’re interested in. This way, we can move forward with analyzing and emulating the captured commands.&lt;/p&gt;

&lt;p&gt;To run Frida with the hooks and capture the output, execute the following command in the terminal:&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;frida &lt;span class=&quot;nt&quot;&gt;-U&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; com.xiaoyu.hlight &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; bt_hooks.js
&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;bt_hooks.js&lt;/code&gt; is the filename of the JavaScript code containing the hooks and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com.xiaoyu.hlight&lt;/code&gt; is the package name of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HappyLighting&lt;/code&gt; app.&lt;/p&gt;

&lt;p&gt;Once the Frida script is running, you can test the functionality by turning the LED strip on and off using the app. The console output should display the captured commands.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/from-laziness-to-control5.png&quot; alt=&quot;On &amp;amp; Off console log&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In this case, we see that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cc2333&lt;/code&gt; is the command for turning on the LED strip, while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cc2433&lt;/code&gt; is the command for turning it off. The static parts &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cc&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;33&lt;/code&gt; indicate some command indicator, and we can assume that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;23&lt;/code&gt; is for turning on the LED strip and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;24&lt;/code&gt; is for turning it off.&lt;/p&gt;

&lt;p&gt;Hopefully, by sending these commands (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cc2333&lt;/code&gt; to turn on and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cc2433&lt;/code&gt; to turn off) to the LED strip ourselves, we can control its status accordingly.&lt;/p&gt;

&lt;p&gt;To further explore the functionality and reverse-engineer the commands, let’s change the LED strip’s mode through the application and observe the corresponding commands. By switching between the “Rainbow pulsating” and “Red pulsating” modes multiple times, we can capture the commands associated with each mode.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/from-laziness-to-control6.png&quot; alt=&quot;Mode switch console log&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After analyzing the captured commands, we can observe that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bb260f44&lt;/code&gt; corresponds to the “Rainbow pulsating” mode, while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bb250f44&lt;/code&gt; corresponds to the “Red pulsating” mode. From our previous understanding of the command structure, we can deduce that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bb&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;44&lt;/code&gt; parts likely serve as command indicators.&lt;/p&gt;

&lt;p&gt;However, we notice another part in the commands: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0f&lt;/code&gt;. By further experimentation, specifically by adjusting the speed of the effect, we can observe that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0f&lt;/code&gt; portion changes accordingly. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;01&lt;/code&gt; represents the maximum speed, while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1f&lt;/code&gt; corresponds to the minimum speed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/from-laziness-to-control7.png&quot; alt=&quot;Speed change console log&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Therefore, we can conclude that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0f&lt;/code&gt; portion of the command likely represents the speed parameter, with different values indicating various speed settings.&lt;/p&gt;

&lt;p&gt;I believe we can wrap things up at this point since I think I have successfully demonstrated the concept I had in mind. Now, let’s proceed to the next section where we will develop a straightforward client application to control the LED strip.&lt;/p&gt;

&lt;h3 id=&quot;writing-a-custom-client&quot;&gt;Writing a Custom Client&lt;/h3&gt;

&lt;p&gt;To write a simple client, I opted for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Python&lt;/code&gt; as my preferred language since it’s the one I usually turn to when exploring new concepts. However, you are free to choose any programming language that you’re comfortable with.&lt;/p&gt;

&lt;p&gt;Here’s the code:&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;asyncio&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;bleak&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BleakClient&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Bluetooth device information
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device_address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;92:3B:12:00:0D:B2&quot;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# MAC address of the device
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;characteristic_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;0000ffd9-0000-1000-8000-00805f9b34fb&quot;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# UUID of the characteristic
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Payload in hex string format
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromhex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cc2333&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BleakClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_connected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Write the payload to the characteristic
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write_gatt_char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;characteristic_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Disconnect from the device
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disconnect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Run the write_payload coroutine
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asyncio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_event_loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run_until_complete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write_payload&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;In the provided code snippet, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;device_address&lt;/code&gt; variable represents the MAC address of the Bluetooth device you want to connect to. It is a unique identifier assigned to each Bluetooth device. You should replace the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;device_address&lt;/code&gt; value with the actual MAC address of your target device.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;characteristic_uuid&lt;/code&gt; variable represents the UUID (Universally Unique Identifier) of the specific characteristic on the Bluetooth device that you want to interact with. Characteristics are attributes of a Bluetooth device that enable specific functionalities or data exchange. You should replace the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;characteristic_uuid&lt;/code&gt; value with the actual UUID of the characteristic you intend to communicate with.&lt;/p&gt;

&lt;p&gt;By knowing the MAC address and characteristic UUID, you can establish a connection with the Bluetooth device and utilize the corresponding characteristic to perform operations such as reading, writing, or subscribing to data.&lt;/p&gt;

&lt;p&gt;There are multiple methods to obtain the MAC addresses and characteristics UUID of the target device. One approach is to write a simple code snippet using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bleak&lt;/code&gt; library, while another option is to utilize Android applications such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bluetooth Terminal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By following these steps, we have successfully achieved control over the LED strip using our custom client. While we could continue expanding the functionalities of our client, for the purpose of this blog post, it is sufficient to conclude our exploration here.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;In conclusion, through our exploration, we have demonstrated the process of reverse engineering a communication protocol and controlling an LED strip. By utilizing the power of Frida, we were able to identify the relevant functions responsible for sending commands to the LED strip. By hooking these functions and capturing the command payloads, we gained insights into the communication protocol.&lt;/p&gt;

&lt;p&gt;With this knowledge, we successfully developed a custom client that allows us to control the LED strip independently of the original mobile application. By sending the captured commands, we could turn the LED strip on and off, change its colors, and switch between different lighting modes.&lt;/p&gt;

&lt;p&gt;It is important to acknowledge that achieving the desired outcome quickly is not always guaranteed in every reverse engineering scenario. The complexity of protocols and security measures can vary greatly, often necessitating more extensive analysis and reverse engineering efforts. However, in our case, the dynamic analysis approach we employed proved to be highly effective, significantly accelerating the process and saving us many hours of traditional reverse engineering work.&lt;/p&gt;

&lt;p&gt;Overall, this post demonstrates the excitement and possibilities that arise from reverse engineering and taking control over IoT devices, opening up new avenues for customization and creativity.&lt;/p&gt;

&lt;p&gt;I hope it was helpful. If you have any further questions, please feel free to reach out.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.frida.re/docs/javascript-api&quot;&gt;frida.re docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic#setValue(java.lang.String)&quot;&gt;BluetoothGattCharacteristic&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://learnfrida.info/&quot;&gt;Frida HandBook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;read-more&quot;&gt;Read More&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/posts/frida-by-example&quot;&gt;Frida by example: bypassing IsDebuggerPresent() check&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/MikeCoder96/HappyLighting-py&quot;&gt;MikeCoder96 / HappyLighting-py&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 13 Jun 2023 03:30:00 +0330</pubDate>
        <link>https://lopqto.me/posts/from-laziness-to-control</link>
        <guid isPermaLink="true">https://lopqto.me/posts/from-laziness-to-control</guid>
        
        
        <category>reverse-engineering</category>
        
        <category>hardware</category>
        
      </item>
    
      <item>
        <title>Building highly interactive honeypots: CVE-2021-41773 case study</title>
        <description>&lt;p&gt;Every day, as we drink our coffee in the office, new vulnerabilities pop out, some of which are highly critical and need quick reactions. Exploiting some of these vulnerabilities is a cinch, like the one found in Apache HTTPD “&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CVE-2021-41773&lt;/code&gt;”, which is why they attract many attackers. In such situations, a precise solution is required to get information around the attack as quickly as possible. The gathered information can be used for different goals, for example, to assist security engineers in knowing the attack patterns to defend themselves against it, or maybe for security researchers to gather intel and knowledge as much as possible; therefore, they can share it publicly. One of those solutions is a &lt;strong&gt;honeypot&lt;/strong&gt;. Essentially, a honeypot acts as a decoy-based intrusion detection system to help us detect attacks and their patterns, and defend ourselves against them. This post (or maybe a series of posts) will discuss how to build a highly interactive honeypot for a vulnerability immediately and analyze the generated logs after successful or unsuccessful attacks.&lt;/p&gt;

&lt;h3 id=&quot;the-approach&quot;&gt;The approach&lt;/h3&gt;

&lt;p&gt;While numerous honeypot applications are available for free (like &lt;a href=&quot;https://github.com/DinoTools/dionaea&quot;&gt; dionaea
&lt;/a&gt; and &lt;a href=&quot;https://github.com/cowrie/cowrie&quot;&gt;cowire&lt;/a&gt;), these programs attempt to emulate a service and present the attacker with a fake service. Honeypots of this type are effective against autonomic attacks, but they fail to detect manual attacks or attacks with more than one stage. In addition, there are several techniques an attacker can use to uncover a honeypot.&lt;/p&gt;

&lt;p&gt;The aforementioned approach has some shortcomings such as limited emulation on specific services and challenging customization. About customization, researchers find it a time-consuming task where in some specific scenarios, they cannot get the advantage of customizatoin. Moreover, it is good to point out that there is no honeypot for dozens of services.&lt;/p&gt;

&lt;p&gt;To overcome these hardships, rather than trying to emulate every possible aspect of the faked system, we can grant access to a real system as it is easy, so the attacker has no way of knowing whether they are logged on to a honeypot or not. Securing a real system is not easy; however, it can be done using virtualization or containerization.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/building-highly-interactive-honeypots1.jpg&quot; alt=&quot;Approach diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The honeypot is a vulnerable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Docker&lt;/code&gt; container affected by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CVE-2021-41773&lt;/code&gt;. Instances of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Filebeat&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Auditbeat&lt;/code&gt; will collect the logs, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Elasticsearch&lt;/code&gt; will colorate them for us. Finally, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Kibana&lt;/code&gt; can provide a visualized dashboard.&lt;/p&gt;

&lt;h3 id=&quot;vuleranble-container&quot;&gt;Vuleranble container&lt;/h3&gt;

&lt;p&gt;A path traversal vulnerability and exploit just dropped in the wild for a specific version of Apache (Apache/2.4.49). This vulnerability allows an unauthenticated attacker to execute a path traversal attack (and now shown RCE if MOD_CGI is enabled) to read files outside the virtual directory path bounds. .&lt;/p&gt;

&lt;p&gt;To build a vulnerable container for these types of vulnerabilities, we need the source code of that specific vulnerable version. Luckily, there is a mirror of Apache HTTPD at &lt;a href=&quot;https://github.com/apache/httpd/releases&quot;&gt;here!&lt;/a&gt;. After downloading the source code, we compile the vulnerable version and build a docker image we can deploy quickly.&lt;/p&gt;

&lt;p&gt;The assumption is you know how to install and use Docker; if you’re not familiar, please take a look at &lt;a href=&quot;https://docs.docker.com/engine/install/&quot;&gt;This Article!&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the content of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-Dockerfile 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;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; ubuntu:20.04&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;MAINTAINER&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; lopqto &amp;lt;morpix@protonmail.com&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Install the required packages&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;apt-get update  &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    build-essential zlibc libapr1-dev &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    libaprutil1-dev libpcre3-dev zlib1g zlib1g-dev wget &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    subversion python3 autoconf libtool-bin

&lt;span class=&quot;k&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /honeypot&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Download the vulnerable version&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;wget https://github.com/apache/httpd/archive/refs/tags/2.4.49.tar.gz &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-xvf&lt;/span&gt; 2.4.49.tar.gz

&lt;span class=&quot;k&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /honeypot/httpd-2.4.49/&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Compile the vulenrable version&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;svn co http://svn.apache.org/repos/asf/apr/apr/trunk srclib/apr &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./buildconf &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./configure &lt;span class=&quot;nt&quot;&gt;--prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/local/apache2 &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;nt&quot;&gt;--enable-mods-shared&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;all &lt;span class=&quot;nt&quot;&gt;--enable-deflate&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--enable-proxy&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;nt&quot;&gt;--enable-proxy-balancer&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--enable-proxy-http&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; /var/www/html &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; /var/log/apache2/

&lt;span class=&quot;c&quot;&gt;# Update the required permissions for www-data&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;chown&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-hR&lt;/span&gt; www-data:www-data /var/www/html &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chown&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-hR&lt;/span&gt; www-data:www-data /var/log/apache2/ &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chown&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-hR&lt;/span&gt; www-data:www-data /usr/local/apache2/logs/

&lt;span class=&quot;k&quot;&gt;USER&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; www-data&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /var/www/html&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Run apache in foreground mode&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ENTRYPOINT&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; [&quot;/usr/local/apache2/bin/apachectl&quot;, &quot;-D&quot;, &quot;FOREGROUND&quot;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To build the vulnerable image:&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;docker build &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; honeypot:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;test-the-vulnerable-container&quot;&gt;Test the vulnerable container&lt;/h3&gt;

&lt;p&gt;The vulnerability requires specific permissions to be configured. Grab the default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;httpd.conf&lt;/code&gt; file and append these lines end of it:&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;&amp;lt;VirtualHost *:8080&amp;gt;
	DocumentRoot /var/www/html

	ErrorLog /var/log/apache2/error.log
	CustomLog /var/log/apache2/access.log combined

	&amp;lt;Directory /&amp;gt;
		Require all granted
	&amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then try to run the vulnerable container with the new config file:&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;docker run &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 80:8080 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;/httpd.conf:/usr/local/apache2/conf/httpd.conf &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    apache:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Test the vulnerability by running:&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;curl http://localhost/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh -d &apos;echo;whoami&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You should see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;www-data&lt;/code&gt; in output.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/building-highly-interactive-honeypots2.png&quot; alt=&quot;PoC the vulnerability&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;logging&quot;&gt;Logging&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Elasticsearch&lt;/code&gt; ELK stack (Elasticsearch, Logstash, and Kibana) is an ideal solution for search and analytics platforms on honeypot logs.&lt;/p&gt;

&lt;p&gt;There are various how-to’s describing how to get ELK running (see &lt;a href=&quot;https://github.com/deviantony/docker-elk&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html&quot;&gt;here&lt;/a&gt; for example), so I assume you already have a working ELK system.&lt;/p&gt;

&lt;h3 id=&quot;http-requests-logs&quot;&gt;HTTP requests logs&lt;/h3&gt;

&lt;p&gt;A logger with these advantages is needed:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;No need to modify the container’s configuration&lt;/li&gt;
  &lt;li&gt;Prevent attackers from disabling the logger within the container&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By default, Apache stores the access logs inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/apache2/access.log&lt;/code&gt; and error logs inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/apache2/error.log&lt;/code&gt;. We need to export these logs from the container and store them inside an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ElasticSearch&lt;/code&gt; instance. To do this, we will use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Filebeat&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Filebeat is a lightweight shipper for forwarding and centralizing log data. Installed as an agent on your servers, Filebeat monitors the log files or locations that you specify, collects log events, and forwards them either to Elasticsearch or Logstash for indexing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The main configuration file will look like this:&lt;/p&gt;

&lt;div class=&quot;language-yml 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;na&quot;&gt;filebeat.config&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${path.config}/modules.d/*.yml&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;reload.enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;output.elasticsearch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;hosts&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_HOST}:9200&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_USERNAME}&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_PASSWORD}&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;setup.dashboards&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;setup.kibana&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;${KIBANA_HOST}:5601&quot;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_USERNAME}&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_PASSWORD}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apache.yml&lt;/code&gt; we have:&lt;/p&gt;

&lt;div class=&quot;language-yml 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;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;apache&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;access&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;var.paths&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/log/access.log&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;var.paths&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/log/error.log&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Another option for this problem is to configure the containers to forward their Syslog data to the host, but this can be disabled if the attacker has root access, so it is not ideal.&lt;/p&gt;

&lt;h3 id=&quot;executaion-logs&quot;&gt;Executaion logs&lt;/h3&gt;

&lt;p&gt;Docker runs on the same kernel as the host machine, so we can use kernel-level logging to see what is happening inside the container. An off-the-shelf solution is to use a Linux audit system and configure it to log &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execve&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execveat&lt;/code&gt; system calls.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The Linux Audit system provides a way to track security-relevant information on your system. Based on pre-configured rules, Audit generates log entries to record as much information about the events that are happening on your system as possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The sad news is Linux audit system does not support kernel namespaces, so logs cannot be filtered for specific containers and the host machine. To make things easier, we defined a custom user inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;www-data&lt;/code&gt; to filter out the related logs by this user.&lt;/p&gt;

&lt;div class=&quot;language-Dockerfile 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;USER&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; www-data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To log the execution actions, we will use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Auditbeat&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Auditbeat is a lightweight shipper that you can install on your servers to audit the activities of users and processes on your systems. For example, you can use Auditbeat to collect and centralize audit events from the Linux Audit Framework. You can also use Auditbeat to detect changes to critical files, like binaries and configuration files, and identify potential security policy violations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Auditbeat&lt;/code&gt; configuration file will look like this:&lt;/p&gt;

&lt;div class=&quot;language-yml 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;na&quot;&gt;auditbeat.modules&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;auditd&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;audit_rules&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;-a always,exit -F arch=b64 -S execve,execveat -k exec&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;output.elasticsearch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;hosts&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_HOST}:9200&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_USERNAME}&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_PASSWORD}&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;setup.dashboards&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;setup.kibana&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;${KIBANA_HOST}:5601&quot;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_USERNAME}&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ELASTICSEARCH_PASSWORD}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;/h3&gt;

&lt;p&gt;At this point, we have an ELK stack set up and running, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Kibana&lt;/code&gt; dashboards ready to visualize the logs, a vulnerable container prepared to be exposed on the internet, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Filebeat&lt;/code&gt; instance ready to capture HTTP logs, and an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Auditbeat&lt;/code&gt; instance to capture executed commands.&lt;/p&gt;

&lt;p&gt;We can create a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose.yml&lt;/code&gt; file to deploy the honeypot as fast as possible and make things much more manageable. To install the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose&lt;/code&gt;, take a look at &lt;a href=&quot;https://docs.docker.com/compose/install/&quot;&gt;here!&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Content of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose.yml&lt;/code&gt; will be something like this:&lt;/p&gt;

&lt;div class=&quot;language-yml 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;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;3.8&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;honeypot&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;./&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;honeypot&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;honeypot&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;80:8080&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;logs:/var/log/apache2/&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;auditbeat&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;docker.elastic.co/beats/auditbeat:7.15.0&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;auditbeat&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;root&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;host&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;cap_add&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;AUDIT_CONTROL&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;AUDIT_READ&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;honeypot&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;auditbeat:/usr/share/auditbeat/data&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$PWD/auditbeat.yml:/usr/share/auditbeat/auditbeat.yml:ro&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ELASTICSEARCH_HOST=elk.host&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Change&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;KIBANA_HOST=kibana.host&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Change&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ELASTICSEARCH_USERNAME=elastic&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Change&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ELASTICSEARCH_PASSWORD=changeme&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Change&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--strict.perms=false&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;honeypot&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;filebeat&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;docker.elastic.co/beats/filebeat:7.15.0&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;filebeat&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;root&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;honeypot&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;filebeat:/usr/share/filebeat/data&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$PWD/filebeat.yml:/usr/share/filebeat/filebeat.yml&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$PWD/apache.yml:/usr/share/filebeat/modules.d/apache.yml&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;logs:/log/:ro&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ELASTICSEARCH_HOST=elk.host&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Change&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;KIBANA_HOST=kibana.host&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Change&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ELASTICSEARCH_USERNAME=elastic&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Change&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ELASTICSEARCH_PASSWORD=changeme&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Change&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--strict.perms=false&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;honeypot&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;honeypot&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;auditbeat&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;filebeat&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;logs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To bring up the honeypot stack, run the following command:&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;docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it :). Now, we can trace the logs with the help of Kibana and some beautiful dashboards.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Auditbeat&lt;/code&gt; executions Dashboard:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/building-highly-interactive-honeypots3.png&quot; alt=&quot;executions Dashboard&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Filebeat&lt;/code&gt; Apache access and error logs dashboard:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/building-highly-interactive-honeypots4.png&quot; alt=&quot;Apache access and error logs dashboard&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;We can build interactive honeypots for a variety of vulnerabilities in such a short period of time using containers. The ELK stack additionally provides us with some tools to gather valuable logs, manage records easier, and visualize them for better understanding. Spending time and effort, researchers can build honeypots to trace active threats and threat actors, such as miners, and share attack knowledge with other researchers. The information can be used to create threat feeds with a low likelihood of false positives. Additionally, engineers can use honeypots as a decoy system inside of an organization.&lt;/p&gt;

&lt;p&gt;The project has been shared on &lt;a href=&quot;https://github.com/lopqto/CVE-2021-41773_Honeypot&quot;&gt;Github&lt;/a&gt;. You can use it as a starting point. I hope you find it useful.&lt;/p&gt;

&lt;p&gt;You’re more than welcome to share your thoughts and ideas. Feel free to ping me if you have questions about this topic.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

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

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/lopqto/CVE-2021-41773_Honeypot&quot;&gt;CVE-2021-41773_Honeypot&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/blasty/CVE-2021-41773&quot;&gt;CVE-2021-41773 Playground by blasty&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/mrhavens/DockerTrap&quot;&gt;DockerTrap by Mark Havens&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 17 Oct 2021 03:30:00 +0330</pubDate>
        <link>https://lopqto.me/posts/building-highly-interactive-honeypots</link>
        <guid isPermaLink="true">https://lopqto.me/posts/building-highly-interactive-honeypots</guid>
        
        
        <category>security-engineering</category>
        
        <category>threat-analysis</category>
        
      </item>
    
      <item>
        <title>Automated dynamic import resolving using binary emulation</title>
        <description>&lt;p&gt;Analyzing malwares is often not an easy task because there are lots of tricks and techniques that malwares use to evade detection and classification or to make the post-analysis more difficult. One such trick is to resolve windows API calls dynamically (called “dynamic import resolving”).&lt;/p&gt;

&lt;p&gt;In this blog post, we will talk about dynamic import resolving and a pattern to detect it when reversing malwares, how to defeat this trick using binary emulation and Qiling framework (resolve API calls and extract function names), and finally we will integrate our emulation framework with Ghidra.&lt;/p&gt;

&lt;p&gt;In the last section, we will talk about a solution to run Python version 3 and Qiling trough Ghidra so we can see the result of our script inside the decompiler/disassembler view. It will make post-analysis easier.&lt;/p&gt;

&lt;p&gt;As a real-life example, we will analyze Netwalker which used this technique and we will discuss our idea around that sample.&lt;/p&gt;

&lt;h3 id=&quot;what-is-dynamic-import-resolving&quot;&gt;What is dynamic import resolving&lt;/h3&gt;
&lt;p&gt;Let’s talk about dynamic import resolving and indirect function calls. It’s a common technique that malwares use to hide their intention, make the static analysis more difficult, bypass some red flags, etc.&lt;/p&gt;

&lt;p&gt;In this technique, the malware tries to create an IAT (&lt;a href=&quot;https://en.wikipedia.org/wiki/Portable_Executable&quot;&gt;Import Address Table&lt;/a&gt;) during the execution so there is no sign of used API calls in the PE header.&lt;/p&gt;

&lt;p&gt;This technique often shows up in a specific pattern;
At the beginning of the execution, the program will build an array of function pointers which  works like an IAT and the malware can use stored function pointers with indirect calls as shown below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/daily-binary-emulation3.png&quot; alt=&quot;indirect calls&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It’s rather difficult to determine which function would be called by these indirect function calls without actually executing the binary.&lt;/p&gt;

&lt;p&gt;To dynamically make a function pointer, the two API calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadLibraryA()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress()&lt;/code&gt; are often used.&lt;/p&gt;

&lt;p&gt;According to the Microsoft docs, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadLibraryA()&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Loads the specified module into the address space of the calling process. The specified module may cause other modules to be loaded.&lt;/p&gt;
&lt;/blockquote&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;HMODULE&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;LoadLibraryA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;LPCSTR&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lpLibFileName&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;And &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress()&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).&lt;/p&gt;
&lt;/blockquote&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;FARPROC&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetProcAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;HMODULE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;LPCSTR&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;lpProcName&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;Look at this pseudo-code as a demonstration:&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;nf&quot;&gt;ret_type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;__stdcall&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;HINSTANCE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hLibrary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoadLibrary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ntdll.dll&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f_func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LocalNtCreateFile&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;f_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetProcAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hLibrary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NtCreateFile&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;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LocalNtCreateFile&lt;/code&gt; is a function pointer which points to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NtCreateFile&lt;/code&gt;, which can be stored in an array a.k.a IAT.&lt;/p&gt;

&lt;p&gt;To make things more spicy, sometimes malware authors also encrypt the strings passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadLibrary()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress()&lt;/code&gt; like what Netwalker did. It will be near to impossible to analyze malware without solving this problem first.&lt;/p&gt;

&lt;h3 id=&quot;choosing-the-approach&quot;&gt;Choosing the approach&lt;/h3&gt;
&lt;p&gt;To solve these types of techniques and tricks there are a few approaches. For example, we can sometimes decrypt passed strings statically or we can develop an IDA plugin (or any disassembler and decompiler that supports plugins) but that would be a rather time-consuming task. Alternatively, we can use debuggers to execute the malware step by step, and rename variables according to dynamically resolved functions but this is a lot of repetition.&lt;/p&gt;

&lt;p&gt;I chose binary emulation because it gives us the best of both worlds, We can have the power of automation &lt;em&gt;and&lt;/em&gt; the ease of debugging. ‌It’s worth mentioning that emulating can be very slow at times, especially when dealing with encryption and decryption algorithms.
Personally, I think this is an acceptable trade-off.&lt;/p&gt;

&lt;p&gt;For binary emulation we will use Qiling. Read my &lt;a href=&quot;/posts/automated-malware-unpacking#choosing-tools-and-solutions&quot;&gt;previous post&lt;/a&gt; to see why.&lt;/p&gt;

&lt;h3 id=&quot;analyzing-netwalker&quot;&gt;Analyzing Netwalker&lt;/h3&gt;
&lt;p&gt;Today’s sample is NetWalker &lt;a href=&quot;https://malpedia.caad.fkie.fraunhofer.de/details/win.mailto&quot;&gt;link!&lt;/a&gt; . Netwalker used dynamic import resolving technique with encrypted strings so it is a good example for us to demonstrate our idea and approach around that.&lt;/p&gt;

&lt;p&gt;As discussed before, most of the time malwares will try to build an IAT at the beginning of the execution - and NetWalker does this.&lt;/p&gt;

&lt;p&gt;After disassembling the malware, we can see a function call right after the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;entry&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/daily-binary-emulation1.png&quot; alt=&quot;build IAT function call&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Jumping to that function, we can see the pattern mentioned above; A function is called multiple times and the return value is stored in an array.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/daily-binary-emulation2.png&quot; alt=&quot;IAT pattern&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This pattern is a sign of dynamic import resolving. We can confirm our guess with a debugger like below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/daily-binary-emulation8.png&quot; alt=&quot;debugger view of one of the function calls&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s jump to the code and write a script to extract these function names.&lt;/p&gt;

&lt;p&gt;I’ve discussed the basics of the Qiling like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hook_code()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ql.mem.read&lt;/code&gt; in the &lt;a href=&quot;/posts/automated-malware-unpacking&quot;&gt;previous post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In such scenarios, we don’t need to emulate the entire malware, we just need to execute the dynamic import table resolution bit. So we need to find the start and the end of that section. This is rather easy because our target is inside a function, so we only need to emulate that specific function.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/daily-binary-emulation4.png&quot; alt=&quot;start and end of the section&quot; /&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;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0040c1a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0040c1a5&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;In this process of analyzing malwares with binary emulation, you need only be creative.
For example, in this sample, there are plenty of approaches that you can use; however I chose the easiest and fastest (specifically development time, this solution performs rather badly).&lt;/p&gt;

&lt;p&gt;Let’s talk about the approach. As you can see in the image below, the return value of the (probably) decrypter and resolver function is stored in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax&lt;/code&gt; register and then moved to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dword ptr [ecx + int]&lt;/code&gt;. So we just need to hook the code and extract the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax&lt;/code&gt; in the right location.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/daily-binary-emulation5.png&quot; alt=&quot;return value stored in to the eax&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can run the emulator and try to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hook_code()&lt;/code&gt; to catch every instruction that is going to be executed.&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;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract_eax&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 you may notice, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extract_eax()&lt;/code&gt; is a callback function that is designed to extract the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax&lt;/code&gt;. Qiling will pass the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ql&lt;/code&gt; (sandbox) object, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;address&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size&lt;/code&gt; of the instruction to this callback function.&lt;/p&gt;

&lt;p&gt;We can extract the instruction inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extract_eax()&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem.read()&lt;/code&gt; as below:&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;n&quot;&gt;buf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&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;buf&lt;/code&gt; is a Python &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytearray&lt;/code&gt; of our instruction. The next step is detecting the right location to extract &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax&lt;/code&gt;. By looking at the disassembler we can see a pattern. the first part of the opcode is similar.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/daily-binary-emulation6.png&quot; alt=&quot;opcode similarty&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; will detect the right location:&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;8941&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buf&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;to extract &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax&lt;/code&gt; value we need to do this:&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;n&quot;&gt;eax_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eax&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;eax_value&lt;/code&gt; is an address that points to an API call. We can search that address inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import_symbols&lt;/code&gt; to extract the API name.&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;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;import_symbols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eax_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;func_dll&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dll&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;func_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ascii&quot;&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;&quot;found &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func_dll&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func_name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; at &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;address&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;&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;Fulll code will be:&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;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_eax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&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;s&quot;&gt;&quot;8941&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buf&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;c1&quot;&gt;# dword ptr [ECX + hex],EAX
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;eax_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eax&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;import_symbols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eax_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;func_dll&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dll&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;func_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ascii&quot;&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;&quot;found &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func_dll&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func_name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; at &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;address&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;&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;This was easy! right? Next, we need to integrate our scipt with Ghidra to actually use the information we got here. This will help us to see extracted API names inside Ghidra.&lt;/p&gt;

&lt;h3 id=&quot;integrating-qiling-with-ghidra&quot;&gt;Integrating Qiling with Ghidra&lt;/h3&gt;
&lt;p&gt;As you probably know Ghidra uses Jython and Jython only supports Python version 2 but Qiling is based on Python version 3. I found an interesting project called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghidra_bridge&lt;/code&gt; &lt;a href=&quot;https://github.com/justfoxing/ghidra_bridge&quot;&gt;link!&lt;/a&gt; that helps us solve this problem.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;So Ghidra Bridge is an effort to sidestep that problem - instead of being stuck in Jython, set up an RPC proxy for Python objects, so we can call into Ghidra/Jython-land to get the data we need, then bring it back to a more up-to-date Python with all the packages you need to do your work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After installing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghidra_bridge&lt;/code&gt; you can find an example inside the installation directory called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;example_py3_from_ghidra_bridge.py&lt;/code&gt;. By opening this file we will have an idea about how to write scripts based on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghidra_bridge&lt;/code&gt;. Let’s dissect it.&lt;/p&gt;

&lt;p&gt;Most scripts should use this minimal template:&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;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;server_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ghidra_bridge&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ghidra_bridge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GhidraBridge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;globals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response_timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;in_ghidra&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ghidra&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# we&apos;re in ghidra!
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;in_ghidra&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ModuleNotFoundError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# not ghidra
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in_ghidra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ghidra_bridge_server&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;script_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getSourceFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getAbsolutePath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# spin up a ghidra_bridge_server and spawn the script in external python to connect back to it
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;ghidra_bridge_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GhidraBridgeServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run_script_across_ghidra_bridge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;script_file&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;c1&quot;&gt;# we&apos;re being run outside ghidra! (almost certainly from spawned by run_script_across_ghidra_bridge())
&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&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;py3 script that&apos;s expected to be called from ghidra with a bridge&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# the script needs to handle these command-line arguments and use them to connect back to the ghidra server that spawned it
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;--connect_to_host&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;127.0.0.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;IP to connect to the ghidra_bridge server&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;--connect_to_port&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&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;required&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Port to connect to the ghidra_bridge server&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;run_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server_host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect_to_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                   &lt;span class=&quot;n&quot;&gt;server_port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect_to_port&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;We only need to focus on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_script()&lt;/code&gt; function. The other part is static and probably there is no need to change. Only inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_script()&lt;/code&gt; you are allowed to use Python 3 syntax and only here you are allowed to load Python 3 libraries (like Qiling). As you may notice I added  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;response_timeout&lt;/code&gt; to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GhidraBridge&lt;/code&gt; object and sets it’s value to 500 seconds. Why? because as we discussed earlier emulating is a time-consuming task and emulating decryptor functions is likely more time-consuming because there is so much instruction code that needs to be emulated. So we need to set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;response_timeout&lt;/code&gt; to prevent any timeout-related errors.&lt;/p&gt;

&lt;p&gt;Leaving aside the base template, we can now write our Qiling code inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_script()&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;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;server_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qiling&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ghidra_bridge&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ghidra_bridge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GhidraBridge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;globals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response_timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qiling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/home/lopqto/w/automated/samples/netwalker.exe&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/home/lopqto/w/automated/rootfs/x86_windows&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;debug&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract_eax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0040c1a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0040c1a5&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;Back to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extract_eax()&lt;/code&gt; function, we need to integrate it with Ghidra and add extracted API names as a comment into Ghidra. To add a comment from a script first of all we need an address (location). We have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;address&lt;/code&gt; value from Qiling but we need to convert this value to Ghidra’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Address&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;To do this we need &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memory.blocks&lt;/code&gt; object from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;currentProgram&lt;/code&gt; API. But there is a challenge here. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;currentProgram&lt;/code&gt; API only is accessible inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_script()&lt;/code&gt;. But we need this API inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extract_eax()&lt;/code&gt; callback. There is a cool trick to handle this situation. You need to pass things around with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ql&lt;/code&gt; object like below:&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;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_block&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentProgram&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;blocks&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can access to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ql.target_block&lt;/code&gt; inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extract_eax()&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target_block&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memory.blocks[0]&lt;/code&gt;) points to the PE entrypoint at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x00400000&lt;/code&gt;. to convert &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;address&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Address&lt;/code&gt; type we need to calculate offset and do something like this:&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;n&quot;&gt;target_address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getStart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;target_address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00400000&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;Now we have our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target_address&lt;/code&gt; so we need one more step. accessing comment API is similar to above. First we need &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getListring()&lt;/code&gt; object:&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;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;listing&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentProgram&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getListing&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;And to add a comment we can do:&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;n&quot;&gt;codeUnit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;listing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getCodeUnitAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;comment_message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{}.{}&quot;&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;n&quot;&gt;func_dll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;codeUnit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setComment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codeUnit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PRE_COMMENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comment_message&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;Full source code for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extract_eax()&lt;/code&gt; will be this:&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;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;extract_eax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&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;s&quot;&gt;&quot;8941&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buf&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;c1&quot;&gt;# dword ptr [ECX + hex],EAX
&lt;/span&gt;        
        &lt;span class=&quot;n&quot;&gt;eax_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eax&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;import_symbols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eax_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;func_dll&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dll&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;func_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ascii&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;target_address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getStart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;target_address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00400000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;codeUnit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;listing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getCodeUnitAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;comment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{}.{}&quot;&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;n&quot;&gt;func_dll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;codeUnit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setComment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codeUnit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PRE_COMMENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comment&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;Now we have a Ghidra script that will use Python3 to run samples trough Qiling and extract dynamic resolved function names and comment them into Ghidra. See the final result:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/daily-binary-emulation7.png&quot; alt=&quot;Ghidra interface after adding comments&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And we are done. :)&lt;/p&gt;

&lt;h3 id=&quot;tips-and-tricks&quot;&gt;Tips and tricks&lt;/h3&gt;
&lt;p&gt;Two tricks helped me to make this script. First of all, tracing the binary and printing assembly instructions can help a lot while debugging &lt;a href=&quot;https://github.com/qilingframework/qiling/blob/master/examples/hello_x8664_linux_disasm.py&quot;&gt;source!&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;n&quot;&gt;md&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CS_ARCH_X86&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CS_MODE_64&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;print_asm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&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;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;md&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disasm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&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;&quot;:: 0x%x:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%s&quot;&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;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mnemonic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;op_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_asm&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;You can compare emulation result with your disassembler to debug your program.&lt;/p&gt;

&lt;p&gt;The second tip is when you try to run a time-consuming script and write something back to Ghidra (like adding a comment) you may face with an error like 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;ERROR (BackgroundCommandTask) Command Failure: An unexpected error occurred while processing the command: Auto Analysis java.lang.RuntimeException: Timed-out waiting to run a Swing task--potential deadlock!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s because java closed the file and to solve this problem you need to increase timeout. Open the file in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghidra/support/launch.properties&lt;/code&gt; and add this line:&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;nv&quot;&gt;VMARGS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Dghidra&lt;/span&gt;.util.Swing.timeout.seconds&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;3600
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;The idea described in this article can be extended and used to analyze any other malware families that dynamically resolve imports. It’s not an ultimate general solution and you need to change things a little bit to match it against your target binary. I tried to explain my mindset behind the scene as much as possible to help you in this process. Hope this post was helpful.&lt;/p&gt;

&lt;p&gt;Don’t hesitate to ping me if there is something wrong or if you want to discuss about the post. I dropped the final script and the malware sample &lt;a href=&quot;https://github.com/lopqto/YaraRules/tree/master/malwares/netwalker&quot;&gt;here!&lt;/a&gt;.&lt;/p&gt;

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

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://qiling.io/&quot;&gt;Qiling website&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.qiling.io/&quot;&gt;Qiling docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ghidra.re/ghidra_docs/api/index.html&quot;&gt;Ghidra docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=R4xJou6JsIE&quot;&gt;IDA Pro Scripting Intro - Automate Dynamic Import Resolving for REvil Ransomware&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 08 Sep 2020 04:30:00 +0430</pubDate>
        <link>https://lopqto.me/posts/automated-dynamic-import-resolving</link>
        <guid isPermaLink="true">https://lopqto.me/posts/automated-dynamic-import-resolving</guid>
        
        
        <category>reverse-engineering</category>
        
        <category>malware-analysis</category>
        
      </item>
    
      <item>
        <title>Automated malware unpacking with binary emulation</title>
        <description>&lt;p&gt;Probably most of the malwares out there use some sort of packer to evade detection and classification or to make the post-analysis more difficult. So in this blog post, I will talk about one of the most-used packing techniques and how to defeat that with the power of binary emulation. Also, I’ll drop a PoC of the new project that I’m working on. Note that this is a universal generic solution for packers that rely on unpacking code in heap memory and execute it.&lt;/p&gt;

&lt;h3 id=&quot;background&quot;&gt;Background&lt;/h3&gt;

&lt;p&gt;For packers that encrypt or compress a payload, a stub (a piece of code that contains the decompression or decryption routine) acts as a loader, which executes before the malware. So, we have a loader that decrypts or decompress the real malware to execute it. Stub can use so many techniques to achieve its goal.&lt;/p&gt;

&lt;p&gt;There is a technique called self-modifying. In this technique, stub tries to acquire a block of writeable, executable memory, unpack (decrypt/decompress and write) code to the newly allocated memory and finally, transfer execution to the unpacked code in the newly allocated memory.
So, if we manage to somehow read that allocated memory and dump the executable payload, right before the execution, we probably unpacked the real malware.&lt;/p&gt;

&lt;h3 id=&quot;digging-down&quot;&gt;Digging down&lt;/h3&gt;

&lt;p&gt;Let’s dig down more and talk about some Windows APIs. To acquire a new block of memory, malwares will try to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc()&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc()&lt;/code&gt; is a Windows API inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kernel32.dll&lt;/code&gt;. According to Microsoft docs, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc()&lt;/code&gt;:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Reserves, commits, or changes the state of a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero.&lt;/p&gt;
&lt;/blockquote&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;LPVOID&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;VirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;LPVOID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lpAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SIZE_T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dwSize&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;flAllocationType&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;flProtect&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;Important variables here are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dwSize&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flProtect&lt;/code&gt;, and the return value. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dwSize&lt;/code&gt; will define allocated memory block’s size, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flProtect&lt;/code&gt; will define the memory protection and the return value will be the address of the newly allocated memory.&lt;/p&gt;

&lt;p&gt;First of all, we need to catch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flProtect&lt;/code&gt;, since in order to execute code inside a memory region, protection value must be one of the following values:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;PAGE_EXECUTE (0x10)&lt;/li&gt;
  &lt;li&gt;PAGE_EXECUTE_READ (0x20)&lt;/li&gt;
  &lt;li&gt;PAGE_EXECUTE_READWRITE (0x40)&lt;/li&gt;
  &lt;li&gt;PAGE_EXECUTE_WRITECOPY (0x80)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, we need to monitor dynamically allocated memories with executing protection cause they suggest that malware is about to unpack (or otherwise obtain) code to store there.&lt;/p&gt;

&lt;p&gt;There is another interesting API called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect()&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect()&lt;/code&gt; changes the protection of a memory region. Malware can use this API call to change the protection of the allocated memory region if it is not already executable.&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;BOOL&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;VirtualProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;LPVOID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lpAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SIZE_T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dwSize&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;flNewProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;PDWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lpflOldProtect&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;Important variable is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flNewProtect&lt;/code&gt;. like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc()&lt;/code&gt; if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flNewPortect&lt;/code&gt; contains one of the excution values (0x10, 0x20, 0x40 or 0x80) we need to monitor that specific region for unpacked code.&lt;/p&gt;

&lt;p&gt;After we managed to list memory regions with execute protection, we need to set a memory execution breakpoint at those locations. So, if any code executes inside that region (probably unpacked code), we can catch and dump it.&lt;/p&gt;

&lt;h3 id=&quot;choosing-tools-and-solutions&quot;&gt;Choosing tools and solutions&lt;/h3&gt;

&lt;p&gt;I needed a solution to write a cross-platform tool for automatically unpacking malwares with minimal requirements. as a Python developer, I prefer a framework written in Python or with a Python binding. So I chose a binary emulator &lt;a href=&quot;https://www.qiling.io/&quot;&gt;Qiling!&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Qiling Framework is aimed to change IoT security research, malware analysis and reverse engineering landscape. The main objective is to build a cross-platform and multi-architecture framework and not just another reverse engineering tool.
Qiling Framework is designed as a binary instrumentation and binary emulation framework that supports cross-platform and multi-architecture. It is packed with powerful features such as code interception and arbitrary code injection before or during a binary execution. It is also able to patch a packed binary during execution.
Qiling Framework is open source and it is written in Python, a simple and commonly used programming language. This will encourage continuous contributions from the security and open-source community making it a sustainable project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, there is a comparison between Qiling with other tools. take a look at &lt;a href=&quot;https://www.qiling.io/comparison/&quot;&gt;this!&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;writing-a-poc&quot;&gt;Writing a PoC&lt;/h3&gt;

&lt;p&gt;First of all, we need to re-implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect()&lt;/code&gt; APIs in a format that Qiling recognizes. To make this happen, we need to write something like this:&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;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;winapi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;STDCALL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&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;s&quot;&gt;&quot;lpAddress&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;POINTER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;dwSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SIZE_T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;flAllocationType&quot;&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;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;flProtect&quot;&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;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hook_VirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dwSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dwSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem_alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dw_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# allocate memory in heap
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&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;winapi&lt;/code&gt; is a decorator that helps to define the structure of the API call. Here we have an API with calling convention of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;STDCALL&lt;/code&gt; and 4 inputs with the type of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POINTER&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIZE_T&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DWORD&lt;/code&gt;, and yet another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DWORD&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Qiling will pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ql&lt;/code&gt; (sandbox) object as a parameter and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;address&lt;/code&gt; of the location that called the API. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;params&lt;/code&gt; will be a dictionary that contains all passed parameters to that API call.&lt;/p&gt;

&lt;p&gt;For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect()&lt;/code&gt; we can write something like this:&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;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;winapi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;STDCALL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&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;s&quot;&gt;&quot;lpAddress&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;POINTER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;dwSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;flNewProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;lpflOldProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;POINTER&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;hook_VirtualProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&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;mi&quot;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To override default API hooks, Qiling provides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_api&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;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_api&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;VirtualAlloc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hook_VirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_api&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;VirtualProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hook_VirtualProtect&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;Inside hooked APIs we need to catch allocated memory regions with executable protection:&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;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lpAddress&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dw_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dwSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fl_new_protect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;flNewProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# PAGE_EXECUTE (0x10), 
# PAGE_EXECUTE_READ (0x20), 
# PAGE_EXECUTE_READWRITE (0x40), 
# PAGE_EXECUTE_WRITECOPY (0x80),
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fl_new_protect&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# add newly allocated memory to list of memory regions
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;mem_regions&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;s&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dw_size&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 next step will set up a memory execution breakpoint. Qiling offers a function called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hook_code()&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hook_code()&lt;/code&gt; takes 3 parameters. a callback function, beginning, and end of the memory region.&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;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump_memory_region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dw_size&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 any code get excuted inside that memory region, Qiling will call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dump_memory_region()&lt;/code&gt;. To dump that region, Qiling offers &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ql.mem.read()&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read()&lt;/code&gt; takes 2 parameters, start location and size.&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;n&quot;&gt;excuted_mem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&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;Full code for PoC will be:&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;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling&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;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling.os.windows.const&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;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling.os.const&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;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling.os.windows.fncc&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;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling.os.windows.utils&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;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling.os.windows.thread&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;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling.os.windows.handle&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;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling.exception&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;n&quot;&gt;mem_regions&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;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&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;mem_region&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_regions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;start&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;start&apos;&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;mem_region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;size&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;size&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;addr&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;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;# check if address in that memory region
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&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;bp&quot;&gt;None&lt;/span&gt;
            
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dump_memory_region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mem_region&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# check if memory region exists
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# check if that memory region got removed before (duplication)
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_region&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# read memory, start =  first excuted address ; end = end of the region
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;excuted_mem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_region&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;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&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;&quot;&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;address&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;.bin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;wb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;f&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;excuted_mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# write extracted code to a binary file
&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# delete that region to overcome duplication
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;mem_regions&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;s&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_region&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;s&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem_region&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;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;winapi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;STDCALL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&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;s&quot;&gt;&quot;lpAddress&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;POINTER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;dwSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;flNewProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;lpflOldProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;POINTER&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;hook_VirtualProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lpAddress&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dw_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dwSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fl_new_protect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;flNewProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# PAGE_EXECUTE (0x10), 
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# PAGE_EXECUTE_READ (0x20), 
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# PAGE_EXECUTE_READWRITE (0x40), 
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# PAGE_EXECUTE_WRITECOPY (0x80),
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fl_new_protect&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# add newly allocated memory to list of memory regions
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;mem_regions&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;s&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dw_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# add memory on excute breakpoint to newly allocated memory
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump_memory_region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dw_size&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;mi&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;winapi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;STDCALL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&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;s&quot;&gt;&quot;lpAddress&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;POINTER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;dwSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SIZE_T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;flAllocationType&quot;&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;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;flProtect&quot;&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;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hook_VirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dw_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dwSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem_alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dw_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# allocate memory in heap
&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# PAGE_EXECUTE (0x10), 
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# PAGE_EXECUTE_READ (0x20), 
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# PAGE_EXECUTE_READWRITE (0x40), 
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# PAGE_EXECUTE_WRITECOPY (0x80),
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;fl_protect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;flProtect&quot;&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;fl_protect&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x80&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;c1&quot;&gt;# add newly allocated memory to list of memory regions
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;mem_regions&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;s&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dw_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# add memory on excute breakpoint to newly allocated memory
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump_memory_region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dw_size&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;addr&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sandbox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rootfs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# create a sanbox for windows x86
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qiling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rootfs/x86_windows&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;debug&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# set API breakpoints
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_api&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;VirtualAlloc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hook_VirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_api&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;VirtualProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hook_VirtualProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&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;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&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;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&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;o&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;nb&quot;&gt;exit&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;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&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;sandbox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rootfs/x86_windows&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;h3 id=&quot;demonstration&quot;&gt;Demonstration&lt;/h3&gt;

&lt;p&gt;For demonstration, i wrote a small program that runs a shellcode.&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;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;windows.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shellcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;113&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;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x31\xdb\x64\x8b\x7b\x30\x8b\x7f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x77\x20\x8b\x3f\x80\x7e\x0c\x33&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x75\xf2\x89\xc7\x03\x78\x3c\x8b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x57\x78\x01\xc2\x8b\x7a\x20\x01&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xc7\x89\xdd\x8b\x34\xaf\x01\xc6&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x45\x81\x3e\x43\x72\x65\x61\x75&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xf2\x81\x7e\x08\x6f\x63\x65\x73&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x75\xe9\x8b\x7a\x24\x01\xc7\x66&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xb1\xff\x53\xe2\xfd\x68\x63\x61&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x6c\x63\x89\xe2\x52\x52\x53\x53&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x53\x53\x53\x53\x52\x53\xff\xd7&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&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;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;old_protect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;LPVOID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;executable_area&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;113&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MEM_RESERVE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PAGE_READWRITE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;executable_area&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;executable_area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;113&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MEM_COMMIT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PAGE_READWRITE&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;executable_area&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;error in allocating memory&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;memcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;executable_area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shellcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;113&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;VirtualProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;executable_area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;113&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PAGE_EXECUTE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;old_protect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;int&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;f&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&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;p&quot;&gt;)())&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;executable_area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;VirtualFree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;executable_area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;113&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MEM_RELEASE&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;We can try the PoC for that program and see output:
&lt;img src=&quot;/img/automated-malware-unpacking1.png&quot; alt=&quot;PoC output&quot; /&gt;
&lt;img src=&quot;/img/automated-malware-unpacking2.png&quot; alt=&quot;PoC output&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We managed to dump the shellcode successfully. I hope this was helpful. :)&lt;/p&gt;

&lt;p&gt;Please do not hesitate to ping me if there is something wrong!&lt;/p&gt;

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

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://qiling.io/&quot;&gt;Qiling website&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.qiling.io/&quot;&gt;Qiling docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=FctDptnYukQ&quot;&gt;OALabs youtube video about automated malware unpacking&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 24 May 2020 04:30:00 +0430</pubDate>
        <link>https://lopqto.me/posts/automated-malware-unpacking</link>
        <guid isPermaLink="true">https://lopqto.me/posts/automated-malware-unpacking</guid>
        
        
        <category>reverse-engineering</category>
        
        <category>malware-analysis</category>
        
      </item>
    
      <item>
        <title>Decrypting NetWire&apos;s keylog files</title>
        <description>&lt;p&gt;NetWire is recently back to the malware trends again. This new variant of NetWire uses Guloader to distribute itself. After some observation, it seems that NetWire creators changed the encryption routine. In this analysis, I am going to present you how to reverse the new encryption routine and get a clean version of the keylog file.&lt;/p&gt;

&lt;h3 id=&quot;background&quot;&gt;Background&lt;/h3&gt;

&lt;p&gt;According to the malpedia:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Netwire is a RAT, its functionality seems focused on password stealing and keylogging, but includes remote control capabilities as well.
Keylog files are stored on the infected machine in an obfuscated form. &lt;a href=&quot;https://malpedia.caad.fkie.fraunhofer.de/details/win.netwire&quot;&gt;link!&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Netwire has lots of functionalities such as taking remote control of infected PCs, keylogging, taking screenshots and extracting system information. NetWire creators added multiple data encryption layers to make a hard time for researchers. there are some sources out there about the decryption of implemented custom C&amp;amp;C binary protocol but there are limited sources (almost nothing) about decrypting keylog files.&lt;/p&gt;

&lt;h3 id=&quot;netwire-encryption-routine&quot;&gt;NetWire encryption routine&lt;/h3&gt;

&lt;p&gt;Let’s follow the white rabbit down to the rabbit hole. After execution, NetWire makes a folder at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%APPDATA%/Logs&lt;/code&gt; and saves keylog files there. I won’t analyze the whole malware in this blog post, only the encryption routine since with some search, you can find public researchers about analyzing NetWire.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/netwire-decrypting-keylog-file1.png&quot; alt=&quot;keylog file in windows explore&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We need to open NetWire in a disassembler (ida free will be enough) and find the correct function that writes to the log file. To achieve this goal we can look at the import section and search for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WriteFile&lt;/code&gt; Windows API call. xrefing shows there are 2 locations that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WriteFile&lt;/code&gt; got used.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/netwire-decrypting-keylog-file2.png&quot; alt=&quot;ida xref WriteFile&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s look at the first one.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/netwire-decrypting-keylog-file3.png&quot; alt=&quot;ida disassembly window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Dissecting more shows us an interesting string. Probably in this block, NetWire tries to generate keylog file names like what we saw earlier.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/netwire-decrypting-keylog-file4.png&quot; alt=&quot;interesting string &quot; /&gt;&lt;/p&gt;

&lt;p&gt;So Let’s assume this is the right one and dig in more. To cheat we can fire up Ghidra with default config and try to analyze decompiled version of this function.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/netwire-decrypting-keylog-file5.png&quot; alt=&quot;ghidra decompile window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can clean up the code to make it more human-readable. Investigating more shows us an interesting piece of code at the middle of the function. to make it more complicated NetWire tries to load every buffer in 4-bit chunks and do encryption stuff at every bit separately.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/netwire-decrypting-keylog-file6.png&quot; alt=&quot;encryption routine&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And to make things clear we can estimate the algorithm is something like this:&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&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;n&quot;&gt;number_of_bytes_to_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&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;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&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;0x9D&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;0x24&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Reversing this opration is easy. we need to do an operation like this:&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&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;0x24&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;0x9D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;netwire-decryptor&quot;&gt;NetWire decryptor&lt;/h3&gt;

&lt;p&gt;I wrote a small python script that you can find &lt;a href=&quot;https://github.com/lopqto/YaraRules/blob/master/malwares/netwire/decrypt_netwire.py&quot;&gt;here&lt;/a&gt;. Just pass the filename as argv and you can get the decrypted version of the keylog file in output.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/netwire-decrypting-keylog-file7.png&quot; alt=&quot;decryption example&quot; /&gt;&lt;/p&gt;

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

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://any.run/malware-trends/netwire&quot;&gt;Netwire at any.run&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://malpedia.caad.fkie.fraunhofer.de/details/win.netwire&quot;&gt;Netwire RC at malpedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 29 Mar 2020 04:30:00 +0430</pubDate>
        <link>https://lopqto.me/posts/netwire-decrypting-keylog-file</link>
        <guid isPermaLink="true">https://lopqto.me/posts/netwire-decrypting-keylog-file</guid>
        
        
        <category>reverse-engineering</category>
        
        <category>malware-analysis</category>
        
      </item>
    
      <item>
        <title>Crackmes for lazies: angr demonstration</title>
        <description>&lt;p&gt;I have been playing crackmes and CTFs all the time to boost my reverse engineering knowledge and learn new stuff, but there are times that you find some challenges boring or without new unique technics so you develop some automation tools to pass the challenges. So in this blog post, I’m gonna show you my ultimate tool to solve these types of challenges.&lt;/p&gt;

&lt;h3 id=&quot;what-is-angr-and-why&quot;&gt;What is angr and why?&lt;/h3&gt;
&lt;p&gt;According to the angr’s website:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;angr is a multi-architecture binary analysis toolkit, with the capability to perform dynamic symbolic execution (like Mayhem, KLEE, etc.) and various static analyses on binaries.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;why am I using angr? cause angr is a pain-free toolkit with a supporting binding for Python programming language and makes binary analysis easy. the scenario is simple: find the location or function that prints the flag and give the address to angr. If you wait long enough, angr will give you the right input to reach the requested flag&lt;/p&gt;

&lt;h3 id=&quot;symbolic-execution&quot;&gt;Symbolic execution&lt;/h3&gt;
&lt;p&gt;Let’s make things clear for ourselves. What is the goal of a typical crackme? Find the right input that passes the checks (some conditional branches) and prints the flag. According to Wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;In computer science, symbolic execution (also symbolic evaluation) is a means of analyzing a program to determine what inputs cause each part of a program to execute. An interpreter follows the program, assuming symbolic values for inputs rather than obtaining actual inputs as normal execution of the program would. It thus arrives at expressions in terms of those symbols for expressions and variables in the program, and constraints in terms of those symbols for the possible outcomes of each conditional branch. &lt;a href=&quot;https://en.wikipedia.org/wiki/Symbolic_execution&quot;&gt;link!&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So angr will assume the input as a symbolic value and with the power of symbolic execution, it will find the path which leads to eventual printing of the flag. After finding the path, we have a series of conditions that our input needs to pass them to reach that location. angr will solve these conditions using SMT solver, like z3, in order to ask questions like “given the output of this sequence of operations, what must the input have been?”&lt;/p&gt;

&lt;h3 id=&quot;demo-time&quot;&gt;Demo time&lt;/h3&gt;
&lt;p&gt;I found an interesting crackme challenge that has 13 checks. It will be much harder to follow these checks manually but with the power of angr, the challenges will be done with ~10 lines of code and ~30sec of computing time.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/crackmes-for-lazies2.png&quot; alt=&quot;challenge with wrong input&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/crackmes-for-lazies1.png&quot; alt=&quot;challenge checks&quot; /&gt;&lt;/p&gt;

&lt;p&gt;for this challenege,i wrote this code:&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;angr&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;claripy&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;angr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;./keygen&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_options&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;s&quot;&gt;&apos;auto_load_libs&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;argv1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;claripy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BVS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;argv1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&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;s&quot;&gt;&apos;./keygen&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; 
&lt;span class=&quot;n&quot;&gt;sm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;simulation_manager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;explore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x401a5a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;avoid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x401a73&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;found&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;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;solver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cast_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bytes&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;Now it’s the time to dissect the code. First of all, you need to install &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;angr&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt;. angr has dropped python2 support and you need python3 to use angr.&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;pip &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;angr
&lt;span class=&quot;c&quot;&gt;# or &lt;/span&gt;
pip3 &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;angr
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In this line, we create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Project&lt;/code&gt; object and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./keygen&lt;/code&gt; is the relative address to our binary. what about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load_options&lt;/code&gt;?&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;The CFG analysis does not distinguish between code from different binary objects. This means that by default, it will try to analyze control flow through loaded shared libraries. Since processing the shared libraries will probably prolong the analysis to even days, it’s almost never intended behavior. To load a binary without shared libraries, add the following keyword argument to the Project constructor: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load_options={&apos;auto_load_libs&apos;: False}&lt;/code&gt;. &lt;a href=&quot;https://docs.angr.io/built-in-analyses/cfg#shared-libraries&quot;&gt;link!&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&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;n&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;angr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;./keygen&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_options&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;s&quot;&gt;&apos;auto_load_libs&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&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;After that, we need to define our input (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;argv1&lt;/code&gt;) as a symbolic value. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BVS&lt;/code&gt; creates a 32-bit symbolic bit vector with the size of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xF * 8&lt;/code&gt;. you need to define the size equal or bigger than the correct input. &lt;a href=&quot;https://docs.angr.io/built-in-analyses/cfg#shared-libraries&quot;&gt;link!&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;n&quot;&gt;argv1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;claripy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BVS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;argv1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&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;angr has 4 initial states:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blank_state()&lt;/code&gt; constructs a “blank slate” blank state, with most of its data left uninitialized.
When accessing uninitialized data, an unconstrained symbolic value will be returned.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;entry_state()&lt;/code&gt; constructs a state ready to execute at the main binary’s entry point.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;full_init_state()&lt;/code&gt; constructs a state that is ready to execute through any initializers that need to be run before the main binary’s entry point, for example, shared library constructors or preinitializers.
When it is finished with these it will jump to the entry point.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call_state()&lt;/code&gt; constructs a state ready to execute a given function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our binary gets input as an argv and according to the docs:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;If you’re executing in an environment that can take command line arguments or an environment, you can pass a list of arguments through args and a dictionary of environment variables through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;entry_state&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;full_init_state&lt;/code&gt;. The values in these structures can be strings or bitvectors, and will be serialized into the state as the arguments and environment to the simulated execution. &lt;a href=&quot;https://docs.angr.io/core-concepts/states#state-presets&quot;&gt;link!&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;so in this line, we picked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;entry_state&lt;/code&gt; to pass the symbolic value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;argv1&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;n&quot;&gt;initial_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&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;s&quot;&gt;&apos;./keygen&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv1&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;blockquote&gt;
  &lt;p&gt;The most important control interface in angr is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimulationManager&lt;/code&gt;, which allows you to control symbolic execution over groups of states simultaneously, applying search strategies to explore a program’s state space. &lt;a href=&quot;https://docs.angr.io/core-concepts/pathgroups&quot;&gt;link!&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We need to define &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimulationManager&lt;/code&gt; and path the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initial_state&lt;/code&gt; to it.&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;n&quot;&gt;sm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;simulation_manager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initial_state&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;An extremely common operation in symbolic execution is to find a state that reaches a certain address, while discarding all states that go through another address. Simulation manager has a shortcut for this pattern, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.explore()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;When launching &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.explore()&lt;/code&gt; with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt; argument, execution will run until a state is found that matches the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt; condition. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt; condition can be the address of an instruction to stop, a list of addresses to stop, or a function which takes a state and returns whether it meets some criteria. When any of the states in the active stash match the find condition, they are placed in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;found&lt;/code&gt; stash, and execution terminates. You can then explore the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;found&lt;/code&gt; state, or decide to discard it and continue with the other ones. You can also specify an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;avoid&lt;/code&gt; condition in the same format as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt;. When a state matches the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;avoid&lt;/code&gt; condition, it is put in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;avoided&lt;/code&gt; stash, and execution continues.&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;n&quot;&gt;sm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;explore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x401a5a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;avoid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x401a73&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 look at the binary:
&lt;img src=&quot;/img/crackmes-for-lazies3.png&quot; alt=&quot;addresses&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The address of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ACCESS GRANTED&lt;/code&gt; print is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x401a5a&lt;/code&gt; and the adress of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ACCESS DENIED&lt;/code&gt; print is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x401a73&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I wrote the last two lines to grab the first value from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;found&lt;/code&gt; stash and cast that value to byte and print the final result.&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;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;found&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;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;solver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cast_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bytes&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 run our program to see the result:
&lt;img src=&quot;/img/crackmes-for-lazies4.png&quot; alt=&quot;run&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s it, I hope you find this useful.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.angr.io/&quot;&gt;angr docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Symbolic_execution&quot;&gt;Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 01 Mar 2020 19:10:00 +0330</pubDate>
        <link>https://lopqto.me/posts/crackmes-for-lazies</link>
        <guid isPermaLink="true">https://lopqto.me/posts/crackmes-for-lazies</guid>
        
        
        <category>reverse-engineering</category>
        
        <category>crackmes</category>
        
      </item>
    
      <item>
        <title>Frida by example: bypassing IsDebuggerPresent() check</title>
        <description>&lt;p&gt;Almost every malware exists out there has a functionally to make the post-detection analysis more difficult. Threat actors use various anti-debugging techniques, one of the more common ones used to check whether a debugger is on via IsDebuggerPresent() Windows API call. In this blog post, we will discuss how to bypass this technique by Frida.&lt;/p&gt;

&lt;h3 id=&quot;why-frida&quot;&gt;why Frida?&lt;/h3&gt;
&lt;p&gt;Frida is a dynamic instrumentation toolkit. It gives a simple interface where you can develop complex hooking logic rapidly and make changes to it as your requirements. Frida supports Windows, macOS, GNU/Linux, iOS, Android, and QNX.&lt;/p&gt;

&lt;h3 id=&quot;prepare-a-sample-pe&quot;&gt;Prepare a sample PE&lt;/h3&gt;
&lt;p&gt;To allow us to dynamically test our function hooks I wrote a small Windows test application harness in C++. You can see the main functionality below, it’s short and easy to understand.&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;c1&quot;&gt;// target.cpp&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;Windows.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&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;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;check&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsDebuggerPresent&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;check&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;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cool!&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;common ..&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Lets try to look at &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/windows/desktop/ms680345(v=vs.85).aspx&quot;&gt;IsDebuggerPresent()&lt;/a&gt; C++ function prototype.&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;BOOL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WINAPI&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IsDebuggerPresent&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;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;According to Microsoft docs, if the current process is not running in the context of a debugger, the return value will be zero.&lt;/p&gt;

&lt;h3 id=&quot;bypassing-isdebuggerpresent&quot;&gt;Bypassing IsDebuggerPresent()&lt;/h3&gt;
&lt;p&gt;First of all, you need to install Frida, start from here: &lt;a href=&quot;https://www.frida.re/docs/installation/&quot;&gt;documentation&lt;/a&gt;. You can test your installation by running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frida-ps.exe&lt;/code&gt; in Powershell or CMD.&lt;/p&gt;

&lt;p&gt;How The Frida works? Frida will inject Google’s V8 engine to a specific process. After that it will run JavaScript code and generate a dynamic hook. Lets make our hand dirty and write some JavaScript codes. :)&lt;/p&gt;

&lt;p&gt;For hooking purpose we will use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Interceptor&lt;/code&gt; API.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Interceptor.attach(target, callbacks)&lt;/code&gt;: intercept calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target&lt;/code&gt; function. it’s a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NativePointer&lt;/code&gt; specifying the address of the function you would like to intercept calls to.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To begin, we need to find the address of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IsDebuggerPresent()&lt;/code&gt; function by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DebugSymbol&lt;/code&gt; API.&lt;/p&gt;

&lt;div class=&quot;language-javascript 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;// poc.js&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;isDebuggerPresentAddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DebugSymbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getFunctionByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;IsDebuggerPresent&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;function address : &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isDebuggerPresentAddr&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;Using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Interceptor&lt;/code&gt;, we can quickly hook the application and write some basic JS to make &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IsDebuggerPresnt&lt;/code&gt; to always return 0. Notice the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isDebuggerPresentAddr&lt;/code&gt; in the code.&lt;/p&gt;

&lt;div class=&quot;language-javascript 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;// poc.js&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;Interceptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isDebuggerPresentAddr&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;na&quot;&gt;onEnter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&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;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;IsDebuggerPresent() get called ...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&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;na&quot;&gt;onLeave&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;retval&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;nx&quot;&gt;retval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;replace&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;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;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;retval&lt;/code&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NativePointer&lt;/code&gt;-derived object containing the raw return value. We can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;replace()&lt;/code&gt; to change the return value.&lt;/p&gt;

&lt;p&gt;Now it’s time to test the bypass method. First we spawn process without injecting our code:&lt;/p&gt;

&lt;div class=&quot;language-powershell 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;frida.exe&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;\target.exe&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Frida will stop on Entrypoint.Now try to attach your debugger to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target.exe&lt;/code&gt; process and then type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%resume&lt;/code&gt; command to continue execution. debugger will be detected by the process.
&lt;img src=&quot;/img/frida-by-example1.png&quot; alt=&quot;debugger got detect&quot; /&gt;
Run the following command to inject our code and bypass the check:&lt;/p&gt;
&lt;div class=&quot;language-powershell 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;frida.exe&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;\target.exe&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;\poc.js&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can see the result below.
&lt;img src=&quot;/img/frida-by-example2.png&quot; alt=&quot;debugger not detect&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IsDebuggerPresent()&lt;/code&gt; has been bypassed successfully. :)&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.frida.re/docs/javascript-api&quot;&gt;frida.re docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/desktop/apiindex/api-index-portal&quot;&gt;Microsoft MSDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;read-more&quot;&gt;Read more&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.n0p.me/2018/03/2018-03-27-dynamic-binary-analysis/&quot;&gt;Getting started with Dynamic Binary Analysis by Ali Mosajjal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 20 Apr 2019 20:00:00 +0430</pubDate>
        <link>https://lopqto.me/posts/frida-by-example</link>
        <guid isPermaLink="true">https://lopqto.me/posts/frida-by-example</guid>
        
        
        <category>reverse-engineering</category>
        
        <category>malware-analysis</category>
        
      </item>
    
  </channel>
</rss>
