Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
pe-signgen — Geração universal de assinaturas para qualquer função do sistema de todas as compilações do Windows usando o Winbindex | Kitploit
Ferramentas/GitHubGitHub/forentfraps/pe-signgen
Análise EstáticaAnálise de VulnerabilidadesEngenharia ReversaAnálise ForenseAnálise de MalwareAnálise de Binários
GitHubforentfraps/pe-signgen

pe-signgen

Geração universal de assinaturas para qualquer função do sistema de todas as compilações do Windows usando o Winbindex

Ver Repositório
20há 8 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Site

pe-signgen

Assinaturas binárias entre versões e deslocamentos RVA para funções PE do Windows


Visão Geral

pe-signgen é uma ferramenta para engenheiros reversos e pesquisadores de segurança que gera automaticamente:

  • Assinaturas binárias (padrões de bytes com curingas) para funções não exportadas e exportadas
  • Deslocamentos RVA e de arquivo para localizar funções diretamente em binários
  • Assinaturas entre builds que funcionam em muitas versões do Windows
  • Múltiplos formatos de saída otimizados para diferentes casos de uso
  • Suporte para arquiteturas x64, ARM64 e WoW64

A ideia central é fornecer uma maneira sistemática e robusta de acessar funções não exportadas em builds do Windows 10/11. Ela aproveita:

  • O Winbindex para metadados de builds do Windows
  • Os servidores públicos de símbolos da Microsoft para PDBs
  • Cache local para fluxos de trabalho reproduzíveis e amigáveis offline

⚠️ Suporte a versões do Windows pe-signgen suporta apenas Windows 10 e Windows 11. Esta é uma escolha de design deliberada: o Winbindex não fornece dados completos para versões mais antigas.


Casos de Uso

  • Internos não exportados do Windows Gere assinaturas para funções como LdrpInitializeTls, RtlpInsertInvertedFunctionTableEntry, etc.

  • Pesquisa em game hacking / anti-cheat Gere assinaturas estáveis que sobrevivem a atualizações de jogos

  • Pesquisa de segurança Localize rotinas críticas de segurança em builds do Windows

  • Automação Geração de assinaturas e deslocamentos programável para conjuntos inteiros de APIs internas


Formatos de Saída

pe-signgen fornece três formatos de saída distintos para diferentes casos de uso:

1. Formato JSON

Dados estruturados para automação, scripts e integração com outras ferramentas.```bash pe-signgen --signature ntdll!NtCreateFile -o ntcreatefile.json --output-format json

root@kitploit:~
**Estrutura de saída:**```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" }
      ]
    }
  ]
}

Notas:

  • major e minor são derivados da string de build dividindo no primeiro .. Exemplo: "10240.16384" → major = 10240, minor = 16384.
  • build é a chave da string de build original usada internamente.

2. Formato Binário (WSIG/WOFF)

Formatos binários compactos e prontos para execução otimizados para sistemas embarcados e varredura de baixa sobrecarga.

Eles correspondem ao layout em disco implementado em write_wsig() e write_woff().


Formato WSIG (Assinatura do Windows)

Magic: WSO\0 (0x57 0x53 0x4F 0x00) Versão Atual: 1 Propósito: Armazenar assinaturas binárias com máscaras curinga e versões de build associadas do Windows

Estrutura do Arquivo (conceitual)```

┌─────────────────────────────────────┐ │ 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:~
**Notas importantes de layout (corresponde a `write_wsig`)**

* Após o cabeçalho, os nomes da DLL e da função são escritos como bytes UTF‑8.
* Para cada grupo de assinatura, os bytes de padrão e os bytes de máscara são escritos, seguidos pelo vetor de construção para aquele grupo.
* Essas regiões por grupo **não** são agrupadas globalmente por tipo: padrões, máscaras e vetores de construção podem estar intercalados.
* O construtor alinha a **4 bytes** antes de cada vetor de construção e antes da tabela de grupos. Isso pode introduzir preenchimento.
* Os consumidores devem **sempre** seguir os deslocamentos no cabeçalho e nas entradas de grupo; **não** confie no diagrama conceitual para contiguidade física.

##### Layout do Cabeçalho (36 bytes)```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
Entrada de Grupo (24 bytes)

