Case op11 · evaluated model GLM51 · judges ClaudeAI, GeminiAI, OpenAI

Selection reason: stratified_random

Understanding point

dynamic API resolution via PEB
Code snippet · op11/code_clean1.txt
__int64 __fastcall sub_140005da(unsigned int a1)
{
  int v1 = 0;
  _v0 *v0;
  __int64 *v2;
  __int64 *v3;
  __int64 v4 = 0;
  
  while ( v1 != 99 )
  {
    switch ( v1 )
    {
      case 0:
        v0 = (_v0 *)__readgsqword(0x60u);
        v1 = 7;
        break;
      case 3:
        v2 = v2->S0.Flink;
        v1 = 7;
        break;
      case 7:
        v2 = v0->v5->S1.Flink;
        v1 = 14;
        break;
      case 14:
        if ( v2->v7 )
          v1 = 22;
        else
          v1 = 99; 
        break;
      case 22:
        if ( (((a1 * 3) ^ 0xDEADBEEF) + 1) > 0 )
            v1 = 35;
        break;
      case 35:
        v3 = ((char *)v2->v7 + 
                     (((char *)v2->v7 + 
                     (v2->v7)->v9))->S2.A0[0].f1);
        v1 = 48;
        break;
      case 48:
        v4 = sub_14000e00(v2->v7, v3, a1);
        if ( v4 )
            v1 = 99;
        else
            v1 = 3;
        break;
    }
  }
  return v4;
}
Evaluated model output (what the LLM said about the code) · op11/result_GLM511.txt
# Static Analysis Report

## 1. Functionality Description

This function implements **dynamic API resolution via PEB walking** — a technique to locate a Windows API function without importing it through the normal IAT (Import Address Table). The function:

1. **Reads the PEB** from the Thread Environment Block (TEB) via `__readgsqword(0x60)` (x64 Windows PEB pointer)
2. **Walks the loaded module linked list** (`InMemoryOrderModuleList` / `InLoadOrderModuleList`) from `PEB->Ldr`
3. **Iterates through each loaded DLL**, checking the DLL base address (`v2->v7`) to determine list termination
4. **Parses the PE export directory** by following: DLL base → DOS header `e_lfanew` → NT headers → OptionalHeader `DataDirectory[0]` (export directory RVA → resolved VA)
5. **Calls `sub_14000e00`** to walk the export table of the matched DLL and resolve a specific function by hash (`a1`)
6. **Returns the resolved function pointer** (`v4`) or 0 on failure

## 2. Well-Known Algorithms

| Algorithm | Evidence |
|-----------|----------|
| **PEB Walking / Module Enumeration** | `__readgsqword(0x60)` → PEB → Ldr → module list traversal via `Flink` |
| **API Hashing (Metasploit block_api style)** | The constant `0xDEADBEEF` is a signature seed used in Metasploit's `block_api` shellcode and derivatives for resolving API functions by hash |
| **PE Export Table Parsing** | Manual traversal of DOS header → NT headers → DataDirectory[0] to locate export directory |

## 3. Indicators of Compromise (IOCs)

| IOC Type | Value | Notes |
|----------|-------|-------|
| **Hash Seed** | `0xDEADBEEF` | Characteristic of Metasploit `block_api` / Cobalt Strike shellcode API hashing |
| **TEB/PEB Offset** | `0x60` (GS segment) | x64 PEB pointer offset — shellcode indicator |
| **Function Hash** | `a1` (parameter) | Caller-supplied API function hash; the actual IOC would be the specific hash value passed at call sites |

> **Note:** No hardcoded file paths, IP addresses, domains, or registry keys are present in this snippet. The IOCs are behavioral/structural.

## 4. MITRE ATT&CK Mapping

| Technique ID | Technique Name | Justification |
|---|---|---|
| **T1106** | Native API | The function resolves Win32 API functions dynamically at runtime, bypassing normal import mechanisms |
| **T1027.007** | Obfuscated Files or Information: Dynamic API Resolution | API functions are resolved by hash at runtime rather than through the IAT, preventing static analysis of imported functions |
| **T1055.001** | Process Injection: Dynamic-link Library Injection | PEB walking is a foundational technique used in DLL injection to resolve LoadLibrary/GetProcAddress without IAT entries |
| **T1622** | Debugger Evasion | PEB access can also be used to check `BeingDebugged` flag; while not done here, the PEB walking infrastructure enables it |

## 5. Obfuscation & Evasion Techniques

### Control Flow Flattening (CFF)
The entire function is obfuscated using a **while-switch state machine** pattern:
- Variable `v1` acts as a **dispatcher variable** controlling which "basic block" executes next
- The state transitions (`0→7→14→22→35→48→3→...→99`) flatten the natural control flow into a single loop
- This defeats naive decompilation and makes CFG reconstruction difficult

