<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: JM00NJ</title>
    <description>The latest articles on DEV Community by JM00NJ (@jm00nj).</description>
    <link>https://dev.to/jm00nj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4005327%2Fcdc71a8f-4480-456e-b794-da1d549753c0.png</url>
      <title>DEV Community: JM00NJ</title>
      <link>https://dev.to/jm00nj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jm00nj"/>
    <language>en</language>
    <item>
      <title>Linux sends ICMP Echo with 56-byte payload + 8-byte header = 64 bytes total. Windows uses 32 bytes. NDR systems fingerprint hosts by these defaults — before any exploit lands. This post shows how to mimic any OS at the raw socket level.</title>
      <dc:creator>JM00NJ</dc:creator>
      <pubDate>Sat, 27 Jun 2026 12:58:28 +0000</pubDate>
      <link>https://dev.to/jm00nj/linux-sends-icmp-echo-with-56-byte-payload-8-byte-header-64-bytes-total-windows-uses-32-bytes-1jhe</link>
      <guid>https://dev.to/jm00nj/linux-sends-icmp-echo-with-56-byte-payload-8-byte-header-64-bytes-total-windows-uses-32-bytes-1jhe</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/jm00nj/network-fingerprinting-analyzing-default-icmp-structures-and-payload-mimicry-4636" class="crayons-story__hidden-navigation-link"&gt;Network Fingerprinting: Analyzing Default ICMP Structures and Payload Mimicry&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/jm00nj" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4005327%2Fcdc71a8f-4480-456e-b794-da1d549753c0.png" alt="jm00nj profile" class="crayons-avatar__image" width="800" height="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/jm00nj" class="crayons-story__secondary fw-medium m:hidden"&gt;
              JM00NJ
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                JM00NJ
                
              
              &lt;div id="story-author-preview-content-4005878" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/jm00nj" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4005327%2Fcdc71a8f-4480-456e-b794-da1d549753c0.png" class="crayons-avatar__image" alt="" width="800" height="800"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;JM00NJ&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/jm00nj/network-fingerprinting-analyzing-default-icmp-structures-and-payload-mimicry-4636" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 27&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/jm00nj/network-fingerprinting-analyzing-default-icmp-structures-and-payload-mimicry-4636" id="article-link-4005878"&gt;
          Network Fingerprinting: Analyzing Default ICMP Structures and Payload Mimicry
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cybersecurity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cybersecurity&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/assembly"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;assembly&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/linux"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;linux&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/network"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;network&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/jm00nj/network-fingerprinting-analyzing-default-icmp-structures-and-payload-mimicry-4636#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>cybersecurity</category>
      <category>linux</category>
      <category>networking</category>
      <category>security</category>
    </item>
    <item>
      <title>Network Fingerprinting: Analyzing Default ICMP Structures and Payload Mimicry</title>
      <dc:creator>JM00NJ</dc:creator>
      <pubDate>Sat, 27 Jun 2026 12:46:31 +0000</pubDate>
      <link>https://dev.to/jm00nj/network-fingerprinting-analyzing-default-icmp-structures-and-payload-mimicry-4636</link>
      <guid>https://dev.to/jm00nj/network-fingerprinting-analyzing-default-icmp-structures-and-payload-mimicry-4636</guid>
      <description>&lt;h2&gt;
  
  
  Research Context
&lt;/h2&gt;

&lt;p&gt;"In advanced network observability, understanding the default behavior of various operating systems is vital for traffic profiling. This article explores the structural differences in ICMP Echo Requests across different OS environments and analyzes how 'Traffic Mimicry' can be used to evaluate the accuracy of Network Intrusion Detection Systems (NIDS)."&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Anatomy of an ICMP Signature
&lt;/h3&gt;

&lt;p&gt;A standard ICMP Echo Request is not just a simple signal; it carries a specific "fingerprint" based on the operating system that generated it. These fingerprints consist of:&lt;/p&gt;

&lt;p&gt;Total Packet Size&lt;/p&gt;

&lt;p&gt;TTL (Time to Live) values&lt;/p&gt;

&lt;p&gt;Default Payload Content&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Cross-Platform Discrepancies (Linux vs. Windows)
&lt;/h3&gt;

