/*
 * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "jni_util.h"

#include <windows.h>
#include <Sddl.h>
#include <string.h>

#include "sun_tools_attach_VirtualMachineImpl.h"

/* kernel32 */
typedef HINSTANCE (WINAPI* GetModuleHandleFunc) (LPCTSTR);
typedef FARPROC (WINAPI* GetProcAddressFunc)(HMODULE, LPCSTR);

/* only on Windows 64-bit or 32-bit application running under WOW64 */
typedef BOOL (WINAPI *IsWow64ProcessFunc) (HANDLE, PBOOL);

static GetModuleHandleFunc _GetModuleHandle;
static GetProcAddressFunc _GetProcAddress;
static IsWow64ProcessFunc _IsWow64Process;

/* psapi */
typedef BOOL  (WINAPI *EnumProcessModulesFunc)  (HANDLE, HMODULE *, DWORD, LPDWORD );
typedef DWORD (WINAPI *GetModuleFileNameExFunc) ( HANDLE, HMODULE, LPTSTR, DWORD );

/* exported functions in target VM */
typedef jint (WINAPI* EnqueueOperationFunc)
    (const char* cmd, const char* arg1, const char* arg2, const char* arg3, const char* pipename);
typedef jint (WINAPI* EnqueueOperationFunc_v2)
    (const char* pipename);

/* OpenProcess with SE_DEBUG_NAME privilege */
static HANDLE
doPrivilegedOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);

/* Converts jstring to C string, returns JNI_FALSE if the string has been truncated. */
static jboolean jstring_to_cstring(JNIEnv* env, jstring jstr, char* cstr, size_t cstr_buf_size);


/*
 * Data copied to target process
 */

#define MAX_LIBNAME_LENGTH      16
#define MAX_FUNC_LENGTH         32
#define MAX_CMD_LENGTH          16
#define MAX_ARG_LENGTH          1024
#define MAX_ARGS                3
#define MAX_PIPE_NAME_LENGTH    256

typedef struct {
   jint version;
   GetModuleHandleFunc _GetModuleHandle;
   GetProcAddressFunc _GetProcAddress;
   char jvmLib[MAX_LIBNAME_LENGTH];         /* "jvm.dll" */
   char func[MAX_FUNC_LENGTH];
   char func_v2[MAX_FUNC_LENGTH];
   char cmd[MAX_CMD_LENGTH + 1];            /* "load", "dump", ...      */
   char arg[MAX_ARGS][MAX_ARG_LENGTH + 1];  /* arguments to command     */
   char pipename[MAX_PIPE_NAME_LENGTH + 1];
} DataBlock;

/*
 * Return codes from enqueue function executed in target VM
 */
#define ERR_OPEN_JVM_FAIL           200
#define ERR_GET_ENQUEUE_FUNC_FAIL   201

/*
 * Declare library specific JNI_Onload entry if static build
 */
DEF_STATIC_JNI_OnLoad

/*
 * Code copied to target process
 */
#pragma check_stack (off)
/* Switch off all runtime checks (checks caused by /RTC<x>). They cause the
 * generated code to contain relative jumps to check functions which make
 * the code position dependent. */
#pragma runtime_checks ("scu", off)
DWORD WINAPI jvm_attach_thread_func(DataBlock *pData)
{
    HINSTANCE h;

    h = pData->_GetModuleHandle(pData->jvmLib);
    if (h == NULL) {
        return ERR_OPEN_JVM_FAIL;
    }

    if (pData->version == 1) {
        EnqueueOperationFunc addr = (EnqueueOperationFunc)(pData->_GetProcAddress(h, pData->func));
        if (addr == NULL) {
            return ERR_GET_ENQUEUE_FUNC_FAIL;
        }
        /* "null" command - does nothing in the target VM */
        if (pData->cmd[0] == '\0') {
            return 0;
        } else {
            return (*addr)(pData->cmd, pData->arg[0], pData->arg[1], pData->arg[2], pData->pipename);
        }
    } else if (pData->version == 2) {
        EnqueueOperationFunc_v2 addr = (EnqueueOperationFunc_v2)(pData->_GetProcAddress(h, pData->func_v2));
        if (addr == NULL) {
            return ERR_GET_ENQUEUE_FUNC_FAIL;
        }
        return (*addr)(pData->pipename);
    } else {
        return ERR_GET_ENQUEUE_FUNC_FAIL;
    }

}

