|
19 | 19 | // along with Merlin. If not, see <http://www.gnu.org/licenses/>. |
20 | 20 |
|
21 | 21 | package kernel32 |
| 22 | + |
| 23 | +import ( |
| 24 | + // Standard |
| 25 | + "fmt" |
| 26 | + |
| 27 | + // X Packages |
| 28 | + "golang.org/x/sys/windows" |
| 29 | +) |
| 30 | + |
| 31 | +var kernel32 = windows.NewLazySystemDLL("kernel32.dll") |
| 32 | + |
| 33 | +// CreateRemoteThreadEx Creates a thread that runs in the virtual address space of another process and optionally |
| 34 | +// specifies extended attributes such as processor group affinity. |
| 35 | +// HANDLE CreateRemoteThreadEx( |
| 36 | +// |
| 37 | +// [in] HANDLE hProcess, |
| 38 | +// [in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes, |
| 39 | +// [in] SIZE_T dwStackSize, |
| 40 | +// [in] LPTHREAD_START_ROUTINE lpStartAddress, |
| 41 | +// [in, optional] LPVOID lpParameter, |
| 42 | +// [in] DWORD dwCreationFlags, |
| 43 | +// [in, optional] LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, |
| 44 | +// [out, optional] LPDWORD lpThreadId |
| 45 | +// |
| 46 | +// ); |
| 47 | +// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createremotethreadex |
| 48 | +func CreateRemoteThreadEx(hProcess uintptr, lpThreadAttributes uintptr, dwStackSize uintptr, lpStartAddress uintptr, lpParameter uintptr, dwCreationFlags int, lpAttributeList uintptr, lpThreadId uintptr) (addr uintptr, err error) { |
| 49 | + createRemoteThreadEx := kernel32.NewProc("CreateRemoteThreadEx") |
| 50 | + addr, _, err = createRemoteThreadEx.Call(hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, uintptr(dwCreationFlags), lpAttributeList, lpThreadId) |
| 51 | + if err != windows.Errno(0) { |
| 52 | + err = fmt.Errorf("there was an error calling Windows API CreateRemoteThread: %s", err) |
| 53 | + } else { |
| 54 | + err = nil |
| 55 | + } |
| 56 | + return |
| 57 | +} |
| 58 | + |
| 59 | +// QueueUserAPC Adds a user-mode asynchronous procedure call (APC) object to the APC queue of the specified thread. |
| 60 | +// DWORD QueueUserAPC( |
| 61 | +// |
| 62 | +// [in] PAPCFUNC pfnAPC, |
| 63 | +// [in] HANDLE hThread, |
| 64 | +// [in] ULONG_PTR dwData |
| 65 | +// |
| 66 | +// ); |
| 67 | +// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-queueuserapc |
| 68 | +func QueueUserAPC(pfnAPC uintptr, hThread uintptr, dwData uintptr) (err error) { |
| 69 | + queueUserAPC := kernel32.NewProc("QueueUserAPC") |
| 70 | + _, _, err = queueUserAPC.Call(pfnAPC, hThread, dwData) |
| 71 | + if err != windows.Errno(0) { |
| 72 | + err = fmt.Errorf("there was an error calling Windows API QueueUserAPC: %s", err) |
| 73 | + } else { |
| 74 | + err = nil |
| 75 | + } |
| 76 | + return |
| 77 | +} |
| 78 | + |
| 79 | +// VirtualAllocEx Reserves, commits, or changes the state of a region of memory within the virtual address space of a |
| 80 | +// specified process. The function initializes the memory it allocates to zero. |
| 81 | +// |
| 82 | +// LPVOID VirtualAllocEx( |
| 83 | +// [in] HANDLE hProcess, |
| 84 | +// [in, optional] LPVOID lpAddress, |
| 85 | +// [in] SIZE_T dwSize, |
| 86 | +// [in] DWORD flAllocationType, |
| 87 | +// [in] DWORD flProtect |
| 88 | +// ); |
| 89 | +// |
| 90 | +// https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocex |
| 91 | +func VirtualAllocEx(hProcess uintptr, lpAddress uintptr, dwSize int, flAllocationType int, flProtect int) (addr uintptr, err error) { |
| 92 | + virtualAllocEx := kernel32.NewProc("VirtualAllocEx") |
| 93 | + addr, _, err = virtualAllocEx.Call(hProcess, lpAddress, uintptr(dwSize), uintptr(flAllocationType), uintptr(flProtect)) |
| 94 | + if err != windows.Errno(0) { |
| 95 | + err = fmt.Errorf("there was an error calling Windows API VirtualAllocEx: %s", err) |
| 96 | + } else { |
| 97 | + err = nil |
| 98 | + } |
| 99 | + return |
| 100 | +} |
0 commit comments