Giter VIP home page Giter VIP logo

precomp4c's Introduction

Precomp4C

avatar

Precomp4C is a open-source and extensible precompiler for C/C++, converts variant objects to C source, and participate build.

Use case 1: Embedding binary data

Usually, we embed binary to program resource, and calling API like "FindResource" to get binary data at runtime.

But now, Precomp4C provides "Binary" loader, we can embed file as binary data to code and use it directly. For example, let's embed a png image file to C/C++ source:

First, we write Precomp4C configuration file (Precomp4C.config.json) to specify which file to be embedded by using "Binary" loader in Precomp4C:

Precomp4C.config.json

{
    "Loaders": {
        "Binary": [{
            "File": "..\\Resource\\IconMask.png",
            "Export": "PNG_Icon_Mask"
        }]
    }
}

After we integrated Precomp4C to our project, the following outputs will be generated automatically:

Precomp4C.Output.h

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by Precomp4C
//     KNSoft(knsoft.org) - Precomp4C V1.0.0.0
//     https://github.com/KNSoft/Precomp4C
//     Do not change this file manually
// </auto-generated>
//------------------------------------------------------------------------------

#pragma once

extern unsigned char BIN_PNG_Icon_Mask[759];

Precomp4C.Output.c

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by Precomp4C
//     KNSoft(knsoft.org) - Precomp4C V1.0.0.0
//     https://github.com/KNSoft/Precomp4C
//     Do not change this file manually
// </auto-generated>
//------------------------------------------------------------------------------

