
Chargeur PE réflexif écrit en Zig. Charge et exécute des fichiers PE natifs et .NET directement depuis la mémoire.
Chargeur PE réflexif écrit en Zig. Charge et exécute des fichiers PE natifs et .NET directement depuis la mémoire.
__security_cookie pour la sécurité de la mémoire tampon /GS)SetProcessValidCallTargetsFonctions utilitaires pour résoudre les exportations d'une image PE chargée :
getExportByName(base, ntheaders, name) — résolution par nomgetExportByOrdinal(base, ntheaders, ordinal) — résolution par ordinalGère automatiquement les exportations redirigées en chargeant la DLL cible (par exemple, "NTDLL.RtlAllocateHeap" se résout en la fonction réelle dans ntdll.dll).
Résout automatiquement les ensembles d'API Windows (api-ms-win-*, ext-ms-win-*) vers leurs DLL hôtes réelles en utilisant le ApiSetMap du PEB. Cela permet de charger des PE qui importent depuis des DLL d'API virtuelles.
utils.detect_platform(buffer) — Détecte si le PE est 32 ou 64 bitsutils.is_dotnet_assembly(ntheaders) — Vérifie si le PE est un assembly .NETutils.getDotNetVersion(buffer) — Extrait la chaîne de version du runtime .NET depuis les métadonnéesutils.rvaToFileOffset(buffer, rva) — Convertit une RVA en décalage fichier brutClonez le dépôt :
git clone https://github.com/Thoxy67/zig-pe.git
cd zig-pe
Construisez le projet :
zig build
zig build -Ddotnet=false # Désactiver le support .NET (activé par défaut)
zig build # Construire toutes les cibles
zig build run-putty64 # Exécuter l'exemple PE natif 64 bits
zig build run-putty32 # Exécuter l'exemple PE natif 32 bits
zig build run-dotnet # Exécuter l'exemple d'assembly .NET
zig build test # Exécuter les tests unitaires
const pe = @import("pe");
pub fn main() !void {
// Charger et exécuter un fichier PE intégré
try pe.RunPE.init(@embedFile("bin/app.exe")).run();
}
const pe = @import("pe");
pub fn main() !void {
var loader = pe.RunPE.init(@embedFile("bin/app.exe"));
try loader.runWithArgs(&.{ "arg1", "arg2", "arg3" });
}
const std = @import("std");
const pe = @import("pe");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const file_content = try std.fs.cwd().readFileAlloc(
allocator,
"path/to/executable.exe",
std.math.maxInt(usize),
);
defer allocator.free(file_content);
try pe.RunPE.init(file_content).run();
}
const pe = @import("pe");
// Après avoir chargé une DLL en mémoire...
const base: [*]const u8 = @ptrCast(loaded_base);
const ntheaders = // ... obtenir les en-têtes NT
// Résolution par nom
if (pe.getExportByName(base, ntheaders, "ExportedFunction")) |func_ptr| {
const func: *const fn () void = @ptrCast(@alignCast(func_ptr));
func();
}
// Résolution par ordinal
if (pe.getExportByOrdinal(base, ntheaders, 42)) |func_ptr| {
// Utiliser le pointeur de fonction
}
GetCommandLineW() retourne les arguments fournisMain(string[] args) via l'invocation CLRCe projet implique le chargement et l'exécution de code arbitraire, ce qui peut être potentiellement dangereux. N'utilisez ce chargeur qu'avec des fichiers PE de confiance et dans des environnements contrôlés. Les auteurs ne sont pas responsables de toute utilisation abusive ou des dommages causés par ce logiciel.
Les contributions à zig-pe sont les bienvenues ! N'hésitez pas à soumettre des pull requests, à créer des issues ou à faire passer le mot.
git checkout -b feature/AmazingFeature)git commit -m 'Ajout d'une fonctionnalité incroyable')git push origin feature/AmazingFeature)Ce projet est sous licence MIT – voir le fichier LICENSE pour plus de détails.
Ce projet est uniquement à des fins éducatives. Assurez-vous de disposer des droits et autorisations nécessaires avant de charger et d'exécuter un fichier PE.
| Architecture | Code machine | Bitness |
|---|
| i386 | 0x014c | 32 bits |
| AMD64 | 0x8664 | 64 bits |
| IA64 | 0x0200 | 64 bits |
| ARM (ARMNT) | 0x01C4 | 32 bits |
| ARM64 | 0xAA64 | 64 bits |