&lt;p&gt;When a system sends a "ping," the default data size ($D$) and the total packet length ($L$) vary significantly between architectures.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Linux (Typical)&lt;/th&gt;
&lt;th&gt;Windows (Typical)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Data Size ($D$)&lt;/td&gt;
&lt;td&gt;56 Bytes&lt;/td&gt;
&lt;td&gt;32 Bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ICMP Header ($H$)&lt;/td&gt;
&lt;td&gt;8 Bytes&lt;/td&gt;
&lt;td&gt;8 Bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total ICMP Length ($L$)&lt;/td&gt;
&lt;td&gt;64 Bytes&lt;/td&gt;
&lt;td&gt;40 Bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default Payload&lt;/td&gt;
&lt;td&gt;Timestamp + Data&lt;/td&gt;
&lt;td&gt;abcdefg...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Linux Signature&lt;br&gt;
In most Linux distributions, the ping utility sends 56 bytes of data. When combined with the 8-byte ICMP header, it totals 64 bytes. A key characteristic of Linux ICMP traffic is that the first few bytes of the payload are often occupied by a high-resolution timestamp, used to calculate RTT (Round Trip Time) with microsecond precision.&lt;/p&gt;

&lt;p&gt;The Windows Signature&lt;br&gt;
Windows systems default to a 32-byte data payload. The payload content is static and follows a predictable alphabetical sequence: abcdefghijklmnopqrstuvwabcdefghi. This static nature makes Windows ICMP traffic easily identifiable during deep packet inspection (DPI).&lt;/p&gt;
&lt;h3&gt;
  
  
  3. The Concept of Traffic Mimicry
&lt;/h3&gt;

&lt;p&gt;Traffic Mimicry is a research method used to test the resilience of network filters. By aligning custom communication protocols with the default signatures of a specific OS, researchers can evaluate whether a security appliance is biased toward certain traffic patterns.&lt;/p&gt;

&lt;p&gt;For example, when developing a Remote Management Interface in x64 Assembly, ensuring the payload size ($D$) is exactly 32 bytes or 56 bytes allows the traffic to blend into the "Ambient Noise" of a corporate network.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Implementation: Engineering a Mimicry-Aligned Packet Structure
&lt;/h3&gt;

&lt;p&gt;To evaluate the resilience of network monitoring tools, we must construct a packet architecture that adheres strictly to the structural expectations of a standard Linux environment. Below is the assembly-level definition of an ICMP Echo Reply, designed with Structural Alignment in mind.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nasm"&gt;&lt;code&gt;
&lt;span class="c1"&gt;; --- [MIMICRY UPDATE] UPDATED PACKET ARCHITECTURE ---&lt;/span&gt;

&lt;span class="c1"&gt;; This structure strictly aligns with the 64-byte Linux ICMP Echo signature&lt;/span&gt;

&lt;span class="nl"&gt;icmp_packet:&lt;/span&gt;

    &lt;span class="nf"&gt;type&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;                &lt;span class="c1"&gt;; ICMP Type 0 (Echo Reply)&lt;/span&gt;

    &lt;span class="nf"&gt;code&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;                

    &lt;span class="nf"&gt;checksum&lt;/span&gt; &lt;span class="nv"&gt;dw&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;            &lt;span class="c1"&gt;; Checksum placeholder&lt;/span&gt;

    &lt;span class="nf"&gt;identifier&lt;/span&gt; &lt;span class="nv"&gt;dw&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="c1"&gt;; Process Identifier&lt;/span&gt;

    &lt;span class="nf"&gt;sequence&lt;/span&gt; &lt;span class="nv"&gt;dw&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;            &lt;span class="c1"&gt;; Internal signaling sequence&lt;/span&gt;



    &lt;span class="c1"&gt;; --- MIMICRY PADDING (24 BYTES) ---&lt;/span&gt;

    &lt;span class="c1"&gt;; Emulates the default timestamp behavior of modern network stacks&lt;/span&gt;

    &lt;span class="nf"&gt;mimicry_ts&lt;/span&gt; &lt;span class="nv"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="c1"&gt;; 8-byte Dynamic Timestamp (Cycle-accurate timing)&lt;/span&gt;



    &lt;span class="c1"&gt;; 16-byte Sequential Padding: Replicates standard OS data patterns&lt;/span&gt;

    &lt;span class="nf"&gt;mimicry_seq&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt; &lt;span class="mh"&gt;0x10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x17&lt;/span&gt;

                &lt;span class="kd"&gt;db&lt;/span&gt; &lt;span class="mh"&gt;0x18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1F&lt;/span&gt;



    &lt;span class="c1"&gt;; --- DATA TRANSMISSION AREA ---&lt;/span&gt;

    &lt;span class="nf"&gt;payload&lt;/span&gt; &lt;span class="nv"&gt;times&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;    &lt;span class="c1"&gt;; 32-byte payload chunk to hit the 64-byte total&lt;/span&gt;

    &lt;span class="no"&gt;payload_len&lt;/span&gt;&lt;span class="kd"&gt; equ&lt;/span&gt; &lt;span class="kc"&gt;$&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;icmp_packet&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Analysis of the Structural Logic&lt;br&gt;
