Skip to content

blak3y/shellgen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shellgen

shellgen is a tool to generate shellcode from C++ code.

How it works

When shellcode is defined using the CODE_SIGNITURE macro, it prefixes the function name with __CODE__. These names are present in the PDB generated by the compiler (eg: "Console::__CODE__Output"). shellgen parses this PDB to obtain the RVA and size of each shellcode function, then locates them in the current address space and extracts the raw bytes. Variables are located by scanning for the signiture 0xDEADBEEFDEADBEEF - variableIndex, which is zeroed out ready to be replaced upon injection. Variables use indexes to ensure consistent ordering regardless of compilation order.

Usage

To add new shellcode create a new file in the shellcode/groups directory then create a namespace with the group name and place your shellcode inside of it.

Shellcode definition:

CODE_SIGNITURE(returnType, shellcodeName)(args)

CODE_SIGNITURE(void, Output)(const char* string)
{
    // logic here
}

Variable definition:

DEF_VAR(variableName, index /* index starts at 1 */)

// example usage
CODE_SIGNITURE(void, Output)(const char* string)
{
    DEF_VAR(printf, 1);
    INLINE_CALL(void, printf, (const char*), string);
}

Function call:

// argTypes should be wrapped in parentheses eg: (const char*)
INLINE_CALL(returnType, address, argTypes, args);

Compile signiture:

COMPILE_SIGNITURE(shellcodeName)

COMPILE_SIGNITURE(Output)
{
    const char* str = DUMMY_ALLOC(char*);
    CALL_CODE(Output, str);
}

Output

shellgen outputs a shellcode/ directory containing <group>.hpp files for each defined group.

Example

#pragma once

// Generated by shellgen, an shellcode generation tool.

namespace Console
{
    namespace Output {
        static unsigned char bytes[13] = { 0x48,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0xff,0xe0 };
        static unsigned char variables[1] = { 0x02 };
    }
}

Remarks

When passing pointers to the shellcode in the compile signiture it is recommended that you use the DUMMY_ALLOC macro, when this isn't used the compiler can either optimise the value passed to be inlined or if you pass a pointer to a global variable it can be optimised away. An example of DUMMY_ALLOC being used can be found in the usage section.

When calling a function inside of the shellcode it is required that you use the INLINE_CALL macro, when this isn't used the function call will use a relative call to the function address that lives in the IAT as this is shellcode and intended as standalone injectable blobs the relative calls will not be resolved and executing this shellcode will cause a crash.

Roadmap

  • Output variable names alongside their offsets for easier patching

About

shellgen is a tool to generate shellcode from C++ code compiled by MSVC.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors