Crystal Palace Quick Reference

Crystal Palace is a linker and linker script language specialized to the needs of writing tradecraft as position-independent code.

Requirements

Crystal Palace requires:

Crystal Palace assumes a Linux (or Windows Subsystem for Linux) development environment.

Command-line Usage

To use Crystal Palace on the command-line, use:

./link /path/to/loader.spec demo/test.x64.dll out.x64.bin

Crystal Palace includes a shellcode runner and a "Hello World" DLL in the demo/ folder. Try it with your position-independent DLL loader:

./demo/run.x64.exe out.x64.bin

Other CLI Options

-g "out.yar" generates a Yara rule file with out.x64.bin.

KEY=04030201 sets byte[] $KEY to 0x04, 0x03, 0x02, 0x01.

%var="value" sets template string %var to value.

-r %var="fileA, fileB" sets template string %var to /full/path/to/fileA, /full/path/to/fileB

@config.spec runs config.spec before loader.spec runs.

Specification Files

The Crystal Palace linker is driven by specification files. These files are Crystal Palace's linker script.

Here's an example specification file:

Each command works with the program stack and its contents, %string variables, and byte[] $content variables:

Command Reference

Below is a full list of Crystal Palace spec file commands and how they impact the Crystal Palace stack:

Command Pop Push Description
addhook "MOD$Func" OBJECT OBJECT Register MOD$Func's attach "MOD$Func" "hook" chain with __resolve_hook() intrinsic.
addhook "MOD$Func" "hook" OBJECT OBJECT Register MOD$Func hook for use with __resolve_hook() intrinsic.
attach "MOD$Func" "hook" OBJECT OBJECT Rewrite calls and references to MODULE$Function to go through hook(). Preserves MODULE$Function in hook().
before "cmd1": cmd2 %_ Run cmd2 before cmd1 executes. %_ is set to the command+arguments of cmd1. %1 ... %n are set to the individual arguments
call "file.spec" "label" ... Calls "label" from another .spec, using the same target, $VARs, and stack as the current script. Accepts positional arguments, passed as %1, %2, etc.
coffparse "file.txt" ["title"] OBJECT OBJECT Parse object on stack and output a string representation to file.txt (or STDOUT). The COFF parsing will occur at export, after +options are applied, and before patched values are acted on.
dfr "resolver" "method" OBJECT OBJECT (PIC only) Sets default dynamic function resolution resolver function. Rewrites MODULE$Function references in PIC to call resolver. ror13 method passes ror13 module and function hashes to resolver. strings method passes module and function stack strings to resolver.
dfr "res." "method" "M1, M2" OBJECT OBJECT (PIC only) Set dynamic function resolution resolver function for Win32 APIs from MODULE1 and MODULE2. This resolver has priority over the default resolver.
disassemble "file.txt" ["title"] OBJECT OBJECT Disassemble object on stack and write output to file.txt (or STDOUT). The disassemble will occur at export, after +options are applied, and before patched values are acted on. Add +forms option to show iced generic instruction forms in output.
echo ... print arguments to STDOUT (CLI) or SpecLogger (Java API)
export OBJECT BYTES Turn object on stack into bytes
exportfunc "fun" "__tag_fun" OBJECT OBJECT (PICO only) Export function from PICO and generate __tag_function intrinsic (used with PicoGetExport to find func pointer)
filterhooks $DLL|$OBJECT OBJECT OBJECT Walk imports of $DLL or $OBJECT and remove registered hooks for APIs not in import table
fixbss "getBSS" OBJECT OBJECT (PIC only) Rewrites PIC .bss (uninitialized global variables) references to call getBSS(size of bss section) and reference global variables as an offset of the returned pointer. This restores uninitialized global variables in PIC programs.
fixptrs "_caller" OBJECT OBJECT (x86 PIC only) Rewrite x86 PIC to turn partial pointers into full pointers with the help of _caller function. Allows access to strings and linked data without hacks.
foreach %var: cmd %_ For each item in %var (comma separated list of strings), run cmd with %_ set to the current item.
generate $VAR ## Generate ## random bytes and assign to $VAR
import "A, B, C, ..." OBJECT OBJECT Import functions A, B, and C into COFF object.

