Courseiva
Antivirus Evasion →mediumMultiple Select

PEN-200 Antivirus Evasion Practice Question

A penetration tester is building a custom shellcode runner in C for a PEN-200 lab. The compiled loader is being flagged by static analysis before execution. The tester wants to modify the loader's source so the resulting binary is less likely to match signatures, without changing the shellcode's behavior. Which two changes best serve this goal? (Choose two.)

⚠ Common exam trap

The trap here is treating size or dependency changes as evasion, when static signatures key on the shellcode bytes and the import table rather than the binary's overall footprint.

Answer choices

Why each option matters

Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.

Correct answer & explanation

✓

Encrypt the embedded shellcode with a simple XOR key and decrypt it in memory before execution.

Static analysis of the loader is driven by recognizable shellcode bytes and a suspicious import table. XOR-encrypting the shellcode removes its signature-matching bytes from disk, and resolving APIs dynamically with LoadLibrary and GetProcAddress removes telltale imports like VirtualAlloc and VirtualProtect. Optimization, static runtime linking, and padding change size or dependencies but leave the shellcode bytes and imported APIs that triggered detection in place.

Answer analysis

Option-by-option breakdown

For each option: why learners choose it and why it is or isn't the right answer here.

  • ✗

    Statically link the C runtime library so the loader has fewer external dependencies.

    Why it's wrong here

    Static linking changes which runtime functions are bundled, but the loader's own imported Windows APIs and embedded shellcode remain unchanged. Those are the primary static indicators in this scenario. Reducing runtime dependencies may slightly alter the binary, but it does not hide the shellcode bytes or the suspicious API imports, so detection based on those indicators still occurs.

  • ✗

    Add a large embedded PNG image resource to increase the binary's file size.

    Why it's wrong here

    Appending a large resource changes the file size and hash but leaves the code section, shellcode bytes, and import table intact. Static signatures typically match specific byte sequences rather than overall size, so padding does not prevent a match. This is a cosmetic change that consumes space without addressing the indicators that caused the loader to be flagged before execution.

  • ✓

    Encrypt the embedded shellcode with a simple XOR key and decrypt it in memory before execution.

    Why this is correct

    Embedded plaintext shellcode is a strong static indicator because its bytes match known signatures. Storing the shellcode XOR-encrypted and decrypting it at runtime removes those recognizable bytes from the on-disk binary, so signatures targeting the shellcode no longer match. Behavior is preserved because the decrypted buffer is what executes, making this a direct way to reduce static detection while keeping functionality.

  • ✗

    Compile the loader with the /O2 optimization flag to reduce the binary's overall size.

    Why it's wrong here

    Optimization changes code generation and size but does not remove the shellcode bytes or the imported API names that static analysis flags. The same distinctive strings and import entries remain, so signatures keyed on those still match. Optimization may incidentally alter some bytes, but it is not a targeted evasion technique and does not address the specific indicators that trigger detection.

  • ✓

    Replace direct API calls with dynamically resolved function pointers using LoadLibrary and GetProcAddress.

    Why this is correct

    The PE import table lists functions the binary uses, and suspicious combinations such as VirtualAlloc, VirtualProtect, and CreateThread are heuristically interesting. Resolving these at runtime with LoadLibrary and GetProcAddress removes them from the import table, so static analysis of imports no longer sees the telltale set. The calls still occur at runtime, preserving behavior while changing the binary's static profile.

Visual reference

Client Recursive Resolver Root DNS (13 root servers) TLD DNS (.com, .org, …) Authoritative example.com query IP addr answer

About these practice questions

Courseiva writes every PEN-200 question from scratch — 285 in total, each with an explanation and a wrong-answer breakdown. None are copied from real exams or dumps. Learn why practice questions differ from exam dumps →

How Courseiva writes practice questions · Editorial policy

JA

Written and reviewed by Johnson Ajibi, MSc IT Security

Senior Network & Security Engineer · founder of Courseiva

Last reviewed September 2026 · checked against the official OffSec exam blueprint

This PEN-200 practice question is part of Courseiva's free OffSec certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the PEN-200 exam.