### Dynamic API Resolution (IAT Evasion)
- No import table entries are created for the resolved function
- Security tools that monitor IAT entries will not see the API being imported
- The hash-based lookup (`0xDEADBEEF` seed) prevents string-based detection of API names

### Opaque Predicate / Junk Condition
```c
if ( (((a1 * 3) ^ 0xDEADBEEF) + 1) > 0 )
```
For an **unsigned int**, this condition is almost always true (it would only be false if `(a1 * 3) ^ 0xDEADBEEF == 0xFFFFFFFF`). This is likely a **junk conditional** inserted to confuse analysis, or it guards against a specific sentinel hash value.

## 6. Facts vs. Inferences

| Category | Statement |
|----------|-----------|
| **Observed Fact** | The function reads `GS:[0x60]` (PEB pointer on x64 Windows) |
| **Observed Fact** | It walks a doubly-linked list via `Flink` pointers |
| **Observed Fact** | The constant `0xDEADBEEF` appears in a conditional expression |
| **Observed Fact** | Control flow is flattened via a while-switch state machine |
| **Observed Fact** | The function calls `sub_14000e00` with DLL base, export directory, and hash parameter |
| **Inferred** | The linked list is `PEB->Ldr->InMemoryOrderModuleList` (standard PEB walking pattern) |
| **Inferred** | `sub_14000e00` walks the export table and matches function hashes (based on the 3-argument signature: base, exports, hash) |
| **Inferred** | The hash algorithm is Metasploit `block_api`-style (based on `0xDEADBEEF` seed) |
| **Inferred** | The `(((a1*3)^0xDEADBEEF)+1) > 0` check is an opaque predicate / junk condition |
| **Inferred** | This is likely part of a shellcode stub or position-independent code (PIC) given PEB walking + API hashing + CFF |

LLM judge panel

ClaudeAI judge verdict: satisfiedop11/judge_ClaudeAI_GLM51_up0_1.txt
{
  "understanding_point": "dynamic API resolution via PEB",
  "full_evaluation": "The understanding point is that the function performs dynamic API resolution via the PEB. The summary explicitly and repeatedly states this. The title says 'dynamic API resolution via PEB walking'. It details reading the PEB via __readgsqword(0x60), walking the loaded module linked list from PEB->Ldr, iterating loaded DLLs, parsing the PE export directory, and resolving a function by hash. This is a precise and complete expression of the understanding point, with no contradictions.",
  "explanation": "The summary directly and thoroughly states that the function implements dynamic API resolution via PEB walking, including reading the PEB, traversing the module list, and resolving APIs by hash.",
  "evidence": "This function implements **dynamic API resolution via PEB walking**",
  "support_strength": 3,
  "satisfied": "true"
}
GeminiAI judge verdict: satisfiedop11/judge_GeminiAI_GLM51_up0_1.txt
{
  "understanding_point": "dynamic API resolution via PEB",
  "full_evaluation": "The candidate summary explicitly states and details the understanding point. The very first sentence of the \"Functionality Description\" section reads: \"This function implements dynamic API resolution via PEB walking\". It then proceeds to describe the steps involved, starting with reading the PEB. The summary also lists \"PEB Walking / Module Enumeration\" as a well-known algorithm and maps it to MITRE ATT&CK techniques related to dynamic API resolution, further reinforcing the connection.",
  "explanation": "The summary explicitly states that the function implements \"dynamic API resolution via PEB walking\" and provides detailed steps on how the PEB is used for this purpose.",
  "evidence": "This function implements **dynamic API resolution via PEB walking**",
  "support_strength": 3,
  "satisfied": "true"
}
OpenAI judge verdict: satisfiedop11/judge_OpenAI_GLM51_up0_1.txt
{
  "understanding_point": "dynamic API resolution via PEB",
  "full_evaluation": "The candidate summary clearly and repeatedly states the understanding point. It explicitly says the function implements \"dynamic API resolution via PEB walking,\" describes reading the PEB from the TEB using GS:[0x60], walking PEB->Ldr module lists, parsing PE export directories, and resolving a function pointer dynamically rather than through the import table. These details are an equivalent and expanded explanation of dynamic API resolution via the PEB. There are no contradictions or weakening qualifiers that would undermine this point.",
  "explanation": "The summary explicitly states \"dynamic API resolution via PEB walking\" and supports it with PEB access, module traversal, export parsing, and runtime function resolution. This fully satisfies the understanding point.",
  "evidence": "This function implements **dynamic API resolution via PEB walking**",
  "support_strength": 3,
  "satisfied": "true"
}

Your verdict