yapi

by ez8-co

ez8-co / yapi

💉 全能进程注入器 [Yet Another Process Injector] that reduce differences between x64, wow64 and x86 process...

133 Stars 58 Forks Last release: Not found MIT License 43 Commits 0 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

YAPI -- Yet Another Process Injector

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 Name | x86 Equivalent | Notes | |---------------|------------------------|---------------| | GetNtDll64 | | | | GetModuleHandle64 | GetModuleHandle | overloaded version | | GetProcAddress64 | GetProcAddress | overloaded version | | SetLastError64 | SetLastError | | | VirtualQueryEx64 | VirtualQueryEx | | | VirtualAllocEx64 | VirtualAllocEx | | | VirtualFreeEx64 | VirtualFreeEx | | | VirtualProtectEx64 | VirtualProtectEx | | | ReadProcessMemory64 | ReadProcessMemory | | | WriteProcessMemory64 | WriteProcessMemory | | | LoadLibrary64 | LoadLibrary | | | CreateRemoteThread64 | CreateRemoteThread | |

  • Class List:

    | Class Name | 32-bit OS Support | 64-bit OS Compatiblity | |---------------|------------------------|---------------| | X64Call | :whitecheckmark: | NOT READY NOW | | ProcessWriter | :whitecheckmark: | :whitecheckmark: | | YAPICall | :whitecheckmark: | :whitecheckmark: |

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 System | Notes | |-----------------------|----------| | Windows 10 | Tested on 64-bit, should also work on 32-bit | | Windows 8 | Should work on both 64-bit and 32-bit | | Windows 7 | Tested on 64-bit, should also work on 32-bit | | Windows Vista | Should work on both 64-bit and 32-bit | | Windows XP | Should 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.

Misc

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

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.