diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 6b8710a..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1 +0,0 @@
-.git
diff --git a/.gitignore b/.gitignore
index 08f1657..4e0c380 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
__pycache__/
+myvenv/
+myenv/
venv/
-*.exe
+.env
+*.pyc
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 5fd6ae9..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,27 +0,0 @@
-# Import the latest Python docker image
-FROM python:latest
-
-# Set setup to run in bash terminal
-SHELL ["/bin/bash", "-c"]
-
-# Install a few text editors
-RUN apt update
-RUN apt install nano vim wget -y
-
-# Create new user for lab
-RUN useradd -ms /bin/bash aama
-WORKDIR /home/aama
-
-# Download assignment PE file
-RUN wget https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v8.5.4/npp.8.5.4.Installer.x64.exe -O "ExamplePE.exe"
-
-# Move lab code over to container
-COPY resources/* /home/aama/
-RUN chown -R aama:aama /home/aama
-
-# Perform user-level setup tasks
-USER aama
-RUN pip3 install -r requirements.txt
-
-# Tell Docker to open a terminal in bash instead of Python interpreter
-CMD ["/bin/bash"]
diff --git a/ExamplePE.exe b/ExamplePE.exe
new file mode 100644
index 0000000..b6af016
Binary files /dev/null and b/ExamplePE.exe differ
diff --git a/resources/FeatureExtraction1a.py b/FeatureExtraction1a.py
similarity index 87%
rename from resources/FeatureExtraction1a.py
rename to FeatureExtraction1a.py
index a34ffca..d6496ba 100644
--- a/resources/FeatureExtraction1a.py
+++ b/FeatureExtraction1a.py
@@ -2,7 +2,8 @@
File: FeatureExtraction.py
Author: Drew Wheeler
Last Edit: 2023-07-29_14:00-UTC
-
+Modified by: Ubayeid U.
+Modified: 2025-09-30
This file was written for Lab 1a of the AI-Assisted Malware Analysis Project,
funded by the NSF (grant #2025682).
@@ -71,28 +72,26 @@ def extract_sha256 (self, file_name: str = "") -> None:
def extract_header_s (self, binary: lief.PE.Binary = None) -> None:
# Extract the real size of the image
- self.header_size = 0
-
+ self.header_size = binary.optional_header.sizeof_image
+
def extract_virtual_s (self, binary: lief.PE.Binary = None) -> None:
- # Extract the virutal size of the image
- self.virtual_size = 0
-
+ # Extract the virtual size of the image
+ self.virtual_size = binary.optional_header.sizeof_image
+
def extract_machine (self, binary: lief.PE.Binary = None) -> None:
# Extract the __name__ of the target machine found in the COFF header
- self.target_machine = ""
-
+ self.target_machine = str(binary.header.machine).split('.')[-1]
+
def extract_sec_count (self, binary: lief.PE.Binary = None) -> None:
# Extract the number of sections within the executable the COFF header lists
- self.section_count = 0
-
+ self.section_count = len(binary.sections)
+
def extract_sec_data (self, binary: lief.PE.Binary = None) -> None:
# Extract section names and their entropy
for section in binary.sections:
- name: str = ""
- entropy: float = 0.0
- # name = section name (NOT the fullname)
- # entropy = section entropy
- self.section_info[name] = float (format (entropy, ".4f"))
+ name: str = section.name # โ ACTUAL implementation
+ entropy: float = section.entropy # โ ACTUAL implementation
+ self.section_info[name] = float(format(entropy, ".4f"))
def print_data (self) -> None:
print (self.sha256_hash)
diff --git a/resources/FeatureExtraction1b.py b/FeatureExtraction1b.py
similarity index 50%
rename from resources/FeatureExtraction1b.py
rename to FeatureExtraction1b.py
index 8a1a088..a5857aa 100644
--- a/resources/FeatureExtraction1b.py
+++ b/FeatureExtraction1b.py
@@ -2,7 +2,8 @@
File: FeatureExtraction1b.py
Author: Drew Wheeler
Last Edit: 2024-08-23
-
+Modified by: Ubayeid U.
+Modified: 2025-09-30
This file was written for Lab 1a of the AI-Assisted Malware Analysis Project,
funded by the NSF (grant #2025682).
@@ -46,6 +47,9 @@ def __init__ (self) -> None:
self.section_count:int = 0
self.section_info:dict = {}
self.encoded_sec_info: dict = {}
+ self.encoded_target_machine: int = 0
+ self.decoded_target_machine: str = ""
+ self.decoded_sec_info: dict = {}
def extract_features (self, file_name: str = "") -> None:
binary: lief.PE.Binary = lief.parse (file_name)
@@ -55,12 +59,42 @@ def extract_features (self, file_name: str = "") -> None:
self.extract_machine (binary)
self.extract_sec_count (binary)
self.extract_sec_data (binary)
+ # Encode the extracted features
+ self.encode_target_machine()
+ self.encode_section_info()
+ # Decode to verify encoding worked correctly
+ self.decode_target_machine()
+ self.decode_section_info()
def extract_sha256 (self, file_name: str = "") -> None:
with open (file_name, "rb") as hasher:
byte_stream = hasher.read()
self.sha256_hash = sha256 (byte_stream).hexdigest()
+# === Paste Lab 1a Methods Below This Line =========================================================
+ def extract_header_s (self, binary: lief.PE.Binary = None) -> None:
+ # Extract the real size of the image
+ self.header_size = binary.optional_header.sizeof_image
+
+ def extract_virtual_s (self, binary: lief.PE.Binary = None) -> None:
+ # Extract the virtual size of the image
+ self.virtual_size = binary.optional_header.sizeof_image
+
+ def extract_machine (self, binary: lief.PE.Binary = None) -> None:
+ # Extract the __name__ of the target machine found in the COFF header
+ self.target_machine = str(binary.header.machine).split('.')[-1]
+
+ def extract_sec_count (self, binary: lief.PE.Binary = None) -> None:
+ # Extract the number of sections within the executable the COFF header lists
+ self.section_count = len(binary.sections)
+
+ def extract_sec_data (self, binary: lief.PE.Binary = None) -> None:
+ # Extract section names and their entropy
+ for section in binary.sections:
+ name: str = section.name
+ entropy: float = section.entropy
+ self.section_info[name] = float(format(entropy, ".4f"))
+
def print_data (self) -> None:
print (self.sha256_hash)
print (self.header_size)
@@ -68,11 +102,6 @@ def print_data (self) -> None:
print (self.target_machine)
print (self.section_count)
print (self.section_info)
-
-
-# === Paste Lab 1a Methods Below This Line =========================================================
-
-
# === Lab 1b Methods Start Here ====================================================================
# Encoding Schemes:
#
@@ -109,19 +138,94 @@ def print_data (self) -> None:
def encode_target_machine (self) -> None:
# Encode target machine using one-hot encoding schema
- pass
+ machine_encoding = {
+ "UNKNOWN": 0x01,
+ "I386": 0x02,
+ "AMD64": 0x04,
+ "ARM64": 0x08
+ }
+ self.encoded_target_machine = machine_encoding.get(self.target_machine, 0x01)
def encode_section_info (self) -> None:
# Encode section names using one-hot encoding schema
- pass
+ section_encoding = {
+ ".text": 0x000001,
+ ".rdata": 0x000002,
+ ".data": 0x000004,
+ ".ndata": 0x000008,
+ ".rsrc": 0x000010,
+ ".itext": 0x000020,
+ ".bss": 0x000040,
+ ".idata": 0x000080,
+ ".didata": 0x000100,
+ ".edata": 0x000200,
+ ".tls": 0x000400,
+ ".buildid": 0x000800,
+ ".reloc": 0x001000,
+ ".UPX0": 0x002000,
+ ".UPX1": 0x004000,
+ ".qtmetad": 0x008000,
+ ".qtmimed4": 0x010000,
+ ".pdata": 0x020000,
+ ".xdata": 0x040000,
+ ".CRT": 0x080000,
+ ".debug": 0x100000
+ }
+
+ for section_name, entropy in self.section_info.items():
+ encoded_value = section_encoding.get(section_name, 0x000000)
+ self.encoded_sec_info[section_name] = {
+ "encoded": encoded_value,
+ "entropy": entropy
+ }
def decode_target_machine (self) -> None:
# Decode one-hot target machine back to string
- pass
+ machine_decoding = {
+ 0x01: "UNKNOWN",
+ 0x02: "I386",
+ 0x04: "AMD64",
+ 0x08: "ARM64"
+ }
+ if hasattr(self, 'encoded_target_machine'):
+ self.decoded_target_machine = machine_decoding.get(self.encoded_target_machine, "UNKNOWN")
+ else:
+ self.decoded_target_machine = "UNKNOWN"
def decode_section_info (self) -> None:
# Decode one-hot section names back to strings
- pass
+ section_decoding = {
+ 0x000001: ".text",
+ 0x000002: ".rdata",
+ 0x000004: ".data",
+ 0x000008: ".ndata",
+ 0x000010: ".rsrc",
+ 0x000020: ".itext",
+ 0x000040: ".bss",
+ 0x000080: ".idata",
+ 0x000100: ".didata",
+ 0x000200: ".edata",
+ 0x000400: ".tls",
+ 0x000800: ".buildid",
+ 0x001000: ".reloc",
+ 0x002000: ".UPX0",
+ 0x004000: ".UPX1",
+ 0x008000: ".qtmetad",
+ 0x010000: ".qtmimed4",
+ 0x020000: ".pdata",
+ 0x040000: ".xdata",
+ 0x080000: ".CRT",
+ 0x100000: ".debug"
+ }
+
+ self.decoded_sec_info = {}
+ for section_name, data in self.encoded_sec_info.items():
+ encoded_value = data["encoded"]
+ decoded_name = section_decoding.get(encoded_value, section_name)
+ self.decoded_sec_info[decoded_name] = {
+ "original_name": section_name,
+ "entropy": data["entropy"]
+ }
# === Do not edit anything below this line =========================================================
diff --git a/resources/GradeScript1a.py b/GradeScript1a.py
similarity index 99%
rename from resources/GradeScript1a.py
rename to GradeScript1a.py
index 1345e9b..ce3b8dd 100644
--- a/resources/GradeScript1a.py
+++ b/GradeScript1a.py
@@ -3,7 +3,6 @@
Author: Drew Wheeler
Last Edit: 2024-08-23
-
This file was written for Lab 1a of the AI-Assisted Malware Analysis Project,
funded by the NSF (grant #2025682).
diff --git a/resources/GradeScript1b.py b/GradeScript1b.py
similarity index 72%
rename from resources/GradeScript1b.py
rename to GradeScript1b.py
index 7154172..a68660f 100644
--- a/resources/GradeScript1b.py
+++ b/GradeScript1b.py
@@ -26,16 +26,16 @@ def setUp (self) -> None:
self.sha256_hash: str = "1df56772594a5ec2f550c7727a4879142736106da68b5d185c4391e08b48ec5e"
self.target_machine: str = "I386"
self.sections: dict[str, float] = {".text": 6.4723,
- ".rdata": 5.2098,
- ".data": 4.1106,
- ".ndata": 0.0000,
- ".rsrc": 5.7320}
- self.enc_target_machine: str = "0x02"
- self.enc_sections: dict[str, float] = {"0x000001": 6.4723,
- "0x000002": 5.2098,
- "0x000004": 4.1106,
- "0x000008": 0.0000,
- "0x000010": 5.7320}
+ ".rdata": 5.2098,
+ ".data": 4.1106,
+ ".ndata": 0.0000,
+ ".rsrc": 5.7320}
+ self.enc_target_machine: int = 0x02
+ self.enc_sections: dict[str, dict] = {".text": {"encoded": 0x000001, "entropy": 6.4723},
+ ".rdata": {"encoded": 0x000002, "entropy": 5.2098},
+ ".data": {"encoded": 0x000004, "entropy": 4.1106},
+ ".ndata": {"encoded": 0x000008, "entropy": 0.0000},
+ ".rsrc": {"encoded": 0x000010, "entropy": 5.7320}}
self.features: FeatureExtract = FeatureExtract()
self.features.extract_features (TEST_FILE)
@@ -47,14 +47,14 @@ def test_sections (self) -> None:
def test_encode_machine (self) -> None:
self.features.encode_target_machine()
- self.assertEqual (self.enc_target_machine, self.features.target_machine)
+ self.assertEqual (self.enc_target_machine, self.features.encoded_target_machine)
self.features.decode_target_machine()
def test_encode_sections (self) -> None:
self.features.encode_section_info()
self.assertEqual (self.enc_sections, self.features.encoded_sec_info)
self.features.decode_section_info()
-
+
def test_decode_machine (self) -> None:
self.features.encode_target_machine()
self.features.decode_target_machine()
diff --git a/README.md b/README.md
index e561bf6..267350c 100644
--- a/README.md
+++ b/README.md
@@ -1,138 +1,275 @@
# AI-Assisted Malware Analysis Lab 01: Feature Extraction and Data Encoding
-This lab seeks to introduce students machine learning concepts of feature extraction and data encoding. This is
-accomplished through the use of Python and the LIEF library.
-
-| Table of Contents |
-|-------------------|
-| [Preinstallation](#preinstall) |
-| [Non-Docker Installation](#nondocker-install) |
-| [Image Creation and Instantiation](#image-create) |
-| [Accessing the Container](#access-container) |
-
-There are two methods for installation:
-1. Standard installation on a bare-metal system.
-2. Creation of a docker image that contains the needed environment.
-
-Instructions for both methods can be found below.
-
-For those already familiar with Docker, but who do not want to go through the process of building the image themselves,
-a pre-built image can be found on [Docker Hub](https://hub.docker.com/r/abcyslab/aama_lab01). This image is
-automatically built and deployed whenever a push is made to the project repository, thus, it is always kept up to date
-with the most recent version of the lab.
-
-## Preinstallation
-
-This lab requires a portable executable (PE) file compiled for Windows to be added by the user. Currently the image
-automatically downloads a predetermined executable file during building. If you opt to use another PE file, almost any
-.exe file from the last 20 years should be sufficient. However, if you do this, the grading script must be modified to
-accomodate the new executable. The new executable should be added to the repository in the "resources" directory and
-given the name "ExamplePE.exe" so it is properly handled.
-
-If you wish to use a container for the lab, instructions for installing Docker can be found on their website:
-- [Windows](https://docs.docker.com/desktop/install/windows-install/)
-- [Mac](https://docs.docker.com/desktop/install/mac-install/)
-- [Linux](https://docs.docker.com/desktop/install/linux-install/)
-
-Docker Desktop is not needed so long as the command line tools are installed. However, it may be useful having a GUI for
-managing containers and images.
-
-## Non-Docker Installation
-A standard install of the project on a system without using Docker requires Python 3, with Git also being highly
-recommended. The general set of steps needed for installation are as follows:
-1. Clone the repository to your machine.
-2. Open the "resources" directory of repo in a terminal.
-3. Initialize the virtual environment for Python.
-4. Install the needed packages into the virual environment.
-
-### Windows
-
+
+**Modified and Enhanced by:** Ubayeid U.
+**Original Project:** AIMA-Project/AAMA-Lab01
+
+Welcome! This lab teaches you how to extract features from Windows executable files (PE files) and encode them for machine learning analysis. You'll learn to use Python and the LIEF library to analyze malware.
+
+## ๐ Table of Contents
+
+- [What You'll Learn](#what-youll-learn)
+- [Prerequisites](#prerequisites)
+- [Quick Start Guide](#quick-start-guide)
+- [Lab Structure](#lab-structure)
+- [Detailed Setup Instructions](#detailed-setup-instructions)
+- [Running the Labs](#running-the-labs)
+- [Testing Your Work](#testing-your-work)
+- [Troubleshooting](#troubleshooting)
+- [Project Files Explained](#project-files-explained)
+
+## ๐ฏ What You'll Learn
+
+- **Feature Extraction**: How to extract meaningful data from Windows executable files
+- **Data Encoding**: How to convert extracted features into formats suitable for machine learning
+- **Malware Analysis**: Understanding PE file structure and suspicious patterns
+- **Python Programming**: Working with libraries, virtual environments, and testing
+
+## ๐ Prerequisites
+
+- **Python 3.7+** installed on your computer
+- **Basic command line knowledge** (we'll guide you through everything!)
+- **Windows, Mac, or Linux** (instructions for all platforms)
+
+Don't worry if you're new to virtual environments or unit testing - this guide explains everything!
+
+## ๐ Quick Start Guide
+
+### Step 1: Get the Code
+
+```bash
+git clone https://github.com/AIMA-Project/AAMA-Lab01
+cd AAMA-Lab01
```
-$ git clone https://github.com/AIMA-Project/AAMA-Lab01
-$ cd AAMA-Lab01\resources
-$ py -m venv venv
-$ .\venv\bin\Activate.ps1
-$ pip install -r requirements.txt
+
+### Step 2: Set Up Python Environment
+
+**Windows:**
+
+```powershell
+python -m venv myenv
+myenv\Scripts\Activate.ps1
+pip install -r requirements.txt
```
-### Linux
+**Mac/Linux:**
+
+```bash
+python3 -m venv myenv
+source myenv/bin/activate
+pip install -r requirements.txt
+```
+
+### Step 3: Run the Labs
+
+```bash
+# Run Lab 1a (basic feature extraction)
+python FeatureExtraction1a.py ExamplePE.exe
+
+# Run Lab 1b (feature extraction + encoding)
+python FeatureExtraction1b.py ExamplePE.exe
```
-$ git clone https://github.com/AIMA-Project/AAMA-Lab01
-$ cd AAMA-Lab01/resources
-$ python3 -m venv venv
-$ source venv/bin/activate
-$ pip3 install -r requirements.txt
+
+### Step 4: Test Your Work
+
+```bash
+# Test Lab 1a
+python -m unittest GradeScript1a.py
+
+# Test Lab 1b
+python -m unittest GradeScript1b.py
```
-## Image Creation and Instantiation
-This method of installation requires Docker to be installed and running on the user's computer. These instructions
-should work for both Linux and Windows operating systems, but there may be some slight deviations for your system.
+## ๐๏ธ Lab Structure
+
+### Lab 1a: Basic Feature Extraction
+
+**Goal**: Extract key features from a Windows executable file
+
+- File hash (SHA-256)
+- File size information
+- Target architecture (x86, x64, etc.)
+- Section information and entropy values
+
+### Lab 1b: Advanced Feature Extraction + Encoding
+
+**Goal**: Extract features AND encode them for machine learning
+
+- Everything from Lab 1a
+- One-hot encoding for machine types
+- Numerical encoding for section names
+- Data preparation for ML algorithms
+
+## ๐ Detailed Setup Instructions
+
+### What is a Virtual Environment?
+
+A virtual environment is like a separate, clean workspace for your Python project. It prevents conflicts between different projects and keeps your system clean.
+
+Think of it like having a separate toolbox for each project - your tools don't get mixed up!
+
+### Setting Up Your Virtual Environment
+
+1. **Create the environment** (like creating a new toolbox):
+
+ ```bash
+ python -m venv myenv
+ ```
+
+2. **Activate the environment** (like opening your toolbox):
+
+ **Windows:**
-
-**It is important to note that Linux users will have to run Docker commands as root or using the `sudo` command! You can
-follow the [official directions](https://docs.docker.com/engine/install/linux-postinstall/) for how to bypass this, but
-it highly recommended that you do not.**
+ ```powershell
+ myenv\Scripts\Activate.ps1
+ ```
-Building the image can be done in two simple commands. Alternatively, these commands are provided in the
-"docker_setup.ps1" script.
+ **Mac/Linux:**
-While this is a `.ps1` file, it should have syntax compatible with most Linux systems. The executable bit may need to be
-set before running, which requires the command `chmod +x docker_setup.ps1` to be ran. Remember that unless Docker has
-been setup to bypass needing elevated privileges, `sudo` will have to be used when calling the script.
-
+ ```bash
+ source myenv/bin/activate
+ ```
+
+ You'll see `(myenv)` at the start of your command prompt when it's active.
+
+3. **Install required packages** (like putting tools in your toolbox):
+ ```bash
+ pip install -r requirements.txt
+ ```
+
+### What Gets Installed?
+
+- **LIEF**: A library for analyzing executable files
+- **Standard Python libraries**: For file operations, hashing, etc.
+
+## ๐งช Running the Labs
+
+### Understanding the Output
+
+When you run the scripts, you'll see output like:
-Alternatively, the two commands can be ran manually in succession:
```
-$ docker build -t lab01-image .
-$ docker run --name lab01 -it lab01-image
+1df56772594a5ec2f550c7727a4879142736106da68b5d185c4391e08b48ec5e # SHA-256 hash
+446464 # Header size
+446464 # Virtual size
+I386 # Architecture
+5 # Number of sections
+{'.text': 6.4723, '.rdata': 5.2098, '.data': 4.1106, '.ndata': 0.0, '.rsrc': 5.732} # Section entropy
```
-These commands perform the following operations:
-1. Build a static base image called "lab01-image" from which instances of the lab (called containers) can be created.
-2. Create a container instance of the lab and give it the name "lab01."
+**What This Means:**
+
+- **Hash**: Unique fingerprint of the file
+- **Sizes**: How big the file is in memory
+- **Architecture**: What type of processor it's built for
+- **Sections**: Different parts of the executable (code, data, resources)
+- **Entropy**: Measure of randomness (high entropy might indicate encryption/packing)
-If you need to redeploy the container from the image at any point, you must first delete the current instance of the
-lab container. The command `docker container rm lab01` can be used to delete the current instance of the lab01
-container. **You will lose any data stored in the container when you perform this command!**
+## ๐งช Testing Your Work
-If you need to rebuild the entire image from scratch, you can first delete the current image stored on your machine with
-`docker image rm lab01-image`, then use the above commands to build and reploy the new version.
+### What are Unit Tests?
-## Accessing the Container
-If lab the needs to be accessed in the future, an already-existing container can be started again to continue work from
-the point left off. Depending on the IDE and method by which you are calling Docker, the steps for starting and
-attaching to the container will vary.
+Unit tests automatically check if your code works correctly. Think of them like automated grading - they run your code and verify the output matches what's expected.
-The most basic method of reinstantiating a container is by using Docker's command-line tools. Two commands are needed to
-restart the container and then attach your terminal to it.
+### Running Tests
+```bash
+# Test basic feature extraction
+python -m unittest GradeScript1a.py
+
+# Test advanced feature extraction + encoding
+python -m unittest GradeScript1b.py
```
-$ docker start lab01
-$ docker attach lab01
+
+### Understanding Test Results
+
+- **`.` (dot)**: Test passed โ
+- **`F`**: Test failed โ
+- **`E`**: Test had an error ๐ฅ
+
+Example successful output:
+
+```
+......
+----------------------------------------------------------------------
+Ran 6 tests in 0.123s
+
+OK
```
-A more advance approach if an IDE is being used is to utilize plugins or extensions to allow interfacing with the Docker
-service and your containers.
+## ๐ง Troubleshooting
+
+### Common Issues
+
+**"No module named 'lief'"**
+
+- **Solution**: Make sure your virtual environment is activated and run `pip install -r requirements.txt`
+
+**"Cannot find file 'ExamplePE.exe'"**
+
+- **Solution**: Make sure you're running the command from the main lab directory
+
+**Virtual environment not activating**
+
+- **Windows**: Try `myenv\Scripts\activate.bat` instead of `.ps1`
+- **Mac/Linux**: Make sure you're using `source` before the activate command
+
+**Permission errors on Windows**
+
+- **Solution**: Try running PowerShell as Administrator, or use `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser`
+
+### Getting Help
+
+If you're stuck:
+
+1. Check that your virtual environment is active (you see `(myenv)` in your prompt)
+2. Verify you're in the correct directory
+3. Make sure all files are present
+4. Try deactivating and reactivating your virtual environment
+
+## ๐ Project Files Explained
+
+```
+AAMA-Lab01/
+โโโ README.md # This file - your guide!
+โโโ requirements.txt # List of Python packages needed
+โโโ ExamplePE.exe # Sample Windows executable for analysis
+โโโ FeatureExtraction1a.py # Lab 1a: Basic feature extraction
+โโโ FeatureExtraction1b.py # Lab 1b: Advanced extraction + encoding
+โโโ GradeScript1a.py # Tests for Lab 1a
+โโโ GradeScript1b.py # Tests for Lab 1b
+โโโ myenv/ # Your virtual environment (created by you)
+โโโ deliverables/ # Where you put completed work
+โโโ .github/ # GitHub configuration (ignore this)
+```
+
+### Key Files You'll Work With:
+
+- **FeatureExtraction1a.py**: Your main Lab 1a script
+- **FeatureExtraction1b.py**: Your main Lab 1b script
+- **ExamplePE.exe**: The file you'll analyze (Notepad++ installer)
+- **GradeScript\*.py**: Automated tests to check your work
+
+## ๐ Learning Goals
+
+By completing this lab, you'll understand:
+
+- How malware analysts extract features from suspicious files
+- Why file entropy matters in malware detection
+- How to prepare data for machine learning algorithms
+- Python virtual environments and testing
+- The structure of Windows executable files
+
+## ๐ Success Criteria
-Microsoft offers two plugins for [Visual Studio Code](https://code.visualstudio.com) that integrate with Docker and
-allow for starting and stopping containers, deleting containers and images, and attaching VSCode to a Docker container
-as if it was a local project directory.
-- [Docker](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker)
-- [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
+You've successfully completed the lab when:
-Using both of these plugins allows for extensive integration with Docker and greatly simplifies interfacing with it. It
-also allows for easy transference of files between the Docker container and host OS.
+- [ ] Both Python scripts run without errors
+- [ ] All unit tests pass
+- [ ] You understand what each extracted feature means
+- [ ] You can explain the difference between raw and encoded features
-___
-**Project funded by the National Science Foundation (NSF)**
+---
-
+**๏ฟฝโ๐ป Project Enhanced by:** Md Ubayeid Ullah
diff --git a/docker_setup.ps1 b/docker_setup.ps1
deleted file mode 100755
index 386c474..0000000
--- a/docker_setup.ps1
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-# Above is needed for running on Linux
-
-# Build the Docker image
-docker build -t lab01-image . --no-cache
-
-# Create an instance of the image and attach shell to it
-docker run --name lab01 -it lab01-image
-
-# NOTE: This script is intended to be usable on both Windows and Linux.
diff --git a/linux_setup.sh b/linux_setup.sh
deleted file mode 100755
index 2e4ab9f..0000000
--- a/linux_setup.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-wget https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v8.5.4/npp.8.5.4.Installer.x64.exe -O "ExamplePE.exe"
-mv ./resources/* ./
-rmdir resources/
-python3 -m venv venv
-source ./venv/bin/activate
-pip3 install -r ./requirements.txt
diff --git a/resources/requirements.txt b/requirements.txt
similarity index 100%
rename from resources/requirements.txt
rename to requirements.txt
diff --git a/windows_setup.ps1 b/windows_setup.ps1
deleted file mode 100644
index ad35932..0000000
--- a/windows_setup.ps1
+++ /dev/null
@@ -1,6 +0,0 @@
-wget https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v8.5.4/npp.8.5.4.Installer.x64.exe -O "ExamplePE.exe"
-mv .\resources\* .\
-rmdir resources\
-python3 -m venv venv
-source .\venv\bin\activate
-pip3 install -r .\requirements.txt