mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-23 23:41:52 +08:00
feat: support AgentAttacher Packer
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Copyright 2014 - Present Rafael Winterhalter
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <windows.h>
|
||||
|
||||
#define OPEN_JVM_ERROR 200
|
||||
#define GET_ENQUEUE_FUNCTION_ERROR 201
|
||||
#define CODE_SIZE (SIZE_T) 1024
|
||||
#define MAX_ARGUMENT 1024
|
||||
|
||||
typedef HMODULE (WINAPI *GetModuleHandle_t)(LPCTSTR);
|
||||
typedef FARPROC (WINAPI *GetProcAddress_t)(HMODULE, LPCSTR);
|
||||
typedef int (__stdcall *JVM_EnqueueOperation_t)(char *, char *, char *, char *, char *);
|
||||
|
||||
typedef struct {
|
||||
GetModuleHandle_t GetModuleHandleA;
|
||||
GetProcAddress_t GetProcAddress;
|
||||
char library[32];
|
||||
char command[32];
|
||||
char commandFallback[32];
|
||||
char pipe[MAX_PATH];
|
||||
char argument[4][MAX_ARGUMENT];
|
||||
} EnqueueOperation;
|
||||
|
||||
#pragma check_stack(off)
|
||||
|
||||
/**
|
||||
* Executes the attachment on the remote thread. This method is executed on the target JVM and must not reference any addresses unknown to that address.
|
||||
*
|
||||
* @param argument The argument provided by the JVM executing the attachment.
|
||||
* @return The result of the attachment.
|
||||
*/
|
||||
DWORD WINAPI execute_remote_attach
|
||||
(LPVOID argument)
|
||||
{
|
||||
EnqueueOperation *operation = (EnqueueOperation *) argument;
|
||||
HMODULE library = operation->GetModuleHandleA(operation->library);
|
||||
if (library == NULL) {
|
||||
return OPEN_JVM_ERROR;
|
||||
}
|
||||
JVM_EnqueueOperation_t JVM_EnqueueOperation = (JVM_EnqueueOperation_t) operation->GetProcAddress(library, operation->command);
|
||||
if (JVM_EnqueueOperation == NULL) {
|
||||
JVM_EnqueueOperation = (JVM_EnqueueOperation_t) operation->GetProcAddress(library, operation->commandFallback);
|
||||
}
|
||||
if (JVM_EnqueueOperation == NULL) {
|
||||
return GET_ENQUEUE_FUNCTION_ERROR;
|
||||
}
|
||||
return (DWORD) JVM_EnqueueOperation(operation->argument[0],
|
||||
operation->argument[1],
|
||||
operation->argument[2],
|
||||
operation->argument[3],
|
||||
operation->pipe);
|
||||
}
|
||||
|
||||
#pragma check_stack
|
||||
|
||||
/**
|
||||
* Allocates the code to execute on the remote machine.
|
||||
*
|
||||
* @param process The process handle of the remote process to which to attach.
|
||||
* @return A pointer to the allocated code or {@code NULL} if the allocation failed.
|
||||
*/
|
||||
LPVOID allocate_remote_code
|
||||
(HANDLE process)
|
||||
{
|
||||
LPVOID code = VirtualAllocEx(process, NULL, CODE_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (code == NULL) {
|
||||
return NULL;
|
||||
} else if (!WriteProcessMemory(process, code, execute_remote_attach, CODE_SIZE, NULL)) {
|
||||
VirtualFreeEx(process, code, 0, MEM_RELEASE);
|
||||
return NULL;
|
||||
} else {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates the argument to the remote execution.
|
||||
*
|
||||
* @param process A handle to the remote process to which to attach.
|
||||
* @param pipe The name of the pipe to which the attachment result is written
|
||||
* @param argument0 The first argument to provide to the {@code JVM_EnqueueOperation}.
|
||||
* @param argument1 The second argument to provide to the {@code JVM_EnqueueOperation}.
|
||||
* @param argument2 The third argument to provide to the {@code JVM_EnqueueOperation}.
|
||||
* @param argument3 The forth argument to provide to the {@code JVM_EnqueueOperation}.
|
||||
* @return A pointer to the allocated argument or {@code NULL} if the allocation was not possible.
|
||||
*/
|
||||
LPVOID allocate_remote_argument
|
||||
(HANDLE process, LPCSTR pipe, LPCSTR argument0, LPCSTR argument1, LPCSTR argument2, LPCSTR argument3)
|
||||
{
|
||||
if (strlen(pipe) >= MAX_PATH
|
||||
|| argument0 != NULL && strlen(argument0) >= MAX_ARGUMENT
|
||||
|| argument1 != NULL && strlen(argument1) >= MAX_ARGUMENT
|
||||
|| argument2 != NULL && strlen(argument2) >= MAX_ARGUMENT
|
||||
|| argument3 != NULL && strlen(argument3) >= MAX_ARGUMENT) {
|
||||
return NULL;
|
||||
}
|
||||
EnqueueOperation operation;
|
||||
operation.GetModuleHandleA = GetModuleHandleA;
|
||||
operation.GetProcAddress = GetProcAddress;
|
||||
strcpy(operation.library, "jvm");
|
||||
strcpy(operation.command, "JVM_EnqueueOperation");
|
||||
strcpy(operation.commandFallback, "_JVM_EnqueueOperation@20");
|
||||
strcpy(operation.pipe, pipe);
|
||||
strcpy(operation.argument[0], argument0 == NULL ? "" : argument0);
|
||||
strcpy(operation.argument[1], argument1 == NULL ? "" : argument1);
|
||||
strcpy(operation.argument[2], argument2 == NULL ? "" : argument2);
|
||||
strcpy(operation.argument[3], argument3 == NULL ? "" : argument3);
|
||||
LPVOID allocation = VirtualAllocEx(process, NULL, sizeof(EnqueueOperation), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (allocation == NULL) {
|
||||
return NULL;
|
||||
} else if (!WriteProcessMemory(process, allocation, &operation, sizeof(operation), NULL)) {
|
||||
VirtualFreeEx(process, allocation, 0, MEM_RELEASE);
|
||||
return NULL;
|
||||
} else {
|
||||
return allocation;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user