"A, B, C, ..." maps members of IMPORTFUNCS struct passed to PicoLoader to function symbols in COFF. First two values are always LoadLibraryA and GetProcAddress. Extend IMPORTFUNCS struct to pass the other pointers
ised verb pttrn $CODE +opts OBJECT OBJECT Program rewriting tool. 'replace' or 'insert' $CODE where pattern matches. Pattern is one or more strings containing a disassembled instruction string, iced generic form (e.g., CALL rel32), or instruction mnemonics (e.g., CALL). Options include: +split (insert block break), +safe (attest $CODE is RFLAGS aware), +first / +last (which instruction to act on), and +before / +after (where to insert $CODE or +split)
load "file" BYTES Load contents of file onto stack
load $VAR "file" Load contents of file into $VAR
link "section" BYTES, OBJECT OBJECT Link (data) bytes on the stack to section __attribute__((section("section"))) in object on the stack.
linkfunc "symbol" BYTES, OBJECT OBJECT Link (code) bytes on the stack to function symbol in object on stack
magic "0x##, 0x##, ..." Set magic values used by +mutate to break up constants
make coff [+options] BYTES OBJECT Turn contents on stack into a COFF-exporter object.

Options are +optimize (Link-time optimization), +disco (randomize function order), +mutate (constants mutator), and others
make object [+options] BYTES OBJECT Turn contents on stack into a PICO-exporter object.

Options are +optimize (Link-time optimization), +disco (randomize function order), +mutate (constants mutator), and others
make pic [+options] BYTES OBJECT Turn contents on stack into PIC-exporter object.

Options are +optimize (Link-time optimization), +disco (randomize function order), +mutate (constants mutator), +gofirst (make go the first function), and others
merge BYTES, OBJECT OBJECT Merge bytes on stack (COFF content) to object on stack
mergelib "lib.x##.zip" OBJECT OBJECT Merges each COFF file within zip archive to object on stack
meta "verb" "value" Update meta-information for current .spec file.
Verbs: author, describe, license, name, and reference.
next "%var": cmd %_ Remove first element from %var and run cmd with %_ set to the removed element. Do nothing if %var is empty.
options [+options] OBJECT OBJECT Turn on more +options for this export configuration object.

Options are +optimize (Link-time optimization), +disco (randomize function order), +mutate (constants mutator), and others
optout "target" "h1, h2, ..." OBJECT OBJECT Do not allow redirect or attachs hooks hook1, hook2, etc. (or hooks that call them) in target function
pack $VAR "template" ... Marshal "string" arguments into $VAR with types specified in template. See Pack Reference.
patch "symbol" $VAR OBJECT OBJECT Patch "symbol" within COFF/PIC with contents of $VAR
pop $VAR BYTES Pop content from stack and store in $VAR
preplen BYTES BYTES Prepend length (of content) to the content on the stack
Length is a 4-byte integer in arch-native byte order.
prepsum BYTES BYTES Calculate and prepend Adler32 checksum to content on the stack
Checksum is a 4-byte integer in arch-native byte order.
preserve "target" "f1, f2, ..." OBJECT OBJECT Prevent attach and redirect hooks on MODULE$Function or target within func1, func2, etc.
protect "func1, func2, etc." OBJECT OBJECT Prevent all attach and redirect hooks within func1, func2, etc.
push $VAR BYTES Push $var onto stack
rc4 $VAR BYTES BYTES RC4 encrypt content on stack with $VAR as key
redirect "function" "hook" OBJECT OBJECT Rewrite calls and references to function() to go through hook(). Preserves function() in hook().
remap "old" "new" OBJECT OBJECT Rename a symbol in the current COFF. (Use ./coffparse to see symbol names)
resolve "%var" Resolves and updates comma-separated partial file paths in %var to full-paths relative to current .spec file location
rule "name" max ... OBJECT OBJECT Configure Yara rule for object on stack. Full options are: rule "name" [maxSigs] [minAgree] [minSigLength-maxSigLength] ["func1, func2"]. The last parameter is a list of functions to generate signatures from.
run "foo.spec" ... Run another .spec, using the same target, $VARs, and stack as the current script. Accepts positional arguments, passed as %1, %2, etc.
set "%var" "value" Sets %var to value in the local scope (e.g., visible to the current running label context only)
setg "%var" "value" Sets %var to value in the global scope (e.g., accessible globally through this linking session)
xor $VAR BYTES BYTES Mask content on stack using $VAR as key

Pack Reference

pack is Crystal Palace's command to marshal arguments into a byte array $VARIABLE. The syntax is:

pack $VARIABLE "template" arg1 arg2 arg3

Numerical and multi-byte ('Z') characters are packed in little-end byte order.

Here is the template reference:

Template Argument Type Size (b) Notes
a "string" UTF-8 string var
b number byte 1
h "hex-pair string" byte string var
i number int 4
l number long 8
p number pointer 4, 8 size is arch dependent
s number short 2
v $VAR byte string var
x No arg NULL byte! 1
w "string" UTF-16LE string var
z "string" UTF8 string var string is null-terminated
Z "string" UTF16-LE string var string is null-terminated
@4, @8, @n No arg NULL byte(s) var Align packed string to 4, 8, or architecture's natural boundary bytes.
#t var int var Process template t and prepend 4-byte length to it

Java API

Use the following Java API to apply a .spec file from a Java program.