DotFix Script — Custom Scripting Engine


DotFix Script is the built-in automation language of DotFix NiceProtect. It lets you run your own scripts immediately before and after the protection stage — to prepare input files, edit the PE header, strip unwanted resources, patch the protected binary, compute checksums, sign it, or kick off your installer build — without leaving the tool.

Overview

A DotFix Script is plain text, interpreted line by line at runtime. Each line is one command followed by comma‑separated parameters. There is no separate compile step you manage: you write the script, and the engine reads it from top to bottom, executing one command per line.

NiceProtect can invoke a script at two points in a protection job:

  • Pre‑protection — before the file is processed. Use it to stage source files, clean previous output, generate inputs, or read settings.
  • Post‑protection — after the protected binary is written. Use it to patch the output, adjust PE headers, hash or sign the result, copy it to a release folder, or notify the user.

The file being produced is exposed to the script through the predefined register @output. Commands that read or write a binary without an explicit path operate on this output file by default.

  • The number of script lines is not limited.
  • Empty lines are skipped.
  • Lines beginning with ;, #, or ! are comments.
  • An unknown command is reported as an error; the script continues with the next line.
  • Lines starting with GPS are treated as obfuscated and decrypted automatically, so you can ship scripts whose contents are not easily readable.
Return code A script run returns 0 if it finished with no errors, or 1 if one or more errors were recorded — so a faulty script can fail your build pipeline.

Syntax

One command per line. The command name is separated from its parameters by the first space; parameters are separated by commas. A command takes up to ten parameters. Command names are case‑insensitive, and leading spaces in a parameter are trimmed.

; set register _name to the literal text "build42" set build42, _name ; join two values into _path concat @current, output\, _path

To include commas or spaces literally, wrap a parameter in double quotes; a doubled quote ("") inside produces one literal quote. The escape \n is converted to a line break.

Registers & macros

A register is a named slot holding a string. You create one simply by writing to it; most commands take the destination register name as their last parameter. Prefix a name with @ anywhere in a parameter to substitute its current value before the command runs.

set Hello, _greeting concat @_greeting, " World", _line ; _line = "Hello World" status @_line ; prints: Hello World

Several predefined registers are filled in automatically:

RegisterValue
@windowsWindows directory, with trailing backslash.
@tempUser temp directory, with trailing backslash.
@currentDirectory of the running NiceProtect executable.
@outputFull path of the output file for the current job.
@crlfA carriage‑return + line‑feed pair.

How numbers are read

Numbers are decimal by default throughout the engine. A value written with a 0x (or $) prefix is hexadecimal; anything else is decimal. Every command that produces a number writes it in decimal, so the result of one operation feeds straight into the next.

add 0x10, 5, _a ; _a = "21" (16 + 5) add @_a, 4, _b ; _b = "25" (previous result reused directly)

Calculation and byte layout are two separate ideas. Use calc to compute a value, then pack to turn it into a fixed‑width little‑ or big‑endian byte string for writing into a file.

calc (0x1000 + 16) * 2, _v ; _v = "8224" pack @_v, dword, le, _bytes ; _bytes = "20200000" (LE DWord) putcode 0x1000, @_bytes
Note Raw byte payloads differ from numbers: the data argument of putcode and the result of getcode are hex byte strings (for example 90909090), not decimal quantities.

Conditions (the IF modifier)

Any command can be made conditional by appending an IF clause as its last parameter. If the condition is false, the command is skipped.

goto done, IF @_count = 3

A condition is one or more comparisons of the form value OP value:

OperatorMeaningComparison
=equalstring
^not equal (also !=, <>)string
>greater thannumeric
<less thannumeric
>=greater or equalnumeric
<=less or equalnumeric

The relational operators compare numerically, using the 0x/decimal rule above. Comparisons can be joined with AND and OR, evaluated left to right.

goto ready, IF @_size > 0 AND @_state = ok goto retry, IF @_code = 1 OR @_code = 2
Spaces in IF values A condition is split on spaces, so values inside an IF clause must not contain spaces. To compare text with spaces, store it in a register and compare the register, or test emptiness with length.

Commands — variables & math

Math commands accept decimal or hex input and write a decimal result.

set value, destReg

Stores value verbatim into destReg.

calc expression, destReg [, hex]

Evaluates an arithmetic expression with + - * / and parentheses; numbers may be decimal or hex. Result is decimal, or an unpadded hex string when the third parameter is hex.

pack value, byte|word|dword|qword, le|be, destReg write

Encodes value as a fixed‑width hex byte string in little‑ or big‑endian order, ready for putcode.

unpack hexBytes, le|be, destReg read

Decodes a hex byte string back into a decimal number.

add / sub / mul / div a, b, destReg

Addition, subtraction, multiplication, integer division. Inputs decimal or hex; decimal result. div reports an error on a zero or missing divisor.

invert value, destReg

Encodes value as a little‑endian 4‑byte hex string. Retained for compatibility; pack value, dword, le, dest is the clearer equivalent.

Commands — strings

concat a, b, destReg

Joins a and b.

length value, destReg

Stores the length of value (decimal).

substr source, start, count, destReg

Extracts count characters from source starting at position start (1‑based).

createstring char, count, destReg

Builds a string of count repetitions of the first character of char.

chrtohex char, destReg  /  hextochr hex, destReg

Convert a character to its two‑digit hex code and back.

