Eine DLL oder Datendatei, die Ihre Anwendung auf die Festplatte schreibt, ist aus Sicht eines Angreifers der einfache Fall. Sie ist eine kopierbare Datei in einem Ordner. Sie lässt sich in einem Disassembler öffnen, während Ihr Programm nicht einmal läuft, patchen und zurücktauschen, und sie bleibt auf der Festplatte, lange nachdem die Sitzung, die sie brauchte, beendet ist.
In-Memory-Laden ist die Antwort auf dieses Problem: Das sensible Modul wird aus einer verschlüsselten Quelle in den laufenden Prozess abgebildet, sodass die lauffähigen Bytes im Klartext nie auf die Festplatte geschrieben werden. Dieser Leitfaden erklärt, warum sich Dateien auf der Festplatte leicht abgreifen lassen, was In-Memory-Laden tatsächlich tut, wie PapelShip Dateien in den Speicher abbildet, wo die Technik an ihre Grenzen stößt und womit Sie sie kombinieren sollten.
Warum sich Dateien auf der Festplatte leicht abgreifen lassen
Die Schwäche einer Datei auf der Festplatte liegt nicht in einem einzelnen Fehler, sondern in allem, was es heißt, eine Datei zu sein. Sobald sensible Logik als Bytes in einem Ordner ausgeliefert wird, kommen vier Probleme gleichzeitig mit.
- Kopierbar. Eine Datei sind nur Bytes auf der Festplatte; wer den Ordner lesen kann, kann sie anderswo mitnehmen.
- Im Ruhezustand untersuchbar. Eine DLL auf der Festplatte lässt sich in einem Disassembler öffnen, ohne dass das Programm je läuft.
- Patchbar. Die Datei lässt sich verändern und zurücktauschen, sodass sich das Verhalten des Programms beim nächsten Start ändert.
- Dauerhaft vorhanden. Sie bleibt auf der Festplatte, nachdem die App geschlossen wurde, und wartet darauf, gefunden zu werden, lange nachdem die Sitzung, die sie brauchte, beendet ist.
Als Datei auf der Festplatte ausgeliefert
- Eine kopierbare Datei in einem Ordner
- Im Ruhezustand für statische Werkzeuge lesbar
- Kann gepatcht und zurückgetauscht werden
- Bleibt zurück, nachdem die App geschlossen wurde
Im Speicher abgebildet
- Keine Klartextdatei auf der Festplatte
- Nur im laufenden Prozess entschlüsselt
- Weg, sobald der Prozess beendet wird
- Nur an eine authentifizierte Sitzung ausgeliefert
Die Lücke zwischen diesen beiden Spalten ist das ganze Argument für In-Memory-Laden. Eine Datei auf der Festplatte ist jedem zugänglich, der Zugriff auf den Rechner hat, jederzeit, egal ob Ihr Programm läuft oder nicht. Ein Modul, das nur innerhalb eines laufenden, authentifizierten Prozesses existiert, ist für ein weit engeres Zeitfenster verfügbar, für einen weit engeren Personenkreis, und es hinterlässt danach nichts, was man in Ruhe untersuchen könnte.
Was In-Memory-Laden tatsächlich tut
Wenn ein Programm eine normale DLL verwendet, liest das Betriebssystem diese DLL von der Festplatte und bildet sie in den Speicher des Programms ab, damit der Prozessor sie ausführen kann. In-Memory-Laden übernimmt den Abbildungsschritt selbst: Es nimmt das Modul aus einer verschlüsselten Quelle und legt es direkt im Adressraum des Prozesses an, sodass die lauffähigen Bytes im Klartext nie als Datei auf die Festplatte geschrieben werden. Das Feature Map Files von PapelShip funktioniert wie ein PE-Loader und bildet Ihre Dateien in den Speicher ab. Der Pfad für die Ausführung im Speicher kann verschlüsselte DLLs in den Speicher streamen, ohne Bytes auf die Festplatte zu schreiben.
Die praktische Wirkung: Die einfachen Angriffe verschwinden. Es gibt keine Datei in einem Ordner mehr, die man kopieren könnte, nichts auf der Festplatte, das ein statisches Werkzeug im Ruhezustand öffnen könnte, und nichts, das beim Beenden des Prozesses zurückbleibt. Ein Angreifer muss gegen einen laufenden Prozess arbeiten statt gegen eine ruhende Datei, und das ist eine deutlich höhere Hürde.
Das Wort „sicher“ verdient eine genaue Betrachtung. Eine Datei nur in den Speicher abzubilden ist für sich genommen eine Ladetechnik; die Sicherheit entsteht dadurch, wo die Bytes beginnen und wie sie unterwegs geschützt sind. Bei PapelShip wird das Modul auf dem Server verschlüsselt gespeichert und nur an einen Client gesendet, der sich bereits authentifiziert hat. Das Abbilden in den Speicher ist also das Ende eines geschützten Pfads und kein Trick, der auf eine ungeschützt herumliegende Datei angewendet wird.
Wie PapelShip Dateien in den Speicher abbildet
Bei PapelShip baut das auf der serverseitigen Auslieferung auf. Das Modul wird verschlüsselt auf dem Server gehalten und nur an eine authentifizierte Lizenz ausgeliefert, so wie serverseitige Strings und Dateien funktionieren. Danach wird es in den Prozess abgebildet, statt auf der Festplatte zu landen. Der Ablauf ist kurz.
- 01
Authentifizieren
Die App startet eine Sitzung und authentifiziert die Lizenz für dieses Gerät. Vor einem erfolgreichen Ergebnis wird nichts Geschütztes ausgeliefert.
- 02
Das Modul anfordern
Der authentifizierte Client fordert das verschlüsselte Modul über den geschützten Kanal vom Server an.
- 03
Verschlüsselt streamen
Die Bytes kommen verschlüsselt an. Irgendwo auf dem Weg wird keine Klartextkopie in eine Datei geschrieben.
- 04
In den Speicher abbilden
Map Files legt das Modul im Adressraum des Prozesses an, wie es ein PE-Loader täte, sodass es lauffähig ist.
- 05
Ausführen, dann verwerfen
Das Modul läuft für die Dauer der Sitzung aus dem Speicher und ist verschwunden, sobald der Prozess beendet wird.
Für die ausgelieferte ausführbare Datei selbst ergänzt qPapelPacker+ eine weitere Verpackungsschicht, sodass auch das Binary, das ein Kunde herunterlädt, im Ruhezustand schwerer zu lesen ist. In-Memory-Laden schützt die Module, die Sie nach der Authentifizierung ausliefern; Packing schützt den Launcher, der sie anfordert.
Was in den Speicher gehört und was nicht
In-Memory-Laden hat einen Preis: Das Modul muss zur Laufzeit geladen und abgebildet werden, deshalb lohnt es sich, die Methode für die Teile zu reservieren, die tatsächlich zählen. Der Test ist einfach: Würde ein Angreifer etwas Nützliches erfahren oder echten Aufwand sparen, wenn er dies auf der Festplatte läse? Wenn ja, ist es ein Kandidat für die Auslieferung im Speicher. Wenn nicht, rechtfertigt die Komplexität ihren Aufwand nicht.
- Gute Kandidaten: Module mit Ihrer eigentlichen Logik, Premium-Funktionen oder dem Code, der festlegt, was eine Lizenz darf.
- Ebenfalls besser serverseitig: Schlüssel, URLs und Konstanten gehören in serverseitige Strings und Dateien statt in irgendeine Client-Datei.
- Auf der Festplatte meist in Ordnung: große, nicht sensible Assets und alles, was ohnehin öffentlich ist, denn das Abbilden in den Speicher kostet hier Leistung, ohne Schutz zu bringen.
Seien Sie ehrlich über die Grenzen
In-Memory-Laden ist eine Technik, die Angriffe verteuert, kein Zauber. Der lauffähige Code muss im Speicher existieren, damit der Prozessor ihn ausführen kann, und wer die volle Kontrolle über einen Rechner hat, kann grundsätzlich den Speicher eines darauf laufenden Prozesses untersuchen. Das ist eine Eigenschaft, wie Computer funktionieren, und keine Schwäche eines einzelnen Produkts.
Was In-Memory-Laden entfernt, ist der billige, wiederholbare Angriff: eine Datei kopieren, im Ruhezustand lesen, patchen und zurücktauschen. Was es nicht entfernt, ist ein entschlossener Angreifer, der gegen den laufenden Prozess arbeitet. Es als gesamte Verteidigung zu betrachten ist der Fehler; es als eine starke Schicht zu betrachten ist richtig.
Die ehrliche Einordnung ist eine Frage der Wirtschaftlichkeit, nicht der Absolutheit. Schutz heißt, einen Angriff teurer zu machen, als sein Ergebnis wert ist, und zwar lange genug, dass Ihr Produkt bis dahin weiterentwickelt ist. In-Memory-Laden verschiebt dieses Gleichgewicht zu Ihren Gunsten; es beendet das Spiel nicht. Jeder Anbieter, der Ihnen erzählt, ein einziges Feature mache Code unmöglich zu extrahieren, verkauft Zuversicht, keine Sicherheit.
Mit Integritätsprüfungen und qPAnalyzer kombinieren
Ein Modul im Speicher sollte überwacht werden, nicht nur vor der Festplatte verborgen. Zwei Dinge leisten das, und sie lösen andere Probleme als das Abbilden selbst.
Erstens bestätigen Laufzeit-Integritätsprüfungen, dass der Code im Speicher der Code ist, den Sie ausgeliefert haben. qPapel Auth stellt auth.CheckMemoryIntegrity() bereit, das nicht autorisierte Änderungen erkennt, etwa das Patchen von Instruktionen, einschließlich JMP- und NOP-Änderungen, sowie auth.CheckTextIntegrity(), das CRC-, sitzungsbasierte und JMP/NOP-Prüfungen durchführt. Führen Sie sie aus, bevor Sie einem abgebildeten Modul vertrauen.
// Check the running code before using a mapped module.
if (!auth.CheckMemoryIntegrity()) {
// Memory was patched (for example JMP/NOP edits). Stop here.
return;
}
if (!auth.CheckTextIntegrity()) {
// CRC or session-based check failed. Stop here.
return;
}
// Only now request and map the protected module.Zweitens überwacht qPAnalyzer die Umgebung, in der der Prozess läuft, und markiert Dumper, Speicher-Scanner und umbenannte Analysewerkzeuge, die statische Sperrlisten übersehen. Zusammen gilt dann: Die Datei liegt nicht auf der Festplatte, der Code im Speicher wird verifiziert, und die Werkzeuge, die darauf zugreifen wollen, werden erkannt.
In-Memory-Laden
Keine Klartextdatei auf der Festplatte
Serverseitige Auslieferung
Module nur nach der Authentifizierung gesendet
Integritätsprüfungen
Speicher und Code zur Laufzeit verifiziert
qPAnalyzer
Dumper und umbenannte Werkzeuge werden markiert
Das vollständige Bild, wie diese Schichten ineinandergreifen, zeigen der Software-Schutz-Stack für C++ und C# und warum Schutz über statische Sperrlisten hinausgehen muss.
Die Reihenfolge ist genauso wichtig wie die Teile. Zuerst authentifizieren, damit sich nichts Geschütztes bewegt, bevor die Lizenz geprüft ist; dann das Modul verschlüsselt ausliefern und in den Speicher abbilden, damit es keine Datei gibt, die man abgreifen kann; zur Laufzeit verifizieren, damit ein manipuliertes Modul erkannt wird; und die Umgebung überwachen, damit die Werkzeuge, die es angreifen würden, markiert werden. Jeder Schritt setzt den vorherigen voraus, weshalb sich die Schritte gemeinsam lohnen und nicht einzeln.
Häufig gestellte Fragen
auth.CheckMemoryIntegrity() und auth.CheckTextIntegrity(), damit ein abgebildetes Modul als unverändert bestätigt ist, bevor Sie ihm vertrauen.Die wertvollen Teile von der Festplatte fernhalten
In-Memory-Laden ist eine einfache Idee mit einem echten Nutzen: Die Teile Ihres Produkts, die sich zu stehlen lohnen, werden nie auf die Festplatte geschrieben, wo sie leicht abzugreifen sind. Bilden Sie sie aus einer verschlüsselten, authentifizierten Quelle in den Speicher ab, verifizieren Sie sie zur Laufzeit und lassen Sie qPAnalyzer die Umgebung um sie herum überwachen.
Keine dieser Maßnahmen macht Ihren Code unantastbar, und jede ehrliche Darstellung von Software-Schutz sagt das auch. Was sie leistet: Sie verwandelt einen schnellen Kopierjob in einen langen, ungewissen, und das ist für die meisten Produkte genau der richtige Tausch.
qPapel-Security-Team
Lizenzierung und Softwareschutz