build_signet - Build a custom signet loader

The signet.command.build_signet module is responsible for building and compiling signet loaders. It provides all the facilities you require for scanning your module’s dependencies, and building a custom signet loader.

The built loader will be installed in the same directory as the script file.

class signet.command.build_signet.build_signet[source]
build_extension(arguments)[source]

This is the main function responsible for generating your signet loader. It is not expected to be invoked directly by your code, but installs itself into the distutils.command heirarcy by nature of it’s inheritance from disutils.command.build_ext .

build_signet makes available additional arguments you can specify when calling distutils.core.setup()

argument name value type
template The path to a custom loader to override the default loader provided by signet. a string
cflags any extra platform- and compiler- specific settings to use when compiling the custom loader. If you specify this setting on windows you override our default ‘/EHsc’. a list of strings
ldflags any extra platform- and compiler- specific settings to use when linking the custom loader. If you specify this setting on posix, you override our default ‘-lstdc++’ a list of strings
detection The default tamper protection used by your loader. Valid choices are; 3 require signed binary, 2 normal detection (default), 1 warn only, 0 disable detection an int
ext_modules The list of python modules to build signet loader(s) for. REQUIRED a list of instances of distutils.core.Extension
excludes The list of python module dependencies to exclude from the signet loader. a list of strings
mkresource Dynamic generation of windows resources. If you plan to use code signing, it’s recommended you set this option to True a boolean
skipdepends Instruct signet to not scan script dependencies. This is a minimum securty option. a boolean
virtualenv Build a virtualenv compatible loader. Exclude those modules that are replaced by the virtualenv pkg. a boolean

Windows Resources

In Windows, resources are read-only data embedded in exe’s. These resources contain meta-data about your executables that users can inspect with Explorer, Task Manager and other administrative tools (Read more).

From a secuity perspective, the VESIONINFO resources are an important tool to verify the details of a binary. build_signet will generate embedded VERSIONINFO resources for your loader when you enable the mkresource option in setup.py. Once enabled you need to specify the resource details for your project. There are two mechanisms for specifying the required information. The simplest is to add special variables to your script, which build_signet will scan and extract.

There are seven resources scanned by mkresource option; six are required and a seventh is optional. They are:

special string value
__companyname__ REQUIRED: Your organization’s name
__fileversion__ REQUIRED: Version number of your script
__filedescription__ REQUIRED: Simple file description.
__legalcopyright__ REQUIRED: The copyright notice that applies to your script.
__productname__ REQUIRED: The name of the project this script is part of.
__productversion__ REQUIRED: Version number of the project this script is part of.
__icon__ OPTIONAL: Path name of ico file to add to your .exe (defaults to app.ico)

The special variables must be in column 1 in your script, And their values must be hard coded. Try not to get too frisky with whitespace or formatting – build_signet uses a simple regex pattern to find them.

The second mechanism to specify required resources is to add them to setup.py, for example:

setup(
    name = "hello",                 # mapped to __productname__
    maintainer = "Acme, Inc",       # mapped to __companyname__
    description = "Cheese Grater",  # mapped to __filedescription__
    license = 'BSD'                 # mapped to __leaglcopyright__
    version = '1.0.2'               # mapped to __fileversion__ and __productversion__
    ...

You can mix and match mechanism 1 and 2, specifying some settings in your script and other in setup.py. Settings in your script take precendence.

Virtualenv Compatible Loaders

virtualenv is a tool for creating isolated python environments. Essentially, it creates a complete python environment on your client’s computer, and populates it with the packages and modules your software requires which solves the problem of dependency versioniong. You can safely include any module you require without fear of breaking something in your client’s environment.

The virtualenv package includes replacements modules for several packages. This presents a potential problems for signet. If your script imports one of these dependencies, the hashes calculated will likely not match the version of virtualenv (unless you build your loader from withn an active virtualenv environment).

We’ve collected the module replacements from virtualenv into a predefined exclude list. If your setup.py uses the –virtualenv option, the loader will be built with these excludes.

Examples

Simple example, hello.py:

print('hello world\n')

setup.py:

from distutils.core import setup, Extension
from signet.command.build_signet import build_signet

setup(name = 'hello',
    cmdclass = {'build_signet': build_signet},
    ext_modules = [Extension('hello', sources=['hello.py'])],
    )

An example to create Windows resource file, hello.py:

__companyname__ = "Acme, Inc."
__filedescription__ = "Cheese shop"
__fileversion__ = "1"
__legalcopyright__ = "BSD"
__productname__ = "Cheesy Income"

print('Hello world')

setup.py:

from distutils.core import setup, Extension
from signet.command.build_signet import build_signet

setup(name = 'hello',
    cmdclass = {'build_signet': build_signet},
    options = {'build_signet' : { 
                    'mkresources': True,
                    }
              },
    ext_modules = [Extension('hello', sources=['hello.py'])],
    )

An example to exclude certain dependencies

setup.py:

from distutils.core import setup, Extension
from signet.command.build_signet import build_signet

setup(name = 'hello',
    cmdclass = {'build_signet': build_signet},
    options = {'build_signet' : { 
                    'excludes': ['distutils'] ,
                    }
              },
    ext_modules = [Extension('hello', sources=['hello.py'])],
    )

An example to build a virtualenv compatible loaders

setup.py:

from distutils.core import setup, Extension
from signet.command.build_signet import build_signet

setup(name = 'hello',
    cmdclass = {'build_signet': build_signet},
    options = {'build_signet' : { 
                    'virtualenv': True,
                    }
              },
    ext_modules = [Extension('hello', sources=['hello.py'])],
    )

Utility Functions

signet.command.build_signet.module_signatures(py_source, verbose=True)[source]

Scan py_source for dependencies, and return list of 2-tuples [(hexdigest, modulename), ...], sorted by modulename.

To see what signatures signet will use when building your loader:

from signet.command.build_signet import module_signatures
for hash, mod in module_signatures('hello.py'):
    print hash, mod
signet.command.build_signet.generate_sigs_decl(py_source, verbose=True, excludes=None, includes=None)[source]
Scan py_source, and returns C declaration as string.

If verbose is true, display diagnostic output. Any modules or it’s decendants in the excludes list will be excluded from signatures declaration. If includes list is provided, ONLY generate declarations for the modules in the list.

The returned string will be formatted:

const Signature SIGS[] = {
        {"hexdigest1", "module1"},
        {"hexdigest2", "module2"},
        };

Table Of Contents

Previous topic

signet package

Next topic

sign_code - Digially sign code

This Page