YAPI -- Yet Another Process Injector

August 10, 2022 ยท View on GitHub

A fusion injector that reduce differences between x64, wow64 and x86 processes according to Mr.Rewolf's article.

Keywords: HEADER-ONLY, DLL-FREE, ANY-CALLEE, ANY-CALLER, ANY-WIN-OS, LOCAL-LIKE

license Mentioned in Awesome Go

Wiki

  • Wow64: Windows-on-Windows 64-bit, which 32-bit process works in.

Features

  • Cross x86 & x64 injection without any external *.dll or even *.lib:

    • x86 injector -> x86 process @ 32-bit OS
    • wow64 injector -> wow64 process @ 64-bit OS
    • wow64 injector -> x64 process @ 64-bit OS
    • x64 injector -> wow64 process @ 64-bit OS
    • x64 injector -> x64 process @ 64-bit OS
  • In-process call x64 functions / APIs for Wow64 process

  • Local-like remote call of target process

    • Remote call multi-params (more than one) windows API of target process
    • Remote call windows API that return 64-bit result of target process

How to use

  • X64Call example (Unload dll in remote process)

        X64Call RtlCreateUserThread("RtlCreateUserThread");
        // Validate RtlCreateUserThread
        if (!RtlCreateUserThread) return 0;
    
        X64Call LdrUnloadDll("LdrUnloadDll");
        // Validate LdrUnloadDll
        if (!LdrUnloadDll) return 0;
    
        // => local-like call
        DWORD64 ret = RtlCreateUserThread(hProcess, NULL, FALSE, 0, 0, NULL, LdrUnloadDll, dllBaseAddr, NULL, NULL);
    
    • Available constructors:

      • Specified module is allowed (ntdll.dll as default)

        X64Call(const char* funcName);
            
        X64Call(DWORD64 module, const char* funcName);
        
  • YAPICall example (MessageBox in remote process)

        YAPICall MessageBoxA(hProcess, _T("user32.dll"), "MessageBoxA");
    
        // => local-like call
        MessageBoxA(NULL, "MessageBoxA : Hello World!", "From ez8.co", MB_OK);
    
        YAPI(hProcess, _T("user32.dll"), MessageBoxW)
            (NULL, L"MessageBoxW: Hello World!", L"From ez8.co", MB_OK);
    
    • Available constructors:

      • Specified module or module name is allowed (ntdll.dll as default).

      • NOTICE: If failed to fetch 64-bit module, will automatically fetch 32-bit modules in wow64 process under 64-bit OS.

        YAPICall(HANDLE hProcess, const char* funcName);
        
        YAPICall(HANDLE hProcess, DWORD64 moudle, const char* funcName);
        
        YAPICall(HANDLE hProcess, const TCHAR* modName, const char* funcName);
        
  • 64-bit result example (GetModuleHandle of user32.dll under 64-bit OS)

        YAPICall GetModuleHandle(hProcess, _T("kernel32.dll"), sizeof(TCHAR) == sizeof(char) ? "GetModuleHandleA" : "GetModuleHandleW");
        DWORD64 user32Dll = GetModuleHandle.Dw64()(_T("user32.dll"));
    
  • Timeout example (GetCurrentProcessId in 300ms)

        YAPICall GetCurrentProcessId(hProcess, _T("kernel32.dll"), "GetCurrentProcessId");
        DWORD pid = GetCurrentProcessId.Timeout(300)();
    
  • Timeout & 64-bit result example (GetModuleHandle in 300ms)

        DWORD64 user32Dll = GetModuleHandle.Dw64().Timeout(300)(_T("user32.dll"));
    
  • Popular LoadLibrary example

        YAPICall LoadLibraryA(hProcess, _T("kernel32.dll"), "LoadLibraryA");
        DWORD64 x86Dll = LoadLibraryA("D:\\x86.dll");
        DWORD64 x64Dll = LoadLibraryA.Dw64()("D:\\x64.dll");
        _tprintf(_T("X86: %I64x\nX64: %I64x\n"), x86Dll, x64Dll);
    
  • API List:

    API Namex86 EquivalentNotes
    GetNtDll64
    GetModuleHandle64GetModuleHandleoverloaded version
    GetProcAddress64GetProcAddressoverloaded version
    SetLastError64SetLastError
    VirtualQueryEx64VirtualQueryEx
    VirtualAllocEx64VirtualAllocEx
    VirtualFreeEx64VirtualFreeEx
    VirtualProtectEx64VirtualProtectEx
    ReadProcessMemory64ReadProcessMemory
    WriteProcessMemory64WriteProcessMemory
    LoadLibrary64LoadLibrary
    CreateRemoteThread64CreateRemoteThread
  • Class List:

    Class Name32-bit OS Support64-bit OS Compatiblity
    X64Call:white_check_mark:NOT READY NOW
    ProcessWriter:white_check_mark::white_check_mark:
    YAPICall:white_check_mark::white_check_mark:

Inside principle

  • Nomal x64->x64, x86->x86 injection:

  • Multi-params windows API:

    • Pack function address and params in one structure and use shell code to execute in remote process.
    • See X86/X64Delegator_disassemble for details in disassemble directory.
  • x64 call for wow64 process:

  • x64 process inject to wow64 process:

    • Use trampoline:
      • CreateRemoteThread(x64): x64 shell code with x86 mode switch (1 arg: function->x86 shell code with one param, param->packed x86 structure) -> pass packed structure (x86 real to call function address and params) to x86 shell code -> pass params to real function.
    • NOTICE: function address(target module) should be valid in target process, but not needed in source injector.
  • 64-bit result:

    • Add a DWORD64 result field to package.
    • Obtain result if needed.
    • ReadProcessMemory after remote thread finished.

Compatibility

  • Operating systems that have been tested are shown in table below.

    Operating SystemNotes
    Windows 10Tested on 64-bit, should also work on 32-bit
    Windows 8Should work on both 64-bit and 32-bit
    Windows 7Tested on 64-bit, should also work on 32-bit
    Windows VistaShould work on both 64-bit and 32-bit
    Windows XPShould work on both 64-bit and 32-bit

References

Roadmap

  • More simple impl of X64Call.
  • 64-bit OS compatible support of X64Call.
  • Finish shell codes that more than 6 arguments for YAPICall.
  • Support to fetch specified bit module for YAPICall (32-bit or 64-bit).
  • Same function call (mirror call) automatically in remote process.
  • Self-defined function call in remote process.
  • IAT/inline hook in remote process.
  • Support other 7 optional inject methods.

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]


][Noname][

Contributors

This project exists thanks to all the people who contribute.

Please give us a ๐Ÿ’– star ๐Ÿ’– to support us. Thank you.

And thank you to all our backers! ๐Ÿ™

Misc

  • Please feel free to use yapi.
  • Looking forward to your suggestions.