Skip to content

Commit

Permalink
[Issue jenkinsci#29] - Native code should be tolerant against the mis…
Browse files Browse the repository at this point in the history
…sing IsWow64Process API method
  • Loading branch information
oleg-nenashev committed Apr 20, 2017
1 parent 442988f commit 7542b57
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 15 deletions.
35 changes: 24 additions & 11 deletions native/envvar-cmdline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,17 +169,20 @@ jstring getCmdLineAndEnvVars(
// There is a risk that somebody starts the 32bit DLL in x64 process, but within WinP JAR it must not happen.
// TODO: Consider adding defensive logic just in case
BOOL procIsWow64 = FALSE;
if (!IsWow64Process(hProcess, &procIsWow64))
if (fnIsWow64Process != NULL)
{
reportError(pEnv, "Failed to determine if the process is a 32bit or 64bit executable");
return NULL;
}

if (!procIsWow64) {
// We are trying to query a 64-bit process from a 32-bit DLL
sprintf_s<ERRMSG_SIZE>(errorBuffer, "Process with pid=%d is not a 32bit process (or it is not running). Cannot query it from a 32bit library", pid);
reportErrorWithCode(pEnv, 2, errorBuffer);
return NULL;
if (!fnIsWow64Process(hProcess, &procIsWow64))
{
reportError(pEnv, "Failed to determine if the process is a 32bit or 64bit executable");
return NULL;
}

if (!procIsWow64) {
// We are trying to query a 64-bit process from a 32-bit DLL
sprintf_s<ERRMSG_SIZE>(errorBuffer, "Process with pid=%d is not a 32bit process (or it is not running). Cannot query it from a 32bit library", pid);
reportErrorWithCode(pEnv, 2, errorBuffer);
return NULL;
}
}

#endif
Expand All @@ -194,7 +197,17 @@ jstring getCmdLineAndEnvVars(
// from there to PEB
PEB ProcPEB;
if(!ReadProcessMemory(hProcess, ProcInfo.PebBaseAddress, &ProcPEB, sizeof(ProcPEB), &sRead)) {
reportError(pEnv, "Failed to read PEB");
#ifndef _WIN64
if (fnIsWow64Process == NULL) {
// We are unable to determine it, no API call available
reportError(pEnv, "Failed to read PEB. Probably the process is 64bit, which cannot be read from the 32bit WinP DLL");
}
else {
#endif
reportError(pEnv, "Failed to read PEB");
#ifndef _WIN64
}
#endif
return NULL;
}

Expand Down
5 changes: 5 additions & 0 deletions native/runtime.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#include "stdafx.h"
#include "winp.h"

LPFN_ISWOW64PROCESS fnIsWow64Process;

extern "C"
BOOL WINAPI _DllMainCRTStartup(HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) {
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
return TRUE;
}

Expand Down
10 changes: 6 additions & 4 deletions native/winp.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ void error(JNIEnv* env, const char* file, int line, const char* msg);
//
// Kernel32.dll
//

BOOL WINAPI KillProcessEx(IN DWORD dwProcessId, IN BOOL bTree);

// https://msdn.microsoft.com/en-us/library/ms684139.aspx
extern "C" BOOL WINAPI IsWow64Process(HANDLE, PBOOL);
// https://msdn.microsoft.com/en-us/library/ms683189(VS.85).aspx
//BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD);
//VOID WINAPI SetLastError(DWORD);
typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
// Reference to the IsWow64Process method.
// It is being handled via the reference, because the method is not available for the non-desktop-app mode (e.g. Windows service or AppVeyor build)
extern LPFN_ISWOW64PROCESS fnIsWow64Process;

//
// NTDLL functions
Expand Down

0 comments on commit 7542b57

Please sign in to comment.