Case op23 · evaluated model gemma431Bit · judges ClaudeAI, GeminiAI, OpenAI

Selection reason: stratified_random

Understanding point

dynamic API resolution
Code snippet · op23/code1.txt
__int64 __fastcall unk_function(LPCSTR a1, int a0)
{
  HMODULE ModuleHandleA; // r10
  __int64 v5; // r8
  _DWORD *v6; // rcx
  char *v7; // rbx
  unsigned int *v8; // r9
  unsigned int v9; // r11d
  char *v10; // rsi
  int v11; // eax
  _BYTE *v12; // rcx
  int i; // edx

  ModuleHandleA = GetModuleHandleA(a1);
  if ( !ModuleHandleA )
    ModuleHandleA = LoadLibraryA(a1);
  v5 = 0;
  v6 = (ModuleHandleA + *(ModuleHandleA + *(ModuleHandleA + 0xF) + 0x88));
  v7 = ModuleHandleA + v6[7];
  v8 = (ModuleHandleA + v6[8]);
  v9 = v6[5];
  v10 = ModuleHandleA + v6[9];
  if ( !v9 )
    return 0;
  while ( 1 )
  {
    v11 = 0;
    v12 = ModuleHandleA + *v8;
    for ( i = *v12; *v12; i = *v12 )
    {
      ++v12;
      v11 = i + 65599 * v11;
    }
    if ( v11 == a0 )
      break;
    v5 = (v5 + 1);
    ++v8;
    if ( v5 >= v9 )
      return 0;
  }
  return ModuleHandleA + *&v7[4 * *&v10[2 * v5]];
}
Evaluated model output (what the LLM said about the code) · op23/result_gemma431Bit1.txt
This code is a classic implementation of a **Dynamic API Resolver** using **API Hashing**. This technique is widely used by malware to hide its dependencies and evade detection by security software that monitors the Import Address Table (IAT) or looks for specific strings (like `CreateRemoteThread` or `WriteProcessMemory`) in the binary.

### 1. Functionality Description
The function `unk_function` takes a DLL name (`a1`) and a pre-calculated hash (`a0`) as input. Instead of calling `GetProcAddress` to find a function's address, it manually parses the Portable Executable (PE) export table of the specified DLL.

**Step-by-step execution:**
1.  **Module Acquisition:** It attempts to get a handle to the DLL using `GetModuleHandleA`. If the DLL is not already loaded in the process memory, it loads it using `LoadLibraryA`.
2.  **PE Header Parsing:** It navigates the PE structure to find the **Export Directory**. It accesses the NT Headers and the Optional Header to locate the `IMAGE_EXPORT_DIRECTORY` structure (indicated by the offset `0x88` in the Optional Header).
3.  **Export Iteration:** It retrieves the number of exported functions and the addresses of the function names, ordinals, and the functions themselves.
4.  **API Hashing:** It iterates through every function name exported by the DLL. For each name, it calculates a hash using a specific mathematical formula.
5.  **Comparison:** It compares the calculated hash of the current function name with the target hash `a0`.
6.  **Address Resolution:** Once a match is found, it uses the function's ordinal to look up the actual memory address of the function and returns that address to the caller.

### 2. Well-Known Algorithms
The code uses a **Polynomial Rolling Hash** (a variation of a custom additive hash).
*   **The Formula:** `hash = (hash * 65599) + character`
*   **Constant:** The prime number `65599` is used as the multiplier to ensure a relatively low collision rate. This is a common pattern in custom malware loaders to replace plaintext API strings.

### 3. Indicators of Compromise (IOCs)
Because this is a generic resolver function, there are no hardcoded C2 domains or file paths. However, the following are **behavioral IOCs**:
*   **Constants:** The use of the constant `65599` in a loop iterating over module exports is a strong signature for this specific hashing algorithm.
*   **API Sequence:** The sequence of `GetModuleHandleA` $\rightarrow$ `LoadLibraryA` $\rightarrow$ Manual PE parsing.
*   **Behavior:** Any binary containing this function is likely attempting to hide its actual API calls from static analysis tools.

### 4. MITRE ATT&CK Mapping

| Technique ID | Technique Name | Justification |
| :--- | :--- | :--- |
| **T1027** | Obfuscated Files or Information | The code uses API hashing to hide the names of the functions it intends to call, preventing analysts from seeing the malware's capabilities via the IAT. |
| **T1106** | Native API | The code manually parses the PE Export Directory to resolve function addresses, bypassing standard Windows API resolution mechanisms. |
| **T1562.001** | Impair Defenses: Disable or Modify Tools | By avoiding `GetProcAddress`, the malware evades EDR/AV hooks that specifically monitor that function to detect malicious API resolution. |

