<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[m.alvar.es]]></title><description><![CDATA[m.alvar.es]]></description><link>https://m.alvar.es</link><generator>RSS for Node</generator><lastBuildDate>Sun, 15 Mar 2026 10:59:18 GMT</lastBuildDate><atom:link href="https://m.alvar.es/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><atom:link rel="first" href="https://m.alvar.es/rss.xml"/><item><title><![CDATA[[Anti-Analysis] Watching Memory Regions using GetWriteWatch API]]></title><description><![CDATA[<p>I have been exploring some anti-debug techniques listed in the <a href="https://anti-debug.checkpoint.com/techniques/misc.html#getwritewatch">CheckPoint Anti-Debug Knowledge Base</a>. This one really caught my attention. It uses the <a href="https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-getwritewatch">Kernel32.GetWriteWatch</a> API to detect changes to a memory region (including changes made by debuggers).</p>
<p>Using this API is more efficient than manually calculating checksums, and it can be used to protect sensitive code (<em>e.g.</em> hooks and shellcodes).</p>
<p>I developed this <a href="https://github.com/mabj/anti/blob/master/anti-debugging/AD012_GetWriteWatch/src/main.c">small sample that protects a shellcode</a> (which executes calc.exe). In case the process is attached to a debugger and breakpoints are set at the region containing the shellcode, our watchdog thread catches the tampering and logs an event.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769429629165/63f67ecd-1727-4204-9d43-822d45cbeb3c.png" alt="" style="display:block;margin:0 auto" />]]></description><link>https://m.alvar.es/anti-analysis-watching-memory-regions-using-getwritewatch-api</link><guid isPermaLink="true">https://m.alvar.es/anti-analysis-watching-memory-regions-using-getwritewatch-api</guid><category><![CDATA[Anti-Analysis]]></category><category><![CDATA[malware analysis]]></category><dc:creator><![CDATA[Marcos Alvares]]></dc:creator></item><item><title><![CDATA[[Anti-Analysis] Abusing CloseHandle API]]></title><description><![CDATA[<p>The <a href="https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle">documentation of CloseHandle</a> states the following:</p>
<blockquote>
<p>If the application is running under a debugger, the function will throw an exception if it receives either a handle value that is not valid or a pseudo-handle value.</p>
</blockquote>
<p>Because of this specific feature, this API can be abused to detect if a process is running under a debugger.</p>
<pre><code class="language-c">bool __is_debugged() {
    __try {
        // Passing invalid HANDLE to CloseHandle.
        // This raises an exception if the process is attached to a debugger. 
        CloseHandle((HANDLE)(ULONG_PTR)0xDEADBEEF);
    }
    __except (EXCEPTION_INVALID_HANDLE == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        return true;
    }
    return false;
}
</code></pre>
<p>The source to the full test-case can be found in the <a href="https://github.com/mabj/anti/tree/master/anti-debugging/AD007_CloseHandle">Anti repository</a>.</p>
<p>Cheers!</p>
]]></description><link>https://m.alvar.es/anti-analysis-abusing-closehandle-api</link><guid isPermaLink="true">https://m.alvar.es/anti-analysis-abusing-closehandle-api</guid><category><![CDATA[Anti-Analysis]]></category><category><![CDATA[reverse engineering]]></category><category><![CDATA[malware analysis]]></category><dc:creator><![CDATA[Marcos Alvares]]></dc:creator></item><item><title><![CDATA[[Anti-Analysis] Unhandled Exception Filters]]></title><description><![CDATA[<p>Here's another technique for my anti-analysis collection! It uses an Exception Handler and an induced exception to detect debuggers. A handler is registered using the <a href="https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setunhandledexceptionfilter"><strong>kernel32.SetUnhandledExceptionFilter</strong></a> API and it is triggered by a crafted exception.</p>
<p>This technique is used by malware families like <em>SmokeLoader</em> and <em>GuLoader</em>.</p>
<p>The example code below sets the <mark class="bg-yellow-200 dark:bg-yellow-500/30">unhandled_exception_filter handler</mark> using <mark class="bg-yellow-200 dark:bg-yellow-500/30">SetUnhandledExceptionFilter API</mark> and then invokes it with an <mark class="bg-yellow-200 dark:bg-yellow-500/30">INT 3</mark> exception, typically used as software breakpoints by debuggers.</p>
<pre><code class="language-c">// If Debug is active this handler will not get executed and INT3 will be 
// captured by the debugger as a breakpoint.
LONG unhandled_exception_filter(PEXCEPTION_POINTERS pExceptionInfo) {
    PCONTEXT ctx = pExceptionInfo-&gt;ContextRecord;
    #if defined(__x86_64__)
        ctx-&gt;Rip += 3; // Skip \xCC\xEB\x??
    #else
        ctx-&gt;Eip += 3; // Skip \xCC\xEB\x??
    #endif
    return EXCEPTION_CONTINUE_EXECUTION;
}

