Source: Juni_2026_Exams/Advance_Forensics/notes/13-lecture-exercises-step-by-step.md
Lecture Exercises - Complete Step-by-Step Workbook
Purpose
This single workbook combines the lecture exercise instructions with the exact commands and GUI procedures needed to complete them. It answers three questions for every exercise:
- What exactly do I run or click?
- What output should I save?
- What proves the answer?
All malware execution commands are for the isolated university VM only. Paths assume samples are copied to C:\Temp. Replace a path only when the VM stores the supplied tool or sample elsewhere.
Source Map
| Exercises | Source PDF |
|---|---|
| 1-5 | Lecture 1 Malware Analysis - Hashes.pdf |
| 6-15 | Lecture 2-3 PE and memory.pdf |
| 16-21 | Lecture 4 Static Analysis.pdf |
| 22-30 | Lecture 5-6 Dynamic Analysis.pdf |
| 31-35 | Lecture 7.1 Malware Persistence.pdf |
| 36-40 | Lecture 8 Malware Communications - Networking.pdf |
| 41-47 | Lecture 9-10 Classic process injection techniques.pdf |
The commands preserve the lecture's intended workflow while correcting typographic dashes, obvious filename mistakes, and deprecated syntax.
Tool Controls, Commands, and Evidence Guide
Use this section before starting the numbered exercises. It explains what each tool contributes, how its important controls work, and what evidence should be saved. A tool result is useful only when you can explain what produced it and what claim it supports.
Command Prompt and PowerShell
Use Command Prompt for traditional Windows utilities and supplied console programs. Use PowerShell when you need structured objects, hashing, filtering, or repeatable evidence output.
Open an elevated shell only when the task requires administrator rights:
- Open Start.
- Search for
cmdorPowerShell. - Right-click the result.
- Select
Run as administrator. - Record that the shell was elevated because privilege changes results.
Important Command Prompt syntax:
cd /d C:\Temp
dir /a
where ssdeep
"C:\Path With Spaces\tool.exe" argument
tool.exe > output.txt
tool.exe >> output.txt
tool.exe 2>&1
| Syntax | Meaning |
|---|---|
cd /d |
Change drive and directory together |
dir /a |
Show hidden and system entries as well as normal entries |
where tool |
Show which executable Windows will run |
| Quotes | Protect paths containing spaces |
> |
Replace a file with command output |
>> |
Append command output |
2>&1 |
Put error output in the same evidence file as normal output |
Important PowerShell patterns:
Get-FileHash C:\Temp\sample.exe -Algorithm SHA256
Get-Item C:\Temp\sample.exe | Format-List *
Get-Process | Sort-Object Id
Select-String -Path C:\Temp\Results\*.txt -Pattern 'VirtualAllocEx'
Get-ChildItem C:\Temp -Recurse -File | Select-Object FullName,Length
PowerShell sends objects through |, not only text. For example, Get-Process | Sort-Object Id sorts using the numeric Id property. This is more reliable than parsing visually aligned command output.
CFF Explorer
Use it for: PE structure, architecture, header values, sections, imports, exports, resources, and address calculations.
Open a sample with File -> Open. Do not use Save on the original evidence. If an exercise changes a header, first make and hash a working copy.
Important tree items:
| CFF Explorer location | What it answers |
|---|---|
DOS Header |
Is MZ present, and where is e_lfanew? |
NT Headers -> File Header |
x86/x64 machine type and PE characteristics |
NT Headers -> Optional Header |
ImageBase, entry-point RVA, alignment |
Section Headers |
Section name, RVA, raw offset, raw/virtual size, flags |
Import Directory |
DLLs and functions requested statically |
Export Directory |
Functions made available by a DLL |
Resource Directory |
Embedded icons, dialogs, configuration, or payloads |
Hex Editor |
Raw bytes at an exact file offset |
Buttons and actions:
- Open: load a PE without executing it.
- Address Converter: convert between file offset, RVA, and VA. Confirm
whether it uses the preferred or actual runtime ImageBase.
- Hex Editor: inspect bytes directly. Use
Ctrl+Gor the available
go-to-offset control to jump to a file offset.
- Rebuild/Save: writes a modified PE. Use only on a disposable copy.
- Dependency/Import tree expansion: shows DLL names first, then imported
functions or ordinals.
How to interpret addresses:
VA = actual runtime ImageBase + RVA
RVA = VA - actual runtime ImageBase
file offset = PointerToRawData + (RVA - section VirtualAddress)
Do not add an RVA to a file offset. Do not assume the preferred ImageBase is the actual runtime base when ASLR relocated the image.
Evidence to capture:
- complete filename and SHA-256
- Machine value and PE32/PE32+ type
- ImageBase and
AddressOfEntryPoint - section names, RVA, raw/virtual sizes, entropy if available, and flags
- important DLL/function imports
- resource type/name/size
Detect It Easy (DiE)
Use it for: file type, architecture, compiler/linker clues, packer signatures, and entropy.
Workflow:
- Open DiE.
- Drag the sample into the window or use
File -> Open. - Read the main detection tree.
- Open the entropy view.
- Expand PE/compiler/packer detections.
- Save a screenshot containing the filename and detection.
Controls vary by version, but the important views are:
- Scan/Detect: rerun signature detection.
- Entropy: graph byte randomness across the file.
- Strings: quick string view; use a dedicated strings tool for export.
- Hex: inspect bytes around suspicious regions.
Interpretation:
- entropy approaching
8.0can support compression or encryption UPX, unusual section names, few imports, and high entropy together support
packing more strongly than any one indicator
- a compiler signature is a clue, not proof of authorship
Unknowndoes not mean clean or unpacked
PEview and a Hex Editor
Use them for: verifying raw PE bytes and understanding little-endian values.
PEview shows fields beside their file offsets. A hex editor shows the original bytes. When a four-byte field is stored as 80 00 00 00, the numeric little-endian value is 0x00000080.
Useful controls:
- expand/collapse the PE structure tree
- select a field to highlight corresponding bytes
- use
Go to offsetto inspect0x3C, the PE signature, or section data - switch between hexadecimal and decimal display only when you record which
representation you used
Process Hacker
Use it for: process tree, parent PID, integrity, modules, threads, handles, and live memory.
Main window:
- Name/PID: identifies the exact process instance.
- Parent: shows which process created it when that information remains
available.
- User name: shows execution context.
- Integrity: distinguishes low, medium, high, and system integrity.
- CPU/I/O columns: help identify short-lived activity.
Right-click a process and open Properties:
| Tab | Use |
|---|---|
General |
Image path, command line, parent, user, start time |
Threads |
TID, start address, state, priority, stack |
Modules |
Loaded EXEs/DLLs and their runtime base addresses |
Memory |
Private/image/mapped regions, protection, size, strings |
Handles |
Files, registry keys, processes, threads, mutexes |
Environment |
Environment variables inherited by the process |
Important actions:
- Refresh (
F5): update the view. Refresh immediately after execution. - Find Handles or DLLs (
Ctrl+F): search all processes for a filename,
DLL, mutex, or path.
- Properties -> Memory: sort by base address, size, type, or protection.
- Memory -> Read/Strings: inspect a selected region without assuming it
contains executable code.
- Threads -> Stack: inspect a thread's call stack when symbols permit.
Evidence to capture:
- process name, PID, parent PID, command line, user, integrity
- unexpected module path and base address
- suspicious private executable or RWX memory region
- thread start address and whether it falls inside an unexpected region
PIDs and addresses change on every run. Never reuse values from screenshots or previous answers.
VMMap
Use it for: understanding a process's virtual address space.
- Start the target process.
- Open VMMap.
- Select the process by both name and PID.
- Use the top summary to compare image, heap, stack, private, and mapped
memory.
- Expand a category to see individual regions.
- Use
Refreshafter the sample changes memory.
Key terms:
- Committed: backed by RAM or page file and available for use.
- Reserved: address range held for future commitment.
- Private: belongs to the process and is not file-backed.
- Image: mapped from an executable image.
- Mapped file: mapped from another file or shared section.
An unexpected private RWX region is suspicious, but it is not automatically injected malware. Correlate it with allocation, writing, and execution APIs.
Strings and BinText
Use them for: finding human-readable indicators without executing the sample.
Sysinternals Strings:
strings64.exe -n 4 -accepteula C:\Temp\sample.exe
strings64.exe -n 4 -accepteula C:\Temp\sample.exe > C:\Temp\Results\sample-strings.txt
strings64.exe -n 8 -u C:\Temp\sample.exe > C:\Temp\Results\sample-unicode.txt
| Option | Meaning |
|---|---|
-n 4 |
Minimum string length of four characters |
-u |
Search Unicode strings |
-accepteula |
Avoid an interactive first-run prompt |
> |
Save output for searching and submission |
Search the output:
findstr /i "http https ftp cmd.exe powershell mutex user-agent" C:\Temp\Results\sample-strings.txt
In BinText, use the text, Unicode, and offset columns. Export all findings rather than saving only one screenshot.
Strings provide hypotheses. A URL string does not prove a connection occurred, and an API name may be present without being called.
ssdeep
Use it for: approximate binary similarity between sufficiently large, related files.
ssdeep -V
ssdeep -h
ssdeep -b file1.bin > baseline.hash
ssdeep -m baseline.hash file2.bin
ssdeep -b file1.bin file2.bin > family.hashes
ssdeep -m family.hashes file1.bin file2.bin
| Option | Meaning |
|---|---|
-V |
Display version |
-h |
Display the build's supported options |
-b |
Store only the base filename in generated signatures |
-m hashes.txt candidates... |
Match candidates against stored signatures |
A score of 100 means very strong similarity for that comparison. A score of 0 or no printed match does not prove the files share no content. Very small files, compressed containers such as DOCX, and format conversions can produce weak results.
UPX
Use it for: confirming, creating, testing, or removing UPX packing.
upx -V
upx -t C:\Temp\sample.exe
upx -o C:\Temp\packed.exe C:\Temp\original.exe
upx -d C:\Temp\packed.exe -o C:\Temp\unpacked.exe
| Option | Meaning |
|---|---|
-t |
Test whether a file is a valid supported UPX-packed file |
-o |
Write to a new output file |
-d |
Decompress/unpack |
Hash the original, packed, and unpacked files separately. After unpacking, compare size, sections, entropy, imports, strings, and behavior. Never unpack over the only copy.
ProcMon
Use it for: high-volume runtime evidence about files, registry, processes, threads, and some network operations.
Essential controls:
| Control | Shortcut | Meaning |
|---|---|---|
| Capture | Ctrl+E |
Start or stop collecting events |
| Clear | Ctrl+X |
Remove displayed events from the current capture |
| Filter | Ctrl+L |
Add include/exclude rules |
| Process Tree | Ctrl+T |
Show parent/child relationships |
| Find | Ctrl+F |
Find text in displayed events |
| Jump To | Ctrl+J |
Open the selected file or registry location |
| Autoscroll | Ctrl+A |
Follow new events while capturing |
Filter-window fields:
- Select a column such as
Process Name,PID,Operation,Path, or
Result.
- Select a relation such as
is,contains,begins with, orends with. - Enter the value.
- Choose
IncludeorExclude. - Select
Add. - Select
Apply, thenOK.
Example:
Process Name is sample.exe -> Include
Process Name is rundll32.exe -> Include
Path begins with C:\Temp -> Include
Operation is RegSetValue -> Include
Result is ACCESS DENIED -> Include
Filter logic matters. Several include rules on the same field can behave like alternatives, while rules on different fields narrow the result. Always check the visible filter summary.
Correct capture sequence:
- Start ProcMon.
- Stop capture with
Ctrl+E. - Clear old events with
Ctrl+X. - Configure only the minimum initial filters.
- Start capture.
- Execute the sample.
- Wait for the required behavior.
- Stop capture.
- Save All events as
.PML. - Apply narrower investigative filters.
- Export selected rows to CSV only as a supporting copy.
Important columns:
- Time of Day: relative timing and sequence
- Process Name/PID: actor
- Operation: event category
- Path: target object
- Result: success, not found, denied, and so on
- Detail: access flags, data, offsets, lengths, and disposition
Do not call every CreateFile operation file creation. Windows uses it to open existing files and other objects. Read Path, Result, and Detail.
APIMiner and API Monitor
Use them for: runtime API calls, arguments, return values, and call order.
The lecture VM's APIMiner launch pattern is:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\sample.exe
Workflow:
- Restore a clean snapshot.
- Start APIMiner using the supplied launcher.
- Confirm the application path is correct.
- Let the sample reach the required behavior.
- Close or stop tracing cleanly.
- Find every generated trace file.
- Search API families with context, not isolated names.
Select-String -Path C:\Temp\Results\*.txt `
-Pattern 'OpenProcess|VirtualAllocEx|WriteProcessMemory|CreateRemoteThread' `
-Context 4,12
For API Monitor:
- Select API categories before starting monitoring.
- Choose the target process or configure the application to launch.
- Start monitoring.
- Select a call to inspect parameters and return value.
- Expand pointer/structure arguments when supported.
For process injection, group APIs by stage:
Discovery: CreateToolhelp32Snapshot, Process32First/Next
Target access: OpenProcess
Allocation: VirtualAllocEx, NtAllocateVirtualMemory
Writing/mapping: WriteProcessMemory, NtMapViewOfSection
Protection: VirtualProtectEx, NtProtectVirtualMemory
Execution: CreateRemoteThread, NtCreateThreadEx, QueueUserAPC, ResumeThread
An API name alone is weak evidence. Record target PID/handle, address, size, protection, payload path/data, return value, and sequence.
Regshot
Use it for: broad before/after differences in the registry and optionally selected filesystem paths.
- Open Regshot before execution.
- Select output format and destination.
- Select
1st shot -> Shot. - Execute the sample and wait for the required behavior.
- Select
2nd shot -> Shot. - Select
Compare. - Save the comparison report.
Regshot tells you what changed between snapshots. It does not identify the responsible process or exact event time. Use ProcMon to add attribution and sequence.
Autoruns
Use it for: enumerating many persistence mechanisms in one interface.
Important tabs:
| Tab | Typical evidence |
|---|---|
Everything |
All known autorun locations |
Logon |
Startup folders, Run keys, Winlogon entries |
Services |
Service and driver persistence |
Scheduled Tasks |
Task Scheduler entries |
AppInit |
AppInit DLL configuration |
Drivers |
Kernel drivers |
Useful controls:
Options -> Hide Microsoft Entriesreduces noise but can hide abused
Microsoft-signed locations; record whether it was enabled.
Options -> Verify Code Signatureschecks signing status.File -> Savepreserves the autorun inventory.Jump to Entryopens the registry or filesystem source.Jump to Imageopens the referenced executable location.
Do not disable or delete an entry during evidence collection. Record the location, value/task/service name, image path, publisher/signature, and user scope.
Resource Hacker
Use it for: viewing and exporting PE resources.
- Open the sample.
- Expand resource types such as
RCDATA,BIN,ICON,DIALOG, or custom
numeric types.
- Select the resource name and language.
- Record its displayed size and preview.
- Use
Action -> Save [resource] as a binary file. - Hash and identify the exported object.
Do not classify a resource only from its label. Check magic bytes, strings, hash, entropy, and PE headers.
Dependency Walker
Use it for: direct and transitive DLL dependencies and optional runtime profiling.
- Open the EXE or DLL.
- Record direct dependencies before profiling.
- Expand modules to inspect imported functions.
- Use
Profile -> Start Profilingonly in the isolated VM. - Record modules loaded dynamically during the run.
Warnings about modern Windows API sets can be normal in older Dependency Walker versions. Distinguish a parser limitation from a genuinely missing dependency.
FakeNet-NG and ApateDNS
Use them for: safely simulating Internet services and observing malware network intent.
FakeNet-NG:
- Use an isolated VM/network.
- Start FakeNet-NG as administrator.
- Confirm the selected interface and listener configuration.
- Start Wireshark before executing the sample.
- Run the sample.
- Save FakeNet logs and the packet capture.
ApateDNS:
- Select the active analysis interface.
- Set the reply IP, normally the controlled analysis host.
- Start the DNS server.
- Execute the sample.
- Record queried domain names and response mapping.
If FakeNet intercepts a request, write that the sample attempted the connection and FakeNet supplied the response. Do not claim the real public server was contacted.
Wireshark
Use it for: packet-level DNS, TCP, HTTP, TLS, and timing evidence.
Capture controls:
- double-click the correct interface to start
- red square stops capture
- shark-fin button restarts capture
File -> Save Assaves.pcapng- right-click a packet and choose
Follow -> TCP StreamorHTTP Stream
Capture filters are applied before collection:
host 192.168.56.10
port 80
Display filters do not remove packets from the saved capture:
dns
http
tls
ip.addr == 192.168.56.10
tcp.port == 443
dns.qry.name contains "example"
For TLS key logs:
- Open
Edit -> Preferences. - Expand
Protocols -> TLS. - Set
(Pre)-Master-Secret log filename. - Reload or reopen the capture.
- Confirm decrypted application data appears.
Record source/destination IP, ports, domain, method/path, response status, timing, and whether the traffic was simulated or decrypted.
OllyDbg
Use it for: entry point, instructions, breakpoints, registers, memory, and step-by-step execution of 32-bit samples.
Core controls:
| Action | Common key |
|---|---|
| Run | F9 |
| Pause | F12 |
| Step into | F7 |
| Step over | F8 |
| Execute until return | Ctrl+F9 |
| Toggle breakpoint | F2 |
| Restart debuggee | Ctrl+F2 |
Important panes:
- disassembly: current instructions
- registers: EIP/ESP and general registers
- stack: arguments and return addresses
- dump: memory bytes and strings
- modules/memory map: loaded images and regions
Do not single-step thousands of instructions without a hypothesis. Set a breakpoint on the entry point or an API relevant to the question, run to it, and record the arguments and resulting state.
Minimum Evidence Package Per Exercise
Save:
01-command-or-filter.txt
02-tool-result.png
03-raw-output.txt or capture.pml/pcapng
04-observation.txt
05-conclusion.txt
Every screenshot should show the tool name, sample/process identity, relevant field or filter, and result. A cropped value without context is weak evidence.
Complete Exercise Briefs: What Each Exercise Asks
These briefs preserve the complete task intent in clear exam language. The numbered procedure under each corresponding heading shows exactly how to perform it.
Exercises 1-5: Extensions and Hashes
- Misleading extension: Create or inspect a double-extension executable,
compare how it appears with known extensions hidden and visible, and prove why filename/icon alone cannot identify type.
- Cryptographic hashes: Hash the same content with MD5, SHA-1, and
SHA-256, rename it without editing it, compare the results, inspect the supplied MD5 collision pair, and explain exact identity versus collision resistance.
- Fuzzy hashes across formats: Generate and compare ssdeep signatures for
the supplied DOCX and TXT pairs, record the actual scores, and explain why container/compression structure affects similarity.
- DOC versus DOCX: Compare original and modified documents within the
same format and across DOC/DOCX formats, then explain which comparison is meaningful and why.
- Repeated changes: Make repeated small controlled changes to the
supplied script/file, calculate cryptographic and fuzzy hashes after each version, and explain exact hash avalanche versus approximate similarity.
Exercises 6-15: PE Structure and Memory
- Process creation and parentage: Launch the same program from Explorer,
Command Prompt, and an elevated context; identify PID, parent, user, and integrity; explain how launch method changes the process tree.
- VMMap: Open the supplied process in VMMap, identify image, heap, stack,
private, mapped, committed, and reserved memory, and explain what each category means.
- DOS header and
e_lfanew: FindMZ, read the little-endian
e_lfanew field at offset 0x3C, jump to that offset, and verify the PE signature.
- Machine type: Identify the PE target architecture, modify the Machine
value only in a disposable copy, attempt to load it, and explain the loader's response.
- ImageBase: Record the preferred ImageBase from disk and actual module
base in Process Hacker, compare them, and explain relocation/ASLR.
- Entry point: Read
AddressOfEntryPoint, calculate the runtime entry
virtual address, verify it in the debugger, and distinguish RVA from VA.
- Section mapping: Map
.textfrom raw file offset to runtime memory,
verify corresponding bytes, and explain raw size, virtual size, and alignment.
- Identify a DLL: Determine whether the supplied/renamed file is a DLL
using magic bytes and PE characteristics rather than extension.
- Imports and loaded modules: Record static imports, execute the sample,
compare them with Process Hacker's Modules tab, and explain additional transitive or dynamic loads.
- Exports and dependencies: Inspect the DLL Export Directory and use
Dependency Walker to identify direct/transitive dependencies and the difference between imports and exports.
Exercises 16-21: Static Analysis
- Lab01-01 full triage: Analyze both the EXE and DLL for hashes, type,
architecture, timestamps, packing, sections, strings, imports, and host/network indicators; write supported hypotheses without executing.
- UPX packing: Pack a working copy, compare original and packed
versions by size, hash, sections, entropy, imports, strings, and hex, and identify the evidence that supports UPX packing.
- Strings before and after packing: Export strings from original and
packed versions, compare useful indicators, and explain why packed content may become visible only after unpacking or execution.
- Lab01-03 and Lab01-04: Perform static triage on both samples, reach a
supported packed/not-packed decision for each, and translate imports and strings into testable behavior hypotheses.
- Dependency profiling: Compare static dependencies with modules loaded
during Dependency Walker profiling and identify networking or other capability clues.
- Embedded resources: Locate, export, hash, identify, and analyze an
embedded resource; determine whether it is data, configuration, or a PE payload and explain what that does and does not prove.
Exercises 22-30: Dynamic Analysis
- ProcMon filtering: Capture the supplied sample, preserve the complete
PML, apply the required include/exclude/result filters, and report each relevant event with process, operation, path, result, and detail.
- APIMiner: Trace the supplied sample, find process-enumeration APIs,
inspect arguments/return values and neighboring calls, and explain the complete API sequence.
- Lab01-02 unpacking: Confirm UPX, create an unpacked copy, compare both
versions, and identify imports/strings that become visible after unpacking.
- Lab01-03 and Lab01-04 practice: Produce a complete repeatable static
profile for both samples and separately classify any Lab01-04 embedded resource.
- Registry change analysis: Take Regshot before/after snapshots while
invoking the DLL export with rundll32, correlate the differences with ProcMon, and attribute exact key/value changes to the process.
- Sample-13-1: Observe created/manipulated processes and correlate
suspend, resume, and section-mapping APIs by common target handles, PIDs/TIDs, and sequence.
- Sample-13-2: Combine static analysis, Process Hacker, ProcMon,
APIMiner, and simulated networking to classify behavior and verify the mutex and other artifacts actually produced.
- Sample-13-3: Baseline disposable PDF/XLSX files, execute the sample,
prove every changed file with metadata/hash/content comparison, and correlate changes with runtime enumeration/write operations.
- Sample-13-4 memory strings: Compare disk strings with live process
memory, locate the lecture marker if present, and explain whether runtime unpacking or decryption is supported.
Exercises 31-35: Persistence
- Startup folder: Place the supplied executable in the all-users Startup
folder, verify it with filesystem/Autoruns/ProcMon evidence, test the logon trigger, and explain scope.
- Run key: Create the specified Run value, verify hive/key/name/type/data
with command line and Autoruns, test logon execution, and distinguish user from system-wide scope.
- Service: Register
BookServicefor the supplied executable, inspect
configuration, registry and event evidence, attempt start/reboot behavior, and separate successful registration from successful execution.
- Scheduled task: Create task
testwith the requested trigger and
Calculator action, verify it in schtasks, Task Scheduler, Autoruns, task files, and runtime evidence.
- AppInit and DLL export: Inspect AppInit configuration, find the DLL's
installer export, invoke it through rundll32, and distinguish configured persistence from observed loading/execution.
Exercises 36-40: Network Analysis
- DGA output: Run the supplied generator/sample, save generated domains,
identify the repeatable algorithmic pattern or seed/time influence, and explain why it supports DGA behavior.
- FakeNet and Wireshark: Run FakeNet and packet capture in isolation,
execute the sample, correlate DNS and follow-on traffic with FakeNet logs, and report attempted rather than real public communication.
- HTTP C2 strings: Identify static HTTP templates, paths, parameters, or
user-agent strings, execute in the isolated XP/FakeNet environment, and map static clues to observed requests.
- TLS decryption: Compare the encrypted capture before and after loading
the supplied matching key log, verify decrypted application data, and explain why unrelated sessions cannot be decrypted.
- CreateFileA documentation: Use the API documentation and observed
parameters to determine whether the call opens, creates, overwrites, or accesses another object; do not infer behavior from the API name alone.
Exercises 41-47: Process Injection
- Classic DLL injection: Inject the supplied DLL into Notepad using the
lecture sample, verify the unexpected module in the target, and prove the target-access, allocation, write, address-resolution, and remote-thread stages.
- Lab12-01: Perform static and dynamic analysis of the EXE/DLL pair,
identify the target process and injected module, explain the visible behavior/repetition/stop condition, and support the full injection chain.
- Lab19-02: Analyze event/runtime/API evidence for shellcode injection,
identify target/allocation/write/execution stages, and distinguish it from DLL-path injection.
- Sample-10-1 process enumeration: Compare the sample's process list
with Process Hacker or tasklist, trace snapshot/iteration APIs, and explain timing differences.
- Lab12-02 suspended process: Capture suspended process creation,
subsequent memory/context manipulation, and resume; explain why CREATE_SUSPENDED alone does not prove hollowing.
- Sample-10-2 remote allocation: Enter target PID, allocation size, and
protection; locate the returned region in Notepad and Calculator; and explain what VirtualAllocEx proves and what remains unproven.
- Sample-10-3 remote write: Allocate/write the requested marker into
Notepad, verify it at the returned address, correlate WriteProcessMemory parameters, and separate writing from execution.
Before Every Exercise
Open an elevated PowerShell only when the exercise requires administrator rights:
New-Item -ItemType Directory -Force C:\Temp\Results | Out-Null
Get-Date -Format o | Set-Content C:\Temp\Results\start-time.txt
Get-NetIPConfiguration | Format-List | Out-File C:\Temp\Results\network.txt
Get-FileHash C:\Temp\<SAMPLE> -Algorithm SHA256 |
Format-List | Out-File C:\Temp\Results\<SAMPLE>-sha256.txt
Get-Item C:\Temp\<SAMPLE> |
Select-Object FullName,Length,CreationTimeUtc,LastWriteTimeUtc |
Format-List | Out-File C:\Temp\Results\<SAMPLE>-metadata.txt
Use normal PowerShell backticks only when you deliberately split a command. Commands below are generally kept on one line so they can be pasted directly.
How Each Exercise Is Structured
Every exercise now keeps the reasoning beside the procedure:
- Objective: the claim or concept the exercise is testing
- Commands/steps: exactly what to run or click
- Why these steps matter: what each action contributes to the proof
- Expected proof: the observable result that shows the workflow succeeded
- Conclusion: the defensible statement you can write from that evidence
Do not copy an expected result when your VM shows something different. Record your observation, investigate the difference, and base the conclusion on your own evidence.
Exercises 1-5: Extensions and Hashes
1. Misleading Extension
Objective: Prove that a displayed filename and icon can mislead the user about the real file type.
Show all extensions:
control.exe folders
In View, clear Hide extensions for known file types. Create the working copy:
cd /d C:\Temp
copy Sample-3-1.exe "Sample-3-1.pdf.exe"
dir /a
Proof: Explorer filename with extensions enabled plus dir /a output.
Why these steps matter:
- We first expose all extensions because Windows may hide the final
.exe. - We create a copy so the original evidence remains unchanged.
- We use
dir /aas a command-line confirmation independent of Explorer's
visual presentation.
Expected proof: With extensions hidden, the name can look PDF-related. With extensions enabled and in dir, the final .exe is visible.
Conclusion: Extension and icon are not reliable type evidence. Confirm the full name, magic bytes, and PE headers.
2. Cryptographic Hashes
Objective: Prove that hashes describe file content rather than filename, and demonstrate why the selected hash algorithm matters.
Set-Location C:\Temp
'This is the original text.' | Set-Content -NoNewline .\hash.txt
Get-FileHash .\hash.txt -Algorithm MD5
Get-FileHash .\hash.txt -Algorithm SHA1
Get-FileHash .\hash.txt -Algorithm SHA256
Rename-Item .\hash.txt .\hash-renamed.txt
Get-FileHash .\hash-renamed.txt -Algorithm MD5
Get-FileHash .\hash-renamed.txt -Algorithm SHA1
Get-FileHash .\hash-renamed.txt -Algorithm SHA256
Get-FileHash .\md5-1.exe -Algorithm MD5
Get-FileHash .\md5-2.exe -Algorithm MD5
Get-FileHash .\8888888.png -Algorithm SHA256
Proof: identical hash before/after rename; record the actual collision results for the supplied pair.
Why these steps matter:
- The first three commands establish MD5, SHA-1, and SHA-256 baselines.
- Renaming without editing isolates the filename variable. Equal hashes prove
the name is not part of the hashed content.
- The supplied MD5 pair demonstrates that two different files can share a
weak collision-prone hash.
- The PNG SHA-256 provides a stronger identifier for hash-based reputation
lookup without executing the file.
Expected proof: All hashes remain identical after rename. A content edit would change them. Record the supplied collision pair's actual results.
Conclusion: Use SHA-256 for evidence identity. MD5 can assist legacy searches but cannot safely prove uniqueness.
3. Fuzzy Hashes Across Formats
Objective: Prove that ssdeep measures approximate binary similarity, not the semantic or visual similarity of document text.
Check the program:
where ssdeep
ssdeep -V
ssdeep -h
If where fails, run the full university-VM path:
"C:\Tools\ssdeep\ssdeep.exe" -V
Generate signatures:
cd /d C:\Temp\ssdeep-lab
ssdeep file1.docx file2.docx
ssdeep file3.txt file4.txt
Save a baseline signature and get similarity scores:
ssdeep -b file1.docx > file1.hash
ssdeep -m file1.hash file2.docx
ssdeep -b file3.txt > file3.hash
ssdeep -m file3.hash file4.txt
Signature-file method:
ssdeep -b file1.docx file2.docx > docx-hashes.txt
ssdeep -m docx-hashes.txt file1.docx file2.docx
ssdeep -b file3.txt file4.txt > txt-hashes.txt
ssdeep -m txt-hashes.txt file3.txt file4.txt
Interpretation:
100means the compared content is maximally similar.0means ssdeep found no useful match; it does not prove no shared content.- DOCX is ZIP-based, so small document edits can alter container metadata and
compressed streams more than equivalent edits in TXT.
Why these steps matter:
where,-V, and-hverify which ssdeep build is being used and its
available syntax before relying on the result.
- Plain
ssdeep file...generates signatures but does not answer the
comparison question by itself.
ssdeep -b file1 > file1.hashcreates a clean baseline signature.ssdeep -m file1.hash file2asks whether the candidate resembles that
baseline and reports a score when it matches.
- We repeat the same experiment with TXT and DOCX so file format is the only
major variable.
Expected proof: The TXT pair normally produces a clearer similarity match than the DOCX pair. Exact scores depend on content and file size.
Conclusion: A low DOCX score does not prove unrelated text; it may reflect ZIP/XML and compression differences. Compare similar file formats and treat ssdeep as a lead, not a final verdict.
4. DOC Versus DOCX
Objective: Separate the effect of a small content edit from the much larger effect of changing the underlying document format.
cd /d C:\Temp\ssdeep-lab
ssdeep -b Thedoc.doc > Thedoc.hash
ssdeep -m Thedoc.hash Thedocx.docx Thedoc1.doc
ssdeep -b Thedocx.docx > Thedocx.hash
ssdeep -m Thedocx.hash Thedocx1.docx
ssdeep -b Thedoc1.doc > Thedoc1.hash
ssdeep -m Thedoc1.hash Thedocx1.docx
Proof: the same-format old/new comparisons versus the cross-format comparisons.
Why these steps matter:
- The original DOC-to-DOCX comparison tests cross-format similarity.
- DOC-to-modified-DOC and DOCX-to-modified-DOCX test a controlled small edit
within each format.
- Comparing the modified DOC with modified DOCX shows that equal visible text
still does not make binary structures equivalent.
Expected proof: Same-format old/new pairs should generally score higher than DOC-versus-DOCX pairs.
Conclusion: Fuzzy-hash comparisons are most defensible between files of the same or closely related format.
5. Repeated Changes
Objective: Show how fuzzy hashing can link variants that contain small unique changes even though their exact hashes differ.
Create the files:
Set-Location C:\Temp\ssdeep-lab
'Write-Output "Training script"' | Set-Content .\original.ps1
1..3 | ForEach-Object {
$copy = ".\copy$_.ps1"
Copy-Item .\original.ps1 $copy
Add-Content $copy "# GUID: $([guid]::NewGuid())"
}
Compare them:
ssdeep -b original.ps1 > baseline.hash
ssdeep -m baseline.hash copy1.ps1 copy2.ps1 copy3.ps1
ssdeep -b copy1.ps1 > copy1.hash
ssdeep -m copy1.hash copy2.ps1 copy3.ps1
Why these steps matter:
- The original script establishes shared content.
- A new GUID gives each copy a unique byte sequence while leaving most of the
script unchanged.
- Matching all copies against one baseline tests family resemblance.
- Matching modified copies against each other proves the result is not limited
to comparison with the pristine original.
Expected proof: SHA-256 values would all differ, while ssdeep may still report similarity. Very small scripts may produce no match because ssdeep needs enough data for stable blocks.
Conclusion: Use cryptographic hashes for exact identity and fuzzy hashes for possible variant relationships.
Exercises 6-15: PE and Memory
6. Process Creation and Parentage
Objective: Prove that the method used to launch a program changes its process ancestry and security context.
Explorer run: double-click Sample-4-1.exe.
Command-prompt run:
cd /d C:\Temp
Sample-4-1.exe
PowerShell cross-check:
Get-CimInstance Win32_Process -Filter "Name='Sample-4-1.exe'" |
Select-Object Name,ProcessId,ParentProcessId,ExecutablePath,CommandLine
Process Hacker: double-click process -> General. Record path, command line, current directory, parent, integrity, and user.
Why these steps matter:
- Explorer launch creates one known parentage path.
- Command Prompt launch creates a second path for comparison.
- CIM provides a text-based PID/parent-PID record independent of Process
Hacker.
- Integrity and user values show whether elevation changed the security
context.
Expected proof: Explorer launch normally has explorer.exe as parent; Command Prompt launch normally has cmd.exe. The elevated instance should have a higher integrity level.
Conclusion: Parent PID helps reconstruct execution origin, but parentage alone does not prove maliciousness.
7. VMMap
Objective: Understand how Windows divides a process's virtual address space into images, heaps, stacks, mapped files, private memory, and free regions.
"C:\Program Files\Sysinternals\vmmap.exe" Sample-4-1.exe
If attaching by name fails, start VMMap without arguments and choose the process:
"C:\Program Files\Sysinternals\vmmap.exe"
Save with File -> Save As. Record Image, Heap, Stack, Private Data, Mapped File, Commit, and Reserved totals.
Why these steps matter:
- Attaching to the running sample lets VMMap classify its actual runtime
regions.
- Recording both committed and reserved values distinguishes memory backed by
resources from address space merely set aside.
- Saving the report preserves evidence because memory values change between
executions.
Expected proof: The process contains several region types, not only the executable image. Committed and reserved totals should differ.
Conclusion: Memory type, state, and protection provide context for later unpacking and injection analysis.
8. DOS Header and e_lfanew
Objective: Manually prove how the DOS header points to the PE header and practice little-endian interpretation.
Read the first 64 bytes in PowerShell:
Format-Hex -Path C:\Temp\Sample-4-1.exe | Select-Object -First 4
Read and convert e_lfanew from offset 0x3C:
$b = [IO.File]::ReadAllBytes('C:\Temp\Sample-4-1.exe')
$peOffset = [BitConverter]::ToUInt32($b,0x3c)
'e_lfanew decimal: {0}; hex: 0x{0:X}' -f $peOffset
[Text.Encoding]::ASCII.GetString($b,$peOffset,4)
Expected final string: PE followed by two null bytes. Verify the same offset in the hex editor.
Why these steps matter:
Format-Hexproves the physical file begins with4D 5A.- Reading four bytes at
0x3Cobtainse_lfanewexactly as Windows stores it. BitConverter.ToUInt32interprets the little-endian bytes as an offset.- Reading four bytes at that offset verifies the expected PE signature rather
than trusting a parser.
Expected proof: Offset 0x3C resolves to a location containing 50 45 00 00.
Conclusion: e_lfanew links the legacy DOS header to the NT headers. Distinguish byte order from the numeric value displayed by analysis tools.
9. Machine Type
Objective: Demonstrate that the PE Machine field controls which processor architecture Windows expects.
CFF Explorer:
NT Headers -> File Header -> Machine
Save only a copy:
copy C:\Temp\Sample-4-1.exe C:\Temp\Sample-4-1-machine-test.exe
Change Machine, save the copy, then run:
C:\Temp\Sample-4-1-machine-test.exe
Proof: original value, changed value, and Windows loader error.
Why these steps matter:
- We record the original value so the modification is measurable.
- We edit only a copy to preserve the evidence sample.
- Attempting execution tests whether the loader actually enforces the header
field.
Expected proof: An incompatible Machine value should cause Windows to reject or fail to load the modified copy.
Conclusion: Renaming cannot change architecture; PE header fields govern loader interpretation.
10. ImageBase
Objective: Compare the preferred base address stored on disk with the actual base address selected by the Windows loader.
CFF Explorer:
NT Headers -> Optional Header -> ImageBase
Run and locate:
C:\Temp\Sample-4-1.exe
Process Hacker: process -> Modules -> locate the main executable -> Base address. Explain relocation/ASLR if it differs.
Why these steps matter:
- CFF Explorer supplies the preferred ImageBase without executing the sample.
- Process Hacker supplies the actual runtime base.
- Comparing them reveals whether relocation occurred because of ASLR or an
address conflict.
Expected proof: The values may match for a non-relocated image or differ when Windows relocates it.
Conclusion: Use the actual runtime base, not automatically the preferred ImageBase, when converting an RVA to a live virtual address.
11. Entry Point
Objective: Prove that AddressOfEntryPoint is an RVA and calculate the runtime address of the program's first instruction.
CFF Explorer:
Optional Header -> ImageBase
Optional Header -> AddressOfEntryPoint
Calculate:
$imageBase = 0x400000
$entryRva = 0x1040
'Entry VA = 0x{0:X}' -f ($imageBase + $entryRva)
Replace both example values with values read from your file. Open the sample in OllyDbg and compare the initial break address.
Why these steps matter:
- Reading ImageBase and entry-point RVA provides both inputs to the VA
calculation.
- Performing the addition demonstrates the PE addressing rule.
- OllyDbg supplies independent runtime confirmation of the calculated address.
Expected proof: actual ImageBase + AddressOfEntryPoint should correspond to the program entry address, allowing for debugger startup behavior.
Conclusion: Do not report an RVA as though it were a complete memory address.
12. Section Mapping
Objective: Prove how a PE section's on-disk bytes are mapped to its runtime virtual address.
Calculate a section VA:
$actualImageBase = 0x400000
$sectionRva = 0x1000
'Section VA = 0x{0:X}' -f ($actualImageBase + $sectionRva)
Process Hacker: process -> Memory -> find the calculated address -> double-click -> inspect bytes. Compare with CFF Explorer's Section Headers and hex view.
Why these steps matter:
- Section RVA plus actual ImageBase predicts where the loader maps the
section.
- Process Hacker verifies that memory location.
- Comparing bytes with the file proves the relationship between raw data and
mapped content.
- Raw and virtual sizes are recorded because alignment and zero-filled space
can make them differ.
Expected proof: .text begins near actual ImageBase + .text RVA, and its initial bytes correspond to the on-disk section.
Conclusion: PointerToRawData is a file offset; RVA is a location relative to the loaded image.
13. Identify a DLL
Objective: Identify a DLL from PE structure rather than trusting its name.
copy C:\Temp\Sample-2-2 C:\Temp\Sample-2-2.dll
Optional CLI checks when present:
trid C:\Temp\Sample-2-2.dll
sigcheck -nobanner -a -h C:\Temp\Sample-2-2.dll
CFF Explorer: File Header -> Characteristics. Prove that DLL is set.
Why these steps matter:
- Renaming tests whether an extension changes the actual format; it does not.
- TrID/Sigcheck provide independent type and metadata checks.
- The PE DLL characteristic is the structural evidence used by the loader.
Expected proof: The file has PE magic and the DLL characteristic even if the original filename had no .dll extension.
Conclusion: File extensions are hints. PE characteristics and magic bytes support the defensible classification.
14. Imports and Loaded Modules
Objective: Compare statically declared dependencies with everything the Windows loader places in the process at runtime.
CFF Explorer: Import Directory.
Run:
C:\Temp\Sample-4-1.exe
Process Hacker: process -> Modules. Static imports identify direct declared dependencies; the runtime list also includes transitive and dynamically loaded modules.
Why these steps matter:
- The Import Directory establishes direct declared dependencies.
- Executing the file allows loader behavior and dynamic imports to occur.
- The Modules tab captures the resulting runtime set.
Expected proof: Runtime modules should include direct imports plus additional transitive or dynamically loaded libraries.
Conclusion: Absence from the static import table does not prove a DLL or API will be absent at runtime.
15. Exports and Dependencies
Objective: Distinguish functions a DLL provides from functions a PE consumes, and trace dependency chains.
CFF Explorer:
Open Sample-4-2.dll -> Export Directory
Open C:\Windows\System32\msvcrt.dll -> Import/Export Directory
Open Sample-4-1.exe -> Tools/Dependency Walker
Optional Visual Studio tool:
dumpbin /exports C:\Temp\Sample-4-2.dll
dumpbin /imports C:\Temp\Sample-4-1.exe
Why these steps matter:
- The Export Directory identifies callable functions offered by
Sample-4-2.dll.
- Inspecting
msvcrt.dlldemonstrates that a dependency can itself import
other modules.
- Dependency Walker visualizes direct and indirect relationships.
dumpbin, when available, provides text output suitable for evidence.
Expected proof: Export names/ordinals/RVAs appear for the DLL, while the EXE dependency tree contains more modules than its direct imports alone.
Conclusion: Imports are consumed functionality; exports are provided functionality; dependency chaining explains additional runtime modules.
Exercises 16-21: Static Analysis
16. Lab01-01 Full Triage
Objective: Build a defensible static profile by combining identity, structure, packing indicators, strings, and imported capabilities.
Get-FileHash C:\Temp\Lab01-01.exe -Algorithm SHA256
Get-FileHash C:\Temp\Lab01-01.dll -Algorithm SHA256
If Sysinternals Strings is installed:
strings64.exe -n 4 -accepteula C:\Temp\Lab01-01.exe > C:\Temp\Results\Lab01-01-exe-strings.txt
strings64.exe -n 4 -accepteula C:\Temp\Lab01-01.dll > C:\Temp\Results\Lab01-01-dll-strings.txt
findstr /i /r "http ftp \.com \.net [0-9][0-9]*\.[0-9]" C:\Temp\Results\Lab01-01-*-strings.txt
GUI sequence:
PEview -> IMAGE_NT_HEADERS -> IMAGE_FILE_HEADER -> Time Date Stamp
PEiD/DiE -> detection/signature and entropy
CFF Explorer -> Section Headers, Import Directory
BinText -> File -> Open -> Go
Why these steps matter:
- SHA-256 uniquely identifies the exact EXE and DLL being analyzed.
- The compile timestamp is recorded as metadata but treated cautiously because
it can be forged.
- PEiD/DiE signatures, entropy, section names, and raw/virtual sizes provide
independent packing indicators.
- Strings reveal host and network indicators that may not be obvious in the
imports.
- Imports explain possible capabilities such as process creation, sleeping,
or Winsock networking.
Expected proof: Produce one evidence table per file containing hash, timestamp, packing evidence, important strings, and important imports. The lecture points to a suspicious system-DLL-style string in the EXE and an IP address in the DLL; verify the exact values yourself.
Conclusion: State what the static evidence supports, then list hypotheses to test dynamically. Imports show capability, not confirmed execution.
17. UPX Packing
Objective: Create a controlled packed version so you can observe exactly which PE characteristics packing changes.
Check and copy:
upx -V
copy C:\Temp\Sample-7-1.exe C:\Temp\Sample-7-1-working.exe
upx -t C:\Temp\Sample-7-1-working.exe
upx -o C:\Temp\Sample-7-1-packed.exe C:\Temp\Sample-7-1-working.exe
dir C:\Temp\Sample-7-1*.exe
The source slide uses a typographic dash and omits extensions. Use ASCII -o and the real filename. Compare both files in CFF Explorer, DiE, PEiD, and a hex editor.
Why these steps matter:
upx -Vdocuments the tool version.- Copying first preserves the original sample.
upx -tchecks whether the working file is already a valid UPX image.-ocreates a separate packed file for side-by-side comparison.- File size, sections, entropy, imports, and raw bytes measure different
consequences of the same transformation.
Expected proof: The packed file is normally smaller, has UPX sections such as UPX0/UPX1, higher entropy, fewer useful imports/strings, and visibly different bytes.
Conclusion: Packing changes representation and static visibility, not necessarily program purpose. Use several indicators rather than entropy alone.
18. Strings Before and After Packing
Objective: Prove that packing can hide readable content from simple static string extraction.
strings64.exe -n 4 C:\Temp\Sample-7-1-working.exe > C:\Temp\Results\original-strings.txt
strings64.exe -n 4 C:\Temp\Sample-7-1-packed.exe > C:\Temp\Results\packed-strings.txt
findstr /i /c:"Hi rednet on the heap" C:\Temp\Results\original-strings.txt C:\Temp\Results\packed-strings.txt
If only BinText is available, open each file separately and save/export both results.
Why these steps matter:
- Identical minimum string lengths make the two outputs comparable.
- Separate output files preserve the original results for counting and
searching.
- Searching for the lecture marker tests one known string instead of relying
only on subjective inspection.
Expected proof: The unpacked/original file should expose more meaningful strings and is the likely place to find the marker. The packed file should contain fewer useful strings.
Conclusion: Failure to find a string on disk does not prove the program never uses it; packed content may appear only after runtime unpacking.
19. Lab01-03 and Lab01-04
Objective: Practice reaching a packing and capability assessment on unknown samples without relying on one detector.
Get-FileHash C:\Temp\Lab01-03.exe -Algorithm SHA256
Get-FileHash C:\Temp\Lab01-04.exe -Algorithm SHA256
strings64.exe -n 4 C:\Temp\Lab01-03.exe > C:\Temp\Results\Lab01-03-strings.txt
strings64.exe -n 4 C:\Temp\Lab01-04.exe > C:\Temp\Results\Lab01-04-strings.txt
For each: DiE entropy/detection -> CFF sections/imports/resources -> strings. Use at least two independent packing indicators.
Why these steps matter:
- Hashes ensure findings remain tied to the exact samples.
- DiE gives an initial type/signature/entropy lead.
- Section layout tests whether compression or runtime expansion is plausible.
- Imports and strings translate the binary into behavior hypotheses.
- Resource review checks whether a payload or configuration is embedded.
Expected proof: For each file, record at least two consistent packing indicators or explain why packing is not supported. Categorize important imports by filesystem, process, persistence, or network behavior.
Conclusion: Write a separate evidence-based decision for each sample; do not assume both use the same protection.
20. Dependency Profiling
Objective: Compare declared DLL dependencies with modules actually loaded during execution.
depends.exe C:\Temp\Lab12-01.exe
depends.exe C:\Temp\Lab01-01.exe
In Dependency Walker: Profile -> Start Profiling; clear automatic child process opening if the lecture requires it. Save the .dwi session.
Why these steps matter:
- Opening the file statically establishes direct dependencies.
- Profiling records load order and runtime dynamic loading.
- Disabling automatic child-process opening prevents unrelated child activity
from confusing the target profile.
- Saving
.dwipreserves the dependency evidence.
Expected proof: The profiled module set may be larger than the static list. Relevant Winsock libraries/functions support possible networking capability.
Conclusion: Static dependency means the program declares a need; runtime profiling shows what loaded during this execution.
21. Embedded Resources
Objective: Determine whether a PE carries additional data or a payload inside its resource section.
Resource Hacker:
File -> Open -> select sample
Expand resource tree
Right-click resource -> Save [resource] to a binary file
Then:
Get-FileHash C:\Temp\Results\resource.bin -Algorithm SHA256
Format-Hex C:\Temp\Results\resource.bin | Select-Object -First 4
4D 5A indicates a possible embedded PE, but confirm it with CFF Explorer or TrID.
Why these steps matter:
- Resource type/name/language/size documents where the object was stored.
- Exporting allows analysis without executing the parent sample.
- SHA-256 gives the extracted object its own evidence identity.
- Magic-byte inspection tests whether the resource is another PE, script,
image, or configuration blob.
Expected proof: Identify the exported object's type. If it begins with MZ, confirm its PE structure independently.
Conclusion: An embedded executable supports possible dropper behavior, but dynamic evidence is still needed to prove it was written or executed.
Exercises 22-30: Dynamic Analysis
22. ProcMon Filtering
Objective: Capture complete runtime activity, then reduce noise to answer a specific filesystem/registry/process question.
Ctrl+E -> stop
Ctrl+X -> clear
Ctrl+L -> Filter
Path begins with HKCU\Software\Classes -> Exclude
Result contains ACCESS DENIED -> Include
Process Name is Sample-10-1.exe -> Include
Ctrl+E -> start
Run:
C:\Temp\Sample-10-1.exe
Stop with Ctrl+E, save complete trace as PML, then export a filtered CSV.
Why these steps matter:
- Stopping and clearing removes unrelated pre-execution events.
- The process-name include ties events to the sample.
- Excluding a noisy registry path makes review manageable.
ACCESS DENIEDisolates failed operations that may explain behavior.- Saving PML before further filtering preserves evidence that a later filter
could hide.
Expected proof: Every reported row should show process, PID/TID, operation, path, result, and detail. KernelBase-related activity may appear if the sample produces it.
Conclusion: ProcMon proves observable Windows operations, not necessarily the exact high-level API responsible.
23. APIMiner
Objective: Verify runtime API calls and parameters that ProcMon cannot show directly.
Use the VM-provided shortcut command:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Sample-10-1.exe
Find generated traces:
Get-ChildItem C:\Temp -File |
Sort-Object LastWriteTime -Descending |
Select-Object -First 10 Name,Length,LastWriteTime
Select-String -Path C:\Temp\*.txt -Pattern 'CreateToolhelp32Snapshot' -Context 3,8
If APIMiner creates files elsewhere, use that actual output path.
Why these steps matter:
- The APIMiner command launches the sample under API tracing.
- Listing files by modification time locates the new trace without assuming a
filename.
Select-String -Contextpreserves neighboring calls and arguments, which
are necessary to interpret CreateToolhelp32Snapshot.
Expected proof: Find process-enumeration calls and inspect their parameters and return values. Compare them with Process Hacker/ProcMon observations.
Conclusion: A single API name is only a clue. The sequence and shared handles/arguments explain the behavior.
24. Lab01-02 Unpacking
Objective: Confirm UPX packing, produce a controlled unpacked copy, and measure what static evidence becomes visible.
upx -t C:\Temp\Lab01-02.exe
upx -d C:\Temp\Lab01-02.exe -o C:\Temp\Lab01-02-Unpacked.exe
Get-FileHash C:\Temp\Lab01-02.exe -Algorithm SHA256
Get-FileHash C:\Temp\Lab01-02-Unpacked.exe -Algorithm SHA256
Compare both in CFF Explorer, Dependency Walker, and Strings.
Why these steps matter:
upx -tverifies that UPX understands the source before modification.upx -d ... -oprotects the packed original and creates a separate output.- Hashing both proves they are distinct evidence objects.
- Comparing imports and strings shows the analytical value of unpacking.
Expected proof: The unpacked copy should expose more imports and strings. The lecture highlights WinINet and service-related imports; verify their exact names in your output.
Conclusion: Unpacking reveals capabilities hidden by compression but does not prove those capabilities executed.
25. Lab01-03 and Lab01-04 Practice
Objective: Produce complete, repeatable static-analysis answers using the same workflow on two samples.
Use the Exercise 19 commands. For Lab01-04, export the resource using Exercise 21 and hash it separately.
Why these steps matter: Reusing one ordered workflow prevents missing a required category: identity, type, packing, timestamp, imports, strings, indicators, and resources. Hashing the Lab01-04 resource treats it as separate evidence.
Expected proof: A completed findings table for each sample plus a separate classification and hash for the Lab01-04 resource.
Conclusion: Consistent methodology makes results comparable and easier to defend in an exam answer.
26. Registry Change Analysis
Objective: Attribute registry changes made by an exported DLL function to the process that performed them.
Regshot:
1st shot -> Shot
Run the command below
2nd shot -> Shot
Compare
Execution:
cd /d C:\Temp
rundll32.exe C:\Temp\Lab03-02.dll,install
ProcMon filters:
Process Name is rundll32.exe -> Include
Category is Registry -> Include
Save PML, CSV, and the Regshot comparison text.
Why these steps matter:
- Regshot shot 1 establishes the baseline.
rundll32invokes the DLL'sinstallexport because a DLL cannot normally
be executed like an EXE.
- Regshot shot 2 identifies broad system differences.
- ProcMon's process and Registry filters add timing, operation, result, and
process attribution.
Expected proof: The Regshot difference and ProcMon events should agree on the changed keys/values. Record full path, value name, type, and data.
Conclusion: Regshot proves before/after difference; ProcMon proves which process performed the observed operation.
27. Sample-13-1
Objective: Reconstruct process/thread manipulation by correlating API calls that operate on the same targets.
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Sample-13-1.exe
Select-String -Path C:\Temp\*.txt -Pattern 'SuspendThread|ResumeThread|NtMapViewOfSection' -Context 4,10
Run separately under Process Hacker if APIMiner launches and exits too fast:
C:\Temp\Sample-13-1.exe
Why these steps matter:
- APIMiner captures calls that may execute too quickly for visual inspection.
- Searching for suspend, resume, and section-mapping APIs focuses on the
lecture's expected behavior.
- Context lines reveal handles, IDs, and call order.
- A normal run under Process Hacker supplies the process-tree evidence.
Expected proof: The trace should show the expected APIs when that behavior executes, with common target handles or identifiers connecting them.
Conclusion: Explain the ordered sequence and target. An unconnected list of API names is not sufficient proof.
28. Sample-13-2
Objective: Combine static, process, registry, API, and simulated network evidence to classify a sample.
Start Regshot shot 1, FakeNet, ApateDNS, ProcMon, and Process Hacker. APIMiner:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Sample-13-2.exe
Run as administrator only for the required pass:
Start-Process C:\Temp\Sample-13-2.exe -Verb RunAs
Search:
Select-String -Path C:\Temp\*.txt -Pattern 'NtCreateMutant|2GVWNQJz1' -Context 3,8
Then take Regshot shot 2, stop ProcMon, and save all traces.
Why these steps matter:
- Regshot brackets persistent system changes.
- FakeNet/ApateDNS safely expose network intent without real Internet access.
- ProcMon records system operations, while Process Hacker shows live process
relationships.
- APIMiner reveals APIs and arguments, including mutex creation.
- The administrator run tests behavior that may require elevation; it must be
distinguished from the non-elevated run.
Expected proof: Correlate created files, registry values, processes, simulated network requests, and the NtCreateMutant mutex lead 2GVWNQJz1 if actually observed.
Conclusion: Classify from the combined behavior and explicitly identify which evidence came from each tool.
29. Sample-13-3
Objective: Prove whether the sample modifies targeted document files using a controlled before/after experiment.
Create harmless targets:
'Disposable PDF test file' | Set-Content C:\Temp\dummy.pdf
'Disposable spreadsheet test file' | Set-Content C:\Temp\dummy.xlsx
Get-FileHash C:\Temp\dummy.pdf,C:\Temp\dummy.xlsx -Algorithm SHA256 |
Export-Csv C:\Temp\Results\before-hashes.csv -NoTypeInformation
After the isolated run:
Get-ChildItem C:\Temp\dummy.* | Select-Object Name,Length,LastWriteTime
Get-FileHash C:\Temp\dummy.pdf,C:\Temp\dummy.xlsx -Algorithm SHA256 |
Export-Csv C:\Temp\Results\after-hashes.csv -NoTypeInformation
APIMiner:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Sample-13-3.exe
Why these steps matter:
- Disposable targets prevent damage to real documents.
- Before hashes establish exact original content.
- Post-run name, size, timestamp, and hash measurements reveal modification,
rename, deletion, or replacement.
- APIMiner/ProcMon identify the APIs and operations responsible.
Expected proof: Any affected file should have measurable before/after differences supported by runtime write, rename, or delete evidence.
Conclusion: Do not call the behavior encryption based only on an extension change; prove content modification and identify the responsible operations.
30. Sample-13-4 Memory Strings
Objective: Determine whether useful configuration appears only after the sample unpacks or decrypts itself in memory.
On-disk strings:
strings64.exe -n 4 C:\Temp\Sample-13-4.exe > C:\Temp\Results\Sample-13-4-disk-strings.txt
findstr /i "YUIPWDFILE0 YUIPKDFILE0 YUICRYPTED0" C:\Temp\Results\Sample-13-4-disk-strings.txt
Run as required:
Start-Process C:\Temp\Sample-13-4.exe -Verb RunAs
Process Hacker: process -> Memory -> select committed region -> Strings. APIMiner:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Sample-13-4.exe
Why these steps matter:
- Disk strings establish what is visible before execution.
- The elevated run reproduces the lecture-required behavior.
- Process Hacker's memory strings reveal decoded/unpacked runtime content.
- APIMiner correlates those strings with behavior.
Expected proof: Memory may contain more meaningful strings than the file, including the lecture marker beginning YUIPWDFILE0 if the expected behavior occurs.
Conclusion: A string present only in memory supports runtime unpacking or decryption; it does not by itself explain how the value is used.
Exercises 31-35: Persistence
31. Startup Folder
Objective: Create and verify a simple logon persistence artifact using the all-users Startup folder.
Open:
explorer.exe "shell:common startup"
Copy:
copy C:\Temp\Sample-4-1.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\Sample-4-1.exe"
dir "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
Query configured paths:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "Common Startup"
reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v Startup
ProcMon: include Path contains \Start Menu\Programs\Startup. Verify in Autoruns -> Logon.
Why these steps matter:
shell:common startupresolves the real folder instead of relying on a
memorized path.
- Copying the sample creates the persistence artifact.
dirproves the file exists at the destination.- Registry queries verify the paths Windows currently uses.
- ProcMon attributes the copy operation, while Autoruns shows that Windows
recognizes the entry as autostart.
Expected proof: The file appears in the Startup folder and Autoruns. After logon/restart it should launch, subject to VM policy.
Conclusion: Prove both persistence configuration and execution. File presence alone does not prove the logon trigger ran successfully.
32. Run Key
Objective: Create a registry-based logon persistence value and verify its scope, data, and creation process.
Create the lecture's disposable entry:
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v Sample-8-1 /t REG_SZ /d "C:\Temp\Sample-8-1.exe" /f
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v Sample-8-1
All loaded users:
Get-ItemProperty 'Registry::HKEY_USERS\*\Software\Microsoft\Windows\CurrentVersion\Run' -ErrorAction SilentlyContinue
Get-ItemProperty 'Registry::HKEY_USERS\*\Software\Microsoft\Windows\CurrentVersion\RunOnce' -ErrorAction SilentlyContinue
ProcMon filters:
Operation is RegSetValue -> Include
Path contains \CurrentVersion\Run -> Include
Cleanup:
reg delete "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v Sample-8-1 /f
Why these steps matter:
reg addcreates a known Run value for a controlled experiment.reg queryverifies exact name, type, and executable data.- HKEY_USERS queries show how per-user Run keys appear when another user's
hive is loaded.
- ProcMon proves the
RegSetValueoperation and the process responsible. - Cleanup prevents the training artifact from persisting outside the exercise.
Expected proof: The selected Run path contains Sample-8-1 pointing to C:\Temp\Sample-8-1.exe, and ProcMon captures its creation.
Conclusion: Report hive, complete path, value name, type, data, affected users, and logon trigger. HKLM and HKCU/HKU do not have the same scope.
33. Service
Objective: Demonstrate service-based persistence and distinguish service registration from successful service execution.
Elevated Command Prompt:
sc.exe create BookService start= auto binPath= "C:\Temp\Sample-5-1.exe"
sc.exe start BookService
sc.exe query BookService
sc.exe qc BookService
reg query "HKLM\SYSTEM\CurrentControlSet\Services\BookService"
Spaces after start= and binPath= are required by sc.exe.
Event log:
Get-WinEvent -FilterHashtable @{LogName='System';Id=7045} |
Select-Object -First 10 TimeCreated,Id,Message | Format-List
Cleanup:
sc.exe stop BookService
sc.exe delete BookService
Why these steps matter:
sc createwrites the Service Control Manager configuration.start= autorequests boot-time persistence.sc starttests whether the binary behaves as a valid service.sc query,sc qc, and the registry provide three views of state and
configuration.
- Event ID 7045 can independently document service installation.
- Cleanup removes the persistent test artifact.
Expected proof: BookService should exist with the configured ImagePath and automatic start type. Start may fail if the sample is not a valid service; that does not erase proof that registration occurred.
Conclusion: State separately whether the service was created, configured for persistence, started successfully, and observed running.
34. Scheduled Task
Objective: Create and verify time-triggered persistence through Task Scheduler.
Create the lecture task:
schtasks /create /sc minute /tn "test" /tr "C:\Windows\System32\calc.exe" /st 19:00 /f
schtasks /query /tn "test" /fo list /v
The lecture wording says every minute after 19:00. /SC MINUTE defaults to a one-minute interval. The task starts when the scheduled start time is reached.
Inspect task files:
Get-ChildItem C:\Windows\System32\Tasks -Recurse -File |
ForEach-Object {
Select-String -Path $_.FullName -Pattern '<Command>' -SimpleMatch -ErrorAction SilentlyContinue
}
Cleanup:
schtasks /delete /tn "test" /f
Why these steps matter:
/createdefines the trigger, task name, action, and start time./query /vconfirms the effective configuration in text form.- Inspecting
C:\Windows\System32\Tasksshows the underlying task artifact and
action command.
- Task Scheduler/Autoruns supply independent GUI confirmation.
- Deletion prevents the exercise task from continuing to run.
Expected proof: Task test should show a minute schedule, configured start time, and Calculator action. Observe Calculator only after the trigger conditions are satisfied.
Conclusion: Report task name, trigger, action, execution account, and observed run status. Configuration does not by itself prove execution.
35. AppInit and DLL Export
Objective: Examine a DLL-loading persistence configuration and invoke a specific DLL export for behavioral analysis.
Read AppInit configuration:
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" /v AppInit_DLLs
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" /v LoadAppInit_DLLs
Inspect Lab11-02.dll -> Export Directory in CFF Explorer, then:
cd /d C:\Temp
rundll32.exe C:\Temp\Lab11-02.dll,installer
ProcMon: include Process Name is rundll32.exe.
Why these steps matter:
- The registry queries establish whether AppInit loading is enabled and which
DLLs are configured.
- CFF Explorer verifies that
installeris a real exported function. rundll32invokes that export in the intended Windows-supported way.- ProcMon attributes resulting filesystem/registry/process operations to the
host process.
Expected proof: Record AppInit values, the exported function, and the operations produced by invoking it. Modern Windows security settings may keep AppInit inactive.
Conclusion: Separate configured capability from observed execution. Registry presence alone does not prove the mechanism loaded the DLL.
Exercises 36-40: Network Analysis
36. DGA Output
Objective: Identify algorithmically generated domain output without allowing the VM to contact public infrastructure.
Run in the isolated VM:
cd /d C:\Temp
Sample-9-1.exe > C:\Temp\Results\Sample-9-1-domains.txt 2>&1
type C:\Temp\Results\Sample-9-1-domains.txt
Do not resolve generated domains on unrestricted Internet.
Why these steps matter:
- Command-line redirection preserves every generated domain and error message.
- Reviewing the saved sequence reveals length, alphabet, repetition, and
time/seed patterns.
- Isolation prevents accidental contact with a domain that may currently be
registered.
Expected proof: The output should contain multiple domains with a repeatable machine-generated structure.
Conclusion: Describe the observed generation pattern. Unusual appearance alone is weaker evidence than repeated algorithmic structure.
37. FakeNet and Wireshark
Objective: Observe DNS and application traffic safely while providing the sample with simulated network responses.
Start FakeNet from its VM location, commonly:
fakenet.exe
Wireshark capture filter should normally remain empty; use display filters:
dns
dns.flags.rcode == 3
http
ip.addr == <FAKENET_IP>
Run:
C:\Temp\Sample-9-2.exe
Save the PCAPNG and FakeNet log.
Why these steps matter:
- FakeNet intercepts requests and emulates services, keeping analysis isolated.
- An empty capture filter preserves all packets; display filters can be changed
later without losing evidence.
- DNS/NXDOMAIN/HTTP filters answer different questions about resolution and
application behavior.
- Saving both PCAPNG and FakeNet logs provides packet-level and service-level
evidence.
Expected proof: Correlated DNS requests and possible HTTP connections should appear after execution, with timing consistent with the sample run.
Conclusion: Report network intent and simulated responses accurately. Do not claim the real public server was contacted.
38. HTTP C2 Strings
Objective: Connect static HTTP-related strings to requests generated at runtime.
strings64.exe -n 4 C:\Temp\Sample-9-3.exe > C:\Temp\Results\Sample-9-3-strings.txt
findstr /i "http % GET POST User-Agent" C:\Temp\Results\Sample-9-3-strings.txt
Run only in the Windows XP VM specified by the lecture, with FakeNet active. Filter Wireshark with http.request.
Why these steps matter:
- Static extraction finds format strings, methods, paths, parameters, and
user-agent clues without execution.
findstrnarrows a large string set to likely HTTP indicators.- The required XP VM reproduces compatibility expected by the sample.
- FakeNet and Wireshark prove whether those templates become actual requests.
Expected proof: Runtime paths/parameters should correspond to all or part of the static format strings.
Conclusion: Strings suggest a request template; packet capture proves runtime use and shows the final values.
39. TLS Decryption
Objective: Demonstrate what TLS hides and how matching session secrets allow Wireshark to decode application data.
Wireshark:
Edit -> Preferences -> Protocols -> TLS
(Pre)-Master-Secret log filename -> select supplied key-log file
Filters:
tls
http
tcp.stream eq <STREAM_NUMBER>
Proof: same stream before and after loading the key log, with application data visible only after successful decryption.
Why these steps matter:
- Opening the capture without keys establishes the encrypted baseline.
- Loading the supplied key-log file gives Wireshark the session secrets.
- Reviewing the same stream controls all variables except key availability.
- TLS and HTTP filters distinguish encrypted records from decoded application
traffic.
Expected proof: Connection metadata remains visible in both cases, while application content appears only when the key log matches the session.
Conclusion: A key log cannot decrypt unrelated sessions. TLS protects content but not all metadata such as endpoints, ports, timing, and volume.
40. CreateFileA Documentation
Objective: Prove that API behavior must be interpreted from parameters and return values, not from the function name alone.
Use the official declaration to map:
lpFileName
dwDesiredAccess
dwShareMode
lpSecurityAttributes
dwCreationDisposition
dwFlagsAndAttributes
hTemplateFile
In an APIMiner/API Monitor trace, record actual argument values. For dwCreationDisposition, compare:
CREATE_ALWAYS = 2
OPEN_EXISTING = 3
The API name alone does not prove whether a file was created or merely opened.
Why these steps matter:
- Official documentation defines the meaning and valid values of each
parameter.
lpFileNameidentifies the target.dwDesiredAccessshows requested read/write rights.dwCreationDispositiondistinguishes create/overwrite from open-existing.- Return value and last error show whether the operation succeeded.
Expected proof: A trace using CREATE_ALWAYS supports create/overwrite intent; OPEN_EXISTING supports opening an existing target. Confirm the result and subsequent writes.
Conclusion: Report API, arguments, return result, and related operations. CreateFileA by itself does not prove a new file was created.
Exercises 41-47: Process Injection
41. Classic DLL Injection
Objective: Prove all stages of classic remote-thread DLL injection into Notepad.
Copy and start target:
copy C:\Path\To\Samples\Sample-10-5.exe C:\Temp\
copy C:\Path\To\Samples\Sample-10-5b.dll C:\Temp\
start notepad.exe
tasklist /fi "imagename eq notepad.exe"
The lecture sample prompts interactively. Run:
cd /d C:\Temp
Sample-10-5.exe
Enter the Notepad PID, then:
C:\Temp\Sample-10-5b.dll
Process Hacker: Notepad -> Modules -> verify Sample-10-5b.dll. APIMiner:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Sample-10-5.exe
Because APIMiner may not supply interactive stdin correctly, the direct run is the behavior proof and the APIMiner run is the API trace attempt.
Why these steps matter:
- Starting a known target and recording its PID defines the destination.
- Supplying a full DLL path defines the payload.
- The Modules tab proves the DLL became loaded in the target.
- APIMiner should show target opening, remote allocation, DLL-path writing,
LoadLibrary resolution, and remote thread creation.
- The direct and traced runs are separated because interactive input may not
pass through APIMiner.
Expected proof: Sample-10-5b.dll appears in Notepad and the trace links the same target through the injection stages.
Conclusion: The unexpected loaded DLL plus the ordered cross-process API sequence supports classic DLL injection.
42. Lab12-01
Objective: Explain the sample's visible behavior by identifying its target, injected DLL, stop condition, and API sequence.
Static:
strings64.exe -n 4 C:\Temp\Lab12-01.exe > C:\Temp\Results\Lab12-01-exe-strings.txt
strings64.exe -n 4 C:\Temp\Lab12-01.dll > C:\Temp\Results\Lab12-01-dll-strings.txt
Dynamic:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Lab12-01.exe
Also run normally with Process Hacker visible:
C:\Temp\Lab12-01.exe
Record the injected process, loaded DLL, popup behavior, stop condition, and API sequence.
Why these steps matter:
- EXE and DLL strings/imports establish static hypotheses about targets and
behavior.
- Process Hacker reveals the process receiving the module and the visible
process effects.
- APIMiner verifies how the injection was implemented.
- Testing the lecture's stop condition connects program logic with the
observed repeated popups.
Expected proof: Identify the target process, loaded DLL, popup behavior, condition that stops it, and APIs that connect those facts.
Conclusion: Describe the behavior as a causal sequence rather than a list of strings or APIs.
43. Lab19-02
Objective: Identify shellcode-style injection and distinguish it from DLL path injection.
First pass:
C:\Temp\Lab19-02.exe
eventvwr.msc
Restore snapshot. Instrumented pass:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Lab19-02.exe
ProcMon: include Process Name is Lab19-02.exe; preserve PML before filtering.
Why these steps matter:
- The first run establishes visible effects and event-log artifacts.
- Restoring the snapshot prevents the first execution from contaminating the
instrumented baseline.
- APIMiner/API Monitor reveal allocation, writing, protection, and execution
calls.
- ProcMon supplies process and system-operation context.
Expected proof: Find cross-process allocation/write/execution evidence without relying on a DLL path plus LoadLibrary.
Conclusion: Raw payload bytes, executable private memory, and a thread starting there support shellcode injection.
44. Sample-10-1 Process Enumeration
Objective: Prove how the sample obtains a live process list and validate its output against independent system views.
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Sample-10-1.exe
C:\Temp\Sample-10-1.exe > C:\Temp\Results\Sample-10-1-processes.txt
tasklist > C:\Temp\Results\tasklist.txt
Compare names and PIDs with Process Hacker. Search APIMiner for:
Select-String -Path C:\Temp\*.txt -Pattern 'CreateToolhelp32Snapshot|Process32First|Process32Next|OpenProcess' -Context 3,8
Why these steps matter:
- APIMiner reveals the enumeration mechanism.
- Redirecting sample and
tasklistoutputs preserves comparable snapshots. - Process Hacker provides a third visual source.
- Context around the APIs reveals iteration and process identifiers.
Expected proof: Most names/PIDs should correspond at the observation time. Short-lived processes may create small differences.
Conclusion: Snapshot/iteration APIs explain how the output was generated; PID values must come from your own run.
45. Lab12-02 Suspended Process
Objective: Determine whether the sample creates a process suspended and then manipulates it before resuming execution.
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Lab12-02.exe
Search:
Select-String -Path C:\Temp\*.txt -Pattern 'CreateProcess|CREATE_SUSPENDED|GetThreadContext|SetThreadContext|ResumeThread' -Context 4,10
Process Hacker: inspect the child process and Threads tab while the sample runs.
Why these steps matter:
CreateProcessarguments establish whetherCREATE_SUSPENDEDwas used.- Context/memory APIs reveal what happened before execution resumed.
ResumeThreadmarks the transition from preparation to execution.- Process Hacker can corroborate child and thread state if timing permits.
Expected proof: An ordered sequence should show suspended creation followed by manipulation and resume.
Conclusion: CREATE_SUSPENDED alone is not proof of process hollowing; memory unmapping/writing or thread-context evidence is also required.
46. Sample-10-2 Remote Allocation
Objective: Isolate and prove the remote-memory-allocation stage of process injection.
Start Notepad and get PID:
start notepad.exe
tasklist /fi "imagename eq notepad.exe"
Run interactively:
C:\Temp\Sample-10-2.exe
Enter the PID, requested size, and memory protection when prompted. The source deck does not document fixed argument syntax, so do not invent command-line switches. Use the lecture's requested protection; record the entered values.
Process Hacker: Notepad -> Memory -> locate the new private allocation by base address/size/protection. Repeat with Calculator.
Why these steps matter:
- Recording the PID identifies the exact target.
- Entered size/protection values define the expected allocation.
- The address returned by the sample locates the region in Process Hacker.
- Repeating with Calculator proves the technique is not specific to Notepad.
Expected proof: A new private region appears in the target with matching size and protection. Its base address will vary.
Conclusion: VirtualAllocEx proves remote allocation, one injection stage. It does not prove bytes were written or executed.
47. Sample-10-3 Remote Write
Objective: Prove that the sample writes controlled data into another process's memory.
start notepad.exe
tasklist /fi "imagename eq notepad.exe"
C:\Temp\Sample-10-3.exe
Enter the Notepad PID and RWX protection when the program prompts. Record the address printed by the sample.
Process Hacker: Notepad -> Memory -> locate address -> inspect strings -> verify MALWARE ANALYSIS.
APIMiner:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\Sample-10-3.exe
Search:
Select-String -Path C:\Temp\*.txt -Pattern 'VirtualAllocEx|WriteProcessMemory' -Context 4,10
Why these steps matter:
- The target PID ties the operation to a specific Notepad instance.
- The printed address tells you exactly where to inspect.
- Finding
MALWARE ANALYSISin target memory proves the data crossed the
process boundary.
- APIMiner verifies
WriteProcessMemory, destination address, and byte count.
Expected proof: The target memory contains MALWARE ANALYSIS at the reported address, and the API trace references the same target/address.
Conclusion: This proves remote writing. A separate execution-stage API or thread start is still required to prove the written content executed.
Condensed Revision Answers
Use this section after completing an exercise. It describes the result pattern you should obtain, not values to copy without verification.
The following values must always come from your own run:
- cryptographic and fuzzy hashes
- PID, parent PID, and TID values
- memory addresses and allocation sizes
- timestamps and file sizes
- filenames, paths, registry data, domains, and network destinations created
by a sample
Expected Solutions 1-5: Extensions and Hashes
1. Misleading Extension
Expected result: With known extensions hidden, Sample-3-1.pdf.exe can appear to be a PDF-like file even though its final extension is .exe. After enabling extensions, dir and Properties reveal the executable filename.
Conclusion to write: The icon and visible filename are presentation metadata. They do not prove file type. Confirm type using the complete filename, magic bytes, and PE structure.
What this teaches: Attackers use double extensions and misleading icons for social engineering.
2. Cryptographic Hashes
Expected result: Renaming hash.txt does not change MD5, SHA-1, or SHA-256 because its bytes did not change. A one-byte content change produces different cryptographic hashes. The supplied collision pair may share an MD5 while remaining different files; record what your files actually show.
Conclusion to write: Cryptographic hashes identify content, not filenames. MD5 and SHA-1 are unsuitable for collision-resistant security decisions; SHA-256 is the preferred evidence fingerprint.
What this teaches: Hash evidence must include the algorithm, and a malware hash search should normally use SHA-256.
3. Fuzzy Hashes Across Formats
Expected result: The TXT pair should normally produce a clearer or higher similarity score than the DOCX pair when both contain comparable visible changes. DOCX files are ZIP containers whose internal XML, metadata, and compression can change at the binary level.
Conclusion to write: ssdeep compares binary similarity, not visual or semantic similarity. A low DOCX score does not mean the documents have unrelated text.
What this teaches: File format strongly affects fuzzy-hash usefulness.
4. DOC Versus DOCX
Expected result: An original and lightly modified file in the same format should generally be more similar than a .doc compared with a .docx. Cross-format scores may be low or absent even when visible content is the same.
Conclusion to write: Compare like with like. Legacy DOC and ZIP/XML DOCX have different binary structures.
What this teaches: Fuzzy hashes are evidence leads, not universal document similarity measurements.
5. Repeated Changes
Expected result: Each GUID changes the cryptographic hash completely, while ssdeep may still report similarity because most script content remains unchanged. Very small files may produce weak or no fuzzy matches.
Conclusion to write: Fuzzy hashing can group related variants, but its effectiveness depends on file size, structure, and how much content changed.
What this teaches: Use SHA-256 for exact identity and ssdeep for possible family or variant relationships.
Expected Solutions 6-15: PE Structure and Memory
6. Process Creation and Parentage
Expected result: The Explorer-launched process normally has explorer.exe as its parent. The command-prompt-launched process normally has cmd.exe as its parent. The elevated instance should show a higher integrity level.
Conclusion to write: Parentage and integrity reflect the execution method. They are useful context but do not independently prove maliciousness.
What this teaches: Process trees help reconstruct how execution began.
7. VMMap
Expected result: The process address space contains image, heap, stack, private-data, mapped-file, and free/reserved regions. Committed memory consumes backing resources; reserved memory only protects an address range for possible future commitment.
Conclusion to write: A process is not one continuous executable image. Its virtual address space combines multiple memory types with different purposes and protections.
What this teaches: Memory type, state, and protection are essential when investigating unpacking or injection.
8. DOS Header and e_lfanew
Expected result: The file begins with bytes 4D 5A (MZ). e_lfanew is a four-byte little-endian value at offset 0x3C. Jumping to the calculated file offset should reveal 50 45 00 00.
Conclusion to write: e_lfanew points from the DOS header to the PE signature. CFF Explorer may display a multi-byte value in numeric order while the hex editor shows its little-endian byte order.
What this teaches: Correct offset and endianness interpretation prevents PE-header mistakes.
9. Machine Type
Expected result: Changing the Machine value to an incompatible architecture should cause Windows to reject or fail to load the modified copy.
Conclusion to write: The PE File Header tells the loader which architecture the image targets. Renaming a file cannot change its architecture.
What this teaches: Header fields directly influence Windows loader behavior.
10. ImageBase
Expected result: Process Hacker should show the main image at its preferred ImageBase when that address is available. If it differs, Windows relocated the image, commonly because of ASLR or an address conflict.
Conclusion to write: The on-disk ImageBase is preferred, while the runtime module base is the actual address used for VA calculations.
What this teaches: Always use the actual runtime base when correlating RVAs with live memory.
11. Entry Point
Expected result: AddressOfEntryPoint is an RVA, not a complete virtual address. actual ImageBase + entry-point RVA should match the debugger's entry address, subject to debugger startup behavior.
Conclusion to write: PE directory and header addresses are often relative to the loaded image.
What this teaches: Distinguish file offsets, RVAs, and virtual addresses.
12. Section Mapping
Expected result: The .text section should appear in memory at actual ImageBase + .text RVA. Its initial mapped bytes should correspond to the on-disk section, while alignment and zero-filled virtual space may make memory size differ from raw size.
Conclusion to write: PointerToRawData locates bytes in the file; RVA locates the section relative to the loaded image.
What this teaches: Correct disk-to-memory mapping is required for manual PE analysis.
13. Identify a DLL
Expected result: The file remains a PE regardless of its extension. CFF Explorer should show the DLL characteristic when the file is actually a DLL.
Conclusion to write: File type is supported by magic bytes and PE characteristics, not by the renamed extension.
What this teaches: Validate executable format using structural evidence.
14. Imports and Loaded Modules
Expected result: The runtime Modules tab should contain the directly imported DLLs plus additional loader, transitive, and dynamically loaded dependencies.
Conclusion to write: The static Import Directory is not a complete list of everything present at runtime.
What this teaches: Correlate static and dynamic evidence instead of treating either as complete.
15. Exports and Dependencies
Expected result: Sample-4-2.dll exposes names/ordinals and function RVAs in its Export Directory. Dependency Walker should show direct dependencies and their dependency chains.
Conclusion to write: Imports describe external functionality consumed by a PE; exports describe functionality it offers to other modules.
What this teaches: A loaded module may appear because another imported DLL depends on it.
Expected Solutions 16-21: Static Analysis
16. Lab01-01 Full Triage
Expected result: You should obtain hashes, compile timestamps, packer assessment, section measurements, strings, and imports for both files. The lecture points to a suspicious misspelled system DLL-style path in the EXE strings and an IP address in the DLL strings.
Conclusion to write: State whether packing is supported by multiple indicators, then separate host indicators from network indicators. Imports indicate capabilities such as process creation, sleeping, or Winsock use, not confirmed execution.
What this teaches: A defensible static answer combines several independent artifacts.
17. UPX Packing
Expected result: The packed copy should normally be smaller, contain UPX section names such as UPX0/UPX1, have higher entropy, expose fewer useful strings/imports, and differ substantially in hex view.
Conclusion to write: UPX transformed the representation but not the program's intended behavior. Identify packing using signature, sections, entropy, and imports together.
What this teaches: Packing hides useful static evidence until unpacking.
18. Strings Before and After Packing
Expected result: The original should expose more meaningful strings, including the lecture marker if present. The packed version should expose fewer useful strings because most original content is compressed.
Conclusion to write: Missing static strings can be a packing symptom, not proof that the program never uses those values.
What this teaches: Compare on-disk and memory strings for packed samples.
19. Lab01-03 and Lab01-04
Expected result: For each sample, you should reach a supported packed/not packed decision and identify imports related to files, processes, registry, services, or networking. The two samples do not need to produce the same decision.
Conclusion to write: Cite at least two packing indicators and translate important imports into behavior hypotheses.
What this teaches: Static imports guide the dynamic-analysis plan.
20. Dependency Profiling
Expected result: Dependency Walker should show direct DLLs before execution and may reveal additional dynamically resolved or loaded modules during profiling. Winsock dependencies support possible network capability.
Conclusion to write: A static dependency means capability; a profiled load shows the dependency was loaded during that run.
What this teaches: Dynamic dependency profiling can reveal behavior hidden from a simple import-table view.
21. Embedded Resources
Expected result: Resource Hacker should expose resource type, name, language, and size. Exported resources may be configuration, images, scripts, or another PE beginning with MZ.
Conclusion to write: Identify and hash the extracted object before classifying it. An embedded PE supports dropper behavior but does not prove it was written or executed.
What this teaches: Droppers often store payloads inside PE resources.
Expected Solutions 22-30: Dynamic Analysis
22. ProcMon Filtering
Expected result: The exclusion removes noisy HKCU\Software\Classes events, while the include filter reveals operations that returned ACCESS DENIED. Sample-specific KernelBase-related activity should be visible if produced during your run.
Conclusion to write: Report the process, operation, path, result, and detail. ProcMon operation names do not always equal the high-level Win32 API called by the program.
What this teaches: Filters reduce noise but can also hide evidence; always save the complete PML first.
23. APIMiner
Expected result: The trace should contain CreateToolhelp32Snapshot and nearby process-enumeration calls if the lecture sample follows the expected behavior. Arguments and return values should show how the snapshot is used.
Conclusion to write: Runtime API tracing confirms calls that ProcMon may represent only indirectly.
What this teaches: Analyze API sequences and parameters, not names in isolation.
24. Lab01-02 Unpacking
Expected result: upx -t should recognize a valid UPX-packed sample, and upx -d should create an unpacked copy. The unpacked file should reveal more imports and strings, including WinINet and service-related functionality noted by the lecture.
Conclusion to write: Compare both versions and explain what evidence became visible after unpacking.
What this teaches: Unpacking improves static visibility without proving which capabilities execute.
25. Lab01-03 and Lab01-04 Practice
Expected result: You should produce a complete static profile for each sample. Lab01-04 should expose an extractable resource whose type and content can be analyzed separately.
Conclusion to write: Present hash, type, packing evidence, timestamp caveat, imports, strings, indicators, and resource findings in that order.
What this teaches: A repeatable triage structure prevents omitted evidence.
26. Registry Change Analysis
Expected result: Regshot should show before/after registry differences, and ProcMon should identify the exact keys/values written by rundll32.exe ... Lab03-02.dll,install.
Conclusion to write: Attribute each persistence or configuration change to the observed process and record key path, value name, type, and data.
What this teaches: Regshot gives the broad difference; ProcMon adds process and timing context.
27. Sample-13-1
Expected result: Process Hacker should reveal any created or manipulated processes. APIMiner should show SuspendThread, ResumeThread, and NtMapViewOfSection if the expected technique executes, with common handles or target identifiers linking the calls.
Conclusion to write: Explain the ordered sequence and identify the target process or thread using arguments, not API names alone.
What this teaches: Correlated parameters connect separate calls into one behavior.
28. Sample-13-2
Expected result: Static analysis should identify type/packing indicators, while dynamic tools should capture created artifacts, registry changes, processes, and simulated network activity. APIMiner should expose NtCreateMutant; the lecture marker 2GVWNQJz1 is a mutex lead to verify.
Conclusion to write: Classify the sample from the combined behavior and cite the mutex, filesystem, registry, process, and network evidence actually observed.
What this teaches: Malware classification requires correlation across multiple evidence sources.
29. Sample-13-3
Expected result: The disposable PDF/XLSX files may be renamed, modified, encrypted, or otherwise changed. Their post-run hashes or content should differ if affected. ProcMon/APIMiner should reveal enumeration and write APIs.
Conclusion to write: Name every affected file and prove the change with before/after metadata, hashes, and runtime operations.
What this teaches: File-impact claims require baseline evidence and direct comparison.
30. Sample-13-4 Memory Strings
Expected result: Memory inspection should reveal more or different strings than static disk extraction if the sample unpacks or decrypts itself. The lecture marker beginning YUIPWDFILE0... should be searched for and verified, not assumed.
Conclusion to write: A string found only in memory supports runtime decryption/unpacking. Correlate it with process and API behavior.
What this teaches: Packed malware can hide useful configuration until execution.
Expected Solutions 31-35: Persistence
31. Startup Folder
Expected result: The copied executable should appear in the all-users Startup folder, Autoruns Logon tab, and ProcMon file activity. After restart, Windows should launch it for a logged-on user, subject to VM policy.
Conclusion to write: The file persists because Windows executes entries in the Startup folder at user logon.
What this teaches: Persistence evidence must identify the artifact, trigger, target executable, and successful execution.
32. Run Key
Expected result: reg query, PowerShell, Autoruns, and ProcMon should show the value under the chosen Run key and its executable data. HKLM applies system-wide; HKCU/HKU applies to the corresponding user.
Conclusion to write: Record hive, complete key path, value name, value data, scope, and logon trigger.
What this teaches: Registry location determines affected users and required privilege.
33. Service
Expected result: sc query, sc qc, the Services registry key, Autoruns, and possibly Event ID 7045/4697 should show BookService. Its ImagePath should point to C:\Temp\Sample-5-1.exe. Start behavior depends on whether the sample implements a valid Windows service.
Conclusion to write: Separate successful service registration from successful service execution. Report service name, start type, account, and ImagePath.
What this teaches: A created service can provide persistence even when its first start attempt fails.
34. Scheduled Task
Expected result: Task test should appear in schtasks, Task Scheduler, Autoruns, and C:\Windows\System32\Tasks. Its action should reference Calculator and its trigger should begin at the configured time with a one-minute schedule.
Conclusion to write: Record task name, trigger, action, user/context, and whether execution was observed.
What this teaches: Task files, registry cache, command line, and runtime processes provide complementary evidence.
35. AppInit and DLL Export
Expected result: Registry queries reveal whether AppInit DLL loading is enabled and list configured DLLs. CFF Explorer should show the installer export in Lab11-02.dll; rundll32 should invoke that exported function and ProcMon should capture its effects.
Conclusion to write: AppInit configuration may be inactive on modern systems because of Secure Boot or signing settings. Report configuration and observed execution separately.
What this teaches: A persistence mechanism's registry presence does not guarantee it is operational.
Expected Solutions 36-40: Network Analysis
36. DGA Output
Expected result: The sample should print or generate multiple algorithmically structured domain names. They may contain unusual character patterns and change by seed or time.
Conclusion to write: Repeated machine-generated domains support DGA behavior, but document the generation pattern instead of judging only by appearance.
What this teaches: DGAs help malware locate changing command-and-control infrastructure.
37. FakeNet and Wireshark
Expected result: Wireshark should show periodic DNS queries and possibly HTTP connections, while FakeNet supplies simulated responses and logs the requested hosts/paths.
Conclusion to write: Correlate domain, response, destination port, protocol, timing, and sample execution. Do not claim the public destination was contacted when FakeNet intercepted it.
What this teaches: Isolated service simulation reveals network intent without exposing the VM to real infrastructure.
38. HTTP C2 Strings
Expected result: Static strings should expose format specifiers, paths, parameters, user-agent text, or HTTP method clues. The XP/FakeNet run should show how those strings are assembled into requests.
Conclusion to write: Match each observed HTTP path/parameter to the static format string and explain the likely data being transmitted.
What this teaches: Static strings provide a template; packet capture proves runtime use.
39. TLS Decryption
Expected result: Without the supplied key log, TLS application data should remain encrypted. After configuring the correct key log, Wireshark should decode supported streams and expose application-layer content.
Conclusion to write: TLS decryption succeeded only when the session secrets matched the captured connection. A key log cannot decrypt unrelated or unsupported sessions.
What this teaches: Encryption hides content, not connection metadata.
40. CreateFileA Parameters
Expected result: Documentation shows that CreateFileA can create, open, truncate, or access many object types depending on its arguments. CREATE_ALWAYS requests creation/overwrite, while OPEN_EXISTING requires an existing target.
Conclusion to write: Determine behavior from lpFileName, dwDesiredAccess, and dwCreationDisposition, plus return/result evidence.
What this teaches: An API name without parameters is insufficient evidence.
Expected Solutions 41-47: Process Injection
41. Classic DLL Injection
Expected result: After entering Notepad's PID and the DLL path, Sample-10-5b.dll should appear in Notepad's Modules tab. The API sequence should include target opening, remote allocation, DLL-path writing, LoadLibrary address resolution, and remote-thread creation.
Conclusion to write: The loaded unexpected DLL and ordered cross-process API sequence support classic DLL injection.
What this teaches: Strong injection evidence combines target, payload, memory, and execution stages.
42. Lab12-01
Expected result: Running the EXE should produce the lecture's visible popup behavior and inject its DLL into a target process. Strings/imports and APIMiner should explain the target selection and repeated behavior. Determine the stop condition from your observed sample.
Conclusion to write: Identify the injected process, injected module, observable effect, stop condition, and complete API sequence.
What this teaches: Explain how the malware operates, not merely what APIs exist.
43. Lab19-02
Expected result: Event logs and runtime tools should show process activity and an injection sequence involving remote memory allocation/writing and execution. Unlike classic DLL injection, the payload is expected to be shellcode rather than a DLL path loaded with LoadLibrary.
Conclusion to write: Distinguish shellcode injection by payload form, memory protections, and thread start location.
What this teaches: Different injection techniques share stages but use different payload and execution mechanisms.
44. Sample-10-1 Process Enumeration
Expected result: The sample's printed process names and PIDs should substantially correspond to Process Hacker/tasklist at that moment. APIMiner should show snapshot and process-iteration APIs.
Conclusion to write: Small differences can occur because processes start or stop between observations. Use the runtime API sequence to explain how the list was obtained.
What this teaches: Process discovery commonly precedes target selection.
45. Lab12-02 Suspended Process
Expected result: APIMiner should show process creation with a suspended creation flag, followed by thread/context or memory manipulation and ResumeThread. Process Hacker may briefly show the child suspended.
Conclusion to write: The ordered sequence supports suspended-process manipulation or process hollowing only when target-memory/context evidence is also present.
What this teaches: CREATE_SUSPENDED alone is not proof of hollowing.
46. Sample-10-2 Remote Allocation
Expected result: After providing the target PID, size, and permissions, a new private region should appear in Notepad or Calculator with matching size and protection. The base address will vary.
Conclusion to write: VirtualAllocEx against another process proves remote allocation, which is one injection stage but not complete injection by itself.
What this teaches: Report target process, returned base address, size, allocation type, and protection.
47. Sample-10-3 Remote Write
Expected result: The target process should contain the string MALWARE ANALYSIS at the address reported by the sample. APIMiner should show WriteProcessMemory with the same target handle/address and a matching byte count.
Conclusion to write: The memory view and API trace prove data was written into another process. Additional execution evidence would still be required to prove that the written bytes ran.
What this teaches: Keep allocation, writing, protection, and execution as separate injection stages.
Expected Answer Pattern
For every exercise, write the answer in this form:
Result:
I observed [specific value or behavior].
Evidence:
[Tool] showed [exact field/API/operation/path] with [important value].
Interpretation:
This supports [conclusion] because [technical reason].
Limitation:
This does not by itself prove [unsupported stronger claim].
Final 2025 Exam Command Set
Hash and metadata:
Get-FileHash C:\Temp\sample.exe -Algorithm SHA256
Get-Item C:\Temp\sample.exe | Select-Object Name,Length,CreationTime,LastWriteTime
APIMiner:
C:\Users\IEUser\Desktop\APIMiner.lnk --app C:\Temp\sample.exe
ProcMon:
Process Name is sample.exe -> Include
Operation is CreateFile -> Include
Operation contains Thread -> Include
Path begins with C:\Temp -> Include
Packing:
CFF Explorer -> PE type and architecture
DiE -> Entropy and detection
CFF Explorer -> Section Headers and imports
Never reuse PID/TID values from a previous answer. Capture values from the current run.