feat: support AgentAttacher Packer

This commit is contained in:
ReaJason
2025-05-28 01:22:54 +08:00
parent a3704eb7b7
commit 19faf77d5c
24 changed files with 8361 additions and 11 deletions
@@ -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;
}
}