/* This function marks the end of jvm_attach_thread_func. */
void jvm_attach_thread_func_end (void) {
}
#pragma check_stack
#pragma runtime_checks ("scu", restore)

/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    init
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_init
  (JNIEnv *env, jclass cls)
{
    // All following APIs exist on Windows XP with SP2/Windows Server 2008
    _GetModuleHandle = (GetModuleHandleFunc)GetModuleHandle;
    _GetProcAddress = (GetProcAddressFunc)GetProcAddress;
    _IsWow64Process = (IsWow64ProcessFunc)IsWow64Process;
}


/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    generateStub
 * Signature: ()[B
 */
JNIEXPORT jbyteArray JNICALL Java_sun_tools_attach_VirtualMachineImpl_generateStub
  (JNIEnv *env, jclass cls)
{
    /*
     * We should replace this with a real stub generator at some point
     */
    DWORD len;
    jbyteArray array;

    len = (DWORD)((LPBYTE) jvm_attach_thread_func_end - (LPBYTE) jvm_attach_thread_func);
    array= (*env)->NewByteArray(env, (jsize)len);
    if (array != NULL) {
        (*env)->SetByteArrayRegion(env, array, 0, (jint)len, (jbyte*)&jvm_attach_thread_func);
    }
    return array;
}

/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    openProcess
 * Signature: (I)J
 */
JNIEXPORT jlong JNICALL Java_sun_tools_attach_VirtualMachineImpl_openProcess
  (JNIEnv *env, jclass cls, jint pid)
{
    HANDLE hProcess = NULL;

    if (pid == (jint) GetCurrentProcessId()) {
        /* process is attaching to itself; get a pseudo handle instead */
        hProcess = GetCurrentProcess();
        /* duplicate the pseudo handle so it can be used in more contexts */
        if (DuplicateHandle(hProcess, hProcess, hProcess, &hProcess,
                PROCESS_ALL_ACCESS, FALSE, 0) == 0) {
            /*
             * Could not duplicate the handle which isn't a good sign,
             * but we'll try again with OpenProcess() below.
             */
            hProcess = NULL;
        }
    }

    if (hProcess == NULL) {
        /*
         * Attempt to open process. If it fails then we try to enable the
         * SE_DEBUG_NAME privilege and retry.
         */
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
        if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) {
            hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE,
                           (DWORD)pid);
        }

        if (hProcess == NULL) {
            if (GetLastError() == ERROR_INVALID_PARAMETER) {
                JNU_ThrowIOException(env, "no such process");
            } else {
                char err_mesg[255];
                /* include the last error in the default detail message */
                snprintf(err_mesg, sizeof(err_mesg), "OpenProcess(pid=%d) failed; LastError=0x%x",
                    (int)pid, (int)GetLastError());
                JNU_ThrowIOExceptionWithLastError(env, err_mesg);
            }
            return (jlong)0;
        }
    }

    /*
     * On Windows we need to handle 64-bit tools trying to attach to 32-bit
     * processes, which is currently not supported by this implementation.
     */
    if (_IsWow64Process != NULL) {
        BOOL isTarget32bit;
        (*_IsWow64Process)(hProcess, &isTarget32bit);

        if (isTarget32bit) {
            CloseHandle(hProcess);
            JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException",
                "Unable to attach to 32-bit process running under WOW64");
        }
    }

    return (jlong)hProcess;
}


/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    closeProcess
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_closeProcess
  (JNIEnv *env, jclass cls, jlong hProcess)
{
    CloseHandle((HANDLE)hProcess);
}


