Skip to content

mdsecactivebreach/functionpeekaboo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Function Peakaboo

Build Instructions

LLVM backend pass registration

  • The pass logic is implemented in X86RetModPass.cpp

  • Include X86RetModPass.h in llvm-project/llvm/lib/Target/X86/X86TargetMachine.cpp.

  • In X86TargetMachine.cpp, there is a function - void X86PassConfig::addPreEmitPass(), add below code at the end of the function.

    // LLVM will run our pass in PreEmit phase
    addPass(new X86RetModPass());
  • Now we have successfully registered our custom backend pass.

Modifying LLVM internals

  • Here we will modify assembly printer component (X86AsmPrinter class) of LLVM.

  • We will add a new private member EpilogueStubSymbol in X86AsmPrinter class definition.

    llvm-project/llvm/lib/Target/X86/X86AsmPrinter.h
    
  • Following the addition of new class member, we need to modify two X86AsmPrinter class methods as mentioned below:

    • void X86AsmPrinter::emitFunctionBodyStart()
    • void X86AsmPrinter::emitFunctionBodyEnd()
  • You will find the X86AsmPrinter class implementation in the file mentioned below.

    llvm-project/llvm/lib/Target/X86/X86AsmPrinter.cpp
    
  • Just replace the contents in emitFunctionBodyStart() and emitFunctionBodyEnd() with code in X86AsmPrinter.cpp provided in this repo. Dont forget to add the EpilogueStubSymbol in X86AsmPrinter.h

Build LLVM (use CCACHE ) & test executable

  • Now we are ready to build LLVM from scratch with our modification baked into it.
  • Make sure CCACHE is installed among other dependencies for the installation.
--------------------------------------------------------------------------------------------------------------
Configure CCACHE (optional)
--------------------------------------------------------------------------------------------------------------
ccache --max-size=10G

--------------------------------------------------------------------------------------------------------------
llvm building
--------------------------------------------------------------------------------------------------------------
git clone https://github.com/llvm/llvm-project.git

cmake -G Ninja ../llvm-project/llvm   -DLLVM_ENABLE_PROJECTS="clang;lld"   -DCMAKE_BUILD_TYPE=Release   -DLLVM_TARGETS_TO_BUILD="X86"   -DLLVM_ENABLE_ASSERTIONS=ON   -DCMAKE_INSTALL_PREFIX=../llvm-install -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache

ninja install

--------------------------------------------------------------------------------------------------------------
Compile and linking test sample test.cpp
--------------------------------------------------------------------------------------------------------------
llvm-install/bin/clang++ -static -static-libstdc++ -static-libgcc -target x86_64-w64-windows-gnu -fuse-ld=lld -O0 test.cpp -o out.exe -Wl,--strip-all -Wl,--gc-sections -v

--------------------------------------------------------------------------------------------------------------
Inject custom entrypoint stub 
--------------------------------------------------------------------------------------------------------------
python3 modifyEP.py out.exe final.exe



Caution

  • LLVM backward compatibility is very poor, therefore future LLVM updates may (or may not) break compilation.

Testing

  • Do not try to run the binary prior to injecting custom entry point stub, as it will lead to a crash.

  • Test code test.cpp contents are shown below.

    // test.cpp
    #include <windows.h>
    #include <iostream>
    #include <stdint.h>
    
    struct MyStruct 
    {
        void* func;
        uint32_t len;
    };
    
    // Place xor key here, POC uses single byte keys. eg 0x00000008
    __attribute__((section(".funcmeta")))
    uint32_t myfuncsec_key = 0x12345678;
    
    // Macro to register a function
    #define REGISTER_FUNCTION(fn) \
        __attribute__((section(".funcmeta"))) \
        struct MyStruct fn##_entry = { (void*)fn, 0xDEADBEEF }; 
    
    void REG_foo2()
    {
        std::cout << "\nhello from foo2";
    }
    int REG_foo(int a, int b, int c, int d, int e) 
    {
        int i = 0;
        int x = a + b + c + d + e;
        std::cout << "\n" << x;
        MessageBoxA(NULL, "Hello from foo", "Test", MB_OK);
        if (i)
        {
            return 0;
        }
        else{
            i++;
        }
        return x;
    }
    
    //Register your functions here
    REGISTER_FUNCTION(REG_foo)
    REGISTER_FUNCTION(REG_foo2)
    
    int main()
    {
        bool p = VirtualProtect(0,0,0,0);
        std::cout << "MAIN here";
        int a = REG_foo(1,2,3,4,5);
        std::cout << "\n Ret val :" << a;
        REG_foo2();
        return 0;
    }
    

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published