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
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 →
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.