Timestamp Emulation (mimicry_ts): Standard Linux ping requests embed an 8-byte timestamp to calculate RTT. By reserving this space and populating it with high-precision timing data (via RDTSC), our custom communication layer avoids the "Empty Payload" signature that often triggers NIDS anomalies.&lt;/p&gt;

&lt;p&gt;Sequential Byte Padding (mimicry_seq): Many network filters look for entropy in the payload. By utilizing a fixed, sequential padding (0x10 to 0x1F), we replicate the predictable data structures of kernel-level protocol implementations.&lt;/p&gt;

&lt;p&gt;The 64-Byte Structural Boundary: By dedicating 24 bytes to structural emulation and allocating exactly 32 bytes for the data payload, the internal data segment equals the 56-byte Linux standard. When combined with the 8-byte ICMP header, the total packet size is precisely 64 bytes (8 + 24 + 32 = 64). This ensures that the traffic volume remains strictly within the expected "Ambient Noise" threshold.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Defensive Implications: Anomaly Detection
&lt;/h3&gt;

&lt;p&gt;From a Blue Team perspective, identifying "Mimicry" requires looking beyond packet size. Advanced detection strategies include:&lt;/p&gt;

&lt;p&gt;Entropy Analysis: Monitoring the randomness of the payload.&lt;/p&gt;

&lt;p&gt;TTL Consistency: Checking if the TTL value matches the expected OS signature.&lt;/p&gt;

&lt;p&gt;Frequency Analysis: Analyzing if the ICMP requests follow the standard interval pattern of a human-initiated ping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding the "Default State" of network protocols is the first step in advanced system auditing. Mimicry is not just about blending in; it is a critical tool for identifying the limitations of signature-based detection. By mastering the low-level construction of ICMP packets, researchers can develop more robust and observable communication frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Legal Disclaimer
&lt;/h2&gt;

&lt;p&gt;This project is created for educational purposes and security research only. Unauthorized access to computer systems is illegal. The author is not responsible for any misuse of this tool. Operating this tool on networks you do not own is strictly prohibited.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://netacoding.com/posts/icmp_sniffer/" rel="noopener noreferrer"&gt;Building a Low-Level ICMP Sniffer in x64 Assembly (Raw Sockets)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netacoding.com/posts/algorithmforprinting-ip_addresses/" rel="noopener noreferrer"&gt;Solving IP Endianness in x64 Assembly: A Single-Pass Algorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netacoding.com/posts/assembly-httpserver/" rel="noopener noreferrer"&gt;Defying Python: Building a Bare-Metal HTTP Server in x86_64 Assembly&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cybersecurity</category>
      <category>assembly</category>
      <category>linux</category>
      <category>network</category>
    </item>
    <item>
      <title>Solving IP Endianness in x64 Assembly: A Single-Pass Algorithm</title>
      <dc:creator>JM00NJ</dc:creator>
      <pubDate>Sat, 27 Jun 2026 12:34:20 +0000</pubDate>
      <link>https://dev.to/jm00nj/solving-ip-endianness-in-x64-assembly-a-single-pass-algorithm-3n9b</link>
      <guid>https://dev.to/jm00nj/solving-ip-endianness-in-x64-assembly-a-single-pass-algorithm-3n9b</guid>
      <description>&lt;h2&gt;
  
  
  Research Context
&lt;/h2&gt;

&lt;p&gt;When doing low-level network programming in Assembly, you experience firsthand the immense chaos running behind the scenes of operations we solve with a single line in high-level languages (Python, C, etc.). While developing the Nested-ICMP-Communication Analysis project, specifically an Encapsulated ICMP framework, I hit exactly this kind of wall: extracting an IP address from a packet header and printing it to the screen in the correct format.&lt;/p&gt;

&lt;p&gt;Sounds simple, right? However, when x86 architecture and network protocols are involved, seeing 5.1.168.192 instead of 192.168.1.5 on your terminal is extremely common.&lt;/p&gt;