/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    createPipe
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_sun_tools_attach_VirtualMachineImpl_createPipe
  (JNIEnv *env, jclass cls, jint ver, jstring pipename)
{
    HANDLE hPipe;
    char name[MAX_PIPE_NAME_LENGTH];

    SECURITY_ATTRIBUTES sa;
    LPSECURITY_ATTRIBUTES lpSA = NULL;
    // Custom Security Descriptor is required here to "get" Medium Integrity Level.
    // In order to allow Medium Integrity Level clients to open
    // and use a NamedPipe created by an High Integrity Level process.
    TCHAR *szSD = TEXT("D:")                  // Discretionary ACL
                  TEXT("(A;OICI;GRGW;;;WD)")  // Allow read/write to Everybody
                  TEXT("(A;OICI;GA;;;SY)")    // Allow full control to System
                  TEXT("(A;OICI;GA;;;BA)");   // Allow full control to Administrators

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = FALSE;
    sa.lpSecurityDescriptor = NULL;

    if (ConvertStringSecurityDescriptorToSecurityDescriptor
          (szSD, SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL)) {
        lpSA = &sa;
    }

    jstring_to_cstring(env, pipename, name, MAX_PIPE_NAME_LENGTH);

    hPipe = CreateNamedPipe(
          name,                         // pipe name
          (ver == 1 ? PIPE_ACCESS_INBOUND : PIPE_ACCESS_DUPLEX) | // read or read-write access
            FILE_FLAG_FIRST_PIPE_INSTANCE,
          PIPE_TYPE_BYTE |              // byte mode
            PIPE_READMODE_BYTE |
            PIPE_WAIT |                 // blocking mode
            PIPE_REJECT_REMOTE_CLIENTS,
          1,                            // max. instances
          128,                          // output buffer size
          8192,                         // input buffer size
          NMPWAIT_USE_DEFAULT_WAIT,     // client time-out
          lpSA);        // security attributes

    LocalFree(sa.lpSecurityDescriptor);

    if (hPipe == INVALID_HANDLE_VALUE) {
        JNU_ThrowIOExceptionWithLastError(env, "CreateNamedPipe failed");
    }
    return (jlong)hPipe;
}

/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    closePipe
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_closePipe
  (JNIEnv *env, jclass cls, jlong hPipe)
{
    CloseHandle((HANDLE)hPipe);
}

/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    connectPipe
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connectPipe
  (JNIEnv *env, jclass cls, jlong hPipe)
{
    BOOL fConnected;

    fConnected = ConnectNamedPipe((HANDLE)hPipe, NULL) ?
        TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
    if (!fConnected) {
        JNU_ThrowIOExceptionWithLastError(env, "ConnectNamedPipe failed");
    }
}

