The research question
Recognizing a known malicious file is only one part of endpoint protection. I wanted to understand how detection changed when the same known payload was represented differently, packaged as an executable, or run inside a process.
The study examined Avast, Bitdefender, Dr.Web, ESET, F-Secure, Kaspersky and Sophos on Linux. It also included custom C and Python samples representing keylogging, file encryption and Trojan behaviour. The matrix below focuses on the three evasion techniques for which the thesis contains comparative result tables.
One payload. Different representations.
I used known Meterpreter shellcode as a common reference across the evasion experiments. The workflow checked that protection was running, observed the response to the unencoded sample, and then recorded what happened with each variant.
-
01
Establish a baseline
Record whether the product recognizes the known, unencoded shellcode when it reaches the machine.
-
02
Change the execution context
Compare a Python memory loader, a packaged executable, injection into a running process and self-injection into a thread.
-
03
Record the observable result
Capture antivirus notifications and execution evidence, then summarize removal or lack of detection in per-product tables.
The implementations explored memory allocation and execution in
Python, process inspection with ptrace, and C-based
self-injection with an XOR-encoded variant. The focus here is the
experimental comparison and its implications for defensive
visibility.
The recorded results
The following matrix transcribes the three summary tables in Chapter 4. “Removed” means the thesis records detection and removal in that test; “Not detected” reports the observed outcome for the tested variant.
| Product | Unencoded shellcode | Encoded Python loader | PyInstaller ELF | Process injection* | Self-injection, plain | Self-injection, encoded |
|---|---|---|---|---|---|---|
| ESET | Removed | Not detected | Not detected | Not detected | Not detected | Not detected |
| Avast | Removed | Not detected | Not detected | Removed | Removed | Not detected |
| Sophos | Removed | Not detected | Removed | Not detected | Not detected | Not detected |
| F-Secure | Removed | Not detected | Not detected | Not detected | Not detected | Not detected |
| Bitdefender | Removed | Not detected | Not detected | Not detected | Not detected | Not detected |
| Kaspersky | Removed | Not detected | Not detected | Not detected | Not detected | Not detected |
| Dr.Web | Removed | Not detected | Not detected | Not detected | Not detected | Not detected |
* Process injection with the Meterpreter variant. The thesis
separately reports that its simpler /bin/sh variant
was not detected by any of the seven products.
What changed detection?
Packaging mattered
The encoded Python loader was not detected in the recorded tests. Packaging that variant as an ELF executable with PyInstaller changed the result for Sophos, which removed it. File representation was therefore a meaningful variable in this experiment.
The same technique did not imply the same outcome
Avast removed the tested Meterpreter process-injection executable and the unencoded self-injector. It did not detect the encoded self-injection variant. The payload representation and the execution method must both be considered when interpreting the result.
A notification is an observation, not a full explanation
The screenshots and tables establish the recorded detection outcome. They do not, on their own, identify the exact engine rule, prove the absence of all behavioural monitoring, or establish how a newer product version would respond.
Read the results in context
- The work is dated 2022. Products, detection engines and signatures have changed since the experiments.
- The source does not provide a complete, standardized matrix of product versions, signature revisions and configuration details for every test.
- This was a targeted experimental study, not a representative malware corpus or an independent certification benchmark.
- No detection percentages beyond the seven recorded product outcomes are implied. The tables do not establish general protection rates.
What I took away
The most valuable part of this work was learning to separate a hypothesis, an observation and a conclusion. I built test programs in C and Python, compared results across seven products, and documented the differences rather than assuming that one successful test explained an entire security engine.
That approach carries into my work today: define the boundary, collect evidence, describe the impact accurately and make the limits of the result explicit.
Source material
Davide Di Matteo, Analisi di sicurezza e capacità dei software Anti Malware su Linux. Bachelor's thesis in Computer Science, University of Rome “Tor Vergata”, 28 October 2022.
- Chapter 1: protection systems and the seven products studied.
- Chapter 2: custom C and Python samples.
- Chapter 4: shellcode execution, process injection and self-injection; comparative tables and laboratory screenshots.
- Introduction and conclusions: research objectives and interpretation of the results.
This case study is a retrospective summary of the original thesis, prepared in September 2026.