unsigned char BIN_PNG_Icon_Mask[759] = {
	0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x08,
	0x06, 0x00, 0x00, 0x00, 0x57, 0x02, 0xF9, 0x87, 0x00, 0x00, 0x02, 0xBE, 0x49, 0x44, 0x41, 0x54, 0x68, 0x81, 0xED, 0x99, 0xEF, 0x71, 0x9B, 0x40, 0x10,
	0xC5, 0xDF, 0x7A, 0xF2, 0x5D, 0xE9, 0xC0, 0xEA, 0x40, 0x4A, 0x05, 0x72, 0x07, 0x4A, 0x07, 0x56, 0x07, 0xB8, 0x03, 0xA5, 0x03, 0xBB, 0x83, 0x28, 0x15,
    ...

Adds outputs (Precomp4C.Output.h and Precomp4C.Output.c) to project, and we can get binary data of "..\\Resource\\IconMask.png"(specified in configuration file, Precomp4C.config.json) by referencing symbol "BIN_PNG_Icon_Mask"("BIN_" prefix appended by "Binary" loader, "PNG_Icon_Mask" specified in configuration file).

Use case 2: Embedding shellcode written by C/C++

KNSoft/NTAssassin is an example shows how to use C/C++ writes shellcode and inject to remote process by integrated Precomp4C. Let's take a look:

First, NTAssassin writes shellcode in HijackC.c, the function "Hijack_LoadProcAddr_InjectThread". Caution, those C source have no external(or global) symbol(or function) reference, as well as the assembly code generated, so the binary code generated can work perfectly in remote process after injection.

Second, NTAssassin have two C/C++ projects complie this source to different target platform, x86 and x64. Whatever EXE or DLL, Precomp4C needs object file (HijackC.obj) only.

And then we writes Precomp4C.config.json, use "SymExtract" loader to get binary code complied from "Hijack_LoadProcAddr_InjectThread" function:

Precomp4C.config.json

{
    "Loaders": {
        "SymExtract": [{
                "File": "..\\NativeASM\\Hijack_x86\\Release\\HijackC.obj",
                "Symbols": [{
                    "Name": "Hijack_LoadProcAddr_InjectThread",
                    "Export": "Hijack_LoadProcAddr_InjectThread_x86"
                }]
            },
            {
                "File": "..\\NativeASM\\Hijack_x64\\Release\\HijackC.obj",
                "Symbols": [{
                    "Name": "Hijack_LoadProcAddr_InjectThread",
                    "Export": "Hijack_LoadProcAddr_InjectThread_x64"
                }]
            }
        ]
    }
}

Now, Precomp4C outputs "Hijack_LoadProcAddr_InjectThread" function code in HijackC.obj(x86) and named "Hijack_LoadProcAddr_InjectThread_x86", outputs "Hijack_LoadProcAddr_InjectThread" function code in HijackC.obj(x64) and named "Hijack_LoadProcAddr_InjectThread_x64":

Precomp4C.Output.h

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by Precomp4C
//     KNSoft(knsoft.org) - Precomp4C V1.0.0.0
//     https://github.com/KNSoft/Precomp4C
//     Do not change this file manually
// </auto-generated>
//------------------------------------------------------------------------------

#pragma once

extern unsigned char SYM_Hijack_LoadProcAddr_InjectThread_x86[982];
extern unsigned char SYM_Hijack_LoadProcAddr_InjectThread_x64[1120];

Precomp4C.Output.c

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by Precomp4C
//     KNSoft(knsoft.org) - Precomp4C V1.0.0.0
//     https://github.com/KNSoft/Precomp4C
//     Do not change this file manually
// </auto-generated>
//------------------------------------------------------------------------------

unsigned char SYM_Hijack_LoadProcAddr_InjectThread_x86[982] = {
	0x55, 0x8B, 0xEC, 0x8B, 0x45, 0x08, 0x83, 0xEC, 0x38, 0x8B, 0x08, 0x53, 0x56, 0x57, 0x83, 0xF9, 0x04, 0x72, 0x23, 0x8D, 0x58, 0x04, 0xBA, 0x00, 0x00,
	0x00, 0x00, 0x89, 0x5D, 0xC8, 0x83, 0xE9, 0x04, 0x74, 0x13, 0x8D, 0x04, 0x12, 0x42, 0x66, 0x83, 0x3C, 0x18, 0x00, 0x89, 0x55, 0xF8, 0x74, 0x13, 0x83,
    ...
};

unsigned char SYM_Hijack_LoadProcAddr_InjectThread_x64[1120] = {
	0x40, 0x55, 0x56, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x48, 0x81, 0xEC, 0xA0, 0x00, 0x00, 0x00, 0x8B, 0x11, 0x48, 0x83, 0xFA, 0x04, 0x72, 0x2C, 0x48,
	0x8D, 0x69, 0x04, 0x41, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x45, 0x8B, 0xDD, 0x48, 0x83, 0xEA, 0x04, 0x74, 0x19, 0x0F, 0x1F, 0x44, 0x00, 0x00, 0x41, 0x8B,
    ...
};

NTAssassin gets both x86 and x64 shellcode from the same C source by using Precomp4C, and use this shellcode implements Hijack_LoadProcAddr to load DLL and optionally get procedure address in remote process like:

Hijack_LoadProcAddr(ProcessHandle, L"Any.dll", "AnyFunction", ...)

Use case N: Extends more loader for Precomp4C

Precomp4C is extensible, we can use Precomp4C to do more by writting more loaders:

  • Get fingerprint of certification and embedded in code to verify at runtime, avoid hardcode
  • Converts I18N configuration file in JSON format to C source like array or key-value map, KNSoft/AlleyWind is an example
  • ...

All the loaders just needs to implement two interfaces, like "Binary" loader:

public static DateTime GetLastModifyTime(string ProjectDir, CO_Binary[] ConfigObject);
public static bool Process(string ProjectDir, FileStream fsHeader, FileStream fsSource, CO_Binary[] ConfigObject);
  • ProjectDir: Project directory which contains Precomp4C configuration file (Precomp4C.config.json)
  • ConfigObject: JSON configuration object specified in "Precomp4C.config.json" for this loader
  • GetLastModifyTime() returns: A DateTime value, last modify time of source file for this loader, feedbacks to Precomp4C main program to determin rebuild could be skip or not
  • fsHeader: FileStream for Precomp4C.Output.h
  • fsSource: FileStream for Precomp4C.Output.c
  • Process() returns: success or not, Precomp4C main program ignored this return value currently, Loaders call "RTL.RaiseError" to stop build and output error message when encountered a fatal error

How to integrate Precomp4C to C/C++ project?

  1. Write Precomp4C.config.json in project root directory, configures the loader(s) needed, like examples above
  2. Add Pre-Build Event to call Precomp4C before IDE build, pass project directory to Precomp4C, like:
3rdParty\bin\Precomp4C\Precomp4C.exe $(ProjectDir)
  1. Run build task, Precomp4C.Output.h and Precomp4C.Output.c will generated automatically if no error occured, add them to project, the outputs symbols could be referenced now

Those project integrated Precomp4C to improve C/C++ code programmability, maintainability, architecture design:

  1. KNSoft/NTAssassin: Uses "SymExtract" loader to outputs shellcode generated from C source, and targets to multiple platforms (x86 and x64)
  2. KNSoft/AlleyWind: Uses "I18N" loader with I18N library in KNSoft/NTAssassin to support I18N (en/en-US and zh/zh-CN)

Precomp4C is written by C#, the latest .NET runtime is required: https://dotnet.microsoft.com/download

precomp4c's People

Contributors

ratincn avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.