Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
pe-signgen — Génération universelle de signatures pour toute fonction système de toutes les builds Windows à l'aide de Winbindex | Kitploit
Outils/GitHubGitHub/forentfraps/pe-signgen
Analyse StatiqueAnalyse des VulnérabilitésRétro-ingénierieAnalyse ForensiqueAnalyse de MalwareAnalyse de Binaires
GitHubforentfraps/pe-signgen

pe-signgen

Génération universelle de signatures pour toute fonction système de toutes les builds Windows à l'aide de Winbindex

Voir le dépôt
20il y a 8 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
Site web

pe-signgen

Signatures binaires multi-versions et offsets RVA pour les fonctions Windows PE


Vue d'ensemble

pe-signgen est un outil destiné aux ingénieurs en rétro-ingénierie et aux chercheurs en sécurité qui génère automatiquement :

  • Signatures binaires (motifs d'octets avec jokers) pour les fonctions non exportées et exportées
  • Offsets RVA et offsets fichier pour localiser les fonctions directement dans les binaires
  • Signatures multi-builds fonctionnant sur de nombreuses versions de Windows
  • Plusieurs formats de sortie optimisés pour différents cas d'usage
  • Prise en charge des architectures x64, ARM64 et WoW64

L'idée centrale est de fournir un moyen systématique et robuste d'accéder aux fonctions non exportées sur les builds Windows 10/11. L'outil s'appuie sur :

  • Winbindex pour les métadonnées des builds Windows
  • Les serveurs de symboles publics de Microsoft pour les PDB
  • Un cache local pour des workflows reproductibles et utilisables hors ligne

⚠️ Prise en charge des versions Windows pe-signgen prend en charge uniquement Windows 10 et Windows 11. Il s'agit d'un choix de conception délibéré : Winbindex ne fournit pas de données complètes pour les versions plus anciennes.


Cas d'usage

  • Internes Windows non exportés Générer des signatures pour des fonctions comme LdrpInitializeTls, RtlpInsertInvertedFunctionTableEntry, etc.

  • Recherche sur le game hacking / l'anti-triche Générer des signatures stables qui survivent aux mises à jour des jeux

  • Recherche en sécurité Localiser les routines critiques pour la sécurité sur différents builds Windows

  • Automatisation Génération scriptable de signatures et d'offsets pour des ensembles entiers d'API internes


Formats de sortie

pe-signgen fournit trois formats de sortie distincts pour différents cas d'usage :

1. Format JSON

Données structurées pour l'automatisation, les scripts et l'intégration avec d'autres outils.```bash pe-signgen --signature ntdll!NtCreateFile -o ntcreatefile.json --output-format json

root@kitploit:~
**Structure de sortie :**```json
{
  "dll_name": "ntdll",
  "function_name": "NtCreateFile",
  "architecture": "x64",
  "generated": "2024-12-11T15:30:00.123456",
  "total_builds": 1247,
  "unique_signatures": 3,
  "signature_groups": [
    {
      "matched_symbol": "NtCreateFile",
      "signature": "4C 8B DC 49 89 5B 08 49 89 6B 10 49 89 73 18 ...",
      "length": 48,
      "build_count": 845,
      "versions": [
        { "major": 10240, "minor": 16384, "build": "10240.16384" },
        { "major": 10586, "minor": 0, "build": "10586.0" }
      ]
    }
  ]
}

Notes :

  • major et minor sont dérivés de la chaîne de build en la divisant au premier .. Exemple : "10240.16384" → major = 10240, minor = 16384.
  • build est la chaîne de build d’origine utilisée comme clé interne.

2. Format binaire (WSIG/WOFF)

Formats binaires compacts, prêts à l’exécution, optimisés pour les systèmes embarqués et l’analyse à faible surcharge.

Ils correspondent à la disposition sur disque implémentée dans write_wsig() et write_woff().


Format WSIG (signature Windows)

Magic : WSO\0 (0x57 0x53 0x4F 0x00) Version actuelle : 1 Objectif : stocker des signatures binaires avec masques génériques (wildcards) et les versions de build Windows associées

Structure du fichier (conceptuelle)```

┌─────────────────────────────────────┐ │ Header (36 bytes) │ ├─────────────────────────────────────┤ │ DLL Name (variable) │ ├─────────────────────────────────────┤ │ Function Name (variable) │ ├─────────────────────────────────────┤ │ Signature / Mask / Build blobs │ ← Arbitrary order, see notes ├─────────────────────────────────────┤ ← Aligned to 4 bytes │ Groups Table (24 × N bytes) │ └─────────────────────────────────────┘

root@kitploit:~
**Notes importantes sur la disposition (correspond à `write_wsig`)**

* Après l'en-tête, les noms de DLL et de fonction sont écrits sous forme d'octets UTF‑8.
* Pour chaque groupe de signatures, les octets de motif et les octets de masque sont écrits, suivis du tableau de build pour ce groupe.
* Ces régions par groupe ne sont **pas** regroupées globalement par type : les motifs, les masques et les tableaux de build peuvent être entrelacés.
* Le builder s'aligne sur **4 octets** avant chaque tableau de build et avant la table des groupes. Cela peut introduire du remplissage.
* Les consommateurs doivent **toujours** suivre les décalages dans l'en-tête et les entrées de groupe ; ne **pas** se fier au diagramme conceptuel pour la contiguïté physique.

##### Disposition de l'en-tête (36 octets)```c
// Packed as: "<4sIIIIIIII" (little-endian)

typedef struct {
    char     magic[4];   // "WSO\0" (WSIG_MAGIC)
    uint32_t version;    // FORMAT_VERSION (currently 1)
    uint32_t arch;       // Architecture code (1=x64, 2=ARM64, 3=WoW64)
    uint32_t dll_off;    // Offset to DLL name string
    uint32_t dll_len;    // Length of DLL name in bytes
    uint32_t func_off;   // Offset to function name string
    uint32_t func_len;   // Length of function name in bytes
    uint32_t group_count;// Number of signature groups
    uint32_t groups_off; // Offset to groups table
} wsig_header_t; // 36 bytes
Entrée de groupe (24 octets)

Chaque groupe de signatures représente un motif unique qui s'applique à une ou plusieurs builds Windows.```c // Packed as: "<IIIIII" (little-endian)

typedef struct { uint32_t sig_off; // Offset to signature pattern bytes uint32_t sig_len; // Length of signature pattern (in bytes) uint32_t mask_off; // Offset to wildcard mask bytes uint32_t mask_len; // Length of wildcard mask (≈ ceil(sig_len/8)) uint32_t builds_off; // Offset to build version array uint32_t build_cnt; // Number of builds using this signature } wsig_group_t; // 24 bytes

root@kitploit:~
##### Entrée de version de build (8 octets)

Chaque entrée de version de build identifie une version Windows spécifique qui utilise cette signature.```c
typedef struct {
    uint32_t major; // e.g. 19041
    uint32_t minor; // e.g. 1234
} wsig_build_t; // 8 bytes

major et minor proviennent de la décomposition de la chaîne de build (« A.B » → A, B). La chaîne de build d'origine n'est pas stockée dans le format binaire ; si vous en avez besoin, conservez-la en externe (elle est présente dans la sortie JSON).

Format du masque générique (wildcard)

Le masque est un masque de bits (bitmask) où chaque bit correspond à un octet du motif de signature :

  • Bit = 1 : L'octet doit correspondre exactement (octet fixe)
  • Bit = 0 : L'octet est générique (ignorer cet octet lors de la correspondance)

Exemple :``` Signature: 4C 8B DC 49 89 ?? 08 49 Mask bits: 1 1 1 1 1 0 1 1 (MSB first within each byte) Mask byte: 0xBF (binary: 10111111)

root@kitploit:~
Les octets de masque sont stockés et interprétés selon **l'ordre des bits little-endian** au sein de chaque octet (exactement comme dans les helpers C et `parse_signature`) :```c
uint8_t bit = (mask_bytes[byte_index >> 3] >> (byte_index & 7)) & 1u;
Stockage des chaînes
  • Les noms de DLL et de fonctions sont stockés en UTF‑8, sans terminateurs nul.
  • Utilisez *_len pour déterminer la longueur ; ne lisez pas au-delà.
  • Il n'y a aucune exigence d'alignement pour les chaînes elles-mêmes.
  • Les régions de données supplémentaires (tableaux de builds et table des groupes) sont alignées sur des limites de 4 octets ; traitez tout remplissage comme opaque.

Format WOFF (offset Windows)

Magic : WOF\0 (0x57 0x4F 0x46 0x00) Version actuelle : 1 Objectif : Stocker les RVA directes et les offsets de fichier pour les fonctions à travers les builds Windows

Structure du fichier```

┌─────────────────────────────────────┐ │ Header (36 bytes) │ ├─────────────────────────────────────┤ │ DLL Name (variable) │ ├─────────────────────────────────────┤ │ Function Name (variable) │ ├─────────────────────────────────────┤ │ Matched Symbol Names (variable) │ ← One UTF‑8 string per entry ├─────────────────────────────────────┤ ← Aligned to 4 bytes │ Entries Table (32 × N bytes) │ └─────────────────────────────────────┘

root@kitploit:~
Détails de mise en page (correspond à `write_woff`) :

* Après l'espace réservé de l'en-tête, les noms de DLL et de fonctions sont écrits sous forme d'octets UTF‑8.
* Pour chaque build, le nom de symbole correspondant est écrit sous forme de chaîne UTF‑8 (sans terminateur). Ceux-ci forment un simple pool de chaînes.
* L'écrivain aligne ensuite sur 4 octets et écrit la table d'entrées à taille fixe.
* Chaque entrée contient des décalages (`matched_off`, `matched_len`) pointant vers ce pool de chaînes.

##### Mise en page de l'en-tête (36 octets)```c
// Packed as: "<4sIIIIIIII" (little-endian)

typedef struct {
    char     magic[4];   // "WOF\0" (WOFF_MAGIC)
    uint32_t version;    // FORMAT_VERSION (currently 1)
    uint32_t arch;       // Architecture code (1=x64, 2=ARM64, 3=WoW64)
    uint32_t dll_off;    // Offset to DLL name string
    uint32_t dll_len;    // Length of DLL name in bytes
    uint32_t func_off;   // Offset to function name string
    uint32_t func_len;   // Length of function name in bytes
    uint32_t entry_cnt;  // Number of offset entries
    uint32_t entries_off;// Offset to entries table
} woff_header_t; // 36 bytes
Entrée d'offset (32 octets)

Chaque entrée fait correspondre une build Windows à l'emplacement de la fonction dans cette build.```c // Packed as: "<IIQQII" (little-endian)

typedef struct { uint32_t major; // Windows major version (e.g., 19041) uint32_t minor; // Windows minor version (e.g., 1234) uint64_t rva; // Relative Virtual Address in the DLL uint64_t file_offset; // Raw file offset in the DLL on disk uint32_t matched_off; // Offset to matched symbol name string uint32_t matched_len; // Length of matched symbol name } woff_entry_t; // 32 bytes

root@kitploit:~
##### Remarques d'utilisation

* **RVA** est le décalage mémoire lorsque la DLL est chargée à sa base préférée.
* **Décalage de fichier** est la position brute dans le fichier PE sur le disque.
* **Symbole correspondant** peut différer de la fonction demandée (p. ex., exports transférés).
  La chaîne est stockée une seule fois dans le pool de chaînes ; `matched_off`/`matched_len` y font référence.
* Les entrées sont triées par version de build (majeure, puis mineure) pour une recherche efficace.

---

#### Codes d'architecture

Les deux formats binaires utilisent le même encodage d'architecture (via `ARCH_CODE_MAP`) :

| Code | Architecture | Description                  |
| ---- | ------------ | ---------------------------- |
| 1    | x64          | AMD64/Intel64 64 bits        |
| 2    | ARM64        | ARM 64 bits (AArch64)        |
| 3    | WoW64        | x86 32 bits sur Windows 64 bits |

Les chaînes d'architecture inconnues sont définies par défaut sur `1` (x64) en interne ; la CLI limite les valeurs à l'ensemble pris en charge.

---

### 3. **Format d'en-tête C**

En-têtes C prêts à compiler avec des structures à sécurité de type et des tableaux de données.

`pe-signgen` peut générer deux *types* d'en-têtes C :

* **En-têtes WSIG** – pour les données de signature et de masque (depuis `write_wsig_header`).
* **En-têtes WOFF** – pour les tables directes RVA/décalage de fichier (depuis `write_woff_header`).

L'option `--output-format cheader` sélectionne les en-têtes C ; en la combinant avec `--offsets`, on alterne entre les variantes WSIG et WOFF.

#### En-tête C WSIG```bash
pe-signgen --signature ntdll!RtlpInitializeThreadActivationContextStack \
  -o rtlp_init_actx.h --output-format cheader

Structure d'en-tête générée (simplifiée, correspond à write_wsig_header) :```c /* Auto-generated WSIG header for ntdll ! RtlpInitializeThreadActivationContextStack ! x64. */ #ifndef WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_H #define WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_H

#include <stdint.h> #include <stddef.h>

#define WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_DLL_NAME "ntdll" #define WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_FUNCTION_NAME "RtlpInitializeThreadActivationContextStack" #define WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_ARCH "x64"

/* Per-version build identifier. */ typedef struct { uint32_t major; uint32_t minor; } WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_version_t;

/* Signature group entry. */ typedef struct { const uint8_t *pattern; const uint8_t *mask; uint32_t length; uint32_t build_count; const WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_version_t *versions; } WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group_t;

/* One pattern/mask/versions triple per group. / static const uint8_t WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_pattern[] = { / ... / }; static const uint8_t WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_mask[] = { / ... / }; static const WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_version_t WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_versions[] = { { 10240u, 16384u }, / 10240.16384 / / ... */ };

static const WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group_t WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_GROUPS[] = { { WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_pattern, WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_mask, (uint32_t)(sizeof(WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_pattern) / sizeof(WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_pattern[0])), (uint32_t)(sizeof(WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_versions) / sizeof(WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_versions[0])), WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group0_versions }, /* group 0 (RtlpInitializeThreadActivationContextStack) / / ... */ };

static const size_t WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_GROUP_COUNT = sizeof(WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_GROUPS) / sizeof(WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_GROUPS[0]);

#endif /* WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_H */

root@kitploit:~
**Exemple d'intégration (corrigé pour correspondre aux types générés) :**```c
#include "rtlp_init_actx.h"

static inline int match_byte(uint8_t want, uint8_t got,
                             const uint8_t *mbits, uint32_t i) {
    uint8_t bit = (mbits[i >> 3] >> (i & 7)) & 1u;
    return bit ? (want == got) : 1;
}

static const uint8_t *
find_signature(const uint8_t *base, size_t size,
               const uint8_t *pattern,
               const uint8_t *mbits,
               uint32_t sig_len) {
    if (!base || !pattern || !mbits || sig_len == 0)
        return NULL;
    if (size < sig_len)
        return NULL;

    // Find first non-wildcard byte as anchor
    uint32_t anchor = sig_len;
    for (uint32_t i = 0; i < sig_len; ++i) {
        if ((mbits[i >> 3] >> (i & 7)) & 1u) {
            anchor = i;
            break;
        }
    }
    if (anchor == sig_len)
        return base; // all wildcards

    const uint8_t anchor_val = pattern[anchor];
    const size_t last_pos = size - (size_t)sig_len;

    for (size_t pos = 0; pos <= last_pos; ++pos) {
        if (base[pos + anchor] != anchor_val)
            continue;

        uint32_t i = 0;
        for (; i < sig_len; ++i) {
            if (!match_byte(pattern[i], base[pos + i], mbits, i))
                break;
        }
        if (i == sig_len)
            return base + pos;
    }
    return NULL;
}

static void
fetch_signature(uint32_t major, uint32_t minor,
                const WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group_t *groups,
                size_t group_len,
                const uint8_t **signature_dest,
                const uint8_t **mask_dest,
                uint32_t *signature_len_dest) {
    *signature_dest = NULL;
    *mask_dest = NULL;
    *signature_len_dest = 0;

    const WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group_t *closest = NULL;
    uint32_t best_distance = 0xFFFFFFFFu;

    for (size_t gi = 0; gi < group_len; ++gi) {
        const WSIG_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_group_t *g = &groups[gi];
        for (uint32_t vi = 0; vi < g->build_count; ++vi) {
            uint32_t m = g->versions[vi].major;
            uint32_t n = g->versions[vi].minor;

            uint32_t distance = (m > major ? m - major : major - m) * 10000u +
                                (n > minor ? n - minor : minor - n);

            if (distance < best_distance) {
                best_distance = distance;
                closest = g;
            }

            if (m == major && n == minor) {
                *signature_dest = g->pattern;
                *mask_dest = g->mask;
                *signature_len_dest = g->length;
                return;
            }
        }
    }

    if (closest) {
        *signature_dest = closest->pattern;
        *mask_dest = closest->mask;
        *signature_len_dest = closest->length;
    }
}

Vous pouvez ensuite brancher cela dans votre propre code spécifique au chargeur (par exemple en utilisant GetModuleHandleA, en parcourant les sections PE, etc.). L'en-tête ne fournit intentionnellement que des données ; les fonctions utilitaires restent à la charge du consommateur.

En-tête WOFF en C

Pour les cas d'utilisation reposant uniquement sur des offsets, write_woff_header génère un petit en-tête décrivant une table triée d'entrées (major, minor, rva, file_offset).

Disposition (correspond à write_woff_header):```c /* Auto-generated WOFF header for ntdll ! RtlpInitializeThreadActivationContextStack ! x64. */ #ifndef WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_H #define WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_H

#include <stdint.h> #include <stddef.h>

#define WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_DLL_NAME "ntdll" #define WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_FUNCTION_NAME "RtlpInitializeThreadActivationContextStack" #define WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_ARCH "x64"

/* Per-build offset entry. */ typedef struct { uint32_t major; uint32_t minor; uint64_t rva; uint64_t file_offset; } WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_entry_t;

static const WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_entry_t WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_ENTRIES[] = { { 10240u, 16384u, 0x5B195ULL, 0x5A595ULL }, /* 10240.16384 (RtlpInitializeThreadActivationContextStack) / / ... (sorted by major, then minor) ... */ };

static const size_t WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_ENTRY_COUNT = sizeof(WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_ENTRIES) / sizeof(WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_ENTRIES[0]);

#endif /* WOFF_NTDLL_RTLPINITIALIZETHREADACTIVATIONCONTEXTSTACK_X64_H */

root@kitploit:~
Cela est utile lorsque vous faites confiance aux offsets eux-mêmes et n'avez pas besoin de correspondance de motifs.

---

## Installation

### Prérequis

* Python 3.8+
* Git
* Connexion Internet (première exécution)
* ~10 Go d'espace disque pour le cache complet

### Installer via Pip```bash
pip install pe-signgen

Installer à partir des sources```bash

git clone https://github.com/forentfraps/pe-signgen.git cd pe-signgen pip install -r requirements.txt pip install -e .

root@kitploit:~
---

## Démarrage rapide

### Générer une signature```bash
pe-signgen --signature ntdll!LdrLoadDll

Générer les offsets```bash

pe-signgen --signature kernel32!CreateFileW --offsets

root@kitploit:~
### Enregistrer en JSON```bash
pe-signgen --signature ntdll!NtCreateFile -o out.json --output-format json

Options de ligne de commande

Syntaxe de base```bash

pe-signgen --signature DLL!FUNCTION [OPTIONS]

root@kitploit:~
### Architecture```bash
--arch x64   # default
--arch arm64
--arch wow64

Filtrage des versions```bash

--os-version win10 # Only Windows 10 --os-version win11 # Only Windows 11 --min-version 10.0 # Minimum version --max-version 11.0 # Maximum version

root@kitploit:~
### Contrôle de la longueur de signature```bash
--min-length 32          # Minimum signature length
--max-length 64          # Maximum signature length

Options de sortie```bash

-o, --output PATH # Output file path --output-format FORMAT # json | binary | cheader --offsets # Generate offsets instead of signatures

root@kitploit:~
### Performances```bash
--workers 16             # Parallel workers (default: CPU count)
--no-cache               # Disable caching
--no-git-update          # Skip Winbindex updates

Verbosité```bash

--verbose # Detailed output --quiet # Minimal output --no-progress # Disable progress bars

root@kitploit:~
---

## Mise en cache

### Disposition du cache```text
~/.cache/pe-signgen/
│
├── dlls/           # Downloaded DLLs
├── pdbs/           # Downloaded PDBs
├── signatures/     # Generated signatures
└── winbindex_data/ # Winbindex metadata

Contrôle du cache```bash

Disable cache for fresh generation

pe-signgen --signature ntdll!NtCreateFile --no-cache

Clear cache

rm -rf ~/.cache/pe-signgen

Custom cache location

export PE_SIGNGEN_CACHE=/custom/path pe-signgen --signature ntdll!NtCreateFile

root@kitploit:~
---

## Performances

**Exemple de performances (CPU 12 cœurs, 100 Mbps) :**

| Opération                         | Temps       |
| --------------------------------- | ----------- |
| Première exécution (sans cache)   | 5–10 min    |
| Exécution en cache                | < 1 sec     |
| Analyse par build                 | 0,1–0,5 sec |
| Exécution complète (1000 builds, 8 workers) | 2–4 min |

**Ressources requises :**

* **Disque :** ~10 Go pour le cache complet DLL/PDB
* **Mémoire :** ~500 Mo d'utilisation maximale
* **Réseau :** plusieurs Go lors de la première exécution

---

## Limitations connues

* **Couverture des versions Windows :** uniquement Windows **10 et 11** (limitation de Winbindex)
* **Disponibilité des builds :** toutes les builds Win10/11 ne sont pas présentes dans Winbindex

---

## Développement```bash
git clone https://github.com/forentfraps/pe-signgen.git
cd pe-signgen
pip install -e ".[dev]"

# Code formatting
black pe_signgen/

# Type checking
mypy pe_signgen/

Licence

Licence MIT – voir LICENSE.


Crédits

  • Winbindex – métadonnées de build Windows par @m417z
  • pefile – bibliothèque d'analyse PE
  • winpdb-rs – liaisons Python pour l'analyse PDB

Inspiré par le besoin de génération de signatures robuste et automatisée pour les API Windows internes.


Contribution

Les contributions sont les bienvenues ! Merci de :

  1. Forker le dépôt
  2. Créer une branche de fonctionnalité
  3. Ajouter des tests pour les nouvelles fonctionnalités
  4. Soumettre une pull request

Support

  • Problèmes : GitHub Issues
  • Discussions : GitHub Discussions
Télécharger l’outil