Cada grupo de assinatura representa um padrão único que se aplica a uma ou mais builds do 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:~
##### Entrada de Versão de Build (8 bytes)

Cada entrada de build identifica uma versão específica do Windows que usa esta assinatura.```c
typedef struct {
    uint32_t major; // e.g. 19041
    uint32_t minor; // e.g. 1234
} wsig_build_t; // 8 bytes

major e minor vêm da divisão da string de build ("A.B" → A, B). A string de build original não é armazenada no formato binário; se precisar dela, mantenha-a externamente (ela está presente na saída JSON).

Formato de Máscara Curinga

A máscara é uma bitmask onde cada bit corresponde a um byte no padrão de assinatura:

  • Bit = 1: O byte deve corresponder exatamente (byte fixo)
  • Bit = 0: O byte é curinga (ignore este byte durante a correspondência)

Exemplo:``` 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:~
Os bytes de máscara são armazenados e interpretados em **ordem de bits little-endian** dentro de cada byte (exatamente como usado nos helpers C e `parse_signature`):```c
uint8_t bit = (mask_bytes[byte_index >> 3] >> (byte_index & 7)) & 1u;
Armazenamento de Strings
  • Os nomes de DLL e funções são armazenados como UTF‑8, sem terminadores nulos.
  • Use *_len para determinar o comprimento; não leia além disso.
  • Não há requisitos de alinhamento para as próprias strings.
  • Regiões adicionais de dados (arrays de build e a tabela de grupos) estão alinhadas a limites de 4 bytes; trate qualquer preenchimento como opaco.

Formato WOFF (Offset do Windows)

Magic: WOF\0 (0x57 0x4F 0x46 0x00) Versão Atual: 1 Propósito: Armazenar RVA diretos e offsets de arquivo para funções em diferentes versões do Windows

Estrutura do Arquivo```

┌─────────────────────────────────────┐ │ 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:~
Detalhes do layout (corresponde a `write_woff`):

* Após o espaço reservado do cabeçalho, os nomes da DLL e da função são escritos como bytes UTF‑8.
* Para cada construção, o nome do símbolo correspondente é escrito como uma string UTF‑8 (sem terminador). Estes formam um pool de strings simples.
* O escritor então alinha a 4 bytes e escreve a tabela de entradas de tamanho fixo.
* Cada entrada contém deslocamentos (`matched_off`, `matched_len`) apontando para este pool de strings.

##### Layout do Cabeçalho (36 bytes)```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
Offset Entry (32 bytes)

Cada entrada mapeia uma compilação do Windows para a localização da função nessa compilação.```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:~
##### Notas de Uso

* **RVA** é o deslocamento de memória quando a DLL é carregada na sua base preferida.
* **File offset** é a posição bruta no arquivo PE em disco.
* **Matched symbol** pode diferir da função solicitada (ex.: exportações encaminhadas).
  A string é armazenada uma vez no pool de strings; `matched_off`/`matched_len` a referenciam.
* As entradas são **ordenadas por versão de build** (`major`, depois `minor`) para busca eficiente.

---

#### Códigos de Arquitetura

Ambos os formatos binários usam a mesma codificação de arquitetura (via `ARCH_CODE_MAP`):

| Código | Arquitetura | Descrição                        |
| ------ | ----------- | -------------------------------- |
| 1      | x64         | 64 bits AMD64/Intel64            |
| 2      | ARM64       | 64 bits ARM (AArch64)            |
| 3      | WoW64       | 32 bits x86 no Windows 64 bits   |

Strings de arquitetura desconhecidas assumem internamente o valor padrão `1` (x64); a CLI restringe os valores ao conjunto suportado.

---

### 3. **Formato de Cabeçalho C**

Cabeçalhos C prontos para compilar com estruturas type-safe e arrays de dados.

`pe-signgen` pode emitir dois *tipos* de cabeçalhos C:

* **Cabeçalhos WSIG** – para dados de assinatura e máscara (a partir de `write_wsig_header`).
* **Cabeçalhos WOFF** – para tabelas diretas de RVA/deslocamento de arquivo (a partir de `write_woff_header`).

A opção `--output-format cheader` seleciona cabeçalhos C; combiná-la com `--offsets` alterna entre as variantes WSIG e WOFF.

#### Cabeçalho C WSIG```bash
pe-signgen --signature ntdll!RtlpInitializeThreadActivationContextStack \
  -o rtlp_init_actx.h --output-format cheader