rndbyte destReg

Stores a random byte as a two‑digit hex string.

Commands — labels & jumps

label name

Declares a jump target. Labels are resolved before execution, so you can jump forward or backward.

goto label [, IF ...]

Transfers execution to a label, optionally only when a condition holds.

exit

Stops the script immediately.

Commands — files

createpath path fs

Creates a directory, including missing parents.

copyfile source, dest fs

Copies a file. A trailing $ on a path expands to the application directory.

delfile path fs

Deletes a file.

addlog file, text fs

Appends text as a new line to file, creating it if needed.

getfile destReg read

Reads the entire output file into a register.

getfilelength file, destReg read

Stores the size of file in bytes (decimal).

Commands — binary & PE editing

These operate on the output file and understand the Windows PE format. Addresses and offsets accept decimal or hex on input and are returned in decimal.

putcode offset, hexBytes write

Writes a sequence of bytes (hex string) at a file offset. putcode 0x1000, 90909090 writes four NOP bytes.

getcode offset, length, destReg read

Reads length bytes from offset and stores them as a hex string.

getoep destRaw, destRva read

Resolves the original entry point: raw file offset and RVA (both decimal).

setoep rva write

Sets the PE entry point to the given RVA.

getimagebase destReg read

Stores the PE image base address (decimal).

getoem destReg  /  setoem text readwrite

Reads or writes the OEM identifier string in the DOS stub (up to 29 characters).

createsection name, size, destRaw, destRva write

Appends a new PE section with the given name and size (decimal), returning its raw offset and RVA, and updates the image size.

setflag flags write

Sets the characteristics flags on the file's sections (use 0x for a hex bitmask).

xorcode rva, length, destStubReg write

XOR‑encrypts a region of code at the given RVA with a random key, writes it back, and returns a ready‑to‑use decryptor stub (hex) in the register.

Commands — Registry / INI / XML

Across all three stores the convention is the same: set writes, get reads.

registry.set Root, SubKey\ValueName, Type, Value write

Writes a value. Root is one of HKCR HKCU HKLM HKU HKPD HKCC HKDD; Type is REG_DWORD or a string type.

registry.get Root, SubKey\ValueName, destReg [, default] read

Reads a value, with an optional default if it is missing.

ini.set file, Section, Key, Value write

Writes a value to an INI file.

ini.get file, Section, Key, destReg read

Reads a value, or an empty string if absent.

xml.set file, XPath, Value write

Writes Value as the text of the node addressed by XPath (for example /root/item). Creates the file and any missing elements of a simple path automatically; saved as UTF‑8 without a BOM.

xml.get file, XPath, destReg read

Reads the text of the node, or an empty string if the file or node is absent. Loading detects the file's actual encoding, so files from other tools load reliably.

Commands — dialogs & console

messagebox text, type, caption, destReg

Shows a message box and stores the numeric button result.

inputbox prompt, destReg

Prompts for a line of text.

settoclipboard text

Places text on the clipboard.

A console is available for interactive output. It adapts to how the protector was launched: in the console build console.load reuses the existing console; in the GUI build it creates a window, and console.unload closes only what it created. The close button and Ctrl‑C are disabled for a created console so the user cannot terminate the protector by closing it. The status command always writes to the protection log, so console commands are optional.

console.load title  ·  console.print text  ·  console.get destReg

Attach a console / write a line / read a line.

console.color fg, bg  ·  console.attributes mode  ·  console.unload

Set text colour / set mode flags / detach the console.

Commands — system

run commandLine, destReg read

Runs an external command or console application, waits for it to finish, and stores its exit code (decimal). On a start failure it records an error and stores -1.

shell command

Runs a program or opens a file or URL through the shell, without waiting.

getenv name, destReg read

Reads an environment variable into a register.

md5 file, destReg  /  sha256 file, destReg read

Computes the MD5 (32 hex chars) or SHA‑256 (64 hex chars) hash of a file.

loadfunction dll, function, a1, a2, a3, destReg

Loads a DLL, calls an exported function with three integer arguments, and stores the numeric return value.

pause milliseconds  ·  play wavFile

Wait for a number of milliseconds / play a WAV file.

status text

Writes a diagnostic line to the NiceProtect status bar (and the console, if attached). The main way to report progress from a script.

Examples

Copy the protected file into a release folder

concat @current, release\, _dir createpath @_dir concat @_dir, app_protected.exe, _dest copyfile @output, @_dest status [INFO] Copied protected build to release folder

Stamp a checksum and sign the protected binary

sha256 @output, _sum concat @output, .sha256, _sumfile delfile @_sumfile xml.set @_sumfile, /file/sha256, @_sum run signtool sign /f cert.pfx @output, _rc goto signed, IF @_rc = 0 status [FAIL] Signing failed (code @_rc) exit label signed status [PASS] Signed @output

Compute an address and patch bytes

getimagebase _base calc @_base + 0x1000, _addr pack @_addr, dword, le, _bytes putcode 0x400, @_bytes

Errors & diagnostics

Errors are collected during the run and printed to the status bar when it finishes; each begins with ! and names the failing command and line. A failed command does not stop the script — the next line still runs. Use status with a simple convention such as [PASS], [FAIL], and [INFO] prefixes to make results easy to scan, and check the run's return code (0/1) from your build system.



Change language: English German Russian

 

Copyright © 2001 - 2026, DotFix Software