// https://wiki.osdev.org/Inline_Assembly
bool __is_debugged() {
    __asm__ volatile goto
    (
        "INT 3\n\t"                        // CC
        "JMP %l[being_debugged]\n\t"      // EB ??  
        :                                 // No output operands
        :                                 // No input operands
        :                                 // No clobbered registers
        : being_debugged                  // Label operands
    );

    return false;

being_debugged:
    return true;
}
</code></pre>
<p>You can find the <a href="https://github.com/mabj/anti/tree/master/anti-debugging/AD006_SetUnhandledExceptionFilter">full code in this here</a>.</p>
]]></description><link>https://m.alvar.es/anti-analysis-unhandled-exception-filters</link><guid isPermaLink="true">https://m.alvar.es/anti-analysis-unhandled-exception-filters</guid><category><![CDATA[Anti-Analysis]]></category><category><![CDATA[Windows]]></category><category><![CDATA[Malware]]></category><category><![CDATA[malware analysis]]></category><dc:creator><![CDATA[Marcos Alvares]]></dc:creator></item><item><title><![CDATA[[Cheatsheet] Userland WinDbg]]></title><description><![CDATA[<p>I do not need to use WinDbg for userland debugging that often BUT when I need to use it I REALLY need to use it! \O/ I keep forgetting some of the commands and the references I find online are often missing something or just too complex (Microsofts official <a target="_blank" href="https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/commands">WinDbg commands documentation</a>).</p>
<p>Because of that, I decided to put together a list of <a target="_blank" href="https://github.com/mabj/cheatsheet/blob/main/output/windbg.pdf">my most used WinDbg commands in a CheatSheet</a>.</p>
<p>Enjoy it!</p>
<p>Bonus: I also uploaded the <a target="_blank" href="https://github.com/mabj/cheatsheet_template">LaTeX template used for creating this CheatSheet to a GitHub repo</a>.</p>
]]></description><link>https://m.alvar.es/cheatsheet-userland-windbg</link><guid isPermaLink="true">https://m.alvar.es/cheatsheet-userland-windbg</guid><category><![CDATA[cheatsheet]]></category><category><![CDATA[WinDbg]]></category><category><![CDATA[Windows]]></category><category><![CDATA[debugging]]></category><dc:creator><![CDATA[Marcos Alvares]]></dc:creator></item><item><title><![CDATA[[Tool] Messing Around with Gepetto]]></title><description><![CDATA[<p>Recently, I discovered this IDAPro plugin called Gepetto [<a target="_blank" href="https://github.com/JusticeRage/Gepetto">1</a>]. It connects IDA to LLMs and assists in annotating disassembled code interactively directly from the UI.</p>
<p>You can simply right-click on a decompiled functions name and ask Gepetto to explain its behavior.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767790704216/e07a2346-c005-41e9-8dd0-69e052db9ed1.png" alt class="image--center mx-auto" /></p>
<p>This article lists few examples (using Anthropics model <em>Claude 4.5 Sonnet</em>) of annotations provided by Gepetto while co-reversing a sample that I had fully analyzed some time ago. I found it quite accurate and would like to share some thoughts.</p>
<h2 id="heading-cryptography">Cryptography</h2>
<p>Gepetto is quite straight forward and accurate when identifying crypto and variants of popular crypto algorithms. This capability can save time of trained analysts and level-up beginner reversers (by training them in common patterns).</p>
<h3 id="heading-custom-hashing">Custom Hashing</h3>
<p>Gepetto accurately identified a custom hashing function and described its sub-operations, such as converting ASCII characters to lowercase and performing accumulative XOR.</p>
<blockquote>
<p>// ----- Comment generated by Gepetto -----<br />//<br />// This function computes a <strong><mark>custom hash value from a null-terminated string</mark></strong>. It<br />// iterates through each byte, performing a bitwise AND with 0xDF (which converts<br />// lowercase ASCII letters to uppercase, treating the input case-insensitively),<br />// then combines this with the accumulated hash using XOR, a left rotation by 8<br />// bits, and addition. <strong><mark>The function returns a 32-bit hash value derived from the<br />// string's case-normalized characters</mark></strong>.<br />//<br />// Proposed name:<br />// compute_case_insensitive_hash</p>
</blockquote>
<pre><code class="lang-c">__int64 __fastcall _hashing(__int64 a1, __int64 a2, __int64 a3, _BYTE *a4)
{
  <span class="hljs-keyword">char</span> v4; <span class="hljs-comment">// al</span>
  _BYTE *v5; <span class="hljs-comment">// r8</span>
  <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> v6; <span class="hljs-comment">// edx</span>

  v4 = *a4;
  v5 = a4;
  v6 = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">while</span> ( v4 )
  {
    v6 = (v4 &amp; <span class="hljs-number">0xDF</span>) + __ROL4__(v6 ^ v4 &amp; <span class="hljs-number">0xDF</span>, <span class="hljs-number">8</span>);
    v4 = *++v5;
  }
  <span class="hljs-keyword">return</span> v6;
}
</code></pre>
<p>For this case, I also asked Gepetto to generate Python code. This feature can be quite useful when writing configuration extractors and bot emulators. Gepetto was able to completed the task successfully.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">_hashing</span>(<span class="hljs-params">input_string</span>):</span>
    <span class="hljs-string">"""
    Computes a custom hash value from a string.

    This function iterates through each byte, performing a bitwise AND with 0xDF
    (which converts lowercase ASCII letters to uppercase, treating the input 
    case-insensitively), then combines this with the accumulated hash using XOR,
    a left rotation by 8 bits, and addition.

    Args:
        input_string: A string or bytes object to hash

    Returns:
        A 32-bit hash value (unsigned integer)
    """</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">rol32</span>(<span class="hljs-params">value, shift</span>):</span>
        <span class="hljs-string">"""Rotate left operation for 32-bit values"""</span>
        value &amp;= <span class="hljs-number">0xFFFFFFFF</span>  <span class="hljs-comment"># Ensure 32-bit</span>
        shift %= <span class="hljs-number">32</span>  <span class="hljs-comment"># Normalize shift amount</span>
        <span class="hljs-keyword">return</span> ((value &lt;&lt; shift) | (value &gt;&gt; (<span class="hljs-number">32</span> - shift))) &amp; <span class="hljs-number">0xFFFFFFFF</span>

    <span class="hljs-comment"># Convert string to bytes if necessary</span>
    <span class="hljs-keyword">if</span> isinstance(input_string, str):
        data = input_string.encode(<span class="hljs-string">'latin-1'</span>)  <span class="hljs-comment"># or 'utf-8' depending on context</span>
    <span class="hljs-keyword">else</span>:
        data = input_string

    hash_value = <span class="hljs-number">0</span>

    <span class="hljs-keyword">for</span> byte <span class="hljs-keyword">in</span> data:
        normalized = byte &amp; <span class="hljs-number">0xDF</span>  <span class="hljs-comment"># Convert lowercase to uppercase (for ASCII letters)</span>
        hash_value = (normalized + rol32(hash_value ^ normalized, <span class="hljs-number">8</span>)) &amp; <span class="hljs-number">0xFFFFFFFF</span>

    <span class="hljs-keyword">return</span> hash_value
