# 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="/files/rPNSS54V1Q7EHqGsbDX5" 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](/freerasp/freerasp/integration/android/api.md) and [iOS API](/freerasp/freerasp/integration/ios/api.md) 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](/freerasp/freerasp/data-visualisation-portal.md) and register using your [watcherMail](/freerasp/freerasp/wiki/role-of-watchermail.md) 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.talsec.app/freerasp/freerasp/integration/unreal-engine.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
