├── LICENSE ├── README.md ├── demo ├── demo.cpp ├── demo.sln ├── demo.vcxproj ├── demo.vcxproj.filters ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── disas ├── X64Call_disassemble ├── X64Delegator_disassemble ├── X64toX86_disassemble ├── X86Delegator_disassemble └── X86toX64_disassemble └── yapi.hpp /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2010-2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YAPI -- Yet Another Process Injector 2 | A fusion injector that reduce differences between x64, wow64 and x86 processes according to [Mr.Rewolf's article](http://blog.rewolf.pl/blog/?p=102). 3 | 4 | **Keywords: HEADER-ONLY, DLL-FREE, ANY-CALLEE, ANY-CALLER, ANY-WIN-OS, LOCAL-LIKE** 5 | 6 | [![license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/ez8-co/yapi/blob/master/LICENSE) 7 | [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/ExpLife0011/awesome-windows-kernel-security-development#inject-technique-ring3) 8 | 9 | # Wiki 10 | 11 | - **Wow64**: Windows-on-Windows 64-bit, which 32-bit process works in. 12 | 13 | # Features 14 | 15 | - Cross x86 & x64 injection **without any external \*.dll or even \*.lib**: 16 | - x86 injector -> x86 process @ 32-bit OS 17 | - wow64 injector -> wow64 process @ 64-bit OS 18 | - wow64 injector -> x64 process @ 64-bit OS 19 | - x64 injector -> wow64 process @ 64-bit OS 20 | - x64 injector -> x64 process @ 64-bit OS 21 | 22 | - In-process call x64 functions / APIs for Wow64 process 23 | 24 | - Local-like remote call of target process 25 | - Remote call multi-params (more than one) windows API of target process 26 | - Remote call windows API that return 64-bit result of target process 27 | 28 | # How to use 29 | 30 | - `X64Call` example (Unload dll in remote process) 31 | 32 | ```cpp 33 | X64Call RtlCreateUserThread("RtlCreateUserThread"); 34 | // Validate RtlCreateUserThread 35 | if (!RtlCreateUserThread) return 0; 36 | 37 | X64Call LdrUnloadDll("LdrUnloadDll"); 38 | // Validate LdrUnloadDll 39 | if (!LdrUnloadDll) return 0; 40 | 41 | // => local-like call 42 | DWORD64 ret = RtlCreateUserThread(hProcess, NULL, FALSE, 0, 0, NULL, LdrUnloadDll, dllBaseAddr, NULL, NULL); 43 | ``` 44 | 45 | - Available constructors: 46 | 47 | - Specified module is allowed (`ntdll.dll` as default) 48 | 49 | ```cpp 50 | X64Call(const char* funcName); 51 | 52 | X64Call(DWORD64 module, const char* funcName); 53 | ``` 54 | 55 | - `YAPICall` example (`MessageBox` in remote process) 56 | 57 | ```cpp 58 | YAPICall MessageBoxA(hProcess, _T("user32.dll"), "MessageBoxA"); 59 | 60 | // => local-like call 61 | MessageBoxA(NULL, "MessageBoxA : Hello World!", "From ez8.co", MB_OK); 62 | 63 | YAPI(hProcess, _T("user32.dll"), MessageBoxW) 64 | (NULL, L"MessageBoxW: Hello World!", L"From ez8.co", MB_OK); 65 | ``` 66 | 67 | - Available constructors: 68 | 69 | - Specified module or module name is allowed (`ntdll.dll` as default). 70 | 71 | - **NOTICE: If failed to fetch 64-bit module, will automatically fetch 32-bit modules in wow64 process under 64-bit OS**. 72 | 73 | ```cpp 74 | YAPICall(HANDLE hProcess, const char* funcName); 75 | 76 | YAPICall(HANDLE hProcess, DWORD64 moudle, const char* funcName); 77 | 78 | YAPICall(HANDLE hProcess, const TCHAR* modName, const char* funcName); 79 | ``` 80 | 81 | - 64-bit result example (`GetModuleHandle` of `user32.dll` under 64-bit OS) 82 | 83 | ```cpp 84 | YAPICall GetModuleHandle(hProcess, _T("kernel32.dll"), sizeof(TCHAR) == sizeof(char) ? "GetModuleHandleA" : "GetModuleHandleW"); 85 | DWORD64 user32Dll = GetModuleHandle.Dw64()(_T("user32.dll")); 86 | ``` 87 | 88 | - `Timeout` example (`GetCurrentProcessId` in 300ms) 89 | 90 | ```cpp 91 | YAPICall GetCurrentProcessId(hProcess, _T("kernel32.dll"), "GetCurrentProcessId"); 92 | DWORD pid = GetCurrentProcessId.Timeout(300)(); 93 | ``` 94 | 95 | - `Timeout` & 64-bit result example (`GetModuleHandle` in 300ms) 96 | 97 | ```cpp 98 | DWORD64 user32Dll = GetModuleHandle.Dw64().Timeout(300)(_T("user32.dll")); 99 | ``` 100 | 101 | - **Popular `LoadLibrary` example** 102 | 103 | ```cpp 104 | YAPICall LoadLibraryA(hProcess, _T("kernel32.dll"), "LoadLibraryA"); 105 | DWORD64 x86Dll = LoadLibraryA("D:\\x86.dll"); 106 | DWORD64 x64Dll = LoadLibraryA.Dw64()("D:\\x64.dll"); 107 | _tprintf(_T("X86: %I64x\nX64: %I64x\n"), x86Dll, x64Dll); 108 | ``` 109 | 110 | - API List: 111 | 112 | | API Name | x86 Equivalent | Notes | 113 | |---------------|------------------------|---------------| 114 | | GetNtDll64 | | | 115 | | GetModuleHandle64 | GetModuleHandle | overloaded version | 116 | | GetProcAddress64 | GetProcAddress | overloaded version | 117 | | SetLastError64 | SetLastError | | 118 | | VirtualQueryEx64 | VirtualQueryEx | | 119 | | VirtualAllocEx64 | VirtualAllocEx | | 120 | | VirtualFreeEx64 | VirtualFreeEx | | 121 | | VirtualProtectEx64 | VirtualProtectEx | | 122 | | ReadProcessMemory64 | ReadProcessMemory | | 123 | | WriteProcessMemory64 | WriteProcessMemory | | 124 | | LoadLibrary64 | LoadLibrary | | 125 | | CreateRemoteThread64 | CreateRemoteThread | | 126 | 127 | - Class List: 128 | 129 | | Class Name | 32-bit OS Support | 64-bit OS Compatiblity | 130 | |---------------|------------------------|---------------| 131 | | X64Call | :white_check_mark: | NOT READY NOW | 132 | | ProcessWriter | :white_check_mark: | :white_check_mark: | 133 | | YAPICall | :white_check_mark: | :white_check_mark: | 134 | 135 | # Inside principle 136 | 137 | - Nomal x64->x64, x86->x86 injection: 138 | - Use `CreateRemoteThread` / `RtlCreateUserThread` 139 | - You can change other methods by yourself. 140 | - FYR: [fdiskyou/injectAllTheThings](https://github.com/fdiskyou/injectAllTheThings) 141 | 142 | - Multi-params windows API: 143 | - Pack function address and params in one structure and use shell code to execute in remote process. 144 | - See `X86/X64Delegator_disassemble` for details in [disassemble directory](https://github.com/ez8-co/yapi/tree/master/disas). 145 | 146 | - x64 call for wow64 process: 147 | - Switch to x64 mode 148 | - See [references](#references) for details. 149 | 150 | - x64 process inject to wow64 process: 151 | - **Use trampoline:** 152 | - `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. 153 | - **NOTICE: function address(target module) should be valid in target process, but not needed in source injector.** 154 | 155 | - 64-bit result: 156 | - Add a `DWORD64` result field to package. 157 | - Obtain result if needed. 158 | - `ReadProcessMemory` after remote thread finished. 159 | 160 | # Compatibility 161 | 162 | - Operating systems that have been tested are shown in table below. 163 | 164 | | Operating System | Notes | 165 | |-----------------------|----------| 166 | | Windows 10 | Tested on 64-bit, should also work on 32-bit | 167 | | Windows 8 | Should work on both 64-bit and 32-bit | 168 | | Windows 7 | Tested on 64-bit, should also work on 32-bit | 169 | | Windows Vista | Should work on both 64-bit and 32-bit | 170 | | Windows XP | Should work on both 64-bit and 32-bit | 171 | 172 | # References 173 | 174 | - [Mixing x86 with x64 code](http://blog.rewolf.pl/blog/?p=102) @rewolf 175 | 176 | # Roadmap 177 | 178 | - More simple impl of `X64Call`. 179 | - 64-bit OS compatible support of `X64Call`. 180 | - Finish shell codes that more than 6 arguments for `YAPICall`. 181 | - Support to fetch specified bit module for `YAPICall` (32-bit or 64-bit). 182 | - Same function call (mirror call) automatically in remote process. 183 | - Self-defined function call in remote process. 184 | - IAT/inline hook in remote process. 185 | - Support other 7 optional inject methods. 186 | 187 | 188 | 189 | ## Sponsors 190 | 191 | Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/yapi#sponsor)] 192 | 193 | 194 | 195 | 203 | 204 |
196 | 197 | 198 |
199 | ][Noname][ 200 |
201 |
202 |
205 | 206 | 207 | 208 | 209 | 210 | ## Contributors 211 | 212 | This project exists thanks to all the people who contribute. 213 | 214 | Please give us a 💖 star 💖 to support us. Thank you. 215 | 216 | And thank you to all our backers! 🙏 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | # Misc 225 | 226 | - Please feel free to use yapi. 227 | - Looking forward to your suggestions. 228 | -------------------------------------------------------------------------------- /demo/demo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | yapi demo 3 | 4 | Copyright (c) 2010-2018 5 | This library is released under the MIT License. 6 | 7 | Please see LICENSE file or visit https://github.com/ez8-co/yapi for details. 8 | */ 9 | #include "stdafx.h" 10 | #include "../yapi.hpp" 11 | 12 | using namespace yapi; 13 | 14 | int main() 15 | { 16 | #if 0 17 | // bellow shows how to use like windows API 18 | X64Call RtlCreateUserThread("RtlCreateUserThread"); 19 | if (!RtlCreateUserThread) return 0; 20 | X64Call LdrUnloadDll("LdrUnloadDll"); 21 | if (!LdrUnloadDll) return 0; 22 | 23 | HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 24 | PROCESSENTRY32 pe32 = { sizeof(pe32) }; 25 | if (Process32First(hSnapshot, &pe32)) { 26 | do { 27 | HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); 28 | BOOL isRemoteWow64 = FALSE; 29 | IsWow64Process(hProcess, &isRemoteWow64); 30 | if (!isRemoteWow64) { 31 | DWORD64 dllBaseAddr = GetModuleHandle64(hProcess, _T("x64.dll")); 32 | if (dllBaseAddr) { 33 | DWORD64 ret = RtlCreateUserThread(hProcess, NULL, FALSE, 0, 0, NULL, LdrUnloadDll, dllBaseAddr, NULL, NULL); 34 | } 35 | } 36 | } while (Process32Next(hSnapshot, &pe32)); 37 | } 38 | #endif 39 | 40 | #if 0 41 | typedef int (NTAPI *RTL_ADJUST_PRIVILEGE)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN); 42 | RTL_ADJUST_PRIVILEGE RtlAdjustPrivilege = (RTL_ADJUST_PRIVILEGE)GetProcAddress(detail::hNtDll, "RtlAdjustPrivilege"); 43 | RtlAdjustPrivilege(20, 1, 0, NULL); 44 | #endif 45 | 46 | HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 47 | PROCESSENTRY32 pe32 = { sizeof(pe32) }; 48 | if (Process32First(hSnapshot, &pe32)) { 49 | do { 50 | if (_tcsicmp(pe32.szExeFile, _T("explorer.exe"))) 51 | continue; 52 | HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); 53 | 54 | #if 1 55 | 56 | YAPICall MessageBoxA(hProcess, _T("user32.dll"), "MessageBoxA"); 57 | MessageBoxA(NULL, "MessageBoxA : Hello World!", "From ez8.co", MB_OK); 58 | 59 | YAPI(hProcess, _T("user32.dll"), MessageBoxW)(NULL, L"MessageBoxW: Hello World!", L"From ez8.co", MB_OK); 60 | 61 | YAPICall GetCurrentProcessId(hProcess, _T("kernel32.dll"), "GetCurrentProcessId"); 62 | DWORD pid = GetCurrentProcessId(); 63 | _tprintf(_T("[%d]%s => %d\n"), pe32.th32ProcessID, pe32.szExeFile, pid); 64 | 65 | YAPICall LoadLibraryA(hProcess, _T("kernel32.dll"), "LoadLibraryA"); 66 | DWORD64 x86Dll = LoadLibraryA("D:\\x86.dll"); 67 | DWORD64 x64Dll = LoadLibraryA.Dw64()("D:\\x64.dll"); 68 | _tprintf(_T("X86: %I64x\nX64: %I64x\n"), x86Dll, x64Dll); 69 | 70 | #else 71 | 72 | extern void MyMessageBox(HANDLE hProcess); 73 | MyMessageBox(hProcess); 74 | 75 | #endif 76 | 77 | } while (Process32Next(hSnapshot, &pe32)); 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | #if 0 84 | void MyMessageBox(HANDLE hProcess) 85 | { 86 | 87 | DWORD64 user32Dll = GetModuleHandle64(hProcess, _T("user32.dll")); 88 | if (!user32Dll) return; 89 | 90 | // sample show you how to solve CreateRemoteThread + GetExitCodeThread return partial (4/8 bytes) result problem under x64 91 | // method 1: 92 | // extern DWORD64 WINAPI GetModuleHandleDw64(HANDLE hProcess, const TCHAR* moduleName); 93 | // DWORD64 user32Dll2 = GetModuleHandleDw64(hProcess, _T("user32.dll")); 94 | 95 | // method 2: 96 | // YAPICall GetModuleHandle(hProcess, _T("kernel32.dll"), sizeof(TCHAR) == sizeof(char) ? "GetModuleHandleA" : "GetModuleHandleW"); 97 | // DWORD64 user32Dll1 = GetModuleHandle.Dw64()(_T("user32.dll")); 98 | 99 | /* 100 | DWORD WINAPI MessageBoxDelegator(MessageBoxParam* param) 101 | { 102 | 00152A10 55 push ebp 103 | 00152A11 8B EC mov ebp,esp 104 | 00152A13 51 push ecx 105 | return param ? (param->MessageBoxA(param->hWnd, param->lpCaption, param->lpText, param->uType)) : 0; 106 | 00152A14 83 7D 08 00 cmp dword ptr [param],0 107 | 00152A18 74 28 je Delegator+32h (0152A42h) 108 | 00152A1A 8B 45 08 mov eax,dword ptr [param] 109 | 00152A1D 8B 48 10 mov ecx,dword ptr [eax+10h] 110 | 00152A20 51 push ecx 111 | 00152A21 8B 55 08 mov edx,dword ptr [param] 112 | 00152A24 8B 42 0C mov eax,dword ptr [edx+0Ch] 113 | 00152A27 50 push eax 114 | 00152A28 8B 4D 08 mov ecx,dword ptr [param] 115 | 00152A2B 8B 51 08 mov edx,dword ptr [ecx+8] 116 | 00152A2E 52 push edx 117 | 00152A2F 8B 45 08 mov eax,dword ptr [param] 118 | 00152A32 8B 48 04 mov ecx,dword ptr [eax+4] 119 | 00152A35 51 push ecx 120 | 00152A36 8B 55 08 mov edx,dword ptr [param] 121 | 00152A39 8B 02 mov eax,dword ptr [edx] 122 | 00152A3B FF D0 call eax 123 | 00152A3D 89 45 FC mov dword ptr [ebp-4],eax 124 | 00152A40 EB 07 jmp Delegator+39h (0152A49h) 125 | 00152A42 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 126 | 00152A49 8B 45 FC mov eax,dword ptr [ebp-4] 127 | } 128 | 00152A4C 8B E5 mov esp,ebp 129 | 00152A4E 5D pop ebp 130 | 00152A4F C3 ret 131 | */ 132 | /* 133 | DWORD WINAPI MessageBoxDelegator(MessageBoxParam* param) 134 | { 135 | 00007FF69EAA1080 48 8B C1 mov rax,rcx 136 | return param ? (param->MessageBoxA(param->hWnd, param->lpCaption, param->lpText, param->uType)) : 0; 137 | 00007FF69EAA1083 48 85 C9 test rcx,rcx 138 | 00007FF69EAA1086 74 13 je MessageBoxDelegator+1Bh (07FF69EAA109Bh) 139 | 00007FF69EAA1088 44 8B 49 20 mov r9d,dword ptr [rcx+20h] 140 | 00007FF69EAA108C 4C 8B 41 10 mov r8,qword ptr [rcx+10h] 141 | 00007FF69EAA1090 48 8B 51 18 mov rdx,qword ptr [rcx+18h] 142 | 00007FF69EAA1094 48 8B 49 08 mov rcx,qword ptr [rcx+8] 143 | 00007FF69EAA1098 48 FF 20 jmp qword ptr [rax] 144 | 00007FF69EAA109B 33 C0 xor eax,eax 145 | } 146 | 00007FF69EAA109D C3 ret 147 | */ 148 | const unsigned char shellcode_x86[] = { 0x55, 0x8b, 0xec, 0x51, 0x83, 0x7d, 0x08, 0x00, 0x74, 0x28, 0x8b, 0x45, 0x08, 0x8b, 0x48, 0x10, 149 | 0x51, 0x8b, 0x55, 0x08, 0x8b, 0x42, 0x0c, 0x50, 0x8b, 0x4d, 0x08, 0x8b, 0x51, 0x08, 0x52, 0x8b, 150 | 0x45, 0x08, 0x8b, 0x48, 0x04, 0x51, 0x8b, 0x55, 0x08, 0x8b, 0x02, 0xff, 0xd0, 0x89, 0x45, 0xfc, 151 | 0xeb, 0x07, 0xc7, 0x45, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x45, 0xfc, 0x8b, 0xe5, 0x5d, 0xc3 }; 152 | const unsigned char shellcode[] = { 0x48, 0x8b, 0xc1, 0x48, 0x85, 0xc9, 0x74, 0x13, 0x44, 0x8b, 0x49, 0x20, 0x4c, 0x8b, 0x41, 0x10, 153 | 0x48, 0x8b, 0x51, 0x18, 0x48, 0x8b, 0x49, 0x08, 0x48, 0xff, 0x20, 0x33, 0xc0, 0xc3 }; 154 | 155 | struct MessageBoxParam { 156 | DWORD64 MessageBoxA; 157 | DWORD64 hWnd; 158 | DWORD64 lpCaption; 159 | DWORD64 lpText; 160 | DWORD64 uType; 161 | } param = { NULL, NULL, NULL, MB_OK }; 162 | 163 | struct MessageBoxParam1 { 164 | DWORD MessageBoxA; 165 | DWORD hWnd; 166 | DWORD lpCaption; 167 | DWORD lpText; 168 | DWORD uType; 169 | } param1 = { NULL, NULL, NULL, MB_OK }; 170 | 171 | const TCHAR* szCaption = _T("From ez8.co"); 172 | const TCHAR* szText = _T("Hello World!"); 173 | 174 | #ifdef UNICODE 175 | param.MessageBoxA = GetProcAddress64(hProcess, user32Dll, "MessageBoxW"); 176 | #else 177 | param.MessageBoxA = GetProcAddress64(hProcess, user32Dll, "MessageBoxA"); 178 | #endif 179 | 180 | if (!param.MessageBoxA) return; 181 | 182 | ProcessWriter caption(hProcess, szCaption, (lstrlen(szCaption) + 1) * sizeof(TCHAR)); 183 | if (!(param.lpCaption = caption)) return; 184 | 185 | ProcessWriter text(hProcess, szText, (lstrlen(szText) + 1) * sizeof(TCHAR)); 186 | if (!(param.lpText = text)) return; 187 | 188 | param1.MessageBoxA = param.MessageBoxA; 189 | param1.lpCaption = param.lpCaption; 190 | param1.lpText = param.lpText; 191 | ProcessWriter p(hProcess, detail::is64BitOS ? (const void*)¶m : (const void*)¶m1, detail::is64BitOS ? sizeof(param) : sizeof(param1)); 192 | if (!p) return; 193 | 194 | ProcessWriter sc(hProcess, detail::is64BitOS ? shellcode : shellcode_x86, (detail::is64BitOS ? sizeof(shellcode) : sizeof(shellcode_x86)) + 1, PAGE_EXECUTE_READWRITE); 195 | if (!sc) return; 196 | sc.SetDontRelese(); 197 | 198 | HANDLE hThread = CreateRemoteThread64(hProcess, NULL, 0, sc, p, 0, NULL); 199 | WaitForSingleObject(hThread, 1000); 200 | CloseHandle(hThread); 201 | } 202 | 203 | DWORD64 WINAPI GetModuleHandleDw64(HANDLE hProcess, const TCHAR* moduleName) 204 | { 205 | ProcessWriter modName(hProcess, moduleName, (lstrlen(moduleName) + 1) * sizeof(TCHAR)); 206 | if (!modName) return NULL; 207 | 208 | DWORD64 hKernel32 = GetModuleHandle64(hProcess, _T("kernel32.dll")); 209 | struct Param { 210 | DWORD64 func; 211 | DWORD64 arg; 212 | DWORD64 result; 213 | } param = { GetProcAddress64(hProcess, hKernel32, 214 | #ifdef UNICODE 215 | "GetModuleHandleW" 216 | #else 217 | "GetModuleHandleA" 218 | #endif // !UNICODE 219 | ), modName, NULL }; 220 | if (!param.func) return NULL; 221 | 222 | ProcessWriter p(hProcess, ¶m, sizeof(param)); 223 | if (!p) return NULL; 224 | 225 | const unsigned char shellcode_x86[] = { 0x56, 0x8b, 0xf1, 0x85, 0xf6, 0x74, 0x0e, 0xff, 0x76, 0x08, 0x8b, 0x06, 0xff, 0xd0, 0x99, 0x89, 226 | 0x46, 0x10, 0x89, 0x56, 0x14, 0x33, 0xc0, 0x5e, 0xc3 }; 227 | const unsigned char shellcode[] = { 0x40, 0x53, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, 0xd9, 0x48, 0x85, 0xc9, 0x74, 0x0a, 0x48, 0x8b, 228 | 0x49, 0x08, 0xff, 0x13, 0x48, 0x89, 0x43, 0x10, 0x33, 0xc0, 0x48, 0x83, 0xc4, 0x20, 0x5b, 0xc3 }; 229 | /* 230 | DWORD WINAPI helpler(ParamX* param) { 231 | 00B62320 56 push esi 232 | 00B62321 8B F1 mov esi,ecx 233 | 22: if (param) param->result = param->func((LPCSTR)param->arg); 234 | 00B62323 85 F6 test esi,esi 235 | 00B62325 74 0E je helpler+15h (0B62335h) 236 | 00B62327 FF 76 08 push dword ptr [esi+8] 237 | 00B6232A 8B 06 mov eax,dword ptr [esi] 238 | 00B6232C FF D0 call eax 239 | 00B6232E 99 cdq 240 | 00B6232F 89 46 10 mov dword ptr [esi+10h],eax 241 | 00B62332 89 56 14 mov dword ptr [esi+14h],edx 242 | 23: return 0; 243 | 00B62335 33 C0 xor eax,eax 244 | 00B62337 5E pop esi 245 | 24: } 246 | 00B62338 C3 ret 247 | */ 248 | /* 249 | DWORD WINAPI helpler(Param* param) { 250 | 00007FF7E0E81080 40 53 push rbx 251 | 00007FF7E0E81082 48 83 EC 20 sub rsp,20h 252 | 00007FF7E0E81086 48 8B D9 mov rbx,rcx 253 | 91: if(param) param->result = param->func(param->arg); 254 | 00007FF7E0E81089 48 85 C9 test rcx,rcx 255 | 00007FF7E0E8108C 74 0A je helpler+18h (07FF7E0E81098h) 256 | 00007FF7E0E8108E 48 8B 49 08 mov rcx,qword ptr [rcx+8] 257 | 00007FF7E0E81092 FF 13 call qword ptr [rbx] 258 | 00007FF7E0E81094 48 89 43 10 mov qword ptr [rbx+10h],rax 259 | 92: return 0; 260 | 00007FF7E0E81098 33 C0 xor eax,eax 261 | 93: } 262 | 00007FF7E0E8109A 48 83 C4 20 add rsp,20h 263 | 00007FF7E0E8109E 5B pop rbx 264 | 00007FF7E0E8109F C3 ret 265 | */ 266 | ProcessWriter sc(hProcess, detail::is64BitOS ? shellcode : shellcode_x86, (detail::is64BitOS ? sizeof(shellcode) : sizeof(shellcode_x86)) + 1, PAGE_EXECUTE_READWRITE); 267 | if (!sc) return NULL; 268 | 269 | HANDLE hThread = CreateRemoteThread64(hProcess, NULL, 100, sc, p, 0, NULL); 270 | if (!hThread) return FALSE; 271 | WaitForSingleObject(hThread, 1000); 272 | CloseHandle(hThread); 273 | 274 | ReadProcessMemory64(hProcess, p, ¶m, sizeof(param), NULL); 275 | return param.result; 276 | } 277 | #endif 278 | -------------------------------------------------------------------------------- /demo/demo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2026 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "demo.vcxproj", "{23491250-AA07-4046-97C5-9B607FCD6E42}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {23491250-AA07-4046-97C5-9B607FCD6E42}.Debug|x64.ActiveCfg = Debug|x64 17 | {23491250-AA07-4046-97C5-9B607FCD6E42}.Debug|x64.Build.0 = Debug|x64 18 | {23491250-AA07-4046-97C5-9B607FCD6E42}.Debug|x86.ActiveCfg = Debug|Win32 19 | {23491250-AA07-4046-97C5-9B607FCD6E42}.Debug|x86.Build.0 = Debug|Win32 20 | {23491250-AA07-4046-97C5-9B607FCD6E42}.Release|x64.ActiveCfg = Release|x64 21 | {23491250-AA07-4046-97C5-9B607FCD6E42}.Release|x64.Build.0 = Release|x64 22 | {23491250-AA07-4046-97C5-9B607FCD6E42}.Release|x86.ActiveCfg = Release|Win32 23 | {23491250-AA07-4046-97C5-9B607FCD6E42}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {1DE3D280-61E5-4831-BA5E-6B1DC7256076} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /demo/demo.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {23491250-AA07-4046-97C5-9B607FCD6E42} 24 | Win32Proj 25 | demo 26 | 10.0.16299.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | true 91 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | true 93 | 94 | 95 | Console 96 | true 97 | 98 | 99 | 100 | 101 | Use 102 | Level3 103 | Disabled 104 | true 105 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 106 | true 107 | 108 | 109 | Console 110 | true 111 | 112 | 113 | 114 | 115 | Use 116 | Level3 117 | Disabled 118 | true 119 | true 120 | true 121 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 122 | true 123 | 124 | 125 | Console 126 | true 127 | true 128 | true 129 | 130 | 131 | 132 | 133 | Use 134 | Level3 135 | Disabled 136 | true 137 | true 138 | true 139 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 140 | true 141 | 142 | 143 | Console 144 | true 145 | true 146 | true 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | Create 158 | Create 159 | Create 160 | Create 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /demo/demo.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 头文件 26 | 27 | 28 | 29 | 30 | 源文件 31 | 32 | 33 | 源文件 34 | 35 | 36 | -------------------------------------------------------------------------------- /demo/stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ez8-co/yapi/a700188cc4cbbc48b3da8254ec5d433a1de47fb4/demo/stdafx.cpp -------------------------------------------------------------------------------- /demo/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ez8-co/yapi/a700188cc4cbbc48b3da8254ec5d433a1de47fb4/demo/stdafx.h -------------------------------------------------------------------------------- /demo/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ez8-co/yapi/a700188cc4cbbc48b3da8254ec5d433a1de47fb4/demo/targetver.h -------------------------------------------------------------------------------- /disas/X64Call_disassemble: -------------------------------------------------------------------------------- 1 | 55 push ebp 2 | 8B EC mov ebp,esp 3 | 8B 4D 10 mov ecx,dword ptr [argC] 4 | 8D 55 14 lea edx,[ebp+14h] 5 | 83 EC 40 sub esp,40h 6 | 53 push ebx 7 | 56 push esi 8 | 57 push edi 9 | 85 C9 test ecx,ecx 10 | 7E 15 jle X64Call+28h () 11 | 8B 45 14 mov eax,dword ptr [ebp+14h] 12 | 8D 55 1C lea edx,[ebp+1Ch] 13 | 49 dec ecx 14 | 89 45 F0 mov dword ptr [_rcx],eax 15 | 8B 45 18 mov eax,dword ptr [ebp+18h] 16 | 89 4D 10 mov dword ptr [argC],ecx 17 | 89 45 F4 mov dword ptr [ebp-0Ch],eax 18 | EB 08 jmp X64Call+30h () 19 | 0F 57 C0 xorps xmm0,xmm0 20 | 66 0F 13 45 F0 movlpd qword ptr [_rcx],xmm0 21 | 85 C9 test ecx,ecx 22 | 7E 15 jle X64Call+49h () 23 | 49 dec ecx 24 | 83 C2 08 add edx,8 25 | 89 4D 10 mov dword ptr [argC],ecx 26 | 8B 42 F8 mov eax,dword ptr [edx-8] 27 | 89 45 E8 mov dword ptr [_rdx],eax 28 | 8B 42 FC mov eax,dword ptr [edx-4] 29 | 89 45 EC mov dword ptr [ebp-14h],eax 30 | EB 08 jmp X64Call+51h () 31 | 0F 57 C0 xorps xmm0,xmm0 32 | 66 0F 13 45 E8 movlpd qword ptr [_rdx],xmm0 33 | 85 C9 test ecx,ecx 34 | 7E 15 jle X64Call+6Ah () 35 | 49 dec ecx 36 | 83 C2 08 add edx,8 37 | 89 4D 10 mov dword ptr [argC],ecx 38 | 8B 42 F8 mov eax,dword ptr [edx-8] 39 | 89 45 E0 mov dword ptr [_r8],eax 40 | 8B 42 FC mov eax,dword ptr [edx-4] 41 | 89 45 E4 mov dword ptr [ebp-1Ch],eax 42 | EB 08 jmp X64Call+72h () 43 | 0F 57 C0 xorps xmm0,xmm0 44 | 66 0F 13 45 E0 movlpd qword ptr [_r8],xmm0 45 | 85 C9 test ecx,ecx 46 | 7E 15 jle X64Call+8Bh () 47 | 49 dec ecx 48 | 83 C2 08 add edx,8 49 | 89 4D 10 mov dword ptr [argC],ecx 50 | 8B 42 F8 mov eax,dword ptr [edx-8] 51 | 89 45 D8 mov dword ptr [_r9],eax 52 | 8B 42 FC mov eax,dword ptr [edx-4] 53 | 89 45 DC mov dword ptr [ebp-24h],eax 54 | EB 08 jmp X64Call+93h () 55 | 0F 57 C0 xorps xmm0,xmm0 56 | 66 0F 13 45 D8 movlpd qword ptr [_r9],xmm0 57 | 8B C2 mov eax,edx 58 | C7 45 FC 00 00 00 00 mov dword ptr [back_esp],0 59 | 99 cdq 60 | 0F 57 C0 xorps xmm0,xmm0 61 | 89 45 C0 mov dword ptr [restArgs],eax 62 | 8B C1 mov eax,ecx 63 | 89 55 C4 mov dword ptr [ebp-3Ch],edx 64 | 99 cdq 65 | 66 0F 13 45 C8 movlpd qword ptr [_rax],xmm0 66 | 89 45 D0 mov dword ptr [_argC],eax 67 | 89 55 D4 mov dword ptr [ebp-2Ch],edx 68 | C7 45 F8 00 00 00 00 mov dword ptr [back_fs],0 69 | 66 8C 65 F8 mov word ptr [back_fs],fs 70 | B8 2B 00 00 00 mov eax,2Bh 71 | 66 8E E0 mov fs,ax 72 | 89 65 FC mov dword ptr [back_esp],esp 73 | 83 E4 F0 and esp,0FFFFFFF0h 74 | 6A 33 push 33h 75 | E8 00 00 00 00 call X64Call+0D4h () 76 | 83 04 24 05 add dword ptr [esp],5 77 | CB retf 78 | 48 dec eax 79 | 8B 4D F0 mov ecx,dword ptr [_rcx] 80 | 48 dec eax 81 | 8B 55 E8 mov edx,dword ptr [_rdx] 82 | FF 75 E0 push dword ptr [_r8] 83 | 49 dec ecx 84 | 58 pop eax 85 | FF 75 D8 push dword ptr [_r9] 86 | 49 dec ecx 87 | 59 pop ecx 88 | 48 dec eax 89 | 8B 45 D0 mov eax,dword ptr [_argC] 90 | A8 01 test al,1 91 | 75 03 jne X64Call+0F6h () 92 | 83 EC 08 sub esp,8 93 | 57 push edi 94 | 48 dec eax 95 | 8B 7D C0 mov edi,dword ptr [restArgs] 96 | 48 dec eax 97 | 85 C0 test eax,eax 98 | 74 16 je _ls+11h () 99 | 48 dec eax 100 | 8D 7C C7 F8 lea edi,[edi+eax*8-8] 101 | 48 dec eax 102 | 85 C0 test eax,eax 103 | 74 0C je _ls+11h () 104 | FF 37 push dword ptr [edi] 105 | 48 dec eax 106 | 83 EF 08 sub edi,8 107 | 48 dec eax 108 | 83 E8 01 sub eax,1 109 | EB EF jmp _ls () 110 | 48 dec eax 111 | 83 EC 20 sub esp,20h 112 | FF 55 08 call dword ptr [func] 113 | 48 dec eax 114 | 8B 4D D0 mov ecx,dword ptr [_argC] 115 | 48 dec eax 116 | 8D 64 CC 20 lea esp,[esp+ecx*8+20h] 117 | 5F pop edi 118 | 48 dec eax 119 | 89 45 C8 mov dword ptr [_rax],eax 120 | E8 00 00 00 00 call _ls+2Bh () 121 | C7 44 24 04 23 00 00 00 mov dword ptr [esp+4],23h 122 | 83 04 24 0D add dword ptr [esp],0Dh 123 | CB retf 124 | 66 8C D8 mov ax,ds 125 | 66 8E D0 mov ss,ax 126 | 8B 65 FC mov esp,dword ptr [back_esp] 127 | 66 8B 45 F8 mov ax,word ptr [back_fs] 128 | 66 8E E0 mov fs,ax 129 | 8B 45 C8 mov eax,dword ptr [_rax] 130 | 8B 55 CC mov edx,dword ptr [ebp-34h] 131 | 5F pop edi 132 | 5E pop esi 133 | 5B pop ebx 134 | 8B E5 mov esp,ebp 135 | 5D pop ebp 136 | C3 ret -------------------------------------------------------------------------------- /disas/X64Delegator_disassemble: -------------------------------------------------------------------------------- 1 | 0 arg 2 | 3 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 4 | 105: { 5 | 00007FF75E922750 40 53 push rbx 6 | 00007FF75E922752 48 83 EC 20 sub rsp,20h 7 | 00007FF75E922756 48 8B D9 mov rbx,rcx 8 | 106: return param ? (param->ret ? (param->ret = param->func()) 9 | 00007FF75E922759 48 85 C9 test rcx,rcx 10 | 00007FF75E92275C 74 1D je Delegator+2Bh (07FF75E92277Bh) 11 | 00007FF75E92275E 48 83 39 00 cmp qword ptr [rcx],0 12 | 00007FF75E922762 48 8B 41 08 mov rax,qword ptr [rcx+8] 13 | 00007FF75E922766 74 0B je Delegator+23h (07FF75E922773h) 14 | 00007FF75E922768 FF D0 call rax 15 | 00007FF75E92276A 48 89 03 mov qword ptr [rbx],rax 16 | 107: : (param->func())) : 0; 17 | 108: } 18 | 00007FF75E92276D 48 83 C4 20 add rsp,20h 19 | 00007FF75E922771 5B pop rbx 20 | 00007FF75E922772 C3 ret 21 | 00007FF75E922773 48 83 C4 20 add rsp,20h 22 | 00007FF75E922777 5B pop rbx 23 | 106: return param ? (param->ret ? (param->ret = param->func()) 24 | 00007FF75E922778 48 FF E0 jmp rax 25 | 00007FF75E92277B 33 C0 xor eax,eax 26 | 107: : (param->func())) : 0; 27 | 108: } 28 | 00007FF75E92277D 48 83 C4 20 add rsp,20h 29 | 00007FF75E922781 5B pop rbx 30 | 00007FF75E922782 C3 ret 31 | 32 | 1 arg 33 | 34 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 35 | 105: { 36 | 00007FF717592750 40 53 push rbx 37 | 00007FF717592752 48 83 EC 20 sub rsp,20h 38 | 00007FF717592756 48 8B D9 mov rbx,rcx 39 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1)) 40 | 00007FF717592759 48 85 C9 test rcx,rcx 41 | 00007FF71759275C 74 21 je Delegator+2Fh (07FF71759277Fh) 42 | 00007FF71759275E 48 83 3B 00 cmp qword ptr [rbx],0 43 | 00007FF717592762 48 8B 41 08 mov rax,qword ptr [rcx+8] 44 | 00007FF717592766 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 45 | 00007FF71759276A 74 0B je Delegator+27h (07FF717592777h) 46 | 00007FF71759276C FF D0 call rax 47 | 00007FF71759276E 48 89 03 mov qword ptr [rbx],rax 48 | 107: : (param->func(param->arg1))) : 0; 49 | 108: } 50 | 00007FF717592771 48 83 C4 20 add rsp,20h 51 | 00007FF717592775 5B pop rbx 52 | 00007FF717592776 C3 ret 53 | 00007FF717592777 48 83 C4 20 add rsp,20h 54 | 00007FF71759277B 5B pop rbx 55 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1)) 56 | 00007FF71759277C 48 FF E0 jmp rax 57 | 00007FF71759277F 33 C0 xor eax,eax 58 | 107: : (param->func(param->arg1))) : 0; 59 | 108: } 60 | 00007FF717592781 48 83 C4 20 add rsp,20h 61 | 00007FF717592785 5B pop rbx 62 | 00007FF717592786 C3 ret 63 | 64 | 2 arg 65 | 66 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 67 | 105: { 68 | 00007FF66CCA2750 40 53 push rbx 69 | 00007FF66CCA2752 48 83 EC 20 sub rsp,20h 70 | 00007FF66CCA2756 48 8B D9 mov rbx,rcx 71 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2)) 72 | 00007FF66CCA2759 48 85 C9 test rcx,rcx 73 | 00007FF66CCA275C 74 25 je Delegator+33h (07FF66CCA2783h) 74 | 00007FF66CCA275E 48 83 3B 00 cmp qword ptr [rbx],0 75 | 00007FF66CCA2762 48 8B 41 08 mov rax,qword ptr [rcx+8] 76 | 00007FF66CCA2766 48 8B 51 18 mov rdx,qword ptr [rcx+18h] 77 | 00007FF66CCA276A 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 78 | 00007FF66CCA276E 74 0B je Delegator+2Bh (07FF66CCA277Bh) 79 | 00007FF66CCA2770 FF D0 call rax 80 | 00007FF66CCA2772 48 89 03 mov qword ptr [rbx],rax 81 | 107: : (param->func(param->arg1, param->arg2))) : 0; 82 | 108: } 83 | 00007FF66CCA2775 48 83 C4 20 add rsp,20h 84 | 00007FF66CCA2779 5B pop rbx 85 | 00007FF66CCA277A C3 ret 86 | 00007FF66CCA277B 48 83 C4 20 add rsp,20h 87 | 00007FF66CCA277F 5B pop rbx 88 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2)) 89 | 00007FF66CCA2780 48 FF E0 jmp rax 90 | 00007FF66CCA2783 33 C0 xor eax,eax 91 | 107: : (param->func(param->arg1, param->arg2))) : 0; 92 | 108: } 93 | 00007FF66CCA2785 48 83 C4 20 add rsp,20h 94 | 107: : (param->func(param->arg1, param->arg2))) : 0; 95 | 108: } 96 | 00007FF66CCA2789 5B pop rbx 97 | 00007FF66CCA278A C3 ret 98 | 99 | 3 arg 100 | 101 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 102 | 105: { 103 | 00007FF658E62750 40 53 push rbx 104 | 00007FF658E62752 48 83 EC 20 sub rsp,20h 105 | 00007FF658E62756 48 8B D9 mov rbx,rcx 106 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3)) 107 | 00007FF658E62759 48 85 C9 test rcx,rcx 108 | 00007FF658E6275C 74 29 je Delegator+37h (07FF658E62787h) 109 | 00007FF658E6275E 48 83 3B 00 cmp qword ptr [rbx],0 110 | 00007FF658E62762 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 111 | 00007FF658E62766 48 8B 43 08 mov rax,qword ptr [rbx+8] 112 | 00007FF658E6276A 4C 8B 43 20 mov r8,qword ptr [rbx+20h] 113 | 00007FF658E6276E 48 8B 53 18 mov rdx,qword ptr [rbx+18h] 114 | 00007FF658E62772 74 0B je Delegator+2Fh (07FF658E6277Fh) 115 | 00007FF658E62774 FF D0 call rax 116 | 00007FF658E62776 48 89 03 mov qword ptr [rbx],rax 117 | 107: : (param->func(param->arg1, param->arg2, param->arg3))) : 0; 118 | 108: } 119 | 00007FF658E62779 48 83 C4 20 add rsp,20h 120 | 00007FF658E6277D 5B pop rbx 121 | 00007FF658E6277E C3 ret 122 | 00007FF658E6277F 48 83 C4 20 add rsp,20h 123 | 00007FF658E62783 5B pop rbx 124 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3)) 125 | 00007FF658E62784 48 FF E0 jmp rax 126 | 00007FF658E62787 33 C0 xor eax,eax 127 | 107: : (param->func(param->arg1, param->arg2, param->arg3))) : 0; 128 | 108: } 129 | 00007FF658E62789 48 83 C4 20 add rsp,20h 130 | 00007FF658E6278D 5B pop rbx 131 | 00007FF658E6278E C3 ret 132 | 133 | 4 arg 134 | 135 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 136 | 105: { 137 | 00007FF733F328D0 40 53 push rbx 138 | 00007FF733F328D2 48 83 EC 20 sub rsp,20h 139 | 00007FF733F328D6 48 8B D9 mov rbx,rcx 140 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4)) 141 | 00007FF733F328D9 48 85 C9 test rcx,rcx 142 | 00007FF733F328DC 74 2D je Delegator+3Bh (07FF733F3290Bh) 143 | 00007FF733F328DE 48 83 3B 00 cmp qword ptr [rbx],0 144 | 00007FF733F328E2 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 145 | 00007FF733F328E6 48 8B 43 08 mov rax,qword ptr [rbx+8] 146 | 00007FF733F328EA 4C 8B 4B 28 mov r9,qword ptr [rbx+28h] 147 | 00007FF733F328EE 4C 8B 43 20 mov r8,qword ptr [rbx+20h] 148 | 00007FF733F328F2 48 8B 53 18 mov rdx,qword ptr [rbx+18h] 149 | 00007FF733F328F6 74 0B je Delegator+33h (07FF733F32903h) 150 | 00007FF733F328F8 FF D0 call rax 151 | 00007FF733F328FA 48 89 03 mov qword ptr [rbx],rax 152 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4))) : 0; 153 | 108: } 154 | 00007FF733F328FD 48 83 C4 20 add rsp,20h 155 | 00007FF733F32901 5B pop rbx 156 | 00007FF733F32902 C3 ret 157 | 00007FF733F32903 48 83 C4 20 add rsp,20h 158 | 00007FF733F32907 5B pop rbx 159 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4)) 160 | 00007FF733F32908 48 FF E0 jmp rax 161 | 00007FF733F3290B 33 C0 xor eax,eax 162 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4))) : 0; 163 | 108: } 164 | 00007FF733F3290D 48 83 C4 20 add rsp,20h 165 | 00007FF733F32911 5B pop rbx 166 | 00007FF733F32912 C3 ret 167 | 168 | 5 arg 169 | 170 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 171 | 105: { 172 | 00007FF66C2128D0 40 53 push rbx 173 | 00007FF66C2128D2 48 83 EC 30 sub rsp,30h 174 | 00007FF66C2128D6 48 8B D9 mov rbx,rcx 175 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5)) 176 | 00007FF66C2128D9 48 85 C9 test rcx,rcx 177 | 00007FF66C2128DC 74 36 je Delegator+44h (07FF66C212914h) 178 | 00007FF66C2128DE 48 83 3B 00 cmp qword ptr [rbx],0 179 | 00007FF66C2128E2 4C 8B 53 30 mov r10,qword ptr [rbx+30h] 180 | 00007FF66C2128E6 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 181 | 00007FF66C2128EA 48 8B 43 08 mov rax,qword ptr [rbx+8] 182 | 00007FF66C2128EE 4C 8B 4B 28 mov r9,qword ptr [rbx+28h] 183 | 00007FF66C2128F2 4C 8B 43 20 mov r8,qword ptr [rbx+20h] 184 | 00007FF66C2128F6 48 8B 53 18 mov rdx,qword ptr [rbx+18h] 185 | 00007FF66C2128FA 4C 89 54 24 20 mov qword ptr [rsp+20h],r10 186 | 00007FF66C2128FF 74 0B je Delegator+3Ch (07FF66C21290Ch) 187 | 00007FF66C212901 FF D0 call rax 188 | 00007FF66C212903 48 89 03 mov qword ptr [rbx],rax 189 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5))) : 0; 190 | 108: } 191 | 00007FF66C212906 48 83 C4 30 add rsp,30h 192 | 00007FF66C21290A 5B pop rbx 193 | 00007FF66C21290B C3 ret 194 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5)) 195 | 00007FF66C21290C FF D0 call rax 196 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5))) : 0; 197 | 108: } 198 | 00007FF66C21290E 48 83 C4 30 add rsp,30h 199 | 00007FF66C212912 5B pop rbx 200 | 00007FF66C212913 C3 ret 201 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5)) 202 | 00007FF66C212914 33 C0 xor eax,eax 203 | 00007FF66C212916 48 83 C4 30 add rsp,30h 204 | 00007FF66C21291A 5B pop rbx 205 | 00007FF66C21291B C3 ret 206 | 207 | 6 arg 208 | 209 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 210 | 105: { 211 | 00007FF72BE328D0 40 53 push rbx 212 | 00007FF72BE328D2 48 83 EC 30 sub rsp,30h 213 | 00007FF72BE328D6 48 8B D9 mov rbx,rcx 214 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6)) 215 | 00007FF72BE328D9 48 85 C9 test rcx,rcx 216 | 00007FF72BE328DC 74 3F je Delegator+4Dh (07FF72BE3291Dh) 217 | 00007FF72BE328DE 48 83 3B 00 cmp qword ptr [rbx],0 218 | 00007FF72BE328E2 4C 8B 53 38 mov r10,qword ptr [rbx+38h] 219 | 00007FF72BE328E6 4C 8B 5B 30 mov r11,qword ptr [rbx+30h] 220 | 00007FF72BE328EA 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 221 | 00007FF72BE328EE 48 8B 43 08 mov rax,qword ptr [rbx+8] 222 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6)) 223 | 00007FF72BE328F2 4C 8B 4B 28 mov r9,qword ptr [rbx+28h] 224 | 00007FF72BE328F6 4C 8B 43 20 mov r8,qword ptr [rbx+20h] 225 | 00007FF72BE328FA 48 8B 53 18 mov rdx,qword ptr [rbx+18h] 226 | 00007FF72BE328FE 4C 89 54 24 28 mov qword ptr [rsp+28h],r10 227 | 00007FF72BE32903 4C 89 5C 24 20 mov qword ptr [rsp+20h],r11 228 | 00007FF72BE32908 74 0B je Delegator+45h (07FF72BE32915h) 229 | 00007FF72BE3290A FF D0 call rax 230 | 00007FF72BE3290C 48 89 03 mov qword ptr [rbx],rax 231 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6))) : 0; 232 | 108: } 233 | 00007FF72BE3290F 48 83 C4 30 add rsp,30h 234 | 00007FF72BE32913 5B pop rbx 235 | 00007FF72BE32914 C3 ret 236 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6)) 237 | 00007FF72BE32915 FF D0 call rax 238 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6))) : 0; 239 | 108: } 240 | 00007FF72BE32917 48 83 C4 30 add rsp,30h 241 | 00007FF72BE3291B 5B pop rbx 242 | 00007FF72BE3291C C3 ret 243 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6)) 244 | 00007FF72BE3291D 33 C0 xor eax,eax 245 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6))) : 0; 246 | 108: } 247 | 00007FF72BE3291F 48 83 C4 30 add rsp,30h 248 | 00007FF72BE32923 5B pop rbx 249 | 00007FF72BE32924 C3 ret 250 | 251 | 7 arg 252 | 253 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 254 | 105: { 255 | 00007FF6EB732AE0 40 53 push rbx 256 | 00007FF6EB732AE2 48 83 EC 40 sub rsp,40h 257 | 00007FF6EB732AE6 48 8B D9 mov rbx,rcx 258 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7)) 259 | 00007FF6EB732AE9 48 85 C9 test rcx,rcx 260 | 00007FF6EB732AEC 74 57 je Delegator+65h (07FF6EB732B45h) 261 | 00007FF6EB732AEE 48 83 3B 00 cmp qword ptr [rbx],0 262 | 00007FF6EB732AF2 4C 8B 51 40 mov r10,qword ptr [rcx+40h] 263 | 00007FF6EB732AF6 4C 8B 59 38 mov r11,qword ptr [rcx+38h] 264 | 00007FF6EB732AFA 48 8B 51 18 mov rdx,qword ptr [rcx+18h] 265 | 00007FF6EB732AFE 48 8B 41 08 mov rax,qword ptr [rcx+8] 266 | 00007FF6EB732B02 4C 8B 49 28 mov r9,qword ptr [rcx+28h] 267 | 00007FF6EB732B06 4C 8B 41 20 mov r8,qword ptr [rcx+20h] 268 | 00007FF6EB732B0A 4C 89 54 24 30 mov qword ptr [rsp+30h],r10 269 | 00007FF6EB732B0F 48 89 7C 24 50 mov qword ptr [rsp+50h],rdi 270 | 00007FF6EB732B14 48 8B 79 30 mov rdi,qword ptr [rcx+30h] 271 | 00007FF6EB732B18 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 272 | 00007FF6EB732B1C 4C 89 5C 24 28 mov qword ptr [rsp+28h],r11 273 | 00007FF6EB732B21 48 89 7C 24 20 mov qword ptr [rsp+20h],rdi 274 | 00007FF6EB732B26 74 10 je Delegator+58h (07FF6EB732B38h) 275 | 00007FF6EB732B28 FF D0 call rax 276 | 00007FF6EB732B2A 48 8B 7C 24 50 mov rdi,qword ptr [rsp+50h] 277 | 00007FF6EB732B2F 48 89 03 mov qword ptr [rbx],rax 278 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7))) : 0; 279 | 108: } 280 | 00007FF6EB732B32 48 83 C4 40 add rsp,40h 281 | 00007FF6EB732B36 5B pop rbx 282 | 00007FF6EB732B37 C3 ret 283 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7)) 284 | 00007FF6EB732B38 FF D0 call rax 285 | 00007FF6EB732B3A 48 8B 7C 24 50 mov rdi,qword ptr [rsp+50h] 286 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7))) : 0; 287 | 108: } 288 | 00007FF6EB732B3F 48 83 C4 40 add rsp,40h 289 | 00007FF6EB732B43 5B pop rbx 290 | 00007FF6EB732B44 C3 ret 291 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7)) 292 | 00007FF6EB732B45 33 C0 xor eax,eax 293 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7))) : 0; 294 | 108: } 295 | 00007FF6EB732B47 48 83 C4 40 add rsp,40h 296 | 00007FF6EB732B4B 5B pop rbx 297 | 00007FF6EB732B4C C3 ret 298 | 299 | 8 arg 300 | 301 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 302 | 105: { 303 | 00007FF7D0B82AE0 40 53 push rbx 304 | 00007FF7D0B82AE2 48 83 EC 40 sub rsp,40h 305 | 00007FF7D0B82AE6 48 8B D9 mov rbx,rcx 306 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8)) 307 | 00007FF7D0B82AE9 48 85 C9 test rcx,rcx 308 | 00007FF7D0B82AEC 74 6F je Delegator+7Dh (07FF7D0B82B5Dh) 309 | 00007FF7D0B82AEE 48 83 3B 00 cmp qword ptr [rbx],0 310 | 00007FF7D0B82AF2 4C 8B 51 48 mov r10,qword ptr [rcx+48h] 311 | 00007FF7D0B82AF6 4C 8B 59 40 mov r11,qword ptr [rcx+40h] 312 | 00007FF7D0B82AFA 48 8B 51 18 mov rdx,qword ptr [rcx+18h] 313 | 00007FF7D0B82AFE 48 8B 41 08 mov rax,qword ptr [rcx+8] 314 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8)) 315 | 00007FF7D0B82B02 4C 8B 49 28 mov r9,qword ptr [rcx+28h] 316 | 00007FF7D0B82B06 4C 8B 41 20 mov r8,qword ptr [rcx+20h] 317 | 00007FF7D0B82B0A 4C 89 54 24 38 mov qword ptr [rsp+38h],r10 318 | 00007FF7D0B82B0F 48 89 74 24 50 mov qword ptr [rsp+50h],rsi 319 | 00007FF7D0B82B14 48 8B 71 30 mov rsi,qword ptr [rcx+30h] 320 | 00007FF7D0B82B18 4C 89 5C 24 30 mov qword ptr [rsp+30h],r11 321 | 00007FF7D0B82B1D 48 89 7C 24 58 mov qword ptr [rsp+58h],rdi 322 | 00007FF7D0B82B22 48 8B 79 38 mov rdi,qword ptr [rcx+38h] 323 | 00007FF7D0B82B26 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 324 | 00007FF7D0B82B2A 48 89 7C 24 28 mov qword ptr [rsp+28h],rdi 325 | 00007FF7D0B82B2F 48 89 74 24 20 mov qword ptr [rsp+20h],rsi 326 | 00007FF7D0B82B34 74 15 je Delegator+6Bh (07FF7D0B82B4Bh) 327 | 00007FF7D0B82B36 FF D0 call rax 328 | 00007FF7D0B82B38 48 8B 74 24 50 mov rsi,qword ptr [rsp+50h] 329 | 00007FF7D0B82B3D 48 8B 7C 24 58 mov rdi,qword ptr [rsp+58h] 330 | 00007FF7D0B82B42 48 89 03 mov qword ptr [rbx],rax 331 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8))) : 0; 332 | 108: } 333 | 00007FF7D0B82B45 48 83 C4 40 add rsp,40h 334 | 00007FF7D0B82B49 5B pop rbx 335 | 00007FF7D0B82B4A C3 ret 336 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8)) 337 | 00007FF7D0B82B4B FF D0 call rax 338 | 00007FF7D0B82B4D 48 8B 74 24 50 mov rsi,qword ptr [rsp+50h] 339 | 00007FF7D0B82B52 48 8B 7C 24 58 mov rdi,qword ptr [rsp+58h] 340 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8))) : 0; 341 | 108: } 342 | 00007FF7D0B82B57 48 83 C4 40 add rsp,40h 343 | 00007FF7D0B82B5B 5B pop rbx 344 | 00007FF7D0B82B5C C3 ret 345 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8)) 346 | 00007FF7D0B82B5D 33 C0 xor eax,eax 347 | 00007FF7D0B82B5F 48 83 C4 40 add rsp,40h 348 | 00007FF7D0B82B63 5B pop rbx 349 | 00007FF7D0B82B64 C3 ret 350 | 351 | 9 arg 352 | 353 | 104: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 354 | 105: { 355 | 00007FF7B8312AE0 40 53 push rbx 356 | 00007FF7B8312AE2 48 83 EC 50 sub rsp,50h 357 | 00007FF7B8312AE6 48 8B D9 mov rbx,rcx 358 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9)) 359 | 00007FF7B8312AE9 48 85 C9 test rcx,rcx 360 | 00007FF7B8312AEC 74 74 je Delegator+82h (07FF7B8312B62h) 361 | 00007FF7B8312AEE 48 83 3B 00 cmp qword ptr [rbx],0 362 | 00007FF7B8312AF2 4C 8B 51 50 mov r10,qword ptr [rcx+50h] 363 | 00007FF7B8312AF6 4C 8B 59 48 mov r11,qword ptr [rcx+48h] 364 | 00007FF7B8312AFA 48 8B 51 18 mov rdx,qword ptr [rcx+18h] 365 | 00007FF7B8312AFE 48 8B 41 08 mov rax,qword ptr [rcx+8] 366 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9)) 367 | 00007FF7B8312B02 4C 8B 49 28 mov r9,qword ptr [rcx+28h] 368 | 00007FF7B8312B06 4C 8B 41 20 mov r8,qword ptr [rcx+20h] 369 | 00007FF7B8312B0A 4C 89 54 24 40 mov qword ptr [rsp+40h],r10 370 | 00007FF7B8312B0F 48 89 6C 24 60 mov qword ptr [rsp+60h],rbp 371 | 00007FF7B8312B14 48 8B 69 30 mov rbp,qword ptr [rcx+30h] 372 | 00007FF7B8312B18 4C 89 5C 24 38 mov qword ptr [rsp+38h],r11 373 | 00007FF7B8312B1D 48 89 74 24 68 mov qword ptr [rsp+68h],rsi 374 | 00007FF7B8312B22 48 8B 71 38 mov rsi,qword ptr [rcx+38h] 375 | 00007FF7B8312B26 48 89 7C 24 70 mov qword ptr [rsp+70h],rdi 376 | 00007FF7B8312B2B 48 8B 79 40 mov rdi,qword ptr [rcx+40h] 377 | 00007FF7B8312B2F 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 378 | 00007FF7B8312B33 48 89 7C 24 30 mov qword ptr [rsp+30h],rdi 379 | 00007FF7B8312B38 48 89 74 24 28 mov qword ptr [rsp+28h],rsi 380 | 00007FF7B8312B3D 48 89 6C 24 20 mov qword ptr [rsp+20h],rbp 381 | 00007FF7B8312B42 74 1A je Delegator+7Eh (07FF7B8312B5Eh) 382 | 00007FF7B8312B44 FF D0 call rax 383 | 00007FF7B8312B46 48 89 03 mov qword ptr [rbx],rax 384 | 00007FF7B8312B49 48 8B 74 24 68 mov rsi,qword ptr [rsp+68h] 385 | 00007FF7B8312B4E 48 8B 6C 24 60 mov rbp,qword ptr [rsp+60h] 386 | 00007FF7B8312B53 48 8B 7C 24 70 mov rdi,qword ptr [rsp+70h] 387 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9))) : 0; 388 | 108: } 389 | 00007FF7B8312B58 48 83 C4 50 add rsp,50h 390 | 00007FF7B8312B5C 5B pop rbx 391 | 00007FF7B8312B5D C3 ret 392 | 106: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9)) 393 | 00007FF7B8312B5E FF D0 call rax 394 | 00007FF7B8312B60 EB E7 jmp Delegator+69h (07FF7B8312B49h) 395 | 00007FF7B8312B62 33 C0 xor eax,eax 396 | 107: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9))) : 0; 397 | 108: } 398 | 00007FF7B8312B64 48 83 C4 50 add rsp,50h 399 | 00007FF7B8312B68 5B pop rbx 400 | 00007FF7B8312B69 C3 ret 401 | 402 | 10 arg 403 | 404 | 105: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 405 | 106: { 406 | 00007FF6C0AB2AE0 40 53 push rbx 407 | 00007FF6C0AB2AE2 48 83 EC 50 sub rsp,50h 408 | 00007FF6C0AB2AE6 48 8B D9 mov rbx,rcx 409 | 107: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9, param->arg10)) 410 | 00007FF6C0AB2AE9 48 85 C9 test rcx,rcx 411 | 00007FF6C0AB2AEC 0F 84 89 00 00 00 je Delegator+9Bh (07FF6C0AB2B7Bh) 412 | 00007FF6C0AB2AF2 48 83 3B 00 cmp qword ptr [rbx],0 413 | 00007FF6C0AB2AF6 48 8B 41 58 mov rax,qword ptr [rcx+58h] 414 | 00007FF6C0AB2AFA 4C 8B 51 50 mov r10,qword ptr [rcx+50h] 415 | 00007FF6C0AB2AFE 4C 8B 59 48 mov r11,qword ptr [rcx+48h] 416 | 00007FF6C0AB2B02 48 8B 51 18 mov rdx,qword ptr [rcx+18h] 417 | 107: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9, param->arg10)) 418 | 00007FF6C0AB2B06 4C 8B 49 28 mov r9,qword ptr [rcx+28h] 419 | 00007FF6C0AB2B0A 4C 8B 41 20 mov r8,qword ptr [rcx+20h] 420 | 00007FF6C0AB2B0E 48 89 44 24 48 mov qword ptr [rsp+48h],rax 421 | 00007FF6C0AB2B13 48 89 6C 24 60 mov qword ptr [rsp+60h],rbp 422 | 00007FF6C0AB2B18 48 8B 69 30 mov rbp,qword ptr [rcx+30h] 423 | 00007FF6C0AB2B1C 4C 89 54 24 40 mov qword ptr [rsp+40h],r10 424 | 00007FF6C0AB2B21 48 89 74 24 68 mov qword ptr [rsp+68h],rsi 425 | 00007FF6C0AB2B26 48 8B 71 38 mov rsi,qword ptr [rcx+38h] 426 | 00007FF6C0AB2B2A 4C 89 5C 24 38 mov qword ptr [rsp+38h],r11 427 | 00007FF6C0AB2B2F 48 89 7C 24 70 mov qword ptr [rsp+70h],rdi 428 | 00007FF6C0AB2B34 48 8B 79 40 mov rdi,qword ptr [rcx+40h] 429 | 00007FF6C0AB2B38 48 8B 49 10 mov rcx,qword ptr [rcx+10h] 430 | 00007FF6C0AB2B3C 48 89 7C 24 30 mov qword ptr [rsp+30h],rdi 431 | 00007FF6C0AB2B41 48 89 74 24 28 mov qword ptr [rsp+28h],rsi 432 | 00007FF6C0AB2B46 4C 89 74 24 78 mov qword ptr [rsp+78h],r14 433 | 00007FF6C0AB2B4B 4C 8B 73 08 mov r14,qword ptr [rbx+8] 434 | 00007FF6C0AB2B4F 48 89 6C 24 20 mov qword ptr [rsp+20h],rbp 435 | 00007FF6C0AB2B54 74 20 je Delegator+96h (07FF6C0AB2B76h) 436 | 00007FF6C0AB2B56 41 FF D6 call r14 437 | 00007FF6C0AB2B59 48 89 03 mov qword ptr [rbx],rax 438 | 00007FF6C0AB2B5C 48 8B 7C 24 70 mov rdi,qword ptr [rsp+70h] 439 | 00007FF6C0AB2B61 48 8B 74 24 68 mov rsi,qword ptr [rsp+68h] 440 | 00007FF6C0AB2B66 48 8B 6C 24 60 mov rbp,qword ptr [rsp+60h] 441 | 00007FF6C0AB2B6B 4C 8B 74 24 78 mov r14,qword ptr [rsp+78h] 442 | 108: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9, param->arg10))) : 0; 443 | 109: } 444 | 00007FF6C0AB2B70 48 83 C4 50 add rsp,50h 445 | 00007FF6C0AB2B74 5B pop rbx 446 | 00007FF6C0AB2B75 C3 ret 447 | 107: return param ? (param->ret ? (param->ret = param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9, param->arg10)) 448 | 00007FF6C0AB2B76 41 FF D6 call r14 449 | 00007FF6C0AB2B79 EB E1 jmp Delegator+7Ch (07FF6C0AB2B5Ch) 450 | 00007FF6C0AB2B7B 33 C0 xor eax,eax 451 | 108: : (param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9, param->arg10))) : 0; 452 | 109: } 453 | 00007FF6C0AB2B7D 48 83 C4 50 add rsp,50h 454 | 00007FF6C0AB2B81 5B pop rbx 455 | 00007FF6C0AB2B82 C3 ret -------------------------------------------------------------------------------- /disas/X64toX86_disassemble: -------------------------------------------------------------------------------- 1 | 2 | X86_Start & X86_End is copied from http://blog.rewolf.pl/blog/?p=102 3 | 4 | 35: __declspec(noinline) DWORD WINAPI Delegator(Param1* param) 5 | 36: { 6 | 00007FF6B4252F10 48 89 4C 24 08 mov qword ptr [rsp+8],rcx 7 | 00007FF6B4252F15 48 83 EC 28 sub rsp,28h 8 | 37: return param->func(param->arg1); 9 | 00007FF6B4252F19 48 8B 44 24 30 mov rax,qword ptr [param] 10 | 00007FF6B4252F1E 8B 48 08 mov ecx,dword ptr [rax+8] 11 | 00007FF6B4252F21 48 8B 44 24 30 mov rax,qword ptr [param] 12 | 13 | ; 00007FF6B4252F26 FF 10 call qword ptr [rax] 14 | 15 | ; X86_Start 16 | 6A 33 push 33h 17 | E8 00 00 00 00 call $+5 18 | 83 04 24 05 add dword ptr [esp],5 19 | CB retf 20 | 21 | 002F2A26 FF D0 call eax 22 | 23 | ; X86_End 24 | E8 00 00 00 00 call $+5 25 | C7 44 24 04 23 00 00 00 mov dword ptr [esp+4],23h 26 | 83 04 24 0D add dword ptr [esp],0Dh 27 | CB retf 28 | 29 | 38: } 30 | 00007FF6B4252F28 48 83 C4 28 add rsp,28h 31 | 00007FF6B4252F2C C3 ret 32 | 33 | 34 | shell_code: 35 | 36 | 0x48, 0x89, 0x4c, 0x24, 0x08, 0x48, 0x83, 0xec, 0x28, 0x48, 0x8b, 0x44, 0x24, 0x30, 0x8b, 0x48, 0x08, 0x48, 0x8b, 0x44, 0x24, 0x30, 37 | 0x6a, 0x33, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x83, 0x04, 0x24, 0x05, 0xcb, 38 | 0xff, 0xd0, 39 | 0xe8, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x44, 0x24, 0x04, 0x23, 0x00, 0x00, 0x00, 0x83, 0x04, 0x24, 0x0d, 0xcb, 40 | 0x48, 0x83, 0xc4, 0x28, 0xc3 -------------------------------------------------------------------------------- /disas/X86Delegator_disassemble: -------------------------------------------------------------------------------- 1 | 0 arg 2 | 3 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 4 | 42: { 5 | 00802A10 55 push ebp 6 | 00802A11 8B EC mov ebp,esp 7 | 00802A13 51 push ecx 8 | 43: return param ? param->func() : 0; 9 | 00802A14 83 7D 08 00 cmp dword ptr [param],0 10 | 00802A18 74 0C je Delegator+16h (0802A26h) 11 | 00802A1A 8B 45 08 mov eax,dword ptr [param] 12 | 00802A1D 8B 08 mov ecx,dword ptr [eax] 13 | 00802A1F FF D1 call ecx 14 | 00802A21 89 45 FC mov dword ptr [ebp-4],eax 15 | 00802A24 EB 07 jmp Delegator+1Dh (0802A2Dh) 16 | 00802A26 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 17 | 00802A2D 8B 45 FC mov eax,dword ptr [ebp-4] 18 | 44: } 19 | 00802A30 8B E5 mov esp,ebp 20 | 00802A32 5D pop ebp 21 | 00802A33 C3 ret 22 | 23 | 1 arg 24 | 25 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 26 | 42: { 27 | 002F2A10 55 push ebp 28 | 002F2A11 8B EC mov ebp,esp 29 | 002F2A13 51 push ecx 30 | 43: return param ? param->func(param->arg1) : 0; 31 | 002F2A14 83 7D 08 00 cmp dword ptr [param],0 32 | 002F2A18 74 13 je Delegator+1Dh (02F2A2Dh) 33 | 002F2A1A 8B 45 08 mov eax,dword ptr [param] 34 | 002F2A1D 8B 48 04 mov ecx,dword ptr [eax+4] 35 | 002F2A20 51 push ecx 36 | 002F2A21 8B 55 08 mov edx,dword ptr [param] 37 | 002F2A24 8B 02 mov eax,dword ptr [edx] 38 | 002F2A26 FF D0 call eax 39 | 002F2A28 89 45 FC mov dword ptr [ebp-4],eax 40 | 002F2A2B EB 07 jmp Delegator+24h (02F2A34h) 41 | 002F2A2D C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 42 | 002F2A34 8B 45 FC mov eax,dword ptr [ebp-4] 43 | 44: } 44 | 002F2A37 8B E5 mov esp,ebp 45 | 002F2A39 5D pop ebp 46 | 002F2A3A C3 ret 47 | 48 | 2 arg 49 | 50 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 51 | 42: { 52 | 00B02A10 55 push ebp 53 | 00B02A11 8B EC mov ebp,esp 54 | 00B02A13 51 push ecx 55 | 43: return param ? param->func(param->arg1, param->arg2) : 0; 56 | 00B02A14 83 7D 08 00 cmp dword ptr [param],0 57 | 00B02A18 74 1A je Delegator+24h (0B02A34h) 58 | 00B02A1A 8B 45 08 mov eax,dword ptr [param] 59 | 00B02A1D 8B 48 08 mov ecx,dword ptr [eax+8] 60 | 00B02A20 51 push ecx 61 | 00B02A21 8B 55 08 mov edx,dword ptr [param] 62 | 00B02A24 8B 42 04 mov eax,dword ptr [edx+4] 63 | 00B02A27 50 push eax 64 | 00B02A28 8B 4D 08 mov ecx,dword ptr [param] 65 | 00B02A2B 8B 11 mov edx,dword ptr [ecx] 66 | 00B02A2D FF D2 call edx 67 | 00B02A2F 89 45 FC mov dword ptr [ebp-4],eax 68 | 00B02A32 EB 07 jmp Delegator+2Bh (0B02A3Bh) 69 | 00B02A34 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 70 | 00B02A3B 8B 45 FC mov eax,dword ptr [ebp-4] 71 | 44: } 72 | 00B02A3E 8B E5 mov esp,ebp 73 | 44: } 74 | 00B02A40 5D pop ebp 75 | 00B02A41 C3 ret 76 | 77 | 78 | 3 arg 79 | 80 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 81 | 42: { 82 | 01352A10 55 push ebp 83 | 01352A11 8B EC mov ebp,esp 84 | 01352A13 51 push ecx 85 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3) : 0; 86 | 01352A14 83 7D 08 00 cmp dword ptr [param],0 87 | 01352A18 74 21 je Delegator+2Bh (01352A3Bh) 88 | 01352A1A 8B 45 08 mov eax,dword ptr [param] 89 | 01352A1D 8B 48 0C mov ecx,dword ptr [eax+0Ch] 90 | 01352A20 51 push ecx 91 | 01352A21 8B 55 08 mov edx,dword ptr [param] 92 | 01352A24 8B 42 08 mov eax,dword ptr [edx+8] 93 | 01352A27 50 push eax 94 | 01352A28 8B 4D 08 mov ecx,dword ptr [param] 95 | 01352A2B 8B 51 04 mov edx,dword ptr [ecx+4] 96 | 01352A2E 52 push edx 97 | 01352A2F 8B 45 08 mov eax,dword ptr [param] 98 | 01352A32 8B 08 mov ecx,dword ptr [eax] 99 | 01352A34 FF D1 call ecx 100 | 01352A36 89 45 FC mov dword ptr [ebp-4],eax 101 | 01352A39 EB 07 jmp Delegator+32h (01352A42h) 102 | 01352A3B C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 103 | 01352A42 8B 45 FC mov eax,dword ptr [ebp-4] 104 | 44: } 105 | 01352A45 8B E5 mov esp,ebp 106 | 01352A47 5D pop ebp 107 | 01352A48 C3 ret 108 | 109 | 4 arg 110 | 111 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 112 | 42: { 113 | 00152A10 55 push ebp 114 | 00152A11 8B EC mov ebp,esp 115 | 00152A13 51 push ecx 116 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3, param->arg4) : 0; 117 | 00152A14 83 7D 08 00 cmp dword ptr [param],0 118 | 00152A18 74 28 je Delegator+32h (0152A42h) 119 | 00152A1A 8B 45 08 mov eax,dword ptr [param] 120 | 00152A1D 8B 48 10 mov ecx,dword ptr [eax+10h] 121 | 00152A20 51 push ecx 122 | 00152A21 8B 55 08 mov edx,dword ptr [param] 123 | 00152A24 8B 42 0C mov eax,dword ptr [edx+0Ch] 124 | 00152A27 50 push eax 125 | 00152A28 8B 4D 08 mov ecx,dword ptr [param] 126 | 00152A2B 8B 51 08 mov edx,dword ptr [ecx+8] 127 | 00152A2E 52 push edx 128 | 00152A2F 8B 45 08 mov eax,dword ptr [param] 129 | 00152A32 8B 48 04 mov ecx,dword ptr [eax+4] 130 | 00152A35 51 push ecx 131 | 00152A36 8B 55 08 mov edx,dword ptr [param] 132 | 00152A39 8B 02 mov eax,dword ptr [edx] 133 | 00152A3B FF D0 call eax 134 | 00152A3D 89 45 FC mov dword ptr [ebp-4],eax 135 | 00152A40 EB 07 jmp Delegator+39h (0152A49h) 136 | 00152A42 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 137 | 00152A49 8B 45 FC mov eax,dword ptr [ebp-4] 138 | 44: } 139 | 00152A4C 8B E5 mov esp,ebp 140 | 00152A4E 5D pop ebp 141 | 00152A4F C3 ret 142 | 143 | 5 arg 144 | 145 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 146 | 42: { 147 | 00DB2A10 55 push ebp 148 | 00DB2A11 8B EC mov ebp,esp 149 | 00DB2A13 51 push ecx 150 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5) : 0; 151 | 00DB2A14 83 7D 08 00 cmp dword ptr [param],0 152 | 00DB2A18 74 2F je Delegator+39h (0DB2A49h) 153 | 00DB2A1A 8B 45 08 mov eax,dword ptr [param] 154 | 00DB2A1D 8B 48 14 mov ecx,dword ptr [eax+14h] 155 | 00DB2A20 51 push ecx 156 | 00DB2A21 8B 55 08 mov edx,dword ptr [param] 157 | 00DB2A24 8B 42 10 mov eax,dword ptr [edx+10h] 158 | 00DB2A27 50 push eax 159 | 00DB2A28 8B 4D 08 mov ecx,dword ptr [param] 160 | 00DB2A2B 8B 51 0C mov edx,dword ptr [ecx+0Ch] 161 | 00DB2A2E 52 push edx 162 | 00DB2A2F 8B 45 08 mov eax,dword ptr [param] 163 | 00DB2A32 8B 48 08 mov ecx,dword ptr [eax+8] 164 | 00DB2A35 51 push ecx 165 | 00DB2A36 8B 55 08 mov edx,dword ptr [param] 166 | 00DB2A39 8B 42 04 mov eax,dword ptr [edx+4] 167 | 00DB2A3C 50 push eax 168 | 00DB2A3D 8B 4D 08 mov ecx,dword ptr [param] 169 | 00DB2A40 8B 11 mov edx,dword ptr [ecx] 170 | 00DB2A42 FF D2 call edx 171 | 00DB2A44 89 45 FC mov dword ptr [ebp-4],eax 172 | 00DB2A47 EB 07 jmp Delegator+40h (0DB2A50h) 173 | 00DB2A49 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 174 | 00DB2A50 8B 45 FC mov eax,dword ptr [ebp-4] 175 | 44: } 176 | 00DB2A53 8B E5 mov esp,ebp 177 | 00DB2A55 5D pop ebp 178 | 00DB2A56 C3 ret 179 | 180 | 6 arg 181 | 182 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 183 | 42: { 184 | 00142A10 55 push ebp 185 | 00142A11 8B EC mov ebp,esp 186 | 00142A13 51 push ecx 187 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6) : 0; 188 | 00142A14 83 7D 08 00 cmp dword ptr [param],0 189 | 00142A18 74 36 je Delegator+40h (0142A50h) 190 | 00142A1A 8B 45 08 mov eax,dword ptr [param] 191 | 00142A1D 8B 48 18 mov ecx,dword ptr [eax+18h] 192 | 00142A20 51 push ecx 193 | 00142A21 8B 55 08 mov edx,dword ptr [param] 194 | 00142A24 8B 42 14 mov eax,dword ptr [edx+14h] 195 | 00142A27 50 push eax 196 | 00142A28 8B 4D 08 mov ecx,dword ptr [param] 197 | 00142A2B 8B 51 10 mov edx,dword ptr [ecx+10h] 198 | 00142A2E 52 push edx 199 | 00142A2F 8B 45 08 mov eax,dword ptr [param] 200 | 00142A32 8B 48 0C mov ecx,dword ptr [eax+0Ch] 201 | 00142A35 51 push ecx 202 | 00142A36 8B 55 08 mov edx,dword ptr [param] 203 | 00142A39 8B 42 08 mov eax,dword ptr [edx+8] 204 | 00142A3C 50 push eax 205 | 00142A3D 8B 4D 08 mov ecx,dword ptr [param] 206 | 00142A40 8B 51 04 mov edx,dword ptr [ecx+4] 207 | 00142A43 52 push edx 208 | 00142A44 8B 45 08 mov eax,dword ptr [param] 209 | 00142A47 8B 08 mov ecx,dword ptr [eax] 210 | 00142A49 FF D1 call ecx 211 | 00142A4B 89 45 FC mov dword ptr [ebp-4],eax 212 | 00142A4E EB 07 jmp Delegator+47h (0142A57h) 213 | 00142A50 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 214 | 00142A57 8B 45 FC mov eax,dword ptr [ebp-4] 215 | 44: } 216 | 00142A5A 8B E5 mov esp,ebp 217 | 00142A5C 5D pop ebp 218 | 00142A5D C3 ret 219 | 220 | 7 arg 221 | 222 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 223 | 42: { 224 | 00232A10 55 push ebp 225 | 00232A11 8B EC mov ebp,esp 226 | 00232A13 51 push ecx 227 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7) : 0; 228 | 00232A14 83 7D 08 00 cmp dword ptr [param],0 229 | 00232A18 74 3D je Delegator+47h (0232A57h) 230 | 00232A1A 8B 45 08 mov eax,dword ptr [param] 231 | 00232A1D 8B 48 1C mov ecx,dword ptr [eax+1Ch] 232 | 00232A20 51 push ecx 233 | 00232A21 8B 55 08 mov edx,dword ptr [param] 234 | 00232A24 8B 42 18 mov eax,dword ptr [edx+18h] 235 | 00232A27 50 push eax 236 | 00232A28 8B 4D 08 mov ecx,dword ptr [param] 237 | 00232A2B 8B 51 14 mov edx,dword ptr [ecx+14h] 238 | 00232A2E 52 push edx 239 | 00232A2F 8B 45 08 mov eax,dword ptr [param] 240 | 00232A32 8B 48 10 mov ecx,dword ptr [eax+10h] 241 | 00232A35 51 push ecx 242 | 00232A36 8B 55 08 mov edx,dword ptr [param] 243 | 00232A39 8B 42 0C mov eax,dword ptr [edx+0Ch] 244 | 00232A3C 50 push eax 245 | 00232A3D 8B 4D 08 mov ecx,dword ptr [param] 246 | 00232A40 8B 51 08 mov edx,dword ptr [ecx+8] 247 | 00232A43 52 push edx 248 | 00232A44 8B 45 08 mov eax,dword ptr [param] 249 | 00232A47 8B 48 04 mov ecx,dword ptr [eax+4] 250 | 00232A4A 51 push ecx 251 | 00232A4B 8B 55 08 mov edx,dword ptr [param] 252 | 00232A4E 8B 02 mov eax,dword ptr [edx] 253 | 00232A50 FF D0 call eax 254 | 00232A52 89 45 FC mov dword ptr [ebp-4],eax 255 | 00232A55 EB 07 jmp Delegator+4Eh (0232A5Eh) 256 | 00232A57 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 257 | 00232A5E 8B 45 FC mov eax,dword ptr [ebp-4] 258 | 44: } 259 | 00232A61 8B E5 mov esp,ebp 260 | 00232A63 5D pop ebp 261 | 00232A64 C3 ret 262 | 263 | 8 arg 264 | 265 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 266 | 42: { 267 | 00352A10 55 push ebp 268 | 00352A11 8B EC mov ebp,esp 269 | 00352A13 51 push ecx 270 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8) : 0; 271 | 00352A14 83 7D 08 00 cmp dword ptr [param],0 272 | 00352A18 74 44 je Delegator+4Eh (0352A5Eh) 273 | 00352A1A 8B 45 08 mov eax,dword ptr [param] 274 | 00352A1D 8B 48 20 mov ecx,dword ptr [eax+20h] 275 | 00352A20 51 push ecx 276 | 00352A21 8B 55 08 mov edx,dword ptr [param] 277 | 00352A24 8B 42 1C mov eax,dword ptr [edx+1Ch] 278 | 00352A27 50 push eax 279 | 00352A28 8B 4D 08 mov ecx,dword ptr [param] 280 | 00352A2B 8B 51 18 mov edx,dword ptr [ecx+18h] 281 | 00352A2E 52 push edx 282 | 00352A2F 8B 45 08 mov eax,dword ptr [param] 283 | 00352A32 8B 48 14 mov ecx,dword ptr [eax+14h] 284 | 00352A35 51 push ecx 285 | 00352A36 8B 55 08 mov edx,dword ptr [param] 286 | 00352A39 8B 42 10 mov eax,dword ptr [edx+10h] 287 | 00352A3C 50 push eax 288 | 00352A3D 8B 4D 08 mov ecx,dword ptr [param] 289 | 00352A40 8B 51 0C mov edx,dword ptr [ecx+0Ch] 290 | 00352A43 52 push edx 291 | 00352A44 8B 45 08 mov eax,dword ptr [param] 292 | 00352A47 8B 48 08 mov ecx,dword ptr [eax+8] 293 | 00352A4A 51 push ecx 294 | 00352A4B 8B 55 08 mov edx,dword ptr [param] 295 | 00352A4E 8B 42 04 mov eax,dword ptr [edx+4] 296 | 00352A51 50 push eax 297 | 00352A52 8B 4D 08 mov ecx,dword ptr [param] 298 | 00352A55 8B 11 mov edx,dword ptr [ecx] 299 | 00352A57 FF D2 call edx 300 | 00352A59 89 45 FC mov dword ptr [ebp-4],eax 301 | 00352A5C EB 07 jmp Delegator+55h (0352A65h) 302 | 00352A5E C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 303 | 00352A65 8B 45 FC mov eax,dword ptr [ebp-4] 304 | 44: } 305 | 00352A68 8B E5 mov esp,ebp 306 | 00352A6A 5D pop ebp 307 | 00352A6B C3 ret 308 | 309 | 9 arg 310 | 311 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 312 | 42: { 313 | 00072A10 55 push ebp 314 | 00072A11 8B EC mov ebp,esp 315 | 00072A13 51 push ecx 316 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9) : 0; 317 | 00072A14 83 7D 08 00 cmp dword ptr [param],0 318 | 00072A18 74 4B je Delegator+55h (072A65h) 319 | 00072A1A 8B 45 08 mov eax,dword ptr [param] 320 | 00072A1D 8B 48 24 mov ecx,dword ptr [eax+24h] 321 | 00072A20 51 push ecx 322 | 00072A21 8B 55 08 mov edx,dword ptr [param] 323 | 00072A24 8B 42 20 mov eax,dword ptr [edx+20h] 324 | 00072A27 50 push eax 325 | 00072A28 8B 4D 08 mov ecx,dword ptr [param] 326 | 00072A2B 8B 51 1C mov edx,dword ptr [ecx+1Ch] 327 | 00072A2E 52 push edx 328 | 00072A2F 8B 45 08 mov eax,dword ptr [param] 329 | 00072A32 8B 48 18 mov ecx,dword ptr [eax+18h] 330 | 00072A35 51 push ecx 331 | 00072A36 8B 55 08 mov edx,dword ptr [param] 332 | 00072A39 8B 42 14 mov eax,dword ptr [edx+14h] 333 | 00072A3C 50 push eax 334 | 00072A3D 8B 4D 08 mov ecx,dword ptr [param] 335 | 00072A40 8B 51 10 mov edx,dword ptr [ecx+10h] 336 | 00072A43 52 push edx 337 | 00072A44 8B 45 08 mov eax,dword ptr [param] 338 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9) : 0; 339 | 00072A47 8B 48 0C mov ecx,dword ptr [eax+0Ch] 340 | 00072A4A 51 push ecx 341 | 00072A4B 8B 55 08 mov edx,dword ptr [param] 342 | 00072A4E 8B 42 08 mov eax,dword ptr [edx+8] 343 | 00072A51 50 push eax 344 | 00072A52 8B 4D 08 mov ecx,dword ptr [param] 345 | 00072A55 8B 51 04 mov edx,dword ptr [ecx+4] 346 | 00072A58 52 push edx 347 | 00072A59 8B 45 08 mov eax,dword ptr [param] 348 | 00072A5C 8B 08 mov ecx,dword ptr [eax] 349 | 00072A5E FF D1 call ecx 350 | 00072A60 89 45 FC mov dword ptr [ebp-4],eax 351 | 00072A63 EB 07 jmp Delegator+5Ch (072A6Ch) 352 | 00072A65 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 353 | 00072A6C 8B 45 FC mov eax,dword ptr [ebp-4] 354 | 44: } 355 | 00072A6F 8B E5 mov esp,ebp 356 | 00072A71 5D pop ebp 357 | 00072A72 C3 ret 358 | 359 | 10 arg 360 | 361 | 41: __declspec(noinline) DWORD Delegator(Param1* param) 362 | 42: { 363 | 000F2A10 55 push ebp 364 | 000F2A11 8B EC mov ebp,esp 365 | 000F2A13 51 push ecx 366 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9, param->arg10) : 0; 367 | 000F2A14 83 7D 08 00 cmp dword ptr [param],0 368 | 000F2A18 74 52 je Delegator+5Ch (0F2A6Ch) 369 | 000F2A1A 8B 45 08 mov eax,dword ptr [param] 370 | 000F2A1D 8B 48 28 mov ecx,dword ptr [eax+28h] 371 | 000F2A20 51 push ecx 372 | 000F2A21 8B 55 08 mov edx,dword ptr [param] 373 | 000F2A24 8B 42 24 mov eax,dword ptr [edx+24h] 374 | 000F2A27 50 push eax 375 | 000F2A28 8B 4D 08 mov ecx,dword ptr [param] 376 | 000F2A2B 8B 51 20 mov edx,dword ptr [ecx+20h] 377 | 000F2A2E 52 push edx 378 | 000F2A2F 8B 45 08 mov eax,dword ptr [param] 379 | 000F2A32 8B 48 1C mov ecx,dword ptr [eax+1Ch] 380 | 000F2A35 51 push ecx 381 | 000F2A36 8B 55 08 mov edx,dword ptr [param] 382 | 000F2A39 8B 42 18 mov eax,dword ptr [edx+18h] 383 | 000F2A3C 50 push eax 384 | 000F2A3D 8B 4D 08 mov ecx,dword ptr [param] 385 | 000F2A40 8B 51 14 mov edx,dword ptr [ecx+14h] 386 | 000F2A43 52 push edx 387 | 000F2A44 8B 45 08 mov eax,dword ptr [param] 388 | 43: return param ? param->func(param->arg1, param->arg2, param->arg3, param->arg4, param->arg5, param->arg6, param->arg7, param->arg8, param->arg9, param->arg10) : 0; 389 | 000F2A47 8B 48 10 mov ecx,dword ptr [eax+10h] 390 | 000F2A4A 51 push ecx 391 | 000F2A4B 8B 55 08 mov edx,dword ptr [param] 392 | 000F2A4E 8B 42 0C mov eax,dword ptr [edx+0Ch] 393 | 000F2A51 50 push eax 394 | 000F2A52 8B 4D 08 mov ecx,dword ptr [param] 395 | 000F2A55 8B 51 08 mov edx,dword ptr [ecx+8] 396 | 000F2A58 52 push edx 397 | 000F2A59 8B 45 08 mov eax,dword ptr [param] 398 | 000F2A5C 8B 48 04 mov ecx,dword ptr [eax+4] 399 | 000F2A5F 51 push ecx 400 | 000F2A60 8B 55 08 mov edx,dword ptr [param] 401 | 000F2A63 8B 02 mov eax,dword ptr [edx] 402 | 000F2A65 FF D0 call eax 403 | 000F2A67 89 45 FC mov dword ptr [ebp-4],eax 404 | 000F2A6A EB 07 jmp Delegator+63h (0F2A73h) 405 | 000F2A6C C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 406 | 000F2A73 8B 45 FC mov eax,dword ptr [ebp-4] 407 | 44: } 408 | 000F2A76 8B E5 mov esp,ebp 409 | 000F2A78 5D pop ebp 410 | 000F2A79 C3 ret -------------------------------------------------------------------------------- /disas/X86toX64_disassemble: -------------------------------------------------------------------------------- 1 | 2 | X64_Start & X64_End is copied from http://blog.rewolf.pl/blog/?p=102 3 | 4 | 31: __declspec(noinline) DWORD64 WINAPI Delegator(Param1* param) 5 | 32: { 6 | 002F2A10 55 push ebp 7 | 002F2A11 8B EC mov ebp,esp 8 | 002F2A13 51 push ecx 9 | 43: return param ? param->func(param->arg1) : 0; 10 | 002F2A14 83 7D 08 00 cmp dword ptr [param],0 11 | 12 | ; 002F2A18 74 13 je Delegator+1Dh (02F2A2Dh) 13 | 14 | 74 31 je Delegator+1Dh+1Eh 15 | 002F2A1A 8B 45 08 mov eax,dword ptr [param] 16 | 002F2A1D 8B 48 08 mov ecx,dword ptr [eax+8] 17 | 002F2A20 51 push ecx 18 | 002F2A21 8B 55 08 mov edx,dword ptr [param] 19 | 002F2A24 8B 02 mov eax,dword ptr [edx] 20 | 21 | ; 002F2A26 FF D0 call eax 22 | 23 | ; X64_Start 24 | 6A 33 push 33h 25 | E8 00 00 00 00 call $+5 26 | 83 04 24 05 add dword ptr [esp],5 27 | CB retf 28 | 29 | FF D0 callq rax 30 | 31 | ; X64_End 32 | E8 00 00 00 00 call $+5 33 | C7 44 24 04 23 00 00 00 mov dword ptr [esp+4],23h 34 | 83 04 24 0D add dword ptr [esp],0Dh 35 | CB retf 36 | 37 | 002F2A28 89 45 FC mov dword ptr [ebp-4],eax 38 | 002F2A2B EB 07 jmp Delegator+24h (02F2A34h) 39 | 002F2A2D C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 40 | 002F2A34 8B 45 FC mov eax,dword ptr [ebp-4] 41 | 44: } 42 | 002F2A37 8B E5 mov esp,ebp 43 | 002F2A39 5D pop ebp 44 | 002F2A3A C3 ret 45 | 46 | 47 | shell_code: 48 | 49 | 0x55, 0x8b, 0xec, 0x51, 0x83, 0x7d, 0x08, 0x00, 0x74, 0x31, 0x8b, 0x45, 0x08, 0x8b, 0x48, 0x08, 0x51, 0x8b, 0x55, 0x08, 0x8b, 0x02, 50 | 0x6a, 0x33, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x83, 0x04, 0x24, 0x05, 0xcb, 51 | 0xff, 0xd0, 52 | 0xe8, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x44, 0x24, 0x04, 0x23, 0x00, 0x00, 0x00, 0x83, 0x04, 0x24, 0x0d, 0xcb, 53 | 0x89, 0x45, 0xfc, 0xeb, 0x07, 0xc7, 0x45, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x45, 0xfc, 0x8b, 0xe5, 0x5d, 0xc3 -------------------------------------------------------------------------------- /yapi.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | yapi -- Yet Another Process Injector / Your API 3 | A fusion library that reduce differences between x64, wow64 and x86 processes based on rewolf-wow64ext. 4 | 5 | Copyright (c) 2010-2018 6 | This library is released under the MIT License. 7 | 8 | Please see LICENSE file or visit https://github.com/ez8-co/yapi for details. 9 | */ 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #ifndef NT_SUCCESS 18 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 19 | #endif 20 | 21 | #include 22 | 23 | namespace detail { 24 | static HMODULE hNtDll = LoadLibrary(_T("ntdll.dll")); 25 | static HANDLE hCurProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); 26 | 27 | BOOL Is64BitOS() 28 | { 29 | SYSTEM_INFO systemInfo = { 0 }; 30 | GetNativeSystemInfo(&systemInfo); 31 | return systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 32 | || systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64; 33 | } 34 | static const BOOL is64BitOS = Is64BitOS(); 35 | 36 | struct GCBase 37 | { 38 | virtual DWORD64 toDWORD64() = 0; 39 | virtual void gc() = 0; 40 | }; 41 | struct GCHelper 42 | { 43 | ~GCHelper() { 44 | for (size_t i = 0; i < _ptrs.size(); i++) { 45 | _ptrs[i]->gc(); 46 | delete _ptrs[i]; 47 | } 48 | } 49 | DWORD64 add(GCBase* ptr) { _ptrs.push_back(ptr); return ptr->toDWORD64(); } 50 | private: 51 | std::vector _ptrs; 52 | }; 53 | } 54 | 55 | namespace yapi { 56 | 57 | typedef std::basic_string, std::allocator > tstring; 58 | 59 | #ifndef UNICODE 60 | static std::string _W2T(const wchar_t* wcs) 61 | { 62 | int len = ::WideCharToMultiByte(CP_ACP, 0, wcs, -1, NULL, 0, 0, 0); 63 | std::string ret(len, 0); 64 | VERIFY(0 != ::WideCharToMultiByte(CP_ACP, 0, wcs, -1, &ret[0], len, 0, 0)); 65 | ret.resize(len - 1); 66 | return ret; 67 | } 68 | #else 69 | #define _W2T(str) std::wstring(str) 70 | #endif 71 | 72 | #define REPEAT_0(macro) 73 | #define REPEAT_1(macro) REPEAT_0(macro) 74 | #define REPEAT_2(macro) REPEAT_1(macro) macro(1) 75 | #define REPEAT_3(macro) REPEAT_2(macro) macro(2) 76 | #define REPEAT_4(macro) REPEAT_3(macro) macro(3) 77 | #define REPEAT_5(macro) REPEAT_4(macro) macro(4) 78 | #define REPEAT_6(macro) REPEAT_5(macro) macro(5) 79 | #define REPEAT_7(macro) REPEAT_6(macro) macro(6) 80 | #define REPEAT_8(macro) REPEAT_7(macro) macro(7) 81 | #define REPEAT_9(macro) REPEAT_8(macro) macro(8) 82 | #define REPEAT_10(macro) REPEAT_9(macro) macro(9) 83 | #define REPEAT_11(macro) REPEAT_10(macro) macro(10) 84 | #define REPEAT_12(macro) REPEAT_11(macro) macro(11) 85 | #define REPEAT_13(macro) REPEAT_12(macro) macro(12) 86 | #define REPEAT_14(macro) REPEAT_13(macro) macro(13) 87 | #define REPEAT_15(macro) REPEAT_14(macro) macro(14) 88 | #define REPEAT_16(macro) REPEAT_15(macro) macro(15) 89 | #define REPEAT_17(macro) REPEAT_16(macro) macro(16) 90 | #define REPEAT_18(macro) REPEAT_17(macro) macro(17) 91 | #define REPEAT_19(macro) REPEAT_18(macro) macro(18) 92 | #define REPEAT_20(macro) REPEAT_19(macro) macro(19) 93 | 94 | #define END_MACRO_0(macro) 95 | #define END_MACRO_1(macro) macro(1) 96 | #define END_MACRO_2(macro) macro(2) 97 | #define END_MACRO_3(macro) macro(3) 98 | #define END_MACRO_4(macro) macro(4) 99 | #define END_MACRO_5(macro) macro(5) 100 | #define END_MACRO_6(macro) macro(6) 101 | #define END_MACRO_7(macro) macro(7) 102 | #define END_MACRO_8(macro) macro(8) 103 | #define END_MACRO_9(macro) macro(9) 104 | #define END_MACRO_10(macro) macro(10) 105 | #define END_MACRO_11(macro) macro(11) 106 | #define END_MACRO_12(macro) macro(12) 107 | #define END_MACRO_13(macro) macro(13) 108 | #define END_MACRO_14(macro) macro(14) 109 | #define END_MACRO_15(macro) macro(15) 110 | #define END_MACRO_16(macro) macro(16) 111 | #define END_MACRO_17(macro) macro(17) 112 | #define END_MACRO_18(macro) macro(18) 113 | #define END_MACRO_19(macro) macro(19) 114 | #define END_MACRO_20(macro) macro(20) 115 | 116 | #define REPEAT(n, macro, end_macro) REPEAT_##n (macro) END_MACRO_##n(end_macro) 117 | 118 | #define __ARG(n) P ## n 119 | #define __PARAM(n) p ## n 120 | #define __ARG_DECL(n) __ARG(n) __PARAM(n) 121 | 122 | #define TEMPLATE_ARG(n) typename __ARG(n) 123 | #define VOID_TEMPLATE_ARGS(n) typename __ARG(n), 124 | 125 | #define ARG_DECL(n) __ARG_DECL(n) , 126 | #define END_ARG_DECL(n) __ARG_DECL(n) 127 | 128 | #define DECL_VOID_TEMPLATE_ARGS(n) REPEAT(n, VOID_TEMPLATE_ARGS, TEMPLATE_ARG) 129 | #define DECL_PARAMS_LIST(n) REPEAT(n, ARG_DECL, END_ARG_DECL) 130 | 131 | namespace { 132 | template 133 | struct _UNICODE_STRING_T { 134 | union { 135 | struct { 136 | WORD Length; 137 | WORD MaximumLength; 138 | }; 139 | T dummy; 140 | }; 141 | T Buffer; 142 | }; 143 | 144 | template 145 | struct _LIST_ENTRY_T { 146 | T Flink; 147 | T Blink; 148 | }; 149 | 150 | template 151 | struct _PEB_T { 152 | T dummy01; 153 | T Mutant; 154 | T ImageBaseAddress; 155 | T Ldr; 156 | // omit unused fields 157 | }; 158 | 159 | typedef _PEB_T PEB32; 160 | typedef _PEB_T PEB64; 161 | 162 | typedef struct _PROCESS_BASIC_INFORMATION32 { 163 | NTSTATUS ExitStatus; 164 | UINT32 PebBaseAddress; 165 | UINT32 AffinityMask; 166 | UINT32 BasePriority; 167 | UINT32 UniqueProcessId; 168 | UINT32 InheritedFromUniqueProcessId; 169 | } PROCESS_BASIC_INFORMATION32; 170 | 171 | typedef struct _PROCESS_BASIC_INFORMATION64 { 172 | NTSTATUS ExitStatus; 173 | UINT32 Reserved0; 174 | UINT64 PebBaseAddress; 175 | UINT64 AffinityMask; 176 | UINT32 BasePriority; 177 | UINT32 Reserved1; 178 | UINT64 UniqueProcessId; 179 | UINT64 InheritedFromUniqueProcessId; 180 | } PROCESS_BASIC_INFORMATION64; 181 | 182 | template 183 | struct _PEB_LDR_DATA_T { 184 | DWORD Length; 185 | DWORD Initialized; 186 | T SsHandle; 187 | _LIST_ENTRY_T InLoadOrderModuleList; 188 | // omit unused fields 189 | }; 190 | 191 | typedef _PEB_LDR_DATA_T PEB_LDR_DATA32; 192 | typedef _PEB_LDR_DATA_T PEB_LDR_DATA64; 193 | 194 | template 195 | struct _LDR_DATA_TABLE_ENTRY_T { 196 | _LIST_ENTRY_T InLoadOrderLinks; 197 | _LIST_ENTRY_T InMemoryOrderLinks; 198 | _LIST_ENTRY_T InInitializationOrderLinks; 199 | T DllBase; 200 | T EntryPoint; 201 | union { 202 | DWORD SizeOfImage; 203 | T dummy01; 204 | }; 205 | _UNICODE_STRING_T FullDllName; 206 | _UNICODE_STRING_T BaseDllName; 207 | // omit unused fields 208 | }; 209 | 210 | typedef _LDR_DATA_TABLE_ENTRY_T LDR_DATA_TABLE_ENTRY32; 211 | typedef _LDR_DATA_TABLE_ENTRY_T LDR_DATA_TABLE_ENTRY64; 212 | 213 | size_t tcslen(const char* str) { return strlen(str); } 214 | size_t tcslen(const wchar_t* str) { return wcslen(str); } 215 | } 216 | 217 | DWORD64 WINAPI GetProcAddress(HANDLE hProcess, DWORD64 hModule, const char* funcName); 218 | 219 | #ifdef _WIN64 220 | typedef NTSTATUS(WINAPI *NT_QUERY_INFORMATION_PROCESS)( 221 | HANDLE ProcessHandle, ULONG ProcessInformationClass, 222 | PVOID ProcessInformation, UINT32 ProcessInformationLength, 223 | UINT32 * ReturnLength); 224 | 225 | static NT_QUERY_INFORMATION_PROCESS NtWow64QueryInformationProcess64 = (NT_QUERY_INFORMATION_PROCESS)GetProcAddress((HMODULE)detail::hNtDll, "NtQueryInformationProcess"); 226 | #define NtWow64ReadVirtualMemory64 ReadProcessMemory 227 | 228 | #else 229 | 230 | namespace { 231 | typedef NTSTATUS(WINAPI *NT_WOW64_QUERY_INFORMATION_PROCESS64)( 232 | HANDLE ProcessHandle, UINT32 ProcessInformationClass, 233 | PVOID ProcessInformation, UINT32 ProcessInformationLength, 234 | UINT32* ReturnLength); 235 | 236 | typedef NTSTATUS(WINAPI *NT_WOW64_READ_VIRTUAL_MEMORY64)( 237 | HANDLE ProcessHandle, PVOID64 BaseAddress, 238 | PVOID BufferData, UINT64 BufferLength, 239 | PUINT64 ReturnLength); 240 | 241 | static NT_WOW64_QUERY_INFORMATION_PROCESS64 NtWow64QueryInformationProcess64 = (NT_WOW64_QUERY_INFORMATION_PROCESS64)GetProcAddress((HMODULE)detail::hNtDll, "NtWow64QueryInformationProcess64"); 242 | static NT_WOW64_READ_VIRTUAL_MEMORY64 NtWow64ReadVirtualMemory64 = (NT_WOW64_READ_VIRTUAL_MEMORY64)GetProcAddress((HMODULE)detail::hNtDll, "NtWow64ReadVirtualMemory64"); 243 | } 244 | 245 | #endif 246 | 247 | DWORD64 WINAPI GetModuleHandle(HANDLE hProcess, const TCHAR* moduleName) 248 | { 249 | if (!moduleName) return 0; 250 | if (!hProcess) hProcess = detail::hCurProcess; 251 | 252 | HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, GetProcessId(hProcess)); 253 | if (hSnap == INVALID_HANDLE_VALUE) return 0; 254 | MODULEENTRY32 mod = { sizeof(mod) }; 255 | if (Module32First(hSnap, &mod)) { 256 | do { 257 | if (!_tcsicmp(mod.szModule, moduleName)) { 258 | CloseHandle(hSnap); 259 | return (DWORD64)mod.hModule; 260 | } 261 | } while (Module32Next(hSnap, &mod)); 262 | } 263 | CloseHandle(hSnap); 264 | return 0; 265 | } 266 | 267 | DWORD64 WINAPI GetProcAddress(HANDLE hProcess, DWORD64 hModule, const char* funcName) 268 | { 269 | if (!hModule || !funcName) return 0; 270 | if (!hProcess) hProcess = detail::hCurProcess; 271 | 272 | IMAGE_DOS_HEADER idh; 273 | NTSTATUS status = ReadProcessMemory(hProcess, (PVOID)hModule, (PVOID)&idh, sizeof(idh), NULL); 274 | if (!NT_SUCCESS(status)) return 0; 275 | 276 | IMAGE_NT_HEADERS32 inh; 277 | status = ReadProcessMemory(hProcess, (PVOID)(hModule + idh.e_lfanew), (PVOID)&inh, sizeof(inh), NULL); 278 | if (!NT_SUCCESS(status)) return 0; 279 | 280 | IMAGE_DATA_DIRECTORY& idd = inh.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 281 | if (!idd.VirtualAddress)return 0; 282 | 283 | IMAGE_EXPORT_DIRECTORY ied; 284 | status = ReadProcessMemory(hProcess, (PVOID)(hModule + idd.VirtualAddress), (PVOID)&ied, sizeof(ied), NULL); 285 | if (!NT_SUCCESS(status)) return 0; 286 | 287 | std::vector nameTable(ied.NumberOfNames); 288 | status = ReadProcessMemory(hProcess, (PVOID)(hModule + ied.AddressOfNames), (PVOID)&nameTable[0], sizeof(DWORD) * ied.NumberOfNames, NULL); 289 | if (!NT_SUCCESS(status)) return 0; 290 | 291 | for (DWORD i = 0; i < ied.NumberOfNames; ++i) { 292 | std::string func(strlen(funcName), 0); 293 | status = ReadProcessMemory(hProcess, (PVOID)(hModule + nameTable[i]), (PVOID)&func[0], strlen(funcName), NULL); 294 | if (!NT_SUCCESS(status)) continue; 295 | 296 | if (func == funcName) { 297 | WORD ord = 0; 298 | status = ReadProcessMemory(hProcess, (PVOID)(hModule + ied.AddressOfNameOrdinals + i * sizeof(WORD)), (PVOID)&ord, sizeof(WORD), NULL); 299 | if (!NT_SUCCESS(status)) continue; 300 | 301 | DWORD rva = 0; 302 | status = ReadProcessMemory(hProcess, (PVOID)(hModule + ied.AddressOfFunctions + ord * sizeof(DWORD)), (PVOID)&rva, sizeof(DWORD), NULL); 303 | if (!NT_SUCCESS(status)) continue; 304 | 305 | return hModule + rva; 306 | } 307 | } 308 | return 0; 309 | } 310 | 311 | DWORD64 WINAPI GetModuleHandle64(HANDLE hProcess, const TCHAR* moduleName) 312 | { 313 | if (!moduleName) return 0; 314 | if (!hProcess) hProcess = detail::hCurProcess; 315 | 316 | #ifndef _WIN64 317 | if (!NtWow64QueryInformationProcess64 || !NtWow64ReadVirtualMemory64) return 0; 318 | #endif 319 | 320 | PROCESS_BASIC_INFORMATION64 pbi = { 0 }; 321 | const int ProcessBasicInformation = 0; 322 | NTSTATUS status = NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL); 323 | if (!NT_SUCCESS(status)) return 0; 324 | 325 | PEB64 peb; 326 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)pbi.PebBaseAddress, &peb, sizeof(peb), NULL); 327 | if (!NT_SUCCESS(status)) return 0; 328 | 329 | PEB_LDR_DATA64 ldr; 330 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)peb.Ldr, (PVOID)&ldr, sizeof(ldr), NULL); 331 | if (!NT_SUCCESS(status)) return 0; 332 | 333 | DWORD64 LastEntry = peb.Ldr + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList); 334 | 335 | LDR_DATA_TABLE_ENTRY64 head; 336 | head.InLoadOrderLinks.Flink = ldr.InLoadOrderModuleList.Flink; 337 | do { 338 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)head.InLoadOrderLinks.Flink, (PVOID)&head, sizeof(head), NULL); 339 | if (!NT_SUCCESS(status)) continue; 340 | 341 | std::wstring modName((size_t)head.BaseDllName.MaximumLength, 0); 342 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)head.BaseDllName.Buffer, (PVOID)&modName[0], head.BaseDllName.MaximumLength, NULL); 343 | if (!NT_SUCCESS(status)) continue; 344 | 345 | if (!_tcsicmp(moduleName, _W2T(modName).c_str())) 346 | return head.DllBase; 347 | } while (head.InLoadOrderLinks.Flink != LastEntry); 348 | return 0; 349 | } 350 | 351 | DWORD64 WINAPI GetProcAddress64(HANDLE hProcess, DWORD64 hModule, const char* funcName) 352 | { 353 | if (!hModule || !funcName) return 0; 354 | if (!hProcess) hProcess = detail::hCurProcess; 355 | 356 | #ifndef _WIN64 357 | if (!NtWow64ReadVirtualMemory64) return 0; 358 | #endif 359 | 360 | IMAGE_DOS_HEADER idh; 361 | NTSTATUS status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)hModule, (PVOID)&idh, sizeof(idh), NULL); 362 | if (!NT_SUCCESS(status)) return 0; 363 | 364 | IMAGE_NT_HEADERS64 inh; 365 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(hModule + idh.e_lfanew), (PVOID)&inh, sizeof(inh), NULL); 366 | if (!NT_SUCCESS(status)) return 0; 367 | 368 | IMAGE_DATA_DIRECTORY& idd = inh.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 369 | if (!idd.VirtualAddress)return 0; 370 | 371 | IMAGE_EXPORT_DIRECTORY ied; 372 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(hModule + idd.VirtualAddress), (PVOID)&ied, sizeof(ied), NULL); 373 | if (!NT_SUCCESS(status)) return 0; 374 | 375 | std::vector nameTable(ied.NumberOfNames); 376 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(hModule + ied.AddressOfNames), (PVOID)&nameTable[0], sizeof(DWORD) * ied.NumberOfNames, NULL); 377 | if (!NT_SUCCESS(status)) return 0; 378 | 379 | for (DWORD i = 0; i < ied.NumberOfNames; ++i) { 380 | std::string func(strlen(funcName), 0); 381 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(hModule + nameTable[i]), (PVOID)&func[0], strlen(funcName), NULL); 382 | if (!NT_SUCCESS(status)) continue; 383 | 384 | if (func == funcName) { 385 | WORD ord = 0; 386 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(hModule + ied.AddressOfNameOrdinals + i * sizeof(WORD)), (PVOID)&ord, sizeof(WORD), NULL); 387 | if (!NT_SUCCESS(status)) continue; 388 | 389 | DWORD rva = 0; 390 | status = NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(hModule + ied.AddressOfFunctions + ord * sizeof(DWORD)), (PVOID)&rva, sizeof(DWORD), NULL); 391 | if (!NT_SUCCESS(status)) continue; 392 | 393 | return hModule + rva; 394 | } 395 | } 396 | return 0; 397 | } 398 | 399 | DWORD64 GetNtDll64() 400 | { 401 | static DWORD64 hNtdll64 = 0; 402 | if(hNtdll64) return hNtdll64; 403 | hNtdll64 = GetModuleHandle64(detail::hCurProcess, _T("ntdll.dll")); 404 | return hNtdll64; 405 | } 406 | 407 | #ifdef _WIN64 408 | 409 | #define SetLastError64 SetLastError 410 | #define VirtualQueryEx64 VirtualQueryEx 411 | #define VirtualAllocEx64 VirtualAllocEx 412 | #define VirtualFreeEx64 VirtualFreeEx 413 | #define VirtualProtectEx64 VirtualProtectEx 414 | #define ReadProcessMemory64 ReadProcessMemory 415 | #define WriteProcessMemory64 WriteProcessMemory 416 | #define LoadLibrary64 LoadLibrary 417 | #define CreateRemoteThread64 CreateRemoteThread 418 | 419 | #else 420 | 421 | namespace { 422 | #define _(x) __asm __emit (x) 423 | __declspec(naked) DWORD64 x64Call(DWORD64 func, int argC, ...) 424 | { 425 | // see X64Call_disassemble for details 426 | _(0x55)_(0x8b)_(0xec)_(0x8b)_(0x4d)_(0x10)_(0x8d)_(0x55)_(0x14)_(0x83)_(0xec)_(0x40)_(0x53)_(0x56)_(0x57)_(0x85) 427 | _(0xc9)_(0x7e)_(0x15)_(0x8b)_(0x45)_(0x14)_(0x8d)_(0x55)_(0x1c)_(0x49)_(0x89)_(0x45)_(0xf0)_(0x8b)_(0x45)_(0x18) 428 | _(0x89)_(0x4d)_(0x10)_(0x89)_(0x45)_(0xf4)_(0xeb)_(0x08)_(0x0f)_(0x57)_(0xc0)_(0x66)_(0x0f)_(0x13)_(0x45)_(0xf0) 429 | _(0x85)_(0xc9)_(0x7e)_(0x15)_(0x49)_(0x83)_(0xc2)_(0x08)_(0x89)_(0x4d)_(0x10)_(0x8b)_(0x42)_(0xf8)_(0x89)_(0x45) 430 | _(0xe8)_(0x8b)_(0x42)_(0xfc)_(0x89)_(0x45)_(0xec)_(0xeb)_(0x08)_(0x0f)_(0x57)_(0xc0)_(0x66)_(0x0f)_(0x13)_(0x45) 431 | _(0xe8)_(0x85)_(0xc9)_(0x7e)_(0x15)_(0x49)_(0x83)_(0xc2)_(0x08)_(0x89)_(0x4d)_(0x10)_(0x8b)_(0x42)_(0xf8)_(0x89) 432 | _(0x45)_(0xe0)_(0x8b)_(0x42)_(0xfc)_(0x89)_(0x45)_(0xe4)_(0xeb)_(0x08)_(0x0f)_(0x57)_(0xc0)_(0x66)_(0x0f)_(0x13) 433 | _(0x45)_(0xe0)_(0x85)_(0xc9)_(0x7e)_(0x15)_(0x49)_(0x83)_(0xc2)_(0x08)_(0x89)_(0x4d)_(0x10)_(0x8b)_(0x42)_(0xf8) 434 | _(0x89)_(0x45)_(0xd8)_(0x8b)_(0x42)_(0xfc)_(0x89)_(0x45)_(0xdc)_(0xeb)_(0x08)_(0x0f)_(0x57)_(0xc0)_(0x66)_(0x0f) 435 | _(0x13)_(0x45)_(0xd8)_(0x8b)_(0xc2)_(0xc7)_(0x45)_(0xfc)_(0x00)_(0x00)_(0x00)_(0x00)_(0x99)_(0x0f)_(0x57)_(0xc0) 436 | _(0x89)_(0x45)_(0xc0)_(0x8b)_(0xc1)_(0x89)_(0x55)_(0xc4)_(0x99)_(0x66)_(0x0f)_(0x13)_(0x45)_(0xc8)_(0x89)_(0x45) 437 | _(0xd0)_(0x89)_(0x55)_(0xd4)_(0xc7)_(0x45)_(0xf8)_(0x00)_(0x00)_(0x00)_(0x00)_(0x66)_(0x8c)_(0x65)_(0xf8)_(0xb8) 438 | _(0x2b)_(0x00)_(0x00)_(0x00)_(0x66)_(0x8e)_(0xe0)_(0x89)_(0x65)_(0xfc)_(0x83)_(0xe4)_(0xf0)_(0x6a)_(0x33)_(0xe8) 439 | _(0x00)_(0x00)_(0x00)_(0x00)_(0x83)_(0x04)_(0x24)_(0x05)_(0xcb)_(0x48)_(0x8b)_(0x4d)_(0xf0)_(0x48)_(0x8b)_(0x55) 440 | _(0xe8)_(0xff)_(0x75)_(0xe0)_(0x49)_(0x58)_(0xff)_(0x75)_(0xd8)_(0x49)_(0x59)_(0x48)_(0x8b)_(0x45)_(0xd0)_(0xa8) 441 | _(0x01)_(0x75)_(0x03)_(0x83)_(0xec)_(0x08)_(0x57)_(0x48)_(0x8b)_(0x7d)_(0xc0)_(0x48)_(0x85)_(0xc0)_(0x74)_(0x16) 442 | _(0x48)_(0x8d)_(0x7c)_(0xc7)_(0xf8)_(0x48)_(0x85)_(0xc0)_(0x74)_(0x0c)_(0xff)_(0x37)_(0x48)_(0x83)_(0xef)_(0x08) 443 | _(0x48)_(0x83)_(0xe8)_(0x01)_(0xeb)_(0xef)_(0x48)_(0x83)_(0xec)_(0x20)_(0xff)_(0x55)_(0x08)_(0x48)_(0x8b)_(0x4d) 444 | _(0xd0)_(0x48)_(0x8d)_(0x64)_(0xcc)_(0x20)_(0x5f)_(0x48)_(0x89)_(0x45)_(0xc8)_(0xe8)_(0x00)_(0x00)_(0x00)_(0x00) 445 | _(0xc7)_(0x44)_(0x24)_(0x04)_(0x23)_(0x00)_(0x00)_(0x00)_(0x83)_(0x04)_(0x24)_(0x0d)_(0xcb)_(0x66)_(0x8c)_(0xd8) 446 | _(0x66)_(0x8e)_(0xd0)_(0x8b)_(0x65)_(0xfc)_(0x66)_(0x8b)_(0x45)_(0xf8)_(0x66)_(0x8e)_(0xe0)_(0x8b)_(0x45)_(0xc8) 447 | _(0x8b)_(0x55)_(0xcc)_(0x5f)_(0x5e)_(0x5b)_(0x8b)_(0xe5)_(0x5d)_(0xc3) 448 | } 449 | #undef _ 450 | } 451 | 452 | class X64Call 453 | { 454 | template 455 | struct StringHelper : detail::GCBase 456 | { 457 | StringHelper(const char_t* v) : name(0) { 458 | name = new _UNICODE_STRING_T; 459 | name->Buffer = (DWORD64)v; 460 | name->Length = (WORD)tcslen(v) * sizeof(char_t); 461 | name->MaximumLength = name->Length; 462 | } 463 | virtual void gc() { delete name; } 464 | virtual DWORD64 toDWORD64() { return (DWORD64)name; } 465 | private: 466 | _UNICODE_STRING_T* name; 467 | }; 468 | template 469 | DWORD64 ToDWORD64(T v, detail::GCHelper*) { 470 | return DWORD64(v); 471 | } 472 | template<> DWORD64 ToDWORD64(const char* v, detail::GCHelper* helper) { return helper->add(new StringHelper(v)); } 473 | template<> DWORD64 ToDWORD64(const wchar_t* v, detail::GCHelper* helper) { return helper->add(new StringHelper(v)); } 474 | template<> DWORD64 ToDWORD64(char* v, detail::GCHelper* helper) { return helper->add(new StringHelper(v)); } 475 | template<> DWORD64 ToDWORD64(wchar_t* v, detail::GCHelper* helper) { return helper->add(new StringHelper(v)); } 476 | 477 | private: 478 | DWORD64 func; 479 | 480 | public: 481 | X64Call(const char* funcName) : func(GetProcAddress64(0, GetNtDll64(), funcName)) {} 482 | X64Call(DWORD64 module, const char* funcName) : func(GetProcAddress64(0, module, funcName)) {} 483 | 484 | operator DWORD64() { return func; } 485 | 486 | DWORD64 operator()() { return func && x64Call(func, 0); } 487 | 488 | #define __TO_DWORD64_DECL(n) ToDWORD64(__PARAM(n), &helper) 489 | #define TO_DWORD64_DECL(n) __TO_DWORD64_DECL(n) , 490 | #define END_TO_DWORD64_DECL(n) __TO_DWORD64_DECL(n) 491 | #define CALLERS(n) template DWORD64 operator()(DECL_PARAMS_LIST(n)) { detail::GCHelper helper; return func && x64Call(func, n, REPEAT(n, TO_DWORD64_DECL, END_TO_DWORD64_DECL)); } 492 | CALLERS( 1) CALLERS( 2) CALLERS( 3) CALLERS( 4) CALLERS( 5) CALLERS( 6) CALLERS( 7) CALLERS( 8) CALLERS( 9) CALLERS(10) 493 | CALLERS(11) CALLERS(12) CALLERS(13) CALLERS(14) CALLERS(15) CALLERS(16) CALLERS(17) CALLERS(18) CALLERS(19) CALLERS(20) 494 | #undef CALLERS 495 | #undef END_TO_DWORD64_DECL 496 | #undef TO_DWORD64_DECL 497 | #undef __TO_DWORD64_DECL 498 | }; 499 | 500 | VOID WINAPI SetLastError64(DWORD64 status) 501 | { 502 | typedef ULONG (WINAPI *RTL_NTSTATUS_TO_DOS_ERROR)(NTSTATUS Status); 503 | typedef ULONG (WINAPI *RTL_SET_LAST_WIN32_ERROR)(NTSTATUS Status); 504 | 505 | static RTL_NTSTATUS_TO_DOS_ERROR RtlNtStatusToDosError = (RTL_NTSTATUS_TO_DOS_ERROR)GetProcAddress(detail::hNtDll, "RtlNtStatusToDosError"); 506 | static RTL_SET_LAST_WIN32_ERROR RtlSetLastWin32Error = (RTL_SET_LAST_WIN32_ERROR)GetProcAddress(detail::hNtDll, "RtlSetLastWin32Error"); 507 | 508 | if (RtlNtStatusToDosError && RtlSetLastWin32Error) 509 | RtlSetLastWin32Error(RtlNtStatusToDosError((DWORD)status)); 510 | } 511 | 512 | SIZE_T WINAPI VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength) 513 | { 514 | static X64Call NtQueryVirtualMemory("NtQueryVirtualMemory"); 515 | if (!NtQueryVirtualMemory) return 0; 516 | 517 | DWORD64 ret = 0; 518 | DWORD64 status = NtQueryVirtualMemory(hProcess, lpAddress, 0, lpBuffer, dwLength, &ret); 519 | if (!status) return (SIZE_T)ret; 520 | 521 | SetLastError64(ret); 522 | return FALSE; 523 | } 524 | 525 | DWORD64 WINAPI VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) 526 | { 527 | static X64Call NtAllocateVirtualMemory("NtAllocateVirtualMemory"); 528 | if (!NtAllocateVirtualMemory) return 0; 529 | 530 | DWORD64 tmpAddr = lpAddress; 531 | DWORD64 tmpSize = dwSize; 532 | DWORD64 ret = NtAllocateVirtualMemory(hProcess, &tmpAddr, 0, &tmpSize, flAllocationType, flProtect); 533 | if (!ret) return tmpAddr; 534 | 535 | SetLastError64(ret); 536 | return FALSE; 537 | } 538 | 539 | BOOL WINAPI VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType) 540 | { 541 | static X64Call NtFreeVirtualMemory("NtFreeVirtualMemory"); 542 | if (!NtFreeVirtualMemory) return 0; 543 | 544 | DWORD64 tmpAddr = lpAddress; 545 | DWORD64 tmpSize = dwSize; 546 | DWORD64 ret = NtFreeVirtualMemory(hProcess, &tmpAddr, &tmpSize, dwFreeType); 547 | if (!ret) return TRUE; 548 | 549 | SetLastError64(ret); 550 | return FALSE; 551 | } 552 | 553 | BOOL WINAPI VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect) 554 | { 555 | static X64Call NtProtectVirtualMemory("NtProtectVirtualMemory"); 556 | if (!NtProtectVirtualMemory) return 0; 557 | 558 | DWORD64 tmpAddr = lpAddress; 559 | DWORD64 tmpSize = dwSize; 560 | DWORD64 ret = NtProtectVirtualMemory(hProcess, &tmpAddr, &tmpSize, flNewProtect, lpflOldProtect); 561 | if (!ret) return TRUE; 562 | 563 | SetLastError64(ret); 564 | return FALSE; 565 | } 566 | 567 | BOOL WINAPI ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead) 568 | { 569 | static X64Call NtReadVirtualMemory("NtReadVirtualMemory"); 570 | if (!NtReadVirtualMemory) return 0; 571 | 572 | DWORD64 read = 0; 573 | DWORD64 ret = NtReadVirtualMemory(hProcess, lpBaseAddress, lpBuffer, nSize, &read); 574 | if (!ret) { 575 | if (lpNumberOfBytesRead) *lpNumberOfBytesRead = (SIZE_T)read; 576 | return TRUE; 577 | } 578 | 579 | SetLastError64(ret); 580 | return FALSE; 581 | } 582 | 583 | BOOL WINAPI WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten) 584 | { 585 | static X64Call NtWriteVirtualMemory("NtWriteVirtualMemory"); 586 | if (!NtWriteVirtualMemory) return 0; 587 | 588 | DWORD64 written = 0; 589 | DWORD64 ret = NtWriteVirtualMemory(hProcess, lpBaseAddress, lpBuffer, nSize, &written); 590 | if (!ret) { 591 | if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = (SIZE_T)written; 592 | return TRUE; 593 | } 594 | 595 | SetLastError64(ret); 596 | return FALSE; 597 | } 598 | 599 | HANDLE WINAPI CreateRemoteThread64(HANDLE hProcess, 600 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 601 | SIZE_T dwStackSize, 602 | DWORD64 lpStartAddress, 603 | DWORD64 lpParameter, 604 | DWORD dwCreationFlags, 605 | LPDWORD lpThreadId) 606 | { 607 | static X64Call RtlCreateUserThread("RtlCreateUserThread"); 608 | if (!RtlCreateUserThread) return 0; 609 | 610 | BOOLEAN createSuspended = dwCreationFlags & CREATE_SUSPENDED; 611 | ULONG stackSize = dwStackSize; 612 | DWORD64 handle = 0; 613 | DWORD64 status = RtlCreateUserThread(hProcess, lpThreadAttributes, createSuspended, 0, (dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION) ? &stackSize : NULL, &stackSize, lpStartAddress, lpParameter, &handle, NULL); 614 | if (!status) return (HANDLE)handle; 615 | 616 | SetLastError64(status); 617 | return NULL; 618 | } 619 | 620 | #endif 621 | 622 | class ProcessWriter 623 | { 624 | public: 625 | template 626 | ProcessWriter(HANDLE hProcess, T content, SIZE_T dwSize, DWORD flProtect = PAGE_READWRITE) 627 | : _autoRelease(TRUE) 628 | , _hProcess(hProcess) 629 | , _dw64Address(0) 630 | , _dwSize(dwSize) 631 | { 632 | if (!(_dw64Address = VirtualAllocEx64(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, flProtect))) 633 | return; 634 | SIZE_T written = 0; 635 | if (!WriteProcessMemory64(hProcess, _dw64Address, (PVOID)content, dwSize, &written) || written != dwSize) { 636 | VirtualFreeEx64(hProcess, _dw64Address, _dwSize, MEM_DECOMMIT); 637 | _dw64Address = 0; 638 | } 639 | } 640 | ~ProcessWriter() { 641 | if (_dw64Address && _autoRelease) 642 | VirtualFreeEx64(_hProcess, _dw64Address, _dwSize, MEM_DECOMMIT); 643 | } 644 | void SetDontRelese() { 645 | _autoRelease = FALSE; 646 | } 647 | operator DWORD64() { 648 | return (DWORD64)_dw64Address; 649 | } 650 | #ifdef _WIN64 651 | template 652 | operator T*() { 653 | return (T*)_dw64Address; 654 | } 655 | #endif 656 | 657 | private: 658 | BOOL _autoRelease; 659 | HANDLE _hProcess; 660 | #ifdef _WIN64 661 | LPVOID _dw64Address; 662 | #else 663 | DWORD64 _dw64Address; 664 | #endif 665 | SIZE_T _dwSize; 666 | }; 667 | 668 | namespace { 669 | 670 | std::string makeShellCode(int cnt, bool is64Bit) 671 | { 672 | if(is64Bit) { 673 | // see X64Delegator_disassemble for details 674 | static const unsigned char kTmpl_x64[] = { 0x40, 0x53, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, 0xd9, 0x48, 0x85, 0xc9, 0x74, 0x1d, 0x48, 0x83, 675 | 0x39, 0x00, 0x48, 0x8b, 0x41, 0x08, 0x74, 0x0b, 0xff, 0xd0, 0x48, 0x89, 0x03, 0x48, 0x83, 0xc4, 676 | 0x20, 0x5b, 0xc3, 0x48, 0x83, 0xc4, 0x20, 0x5b, 0x48, 0xff, 0xe0, 0x33, 0xc0, 0x48, 0x83, 0xc4, 677 | 0x20, 0x5b, 0xc3 }; 678 | 679 | std::string templ_x64((const char*)kTmpl_x64, sizeof(kTmpl_x64)); 680 | if(!cnt) return templ_x64; 681 | 682 | templ_x64[13] += (cnt <= 4) ? cnt * 4 : (cnt - 4) * 9 + 16; 683 | if(cnt >= 1) 684 | templ_x64[16] = 0x3b; 685 | 686 | if(cnt < 3) { 687 | if(cnt >= 1) { 688 | templ_x64.insert(22, "\x48\x8b\x49\x10", 4); 689 | } 690 | if(cnt >= 2) { 691 | templ_x64.insert(22, "\x48\x8b\x51\x18", 4); 692 | } 693 | } 694 | else { 695 | templ_x64[20] = 0x49; 696 | templ_x64[21] = 0x10; 697 | templ_x64.insert(22, "\x48\x8B\x53\x18", 4); 698 | templ_x64.insert(22, "\x4c\x8b\x43\x20", 4); 699 | templ_x64.insert(22, "\x48\x8b\x43\x08", 4); 700 | if(cnt >= 4) { 701 | templ_x64.insert(26, "\x4c\x8b\x4b\x28", 4); 702 | } 703 | if(cnt >= 5) { 704 | templ_x64.insert(18, "\x4c\x8B\x53\x30", 4); 705 | templ_x64.insert(42, "\x4c\x89\x54\x24\x20", 5); 706 | } 707 | if(cnt >= 6) { 708 | templ_x64[21] = 0x38; 709 | templ_x64.insert(22, "\x4c\x8b\x5b\x30", 4); 710 | templ_x64[50] = 0x28; 711 | templ_x64.insert(51, "\x4c\x89\x5c\x24\x20", 5); 712 | } 713 | // TODO 714 | } 715 | return templ_x64; 716 | } 717 | // see X86Delegator_disassemble for details 718 | static const unsigned char kTmpl_x86[] = { 0x55, 0x8b, 0xec, 0x51, 0x83, 0x7d, 0x08, 0x00, 0x74, 0x0c, 0x8b ,0x45, 0x08, 0x8b, 0x08, 0xff, 719 | 0xd0, 0x89, 0x45, 0xfc, 0xeb, 0x07, 0xc7, 0x45, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x45, 0xfc, 720 | 0x8b, 0xe5, 0x5d, 0xc3 }; 721 | std::string templ_x86((const char*)kTmpl_x86, sizeof(kTmpl_x86)); 722 | // je distance 723 | templ_x86[9] += cnt * 7; 724 | templ_x86[16] += ((1 - cnt) % 3 + 3) % 3; 725 | int pos = 13; 726 | for(int i = 0; i < cnt; ++i) { 727 | switch(i % 3) { 728 | case 0: 729 | templ_x86.insert(pos, "\x8b\x48\xcc\x51\x8b\x55\x08", 7); 730 | break; 731 | case 1: 732 | templ_x86.insert(pos, "\x8b\x42\xcc\x50\x8b\x4d\x08", 7); 733 | break; 734 | case 2: 735 | templ_x86.insert(pos, "\x8b\x51\xcc\x52\x8b\x45\x08", 7); 736 | break; 737 | } 738 | templ_x86[pos + 2] = (cnt - i) << 2; 739 | pos += 7; 740 | } 741 | switch(cnt % 3) { 742 | case 0: 743 | templ_x86[pos + 1] = 0x08; 744 | break; 745 | case 1: 746 | templ_x86[pos + 1] = 0x02; 747 | break; 748 | case 2: 749 | templ_x86[pos + 1] = 0x11; 750 | break; 751 | } 752 | return templ_x86; 753 | } 754 | 755 | template 756 | const std::string& shellCode() { 757 | static std::string kCode = makeShellCode(argCnt, is64Bit); 758 | return kCode; 759 | } 760 | 761 | } 762 | 763 | class YAPICall 764 | { 765 | template 766 | DWORD64 ToDWORD64(T v, HANDLE hProcess, detail::GCHelper*) { 767 | return DWORD64(v); 768 | } 769 | template 770 | struct StringHelper : detail::GCBase 771 | { 772 | StringHelper(HANDLE hProcess, const char_t* v) : name(0) { 773 | name = new ProcessWriter(hProcess, v, (tcslen(v) + 1) * sizeof(char_t)); 774 | } 775 | virtual void gc() { delete name; } 776 | virtual DWORD64 toDWORD64() { return (DWORD64)*name; } 777 | private: 778 | ProcessWriter* name; 779 | }; 780 | template<> DWORD64 ToDWORD64(const char* v, HANDLE hProcess, detail::GCHelper* helper) { return helper->add(new StringHelper(hProcess, v)); } 781 | template<> DWORD64 ToDWORD64(const wchar_t* v, HANDLE hProcess, detail::GCHelper* helper) { return helper->add(new StringHelper(hProcess, v)); } 782 | template<> DWORD64 ToDWORD64(char* v, HANDLE hProcess, detail::GCHelper* helper) { return helper->add(new StringHelper(hProcess, v)); } 783 | template<> DWORD64 ToDWORD64(wchar_t* v, HANDLE hProcess, detail::GCHelper* helper) { return helper->add(new StringHelper(hProcess, v)); } 784 | 785 | private: 786 | HANDLE _hProcess; 787 | ProcessWriter* _sc; 788 | DWORD64 func; 789 | BOOL _dw64Ret; 790 | DWORD _dwTimeout; 791 | BOOL _is64Bit; 792 | 793 | template 794 | bool initShellCoder(ProcessWriter*& sc) { 795 | if(sc) return false; 796 | const std::string& shellcode = _is64Bit ? shellCode() : shellCode(); 797 | sc = new ProcessWriter(_hProcess, shellcode.data(), shellcode.size() + 1, PAGE_EXECUTE_READWRITE); 798 | return true; 799 | } 800 | 801 | template 802 | DWORD64 call(const std::vector& param) { 803 | ProcessWriter p(_hProcess, ¶m[0], sizeof(T) * (param.size())); 804 | if (!p) return -1; 805 | HANDLE hThread = 0; 806 | if (_is64Bit) 807 | hThread = CreateRemoteThread64(_hProcess, NULL, 0, *_sc, p, 0, NULL); 808 | else { 809 | #ifdef _WIN64 810 | // see X64toX86_disassemble for details 811 | static const unsigned char kTmpl_x64_to_x86[] = { 0x48, 0x89, 0x4c, 0x24, 0x08, 0x48, 0x83, 0xec, 0x28, 0x48, 0x8b, 0x44, 0x24, 0x30, 0x8b, 0x48, 812 | 0x08, 0x48, 0x8b, 0x44, 0x24, 0x30, 0x6a, 0x33, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x83, 0x04, 0x24, 813 | 0x05, 0xcb, 0xff, 0xd0, 0xe8, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x44, 0x24, 0x04, 0x23, 0x00, 0x00, 814 | 0x00, 0x83, 0x04, 0x24, 0x0d, 0xcb, 0x48, 0x83, 0xc4, 0x28, 0xc3 }; 815 | std::string x86_shellcode((char*)kTmpl_x64_to_x86, sizeof(kTmpl_x64_to_x86)); 816 | ProcessWriter* sc = new ProcessWriter(_hProcess, x86_shellcode.data(), x86_shellcode.size() + 1, PAGE_EXECUTE_READWRITE); 817 | sc->SetDontRelese(); 818 | hThread = CreateRemoteThread64(_hProcess, NULL, 0, *_sc, p, 0, NULL); 819 | #else 820 | hThread = CreateRemoteThread(_hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)(DWORD64)*_sc, (PVOID)(DWORD64)p, 0, NULL); 821 | #endif 822 | } 823 | if (!hThread) return -1; 824 | if (WaitForSingleObject(hThread, _dwTimeout) != WAIT_OBJECT_0) { 825 | _sc->SetDontRelese(); 826 | CloseHandle(hThread); 827 | return -1; 828 | } 829 | if (!_is64Bit || !_dw64Ret) { 830 | DWORD ret = 0; 831 | GetExitCodeThread(hThread, &ret); 832 | CloseHandle(hThread); 833 | return ret; 834 | } 835 | DWORD64 ret = 0; 836 | CloseHandle(hThread); 837 | ReadProcessMemory64(_hProcess, p, &ret, sizeof(DWORD64), NULL); 838 | return ret; 839 | } 840 | 841 | public: 842 | YAPICall(HANDLE hProcess, const char* funcName) 843 | : _hProcess(hProcess) 844 | , _sc(0) 845 | , func(GetProcAddress64(hProcess, GetNtDll64(), funcName)) 846 | , _dw64Ret(FALSE) 847 | , _dwTimeout(INFINITE) 848 | , _is64Bit(detail::is64BitOS) 849 | { 850 | } 851 | YAPICall(HANDLE hProcess, DWORD64 moudle, const char* funcName) 852 | : _hProcess(hProcess) 853 | , _sc(0) 854 | , func(GetProcAddress64(hProcess, moudle, funcName)) 855 | , _dw64Ret(FALSE) 856 | , _dwTimeout(INFINITE) 857 | , _is64Bit(detail::is64BitOS) 858 | { 859 | } 860 | YAPICall(HANDLE hProcess, const TCHAR* modName, const char* funcName) 861 | : _hProcess(hProcess) 862 | , _sc(0) 863 | , func(GetProcAddress64(hProcess, GetModuleHandle64(hProcess, modName), funcName)) 864 | , _dw64Ret(FALSE) 865 | , _dwTimeout(INFINITE) 866 | , _is64Bit(detail::is64BitOS) 867 | { 868 | if(!func) { 869 | func = GetProcAddress(hProcess, GetModuleHandle(hProcess, modName), funcName); 870 | _is64Bit = FALSE; 871 | } 872 | } 873 | 874 | ~YAPICall() { if (_sc) delete _sc; } 875 | 876 | operator DWORD64() { return func; } 877 | 878 | YAPICall& Dw64() { _dw64Ret = TRUE; return *this; } 879 | YAPICall& Timeout(DWORD dwTimeout) { _dwTimeout = dwTimeout; return *this; } 880 | 881 | #define TO_DWORD64_ARRAY_DECL(n) param[n + 1] = ToDWORD64(__PARAM(n), _hProcess, &helper); 882 | #define TO_DWORD_ARRAY_DECL(n) param[n] = (DWORD)ToDWORD64(__PARAM(n), _hProcess, &helper); 883 | 884 | #define CALLERSX(n) \ 885 | DWORD64 operator()(DECL_PARAMS_LIST(n)) {\ 886 | bool b = initShellCoder(_sc);\ 887 | if(!b || !func || !_sc || !*_sc) return -1;\ 888 | detail::GCHelper helper;\ 889 | if(_is64Bit) {\ 890 | std::vector param(n + 2, 0);\ 891 | param[0] = _dw64Ret;\ 892 | param[1] = func;\ 893 | REPEAT(n, TO_DWORD64_ARRAY_DECL, TO_DWORD64_ARRAY_DECL)\ 894 | return call(param);\ 895 | }\ 896 | std::vector param(n + 1, 0);\ 897 | param[0] = (DWORD)func;\ 898 | REPEAT(n, TO_DWORD_ARRAY_DECL, TO_DWORD_ARRAY_DECL)\ 899 | return call(param);\ 900 | } 901 | #define CALLERS(n) template CALLERSX(n) 902 | CALLERSX( 0) 903 | CALLERS( 1) CALLERS( 2) CALLERS( 3) CALLERS( 4) CALLERS( 5) CALLERS( 6) /*CALLERS( 7) CALLERS( 8) CALLERS( 9) CALLERS(10) 904 | CALLERS(11) CALLERS(12) CALLERS(13) CALLERS(14) CALLERS(15) CALLERS(16) CALLERS(17) CALLERS(18) CALLERS(19) CALLERS(20)*/ 905 | #undef CALLERSX 906 | #undef CALLERS 907 | #undef TO_DWORD_ARRAY_DECL 908 | #undef TO_DWORD64_ARRAY_DECL 909 | }; 910 | 911 | #define YAPI(h, m, f) YAPICall(h, m, #f) 912 | } 913 | --------------------------------------------------------------------------------