</code></pre>
<h3 id="heading-rc4">RC4</h3>
<p>RC4 is a quite popular algorithm among malware developers. Experienced reversers would find identifying this code straightforward. Gepetto was able to describe its behavior accurately.</p>
<blockquote>
<p>// ----- Comment generated by Gepetto -----<br />//<br />// This function implements the <strong><mark>RC4 stream cipher algorithm</mark></strong>. It first initializes a<br />// 256-byte state array with values 0-255, then performs the key-scheduling<br />// algorithm (KSA) using the key provided in parameter a3 of length a6 to permute<br />// the state array. Finally, it executes the pseudo-random generation algorithm<br />// (PRGA) to generate a keystream that is XORed with the input data pointed to by<br />// a4 for a5 bytes, performing in-place encryption or decryption. The function<br />// modifies the buffer at a4 as a side effect and returns the last generated<br />// keystream byte.<br />//<br />// Proposed name: rc4_crypt</p>
</blockquote>
<pre><code class="lang-c"><span class="hljs-function"><span class="hljs-keyword">char</span> __fastcall <span class="hljs-title">sub_2DA5168</span><span class="hljs-params">(__int64 a1, __int64 a2, __int64 a3, _BYTE *a4, <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> a5, <span class="hljs-keyword">unsigned</span> __int8 a6)</span>
</span>{
  __int64 v6; <span class="hljs-comment">// r10</span>
  __int64 v8; <span class="hljs-comment">// rbx</span>
  _BYTE *v11; <span class="hljs-comment">// r11</span>
  <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> i; <span class="hljs-comment">// eax</span>
  __int64 v13; <span class="hljs-comment">// r14</span>
  <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> v14; <span class="hljs-comment">// r9d</span>
  <span class="hljs-keyword">char</span> *v15; <span class="hljs-comment">// r11</span>
  <span class="hljs-keyword">char</span> v16; <span class="hljs-comment">// r8</span>
  <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> v17; <span class="hljs-comment">// edx</span>
  __int64 v18; <span class="hljs-comment">// rax</span>
  __int64 v19; <span class="hljs-comment">// r9</span>
  __int64 v20; <span class="hljs-comment">// r11</span>
  <span class="hljs-keyword">char</span> v21; <span class="hljs-comment">// dl</span>
  _BYTE v23[<span class="hljs-number">256</span>]; <span class="hljs-comment">// [rsp+0h] [rbp-108h] BYREF</span>

  LOBYTE(v6) = <span class="hljs-number">0</span>;
  v8 = a5;
  v11 = v23;
  <span class="hljs-keyword">for</span> ( i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">0x100</span>; ++i )
    *v11++ = i;
  LOBYTE(v13) = <span class="hljs-number">0</span>;
  v14 = <span class="hljs-number">0</span>;
  v15 = v23;
  <span class="hljs-keyword">do</span>
  {
    v16 = *v15;
    v17 = v14 % a6;
    ++v14;
    v13 = (<span class="hljs-keyword">unsigned</span> __int8)(*v15 + v13 + *(_BYTE *)(v17 + a3));
    LOBYTE(v18) = v23[v13];
    *v15++ = v18;
    v23[v13] = v16;
  }
  <span class="hljs-keyword">while</span> ( v14 &lt; <span class="hljs-number">0x100</span> );
  LOBYTE(v19) = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">if</span> ( (_DWORD)v8 )
  {
    v20 = v8;
    <span class="hljs-keyword">do</span>
    {
      v19 = (<span class="hljs-keyword">unsigned</span> __int8)(v19 + <span class="hljs-number">1</span>);
      v21 = v23[v19];
      v6 = (<span class="hljs-keyword">unsigned</span> __int8)(v6 + v21);
      v23[v19] = v23[v6];
      v23[v6] = v21;
      v18 = (<span class="hljs-keyword">unsigned</span> __int8)(v21 + v23[v19]);
      *a4++ ^= v23[v18];
      --v20;
    }
    <span class="hljs-keyword">while</span> ( v20 );
  }
  <span class="hljs-keyword">return</span> v18;
}
</code></pre>
<h3 id="heading-md5-hashing">MD5 hashing</h3>
<p>This case was quite curious because besides pinpointing the general behavior of the function, Gepetto was able to recognize that the sample dynamically imports APIs. After that, it was able to infer the functionality of each function call by analyzing the disposition of the stack (my intuition of the LLM reasoning). Finally, it interprets the post-processing to the resulting hash into a hexadecimal string.</p>
<blockquote>
<p>// ----- Comment generated by Gepetto -----<br />//<br />// This function computes an <strong><mark>MD5 hash of data and formats it as a hexadecimal<br />// string</mark></strong>. It uses a function pointer table (accessed via offsets from a4) to call<br />// various cryptographic operations: initializing a hash context, computing the<br />// hash value, retrieving the 16-byte digest, and then formatting each byte as a<br />// two-character uppercase hex string (e.g., "A3F2..."). The formatted result is<br />// written to a buffer, and the function cleans up by closing the hash context<br />// before returning.<br />//<br />// Proposed name: compute_and_format_md5_hash</p>
</blockquote>
<pre><code class="lang-c"><span class="hljs-function">__int64 __fastcall <span class="hljs-title">sub_2DA5314</span><span class="hljs-params">(
        __int64 a1,
        __int64 a2,
        __int64 a3,
        __int64 a4,
        __int64 a5,
        __int64 a6,
        <span class="hljs-keyword">int</span> a7,
        __int64 a8,
        __int64 a9,
        __int64 a10)</span>
</span>{
  __int64 v10; <span class="hljs-comment">// rbx</span>
  __int64 v12; <span class="hljs-comment">// rsi</span>
  __int64 result; <span class="hljs-comment">// rax</span>
  <span class="hljs-keyword">int</span> v15; <span class="hljs-comment">// ebx</span>
  __int64 v16; <span class="hljs-comment">// rdx</span>
  <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> v17; <span class="hljs-comment">// eax</span>
  <span class="hljs-keyword">int</span> v18; <span class="hljs-comment">// eax</span>
  __int64 v19; <span class="hljs-comment">// rdx</span>
  __int64 v20; <span class="hljs-comment">// [rsp+30h] [rbp-20h]</span>
  __int64 v21; <span class="hljs-comment">// [rsp+38h] [rbp-18h] BYREF</span>
  _BYTE v22[<span class="hljs-number">16</span>]; <span class="hljs-comment">// [rsp+40h] [rbp-10h] BYREF</span>

  a8 = v10;
  a9 = a2;
  v12 = a5;
  result = (*(__int64 (__fastcall **)(__int64, __int64, _QWORD, __int64 *, _QWORD, __int64))(a4 + <span class="hljs-number">4334</span>))(
             a4,
             a5,
             <span class="hljs-number">0</span>,
             &amp;v21,
             <span class="hljs-number">0</span>,
             <span class="hljs-number">1</span>);
  v15 = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">if</span> ( (_DWORD)result )
  {
    (*(<span class="hljs-keyword">void</span> (__fastcall **)(__int64, __int64, __int64, __int64, _QWORD, _QWORD))(a4 + <span class="hljs-number">4350</span>))(a4, v12, <span class="hljs-number">32771</span>, v21, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);
    v17 = (*(__int64 (__fastcall **)(__int64, __int64, __int64, __int64))(a4 + <span class="hljs-number">3806</span>))(a4, v12, v16, a3);
    (*(<span class="hljs-keyword">void</span> (__fastcall **)(__int64, __int64, __int64, __int64, _QWORD, _QWORD))(a4 + <span class="hljs-number">4358</span>))(a4, v12, a3, v20, v17, <span class="hljs-number">0</span>);
    a7 = <span class="hljs-number">16</span>;
    (*(<span class="hljs-keyword">void</span> (__fastcall **)(__int64, __int64, __int64, __int64, _BYTE *, <span class="hljs-keyword">int</span> *))(a4 + <span class="hljs-number">4366</span>))(a4, v12, <span class="hljs-number">2</span>, v20, v22, &amp;a7);
    <span class="hljs-built_in">strcpy</span>((<span class="hljs-keyword">char</span> *)&amp;a10, <span class="hljs-string">"%02X"</span>);
    a7 = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">do</span>
    {
      v18 = (*(__int64 (__fastcall **)(__int64, __int64, __int64 *, __int64, _QWORD))(a4 + <span class="hljs-number">4414</span>))(
              a4,
              v12,
              &amp;a10,
              v12,
              (<span class="hljs-keyword">unsigned</span> __int8)v22[v15]);
      v15 = a7 + <span class="hljs-number">1</span>;
      v12 += v18;
      a7 = v15;
    }
    <span class="hljs-keyword">while</span> ( v15 &lt; <span class="hljs-number">16</span> );
    (*(<span class="hljs-keyword">void</span> (__fastcall **)(__int64, __int64, __int64))(a4 + <span class="hljs-number">4374</span>))(a4, v12, v19);
    <span class="hljs-keyword">return</span> (*(__int64 (__fastcall **)(__int64, __int64, _QWORD, __int64))(a4 + <span class="hljs-number">4342</span>))(a4, v12, <span class="hljs-number">0</span>, v21);
  }
  <span class="hljs-keyword">return</span> result;
}
</code></pre>
<h2 id="heading-anti-analysis">Anti-Analysis</h2>
<p>This case shows a more elaborated snip of code implementing anti-debugging and anti-reversing techniques. The context is limited and it is difficult to pinpoint what is going on without dynamic data. Gepetto provided vague insights but was able to suggest hypotheses about the code's purpose.</p>
<blockquote>
<p>// ----- Comment generated by Gepetto -----<br />//<br />// This function iterates through a loop that repeatedly calls a function pointer<br />// (loc_402A57) with arguments from the stack frame, storing results into an array<br />// pointed to by the frame pointer offset +12. The loop terminates when the<br />// function pointer returns zero or the input a1 is zero, setting a flag at offset<br />// -4 accordingly. After the loop, it performs several obfuscated pointer<br />// arithmetic operations and bit manipulations before calling another function<br />// (loc_4011DC) and returning the flag value. <strong><mark>The presence of debugbreak<br />// instructions, unusual arithmetic patterns, and deliberate obfuscation (magic<br />// constants, pointer manipulation) suggests this may be anti-debugging or anti-<br />// analysis code, possibly part of a software protection scheme.</mark></strong><br />//<br />// Proposed name:<br />// iterate_and_collect_with_obfuscation</p>
</blockquote>
<pre><code class="lang-c"><span class="hljs-keyword">int</span> __userpurge sub_402BA6@&lt;eax&gt;(<span class="hljs-keyword">int</span> a1@&lt;eax&gt;, <span class="hljs-keyword">char</span> a2@&lt;cl&gt;, <span class="hljs-keyword">int</span> a3@&lt;ebx&gt;, <span class="hljs-keyword">int</span> a4@&lt;ebp&gt;, <span class="hljs-keyword">int</span> a5, <span class="hljs-keyword">int</span> a6)
{
  <span class="hljs-keyword">int</span> *v6; <span class="hljs-comment">// esi</span>
  <span class="hljs-keyword">int</span> *i; <span class="hljs-comment">// edi</span>
  _DWORD *v8; <span class="hljs-comment">// eax</span>
  <span class="hljs-keyword">char</span> *v9; <span class="hljs-comment">// eax</span>

  v6 = *(<span class="hljs-keyword">int</span> **)(a4 + <span class="hljs-number">12</span>);
  <span class="hljs-keyword">for</span> ( i = v6; ; ++i )
  {
    __debugbreak();
    <span class="hljs-keyword">if</span> ( !a1 )
      <span class="hljs-keyword">break</span>;
    a1 = ((<span class="hljs-keyword">int</span> (__cdecl *)(_DWORD, <span class="hljs-keyword">int</span>))loc_402A57)(*(_DWORD *)(a4 + <span class="hljs-number">8</span>), a1);
    <span class="hljs-keyword">if</span> ( !a1 )
    {
      *(_DWORD *)(a4 - <span class="hljs-number">4</span>) = <span class="hljs-number">0</span>;
      <span class="hljs-keyword">break</span>;
    }
    *(_DWORD *)(a4 - <span class="hljs-number">4</span>) = <span class="hljs-number">1</span>;
    *i = a1;
  }
  __debugbreak();
  v8 = (_DWORD *)(i[<span class="hljs-number">2</span> * (_DWORD)v6 - <span class="hljs-number">0x1665C7CD</span>] + a1);
  v9 = (<span class="hljs-keyword">char</span> *)v8 - *v8;
  *(_BYTE *)(a3 - <span class="hljs-number">0x3B7CDBFC</span>) += a2;
  LOBYTE(v9) = (_BYTE)v9 - <span class="hljs-number">21</span>;
  <span class="hljs-keyword">do</span>
  {
    v9 += <span class="hljs-number">0xEFEB34EB</span>;
    LOBYTE(v9) = (<span class="hljs-keyword">unsigned</span> __int8)v9 | <span class="hljs-number">0x1A</span>;
  }
  <span class="hljs-keyword">while</span> ( (<span class="hljs-keyword">char</span>)v9 &lt;= <span class="hljs-number">0</span> );
  ((<span class="hljs-keyword">void</span> (__fastcall *)(<span class="hljs-keyword">int</span>, <span class="hljs-keyword">int</span>))loc_4011DC)(<span class="hljs-number">112</span>, <span class="hljs-number">179</span>);
  <span class="hljs-keyword">return</span> *(_DWORD *)(a4 - <span class="hljs-number">4</span>);
}
</code></pre>
<h2 id="heading-persistence">Persistence</h2>
<p>In this case, I manually labeled few functions and asked for Gepetto to describe the main function using them. Gepetto was able to infer the main function (<em>sub_2DA35BC</em>).</p>
<blockquote>
<p>// ----- Comment generated by Gepetto -----<br />//<br />// <strong><mark>This function establishes persistence by creating a Windows scheduled task.</mark></strong> It<br />// retrieves a task name using the fourth parameter, creates the scheduled task via<br />// the Windows Task Scheduler (with the third/sixth parameters set to 0, likely<br />// indicating default or minimal options), and then frees the memory allocated for<br />// the task name. The function returns the result of the memory deallocation<br />// operation.<br />//<br />// Proposed name: create_scheduled_task_persistence</p>
</blockquote>
<pre><code class="lang-c"><span class="hljs-function">__int64 __fastcall <span class="hljs-title">sub_2DA35BC</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a1, __int64 a2, __int64 a3, __int64 a4)</span>
</span>{
  <span class="hljs-keyword">int</span> v5; <span class="hljs-comment">// r8d</span>
  __int64 schedule_task_name; <span class="hljs-comment">// [rsp+20h] [rbp-18h]</span>

  schedule_task_name = _get_schedule_task_name(a4, a2, a3, a4);
  _create_windows_scheduler_task(a4, a2, <span class="hljs-number">0</span>, a4, v5, <span class="hljs-number">0</span>);
  <span class="hljs-keyword">return</span> _wrapper_RtlFreeHeap(a4, a2, schedule_task_name, a4);
}
</code></pre>
<h2 id="heading-take-aways">Take Aways</h2>
<ul>
<li><p>More experienced reversers can use this tool to speed up analysis. It helps in creating a high-level picture of the subject and provides hints on unknown patterns.</p>
</li>
<li><p>Beginners can use it as a training tool to become familiar with known patterns.</p>
</li>
<li><p>It can be utilized in capture-the-flag competitions.</p>
</li>
<li><p>For best results, use it interactively. The tool provides more accurate descriptions as more context is provided, such as function and variable names.</p>
</li>
</ul>
]]></description><link>https://m.alvar.es/experiments-with-gepetto</link><guid isPermaLink="true">https://m.alvar.es/experiments-with-gepetto</guid><category><![CDATA[gepetto]]></category><category><![CDATA[AI]]></category><category><![CDATA[reversing]]></category><category><![CDATA[llm]]></category><category><![CDATA[malware analysis]]></category><dc:creator><![CDATA[Marcos Alvares]]></dc:creator></item><item><title><![CDATA[[Tool] Quick Snip to Detect ntdll.dll]]></title><description><![CDATA[<p>Recently, Ive been reversing this first-stage that dynamically loads a copy of ntdll.dll in order to hide malicious behavior from Sandboxes and EDRs. This technique has been widely documented in open-source research already, [<a target="_blank" href="https://malwareandstuff.com/examining-smokeloaders-anti-hooking-technique/">1</a>][<a target="_blank" href="https://n1ght-w0lf.github.io/malware%20analysis/smokeloader/#:~:text=One%20thing%20to%20note%20here,CreateFileMappingW%20\(0x5b3f901c\)">2</a>][<a target="_blank" href="https://bobvanderstaak.medium.com/unhooking-edr-by-remapping-ntdll-dll-101a99887dfe">3</a>][<a target="_blank" href="https://www.advania.co.uk/blog/security/a-practical-guide-to-bypassing-userland-api-hooking/">4</a>][<a target="_blank" href="https://github.com/ricardojoserf/SharpNtdllOverwrite">5</a>].</p>
<p>Luckily, ntdll.dll is quite recognizable! I vibe-coded (:D) this small detection to be used by a potential tool for intercepting (in userland) malicious code implementing one of the following behaviors:</p>
<ol>
<li><p>dynamically loading side-copies of ntdll.dll, or</p>
</li>
<li><p>restoring hooked APIs from a clean copy of ntdll.dll</p>
</li>
</ol>
<p>It is called is_ntdll and <a target="_blank" href="https://github.com/mabj/is_ntdll">here is the code to it</a>. Enjoy!</p>
]]></description><link>https://m.alvar.es/tool-is-ntdll</link><guid isPermaLink="true">https://m.alvar.es/tool-is-ntdll</guid><category><![CDATA[Anti-Analysis]]></category><category><![CDATA[hooks]]></category><category><![CDATA[ntdll]]></category><category><![CDATA[Windows]]></category><category><![CDATA[malware analysis]]></category><dc:creator><![CDATA[Marcos Alvares]]></dc:creator></item><item><title><![CDATA[Hello World!]]></title><description><![CDATA[<p>After a 6-year hiatus, I'm excited to dive back into writing about my research and to do some technical writing in this new AI-driven era. I decided to start this space fresh and separated from my previous blog but you can still find my old articles at <a target="_blank" href="https://hashnode.com/continue-with-magic-link/2e2092e9-f21a-4be9-a74a-f1e9718076c5"><strong>malvar-es.blogspot.com</strong></a>.</p>
<p>Looking forward to sharing more with you all!</p>
<p>Cheers,<br />Marcos</p>
]]></description><link>https://m.alvar.es/hello-world</link><guid isPermaLink="true">https://m.alvar.es/hello-world</guid><category><![CDATA[Hello World]]></category><dc:creator><![CDATA[Marcos Alvares]]></dc:creator></item></channel></rss>