&lt;p&gt;So why does this happen, and what kind of algorithm did I develop to overcome this issue during the debugging process? Let's dive into the background.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Endianness Problem in Network Headers
&lt;/h3&gt;

&lt;p&gt;When you capture a packet coming over the network and read the source/destination IP address inside the sockaddr_in structure, the data arrives in Network Byte Order (Big-Endian) format. This means the most significant byte is stored at the lowest memory address.&lt;/p&gt;

&lt;p&gt;However, the x86/x64 processor architectures we use rely on Little-Endian (Host Byte Order). When the processor pulls this 4-byte IP data into a register, the reading direction is effectively reversed for our purposes.&lt;/p&gt;

&lt;p&gt;The result? A packet that arrives as 192.168.1.5 appears scrambled if we try to naively print it from memory. The inet_ntoa() function in high-level languages handles this conversion in the background. But if you are writing a custom sniffer in pure Assembly, you must do this conversion byte by byte yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging Hell: The Problems Encountered
&lt;/h3&gt;

&lt;p&gt;While writing this conversion, I encountered a few critical issues that cost me hours in GDB (GNU Debugger):&lt;/p&gt;

&lt;p&gt;Register Clashes: While separating each octet (byte) of the IP address and converting it to an ASCII character (string), you must use the AX register for division operations (DIV). If you don't carefully manage your remainders (AH) and quotients (AL), the numbers of the IP address get completely corrupted.&lt;/p&gt;

&lt;p&gt;The Dot (.) Separator: It's not enough to just convert the numbers; a . (0x2E / 46 in decimal) character must be inserted exactly between each octet, but not at the very end.&lt;/p&gt;

&lt;p&gt;Performance Loss (The Reversing Trap): In standard logic, you parse the IP, convert it to a string, and realize the string is backwards. Then, you write a second loop to reverse that string. This creates unnecessary memory read/write cycles and bloats the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: A Single-Pass Backward Build Algorithm
&lt;/h3&gt;

&lt;p&gt;To solve the problem, instead of creating the string and then reversing it, I designed a more optimized algorithm.&lt;/p&gt;

&lt;p&gt;The logic is simple but highly effective: Read the IP bytes backwards, and write the ASCII string backwards. By starting at the end of the IP address within the sockaddr_in structure (offset 7 down to 4) and writing from the end of a 15-byte output buffer (addr_ip) down to index 0, the string naturally formats itself correctly from left to right.&lt;/p&gt;

&lt;p&gt;Here is the exact critical loop from my engine:&lt;/p&gt;

&lt;h3&gt;
  
  
  ASSEMBLY CODE:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nasm"&gt;&lt;code&gt;
&lt;span class="c1"&gt;; IP ADDRESS TO STRING ALGORITHM (EXTRACT REVERSE BYTE-BY-BYTE AND CONVERT TO ASCII)&lt;/span&gt;

    &lt;span class="nf"&gt;xor&lt;/span&gt; &lt;span class="nb"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;rdx&lt;/span&gt;                &lt;span class="c1"&gt;; Clear rdx&lt;/span&gt;
    &lt;span class="nf"&gt;xor&lt;/span&gt; &lt;span class="nb"&gt;rbx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;rbx&lt;/span&gt;                &lt;span class="c1"&gt;; Clear rbx&lt;/span&gt;
    &lt;span class="nf"&gt;mov&lt;/span&gt; &lt;span class="nb"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;                  &lt;span class="c1"&gt;; Start index for reading IP from sockaddr_in (sin_addr offset)&lt;/span&gt;
    &lt;span class="nf"&gt;mov&lt;/span&gt; &lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;                 &lt;span class="c1"&gt;; Start index for writing to the addr_ip buffer (backwards)&lt;/span&gt;
&lt;span class="nl"&gt;_loopforip:&lt;/span&gt;
    &lt;span class="nf"&gt;mov&lt;/span&gt; &lt;span class="nb"&gt;bl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;                  &lt;span class="c1"&gt;; Divisor for base-10 conversion&lt;/span&gt;
    &lt;span class="nf"&gt;movzx&lt;/span&gt; &lt;span class="nb"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;incoming_addr&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;; Fetch one octet from IP address&lt;/span&gt;