/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    readPipe
 * Signature: (J[BII)I
 */
JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_readPipe
  (JNIEnv *env, jclass cls, jlong hPipe, jbyteArray ba, jint off, jint baLen)
{
    unsigned char buf[128];
    DWORD len, nread, remaining;
    BOOL fSuccess;

    len = sizeof(buf);
    remaining = (DWORD)(baLen - off);
    if (len > remaining) {
        len = remaining;
    }

    fSuccess = ReadFile(
         (HANDLE)hPipe,         // handle to pipe
         buf,                   // buffer to receive data
         len,                   // size of buffer
         &nread,                // number of bytes read
         NULL);                 // not overlapped I/O

    if (!fSuccess) {
        if (GetLastError() == ERROR_BROKEN_PIPE) {
            return (jint)-1;
        } else {
            JNU_ThrowIOExceptionWithLastError(env, "ReadFile");
        }
    } else {
        if (nread == 0) {
            return (jint)-1;        // EOF
        } else {
            (*env)->SetByteArrayRegion(env, ba, off, (jint)nread, (jbyte *)(buf));
        }
    }

    return (jint)nread;
}

/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    writePipe
 * Signature: (J[BII)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_writePipe
  (JNIEnv *env, jclass cls, jlong hPipe, jbyteArray buffer, jint offset, jint length)
{
    jsize remaining = length;
    do {
        jbyte buf[128];
        jsize len = sizeof(buf);
        DWORD written;

        if (len > remaining) {
            len = remaining;
        }
        (*env)->GetByteArrayRegion(env, buffer, offset, len, buf);

        BOOL fSuccess = WriteFile((HANDLE)hPipe, buf, len, &written, NULL);

        if (!fSuccess) {
            JNU_ThrowIOExceptionWithLastError(env, "WriteFile");
            return;
        }

        offset += written;
        remaining -= written;

    } while (remaining > 0);
}

/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    enqueue
 * Signature: (JZLjava/lang/String;[Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue
  (JNIEnv *env, jclass cls, jlong handle, jbyteArray stub, jint ver,
   jstring cmd, jstring pipename, jobjectArray args)
{
    DataBlock data;
    DataBlock* pData;
    DWORD* pCode;
    DWORD stubLen;
    HANDLE hProcess, hThread;
    jint argsLen, i;
    jbyte* stubCode;
    jboolean isCopy;

    /*
     * Setup data to copy to target process
     */
    memset(&data, 0, sizeof(data));
    data.version = ver;

    data._GetModuleHandle = _GetModuleHandle;
    data._GetProcAddress = _GetProcAddress;

    strcpy(data.jvmLib, "jvm");
    strcpy(data.func, "JVM_EnqueueOperation");
    strcpy(data.func_v2, "JVM_EnqueueOperation_v2");

    /*
     * Command and arguments
     */
    if (!jstring_to_cstring(env, cmd, data.cmd, sizeof(data.cmd))) {
        JNU_ThrowByName(env, "com/sun/tools/attach/AttachOperationFailedException",
                        "command is too long");
        return;
    }
    argsLen = (*env)->GetArrayLength(env, args);

    if (argsLen > 0) {
        if (argsLen > MAX_ARGS) {
            JNU_ThrowInternalError(env, "Too many arguments");
            return;
        }
        for (i=0; i<argsLen; i++) {
            jobject obj = (*env)->GetObjectArrayElement(env, args, i);
            if (obj == NULL) {
                data.arg[i][0] = '\0';
            } else {
                if (!jstring_to_cstring(env, obj, data.arg[i], sizeof(data.arg[i]))) {
                    JNU_ThrowByName(env, "com/sun/tools/attach/AttachOperationFailedException",
                                    "argument is too long");
                    return;
                }
            }
            if ((*env)->ExceptionCheck(env)) return;
        }
    }
    for (i = argsLen; i < MAX_ARGS; i++) {
        data.arg[i][0] = '\0';
    }

    /* pipe name */
    if (!jstring_to_cstring(env, pipename, data.pipename, sizeof(data.pipename))) {
        JNU_ThrowByName(env, "com/sun/tools/attach/AttachOperationFailedException",
                        "pipe name is too long");
        return;
    }

    /*
     * Allocate memory in target process for data and code stub
     * (assumed aligned and matches architecture of target process)
     */
    hProcess = (HANDLE)handle;

    pData = (DataBlock*) VirtualAllocEx( hProcess, 0, sizeof(DataBlock), MEM_COMMIT, PAGE_READWRITE );
    if (pData == NULL) {
        JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed");
        return;
    }
    WriteProcessMemory( hProcess, (LPVOID)pData, (LPCVOID)&data, (SIZE_T)sizeof(DataBlock), NULL );


    stubLen = (DWORD)(*env)->GetArrayLength(env, stub);
    stubCode = (*env)->GetByteArrayElements(env, stub, &isCopy);

    if ((*env)->ExceptionCheck(env)) return;

    pCode = (PDWORD) VirtualAllocEx( hProcess, 0, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if (pCode == NULL) {
        JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed");
        VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE);
        (*env)->ReleaseByteArrayElements(env, stub, stubCode, JNI_ABORT);
        return;
    }
    WriteProcessMemory( hProcess, (LPVOID)pCode, (LPCVOID)stubCode, (SIZE_T)stubLen, NULL );
    (*env)->ReleaseByteArrayElements(env, stub, stubCode, JNI_ABORT);

    /*
     * Create thread in target process to execute code
     */
    hThread = CreateRemoteThread( hProcess,
                                  NULL,
                                  0,
                                  (LPTHREAD_START_ROUTINE) pCode,
                                  pData,
                                  0,
                                  NULL );
    if (hThread != NULL) {
        if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0) {
            JNU_ThrowIOExceptionWithLastError(env, "WaitForSingleObject failed");
        } else {
            DWORD exitCode;
            GetExitCodeThread(hThread, &exitCode);
            if (exitCode) {
                switch (exitCode) {
                    case ERR_OPEN_JVM_FAIL :
                        JNU_ThrowIOException(env,
                            "jvm.dll not loaded by target process");
                        break;
                    case ERR_GET_ENQUEUE_FUNC_FAIL :
                        JNU_ThrowIOException(env,
                            "Unable to enqueue operation: the target VM does not support attach mechanism");
                        break;
                    default : {
                        char errmsg[128];
                        snprintf(errmsg, sizeof(errmsg), "Remote thread failed for unknown reason (%d)", exitCode);
                        JNU_ThrowInternalError(env, errmsg);
                    }
                }
            }
        }
        CloseHandle(hThread);
    } else {
        if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) {
            //
            // This error will occur when attaching to a process belonging to
            // another terminal session. See "Remarks":
            // http://msdn.microsoft.com/en-us/library/ms682437%28VS.85%29.aspx
            //
            JNU_ThrowIOException(env,
                "Insufficient memory or insufficient privileges to attach");
        } else {
            JNU_ThrowIOExceptionWithLastError(env, "CreateRemoteThread failed");
        }
    }

    VirtualFreeEx(hProcess, pCode, 0, MEM_RELEASE);
    VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE);
}

/*
 * Attempts to enable the SE_DEBUG_NAME privilege and open the given process.
 */
static HANDLE
doPrivilegedOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId) {
    HANDLE hToken;
    HANDLE hProcess = NULL;
    LUID luid;
    TOKEN_PRIVILEGES tp, tpPrevious;
    DWORD retLength, error;

    /*
     * Get the access token
     */
    if (!OpenThreadToken(GetCurrentThread(),
                         TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
                         FALSE,
                         &hToken)) {
        if (GetLastError() != ERROR_NO_TOKEN) {
            return (HANDLE)NULL;
        }

        /*
         * No access token for the thread so impersonate the security context
         * of the process.
         */
        if (!ImpersonateSelf(SecurityImpersonation)) {
            return (HANDLE)NULL;
        }
        if (!OpenThreadToken(GetCurrentThread(),
                             TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
                             FALSE,
                             &hToken)) {
            return (HANDLE)NULL;
        }
    }

    /*
     * Get LUID for the privilege
     */
    if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
        error = GetLastError();
        CloseHandle(hToken);
        SetLastError(error);
        return (HANDLE)NULL;
    }

    /*
     * Enable the privilege
     */
    ZeroMemory(&tp, sizeof(tp));
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    tp.Privileges[0].Luid = luid;

    error = 0;
    if (AdjustTokenPrivileges(hToken,
                              FALSE,
                              &tp,
                              sizeof(TOKEN_PRIVILEGES),
                              &tpPrevious,
                              &retLength)) {
        /*
         * If we enabled the privilege then attempt to open the
         * process.
         */
        if (GetLastError() == ERROR_SUCCESS) {
            hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
            if (hProcess == NULL) {
                error = GetLastError();
            }
        } else {
            error = ERROR_ACCESS_DENIED;
        }

        /*
         * Revert to the previous privileges
         */
        AdjustTokenPrivileges(hToken,
                              FALSE,
                              &tpPrevious,
                              retLength,
                              NULL,
                              NULL);
    } else {
        error = GetLastError();
    }


    /*
     * Close token and restore error
     */
    CloseHandle(hToken);
    SetLastError(error);

    return hProcess;
}

/* Converts jstring to C string, returns JNI_FALSE if the string has been truncated. */
static jboolean jstring_to_cstring(JNIEnv* env, jstring jstr, char* cstr, size_t cstr_buf_size) {
    jboolean isCopy;
    const char* str;
    jboolean result = JNI_TRUE;

    if (jstr == NULL) {
        cstr[0] = '\0';
    } else {
        str = JNU_GetStringPlatformChars(env, jstr, &isCopy);
        if ((*env)->ExceptionCheck(env)) {
            return result;
        }
        if (strlen(str) >= cstr_buf_size) {
            result = JNI_FALSE;
        }

        strncpy(cstr, str, cstr_buf_size);
        cstr[cstr_buf_size - 1] = '\0';
        if (isCopy) {
            JNU_ReleaseStringPlatformChars(env, jstr, str);
        }
    }
    return result;
}