### 5. Obfuscation and Evasion Techniques
*   **API Hashing:** The most prominent technique. By passing a hash (e.g., `0xABC123`) instead of a string (e.g., `"ShellExecute"`), the malware prevents "strings" analysis from revealing its intent.
*   **Manual PE Parsing:** By manually walking the `IMAGE_EXPORT_DIRECTORY`, the malware avoids creating a detectable import entry in the PE header, making the binary look benign to basic static analysis.
*   **Dynamic Loading:** Using `LoadLibraryA` ensures that the target DLL is only loaded into memory when needed, rather than being a hard dependency.

### 6. Fact vs. Inference

**Observed Facts (Directly from code):**
*   The function calls `GetModuleHandleA` and `LoadLibraryA`.
*   The function accesses the PE Optional Header at offset `0x88` (Export Directory).
*   The function implements a loop that calculates a hash using the multiplier `65599`.
*   The function returns a memory address calculated from the `AddressOfFunctions` array in the export table.

**Inferred Behavior (Reasoning):**
*   **Purpose:** I infer this is a stealth mechanism to resolve APIs because the logic exactly mirrors the internal workings of `GetProcAddress` but adds a hashing layer.
*   **Malicious Intent:** While API resolution can be used in legitimate protectors, this specific pattern (manual PE parsing + hashing) is highly characteristic of malware loaders and shellcode.

LLM judge panel

ClaudeAI judge verdict: satisfiedop23/judge_ClaudeAI_gemma431Bit_up1_1.txt
{
  "understanding_point": "dynamic API resolution",
  "full_evaluation": "The understanding point is 'dynamic API resolution'. The candidate summary explicitly and thoroughly describes this technique. It opens by labeling the code a 'Dynamic API Resolver' using API Hashing, explains that instead of calling GetProcAddress it manually parses the PE export table to resolve function addresses, and details the step-by-step process: module acquisition via GetModuleHandleA/LoadLibraryA, locating the IMAGE_EXPORT_DIRECTORY, iterating exports, hashing names, comparing to a target hash, and returning the resolved address. This is a clear and complete statement of dynamic API resolution with no contradictions.",
  "explanation": "The summary explicitly and in detail describes dynamic API resolution via manual PE export-table parsing and API hashing to resolve function addresses at runtime.",
  "evidence": "This code is a classic implementation of a **Dynamic API Resolver** using **API Hashing**.",
  "support_strength": 3,
  "satisfied": "true"
}
GeminiAI judge verdict: satisfiedop23/judge_GeminiAI_gemma431Bit_up1_1.txt
{
  "understanding_point": "dynamic API resolution",
  "full_evaluation": "The candidate summary explicitly states \"Dynamic API Resolver\" in its opening sentence. The entire document then proceeds to describe the mechanism of this dynamic API resolution, detailing how it uses API hashing, manual PE parsing, and dynamic loading (LoadLibraryA) to resolve function addresses at runtime rather than relying on static imports. This directly and comprehensively covers the understanding point.",
  "explanation": "The summary explicitly uses the term \"Dynamic API Resolver\" and then thoroughly describes the process and techniques involved in dynamic API resolution.",
  "evidence": "This code is a classic implementation of a **Dynamic API Resolver** using **API Hashing**.",
  "support_strength": 3,
  "satisfied": "true"
}
OpenAI judge verdict: satisfiedop23/judge_OpenAI_gemma431Bit_up1_1.txt
{
  "understanding_point": "dynamic API resolution",
  "full_evaluation": "The candidate summary clearly and repeatedly states the understanding point. It explicitly calls the code a \"Dynamic API Resolver\" and describes how it obtains or loads a DLL, manually parses the PE export table, hashes exported function names, compares them to a target hash, and returns the resolved function address. This is an exact description of dynamic API resolution, including the mechanism by which API addresses are resolved at runtime rather than through static imports. There are no contradictions or weakening qualifiers that would undermine the point.",
  "explanation": "The summary explicitly identifies the code as a dynamic API resolver and explains runtime API address resolution through DLL loading, export table parsing, hashing, and returning the matched function address. This fully satisfies the understanding point.",
  "evidence": "This code is a classic implementation of a **Dynamic API Resolver** using **API Hashing**.",
  "support_strength": 3,
  "satisfied": "true"
}

Your verdict