&lt;span class="nl"&gt;_divloop:&lt;/span&gt;
    &lt;span class="nf"&gt;div&lt;/span&gt; &lt;span class="nb"&gt;bl&lt;/span&gt;                      &lt;span class="c1"&gt;; Divide AX by 10; AL = quotient, AH = remainder&lt;/span&gt;
    &lt;span class="nf"&gt;add&lt;/span&gt; &lt;span class="nb"&gt;ah&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;                  &lt;span class="c1"&gt;; Convert remainder to ASCII character&lt;/span&gt;
    &lt;span class="nf"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;addr_ip&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;ah&lt;/span&gt;       &lt;span class="c1"&gt;; Store ASCII character in the output buffer&lt;/span&gt;
    &lt;span class="nf"&gt;dec&lt;/span&gt; &lt;span class="nb"&gt;rdi&lt;/span&gt;                     &lt;span class="c1"&gt;; Move buffer pointer backward&lt;/span&gt;
    &lt;span class="nf"&gt;xor&lt;/span&gt; &lt;span class="nb"&gt;ah&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;ah&lt;/span&gt;                  &lt;span class="c1"&gt;; Clear AH for the next division cycle&lt;/span&gt;
    &lt;span class="nf"&gt;cmp&lt;/span&gt; &lt;span class="nb"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;                   &lt;span class="c1"&gt;; Check if quotient is zero&lt;/span&gt;
    &lt;span class="nf"&gt;jg&lt;/span&gt; &lt;span class="nv"&gt;_divloop&lt;/span&gt;                 &lt;span class="c1"&gt;; If not zero, continue extracting digits&lt;/span&gt;

    &lt;span class="nf"&gt;cmp&lt;/span&gt; &lt;span class="nb"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;                  &lt;span class="c1"&gt;; Check if this is the last octet (first IP block)&lt;/span&gt;
    &lt;span class="nf"&gt;je&lt;/span&gt; &lt;span class="nv"&gt;_contiune&lt;/span&gt;                &lt;span class="c1"&gt;; If last octet, skip adding the dot separator&lt;/span&gt;
    &lt;span class="nf"&gt;mov&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;addr_ip&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;46&lt;/span&gt;  &lt;span class="c1"&gt;; Insert '.' (dot) character&lt;/span&gt;
&lt;span class="nl"&gt;_contiune:&lt;/span&gt;
    &lt;span class="nf"&gt;dec&lt;/span&gt; &lt;span class="nb"&gt;rdi&lt;/span&gt;                     &lt;span class="c1"&gt;; Move buffer pointer backward for the next octet&lt;/span&gt;
    &lt;span class="nf"&gt;dec&lt;/span&gt; &lt;span class="nb"&gt;rcx&lt;/span&gt;                     &lt;span class="c1"&gt;; Move to the next IP octet in sockaddr_in&lt;/span&gt;
    &lt;span class="nf"&gt;cmp&lt;/span&gt; &lt;span class="nb"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;                  &lt;span class="c1"&gt;; Check if all 4 octets have been processed&lt;/span&gt;
    &lt;span class="nf"&gt;jg&lt;/span&gt; &lt;span class="nv"&gt;_loopforip&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This single-pass method successfully converts the raw network bytes into a human-readable ASCII string using minimal CPU cycles, entirely avoiding an extra "string reversing" loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion and Open Source
&lt;/h3&gt;

&lt;p&gt;Network programming in Assembly might seem tedious at first, but it is a unique experience for understanding the true mechanics underlying these systems. Especially when working on tunneling architectures aimed at Evaluating IDS detection resilience, having this level of byte-control is absolutely vital.&lt;/p&gt;

&lt;p&gt;You can find this algorithm in action, along with the complete source code of the asm-icmp-sniffer, on my GitHub profile:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JM00NJ/asm-icmp-sniffer" rel="noopener noreferrer"&gt;JM00NJ/asm-icmp-sniffer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disclaimer: This article and the associated source code are intended for educational purposes and authorized security research only. Understanding low-level network protocols is essential for building better defense mechanisms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://netacoding.com/posts/icmp_sniffer/" rel="noopener noreferrer"&gt;Building a Low-Level ICMP Sniffer in x64 Assembly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netacoding.com/posts/syscall-bss/" rel="noopener noreferrer"&gt;Linux x64 Assembly: Syscalls, Registers, and the .bss Segment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netacoding.com/posts/anti-analysis/" rel="noopener noreferrer"&gt;Linux Process Evasion: ptrace &amp;amp; prctl&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>assembly</category>
      <category>linux</category>
      <category>lowlevel</category>
      <category>security</category>
    </item>
  </channel>
</rss>
