# Unreal Engine

{% hint style="warning" %}
🚨 **freeRASP for Unreal Engine – Early Release \[10/2025]**

We’re excited to introduce **freeRASP for Unreal Engine** as a new flavor of our runtime protection library. As it’s still fresh, you may encounter some **integration issues** that need to be ironed out.

We’d love to hear about your experience—good or bad. Please [open an issue on GitHub](https://github.com/talsec/Free-RASP-UnrealEngine-POC/issues) or write us directly at **<support@talsec.app>**. Your feedback helps us make it better!
{% endhint %}

## 📝 Prerequisites

The freeRASP has the following prerequisites that must be met before starting:

* Supported Unreal Engine Versions: **5.1 or higher**
* Minimum Android Target SDK: **API Level 23**
* Minimum iOS Deployment Target: **15.0**

## 🚀 Integration Steps

{% stepper %}
{% step %}

### 📦 Install Plugin

To install the plugin, download the latest release from the Releases page on GitHub.

1. Navigate to the [Releases page](https://github.com/talsec/Free-RASP-UnrealEngine-POC/releases) on the GitHub repository.
2. Under the latest release (e.g., 1.1.0), find the **Assets** section.
3. Download the `.zip` or `.tar.gz` file, for example, `Free-RASP-UnrealEngine-POC-1.1.0.zip`.
4. Extract the archive. Inside you will find the FreeRASPPlugin folder.

Copy the entire `FreeRASPPlugin` directory into your project's `Plugins` folder. If a `Plugins` folder doesn't exist at the root of your project, you will need to create it first.

The correct final directory structure should look like this:

```
[YourProjectName]/
├── Content/
├── Source/
├── Plugins/              <-- Create if missing
│   └── FreeRASPPlugin/   
└── YourProjectName.uproject
```

{% hint style="warning" %}
To complete the installation, please restart the Unreal Editor to allow it to detect the new plugin.
{% endhint %}
{% endstep %}

{% step %}

### **⚙️** Enabling the Plugin

Enabling the plugin involves two steps: enabling it in the editor and verifying the dependency in the C++ build file.

* In the main Unreal Engine menu, navigate to **Edit -> Plugins**.
* In the left panel, find the **Project -> Security** category.
* Locate the **FreeRASP** plugin and ensure the **Enabled** checkbox is checked.

<figure><img src="https://3557356308-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQ2PxZTOjhquOxcxftTrm%2Fuploads%2FscbqRfZeW9LhzKoPHO2I%2Fimage.png?alt=media&#x26;token=353773e2-1c31-4ea5-be5f-ed0f65633144" alt=""><figcaption></figcaption></figure>

Open your project's build configuration file, named `<project_name>.Build.cs`. Verify that the module name `FreeRASPPlugin` is added to the `PublicDependencyModuleNames` list.

It should look similar to this example:

```cpp
using UnrealBuildTool;

public class freeRASP4 : ModuleRules
{
    public freeRASP4 (ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

        PublicDependencyModuleNames.AddRange(new string[] { 
            "Core",
            "CoreUObject",
            "Engine",
            "InputCore",
            "EnhancedInput",
            "AIModule",
            "StateTreeModule",
            "GameplayStateTreeModule",
            "UMG",
            "FreeRASPPlugin" // <-- check if this line is added
        });
    }
}
```

{% endstep %}

{% step %}

### 📋 Android Permissions

Some checks require additional permissions to work properly. If your app already has these permissions, you don't need to add them again.

Add the required permissions via **Edit ->** **Project Settings → Platforms → Android → Extra Permissions**.

#### Screenshot and Screen Recording Detection

```xml
android.permission.DETECT_SCREEN_CAPTURE
android.permission.DETECT_SCREEN_RECORDING
```

{% hint style="info" %}
Screenshot Detection is supported on Android 14 (API level 34) and higher.&#x20;

Screen Recording Detection is supported on Android 15 (API level 35) and higher.\
\
Application of **FLAG\_SECURE** on Android Window or calling `blockScreenCapture(true)` disables this callback.
{% endhint %}

#### Location Spoofing Detection

```xml
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
```

#### Unsecure WiFi Detection

```xml
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_WIFI_STATE
```

{% hint style="info" %}
Some permissions also require runtime request.
{% endhint %}
{% endstep %}

{% step %}

### 🧠 Handle Detected Threats

With the plugin installed and enabled, it's time to write the code to initialize freeRASP and handle its threat notifications. This process involves preparing a C++ class, initializing the plugin at startup, and implementing a function to handle threats.

#### C++ Class Preparation (.h)

First you need to prepare a class to receive threat notifications. The recommended place for this is your `APlayerController` class, as it persists for the entire game session.

In your class's header file (`.h`), include the plugin's header and define the function that will act as the callback.

Example `AFreeRASPPlayerController.h`:

```cpp
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "FreeRASPPluginLibrary.h" // <-- 1. Include the header file
#include "FreeRASPPlayerController.generated.h"

/**
 * Basic PlayerController class for a game
 */
UCLASS(abstract)
class AFreeRASPPlayerController : public APlayerController
{
    GENERATED_BODY()

protected:
    /** Input Mapping Contexts */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input", meta = (AllowPrivateAccess = "true"))
    TArray<UInputMappingContext*> DefaultMappingContexts;

    /** Input mapping context setup */
    virtual void SetupInputComponent() override;

    virtual void BeginPlay() override; // initialize FreeRASP here

    UFUNCTION()
    void HandleSecurityThreat(ThreatType ThreatType); // define this method to receive threat callbacks
    
    UFUNCTION()                                                                                                          
    void HandleRASPExecutionStatus(RASPExecutionStatus RASPStatus); // define this method to receive RASP execution status callbacks
};
```

#### Plugin Initialization (.cpp)

Initialization should occur as early as possible when the game starts. The `BeginPlay()` method is the ideal place for this. Here, you will connect your `HandleSecurityThreat` and `HandleRASPExecutionStatus` functions and set the configuration parameters for freeRASP.

{% hint style="success" %}
Detailed explanations of each configuration option are available on the [Android API](https://docs.talsec.app/freerasp/freerasp/integration/android/api) and [iOS API](https://docs.talsec.app/freerasp/freerasp/integration/ios/api) pages.

***Configuration Options:** AppBundleIds, AppTeamId, PackageName, SigningCertificates, AlternativeStores, WatcherEmail and IsProduction*
{% endhint %}

Example `MyPlayerController.cpp`:

{% code fullWidth="false" %}

```cpp
#include "AFreeRASPPlayerController.h" // Include your header file
#include "FreeRASPPluginLibrary.h" // Include the plugin header

void AFreeRASPPlayerController::BeginPlay()
{
	Super::BeginPlay();

	// Get the FreeRASP plugin library instance
	if (UFreeRASPPluginLibrary* FreeRASPLib = GetGameInstance()->GetSubsystem<UFreeRASPPluginLibrary>())
	{
		// 1. Bind your function to the threat detection event
		// The class name here MUST match the class you are in (e.g., AMyPlayerController)
		FreeRASPLib->OnSecurityThreatDetected.AddDynamic(this, &AFreeRASPPlayerController::HandleSecurityThreat);
		FreeRASPLib->OnRASPExecutionStatus.AddDynamic(this, &AFreeRASPPlayerController::HandleRASPExecutionStatus);
		
		// 2. Prepare the configuration
		// Important: These values are placeholders. Replace them with your actual data.
		
		// iOS Configuration
		TArray<FString> AppBundleIds;
		AppBundleIds.Add(TEXT("com.game.bundle.id"));
		FString AppTeamId = TEXT("1AB2C3");

		// Android Configuration
		FString PackageName = TEXT("com.talsec.free.rasp.game");
		TArray<FString> SigningCertificates;
		SigningCertificates.Add(TEXT("ilx/AtYu7TpAu5cma4JdDXio5bayFSi89axnyOCjfFo="));
		TArray<FString> AlternativeStores;
        AlternativeStores.Add(TEXT("com.samsung.android.apps.galaxyapp"));
		
		// General Configuration
		FString WatcherEmail = TEXT("your_email_address@example.com");
		bool IsProduction = true; // Set to false for development builds

		// 3. Initialize freeRASP
		FreeRASPLib->InitializeTalsec(
			AppBundleIds,
			AppTeamId,
			PackageName,
			SigningCertificates,
			AlternativeStores,
			WatcherEmail,
			IsProduction
		);
	}
}
```

{% endcode %}

#### Handler Implementation (.cpp)

Finally, implement the logic for the `HandleSecurityThreat` function itself. This part of the code decides what happens when a specific threat is detected.

Example `FreeRASPPlayerController.cpp`:

```cpp
void AFreeRASPPlayerController::HandleSecurityThreat(ThreatType ThreatType)
{
    UE_LOG(LogTemp, Warning, TEXT("Security threat detected: %d"), ThreatType);
    switch (ThreatType) {
    case ThreatType::OnPrivilegedAccess:
        UE_LOG(LogTemp, Warning, TEXT("Privileged access threat detected"));
        break;
    case ThreatType::OnAppIntegrity:
        UE_LOG(LogTemp, Warning, TEXT("App integrity threat detected"));
        break;
    case ThreatType::OnDebug:
        UE_LOG(LogTemp, Warning, TEXT("Debug threat detected"));
        break;
    case ThreatType::OnSimulator:
        UE_LOG(LogTemp, Warning, TEXT("Simulator threat detected"));
        break;
    case ThreatType::OnUnofficialStore:
        UE_LOG(LogTemp, Warning, TEXT("Unofficial store threat detected"));
        break;
    case ThreatType::OnHookDetected:
        UE_LOG(LogTemp, Warning, TEXT("Hook threat detected"));
        break;
    case ThreatType::OnDeviceBinding:
        UE_LOG(LogTemp, Warning, TEXT("Device binding threat detected"));
        break;
    case ThreatType::OnDeviceID:
        UE_LOG(LogTemp, Warning, TEXT("Device ID threat detected"));
        break;
    case ThreatType::OnObfuscationIssues:
        UE_LOG(LogTemp, Warning, TEXT("Obfuscation issues threat detected"));
        break;
    case ThreatType::OnScreenshot:
        UE_LOG(LogTemp, Warning, TEXT("Screenshot threat detected"));
        break;
    case ThreatType::OnScreenRecording:
        UE_LOG(LogTemp, Warning, TEXT("Screen recording threat detected"));
        break;
    case ThreatType::OnPasscode:
        UE_LOG(LogTemp, Warning, TEXT("Passcode threat detected"));
        break;
    case ThreatType::OnPasscodeChange:
        UE_LOG(LogTemp, Warning, TEXT("Passcode change threat detected"));
        break;
    case ThreatType::OnSecureHardwareNotAvailable:
        UE_LOG(LogTemp, Warning, TEXT("Secure hardware not available threat detected"));
        break;
    case ThreatType::OnDevMode:
        UE_LOG(LogTemp, Warning, TEXT("Dev mode threat detected"));
        break;
    case ThreatType::OnADBEnabled:
        UE_LOG(LogTemp, Warning, TEXT("ADB enabled threat detected"));
        break;
    case ThreatType::OnSystemVPN:
        UE_LOG(LogTemp, Warning, TEXT("System VPN threat detected"));
        break;
    case ThreatType::OnMultiInstance:
        UE_LOG(LogTemp, Warning, TEXT("Multi instance threat detected"));
        break;
    case ThreatType::OnUnsecureWifi:
        UE_LOG(LogTemp, Warning, TEXT("Unsecure WiFi threat detected"));
        break;
    case ThreatType::OnTimeSpoofing:
        UE_LOG(LogTemp, Warning, TEXT("Time spoofing threat detected"));
        break;
    case ThreatType::OnLocationSpoofing:
        UE_LOG(LogTemp, Warning, TEXT("Location spoofing threat detected"));
        break;
    case ThreatType::Unknown:
        UE_LOG(LogTemp, Warning, TEXT("Unknown threat detected"));
        break;
    }
}
```

Next, implement the logic for the `HandleRASPExecutionStatus` function. This callback is triggered once freeRASP has completed all its security checks.

```cpp
void AFreeRASPPlayerController::HandleRASPExecutionStatus(RASPExecutionStatus RASPStatus)
{
    switch (RASPStatus) {
    case RASPExecutionStatus::Finished:
        UE_LOG(LogTemp, Warning, TEXT("RASP execution finished - all checks completed"));
        break;
    }
}
```

{% endstep %}
{% endstepper %}

## 🖥️ Check Talsec Portal

Check out [data-visualisation-portal](https://docs.talsec.app/freerasp/freerasp/data-visualisation-portal "mention") and register using your [watcherMail](https://docs.talsec.app/freerasp/freerasp/wiki/role-of-watchermail) to see your data. If you integrated the SDK successfully, the application will be present **after a few hours**. The visualisations will be active later due to the bucketing mechanism.

{% hint style="warning" %}
You have to use the **same email for the Portal** as you used for the **watcherMail** parameter.
{% endhint %}