Estrutura de cabeçalho gerada (simplificada, corresponde a 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:~
**Exemplo de integração (corrigido para corresponder aos tipos gerados):**```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;
    }
}

Você pode então integrar isso no seu próprio código específico de loader (por exemplo, usando GetModuleHandleA, percorrendo seções PE, etc.). O cabeçalho intencionalmente fornece apenas dados; as funções auxiliares ficam a cargo do consumidor.

Cabeçalho C WOFF

Para casos de uso apenas com offset, write_woff_header emite um pequeno cabeçalho descrevendo uma tabela ordenada de entradas (major, minor, rva, file_offset).

Layout (corresponde a 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:~
Isto é útil quando você confia nos próprios offsets e não precisa de correspondência de padrões.

---

## Instalação

### Pré-requisitos

* Python 3.8+
* Git
* Conexão com a internet (primeira execução)
* ~10 GB de espaço em disco para cache completo

### Instalar a partir do Pip```bash
pip install pe-signgen

Instalar a partir do código-fonte```bash

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

root@kitploit:~
## Início Rápido

### Gerar uma Assinatura```bash
pe-signgen --signature ntdll!LdrLoadDll

Gerar Offsets```bash

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

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

Opções da Linha de Comando

Sintaxe Básica```bash

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

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

Filtragem de Versão```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:~
### Controle de Comprimento da Assinatura```bash
--min-length 32          # Minimum signature length
--max-length 64          # Maximum signature length

Opções de Saída```bash

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

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

Verbosidade```bash

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

root@kitploit:~
## Armazenamento em Cache

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

Controle de 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:~
## Desempenho

**Exemplo de desempenho (CPU de 12 núcleos, 100 Mbps):**

| Operação                               | Tempo       |
| -------------------------------------- | ----------- |
| Primeira execução (sem cache)          | 5–10 min    |
| Execução em cache                      | < 1 seg     |
| Análise por build                      | 0,1–0,5 seg |
| Execução completa (1000 builds, 8 workers) | 2–4 min     |

**Requisitos de recursos:**

* **Disco:** ~10 GB para cache completo de DLL/PDB
* **Memória:** ~500 MB de pico de uso
* **Rede:** Vários GB na primeira execução

---

## Limitações Conhecidas

* **Cobertura de versões do Windows:** Apenas Windows **10 e 11** (limitação do Winbindex)
* **Disponibilidade de builds:** Nem todo build do Win10/11 existe no Winbindex

---

## Desenvolvimento```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/

Licença

Licença MIT – veja LICENSE.


Créditos

  • Winbindex – Metadados de builds do Windows por @m417z
  • pefile – Biblioteca de análise de PE
  • winpdb-rs – Ligações Python para análise de PDB

Inspirado pela necessidade de geração robusta e automatizada de assinaturas para APIs internas do Windows.


Contribuindo

Contribuições são bem-vindas! Por favor:

  1. Faça um fork do repositório
  2. Crie um branch de funcionalidade
  3. Adicione testes para a nova funcionalidade
  4. Envie um pull request

Suporte

  • Problemas: GitHub Issues
  • Discussões: GitHub Discussions
Baixar ferramenta