Author: mladen.turk(a)jboss.com
Date: 2007-10-16 12:55:48 -0400 (Tue, 16 Oct 2007)
New Revision: 1115
Modified:
trunk/sight/examples/org/jboss/sight/ListProcesses.java
trunk/sight/native/include/arch/windows/sight_private.h
trunk/sight/native/os/windows/console.c
trunk/sight/native/os/windows/main.c
trunk/sight/native/os/windows/process.c
Log:
Use undocumented PEB structures instead directly reading memory.
Modified: trunk/sight/examples/org/jboss/sight/ListProcesses.java
===================================================================
--- trunk/sight/examples/org/jboss/sight/ListProcesses.java 2007-10-15 11:05:10 UTC (rev
1114)
+++ trunk/sight/examples/org/jboss/sight/ListProcesses.java 2007-10-16 16:55:48 UTC (rev
1115)
@@ -42,19 +42,19 @@
for (Process p : Process.getProcesses()) {
User u = new User(p.UserId);
Group g = new Group(p.GroupId);
- if (p.Arguments==null)
- System.out.println("Process\t[" + p.Id + "] \t"
+
- p.State + " : " + p.BaseName +
- " User(" + u.Name + ") Group(" +
- g.Name +")" + "\t " +
- p.CurrentWorkingDirectory);
- else
- System.out.println("Process\t[" + p.Id + "] \t"
+
- p.State + " : " + p.BaseName +
- " User(" + u.Name + ") Group(" +
- g.Name +")" + "\t " +
- p.CurrentWorkingDirectory + "\t " +
- p.Arguments[0]);
+
+ System.out.print("Process\t[" + p.Id + "] \t" +
+ p.State + " : " + p.BaseName +
+ " User(" + u.Name + ") Group(" +
+ g.Name +")" + "\t " +
+ p.CurrentWorkingDirectory);
+ if (p.Arguments != null)
+ System.out.print("\t " + p.Arguments[0]);
+ if (p.Environment != null)
+ System.out.print("\t " + p.Environment[0]);
+
+ System.out.println();
+
}
} catch (Exception e) {
e.printStackTrace();
Modified: trunk/sight/native/include/arch/windows/sight_private.h
===================================================================
--- trunk/sight/native/include/arch/windows/sight_private.h 2007-10-15 11:05:10 UTC (rev
1114)
+++ trunk/sight/native/include/arch/windows/sight_private.h 2007-10-16 16:55:48 UTC (rev
1115)
@@ -72,6 +72,131 @@
SYSDLL_defined = 5 // must define as last idx_ + 1
} sight_dlltoken_e;
+/* Copied from
http://source.winehq.org/source/include/winternl.h */
+
+typedef struct _CURDIR
+{
+ UNICODE_STRING DosPath;
+ PVOID Handle;
+} CURDIR, *PCURDIR;
+
+typedef struct RTL_DRIVE_LETTER_CURDIR
+{
+ USHORT Flags;
+ USHORT Length;
+ ULONG TimeStamp;
+ UNICODE_STRING DosPath;
+} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
+
+typedef struct tagRTL_BITMAP {
+ ULONG SizeOfBitMap; /* Number of bits in the bitmap */
+ PULONG Buffer; /* Bitmap data, assumed sized to a DWORD boundary */
+} RTL_BITMAP, *PRTL_BITMAP;
+
+typedef struct _RTL_USER_PROCESS_PARAMETERS
+{
+ ULONG AllocationSize;
+ ULONG Size;
+ ULONG Flags;
+ ULONG DebugFlags;
+ HANDLE ConsoleHandle;
+ ULONG ConsoleFlags;
+ HANDLE hStdInput;
+ HANDLE hStdOutput;
+ HANDLE hStdError;
+ CURDIR CurrentDirectory;
+ UNICODE_STRING DllPath;
+ UNICODE_STRING ImagePathName;
+ UNICODE_STRING CommandLine;
+ PWSTR Environment;
+ ULONG dwX;
+ ULONG dwY;
+ ULONG dwXSize;
+ ULONG dwYSize;
+ ULONG dwXCountChars;
+ ULONG dwYCountChars;
+ ULONG dwFillAttribute;
+ ULONG dwFlags;
+ ULONG wShowWindow;
+ UNICODE_STRING WindowTitle;
+ UNICODE_STRING Desktop;
+ UNICODE_STRING ShellInfo;
+ UNICODE_STRING RuntimeInfo;
+ RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
+} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
+
+typedef struct _PEB_LDR_DATA
+{
+ ULONG Length;
+ BOOLEAN Initialized;
+ PVOID SsHandle;
+ LIST_ENTRY InLoadOrderModuleList;
+ LIST_ENTRY InMemoryOrderModuleList;
+ LIST_ENTRY InInitializationOrderModuleList;
+} PEB_LDR_DATA, *PPEB_LDR_DATA;
+
+/***********************************************************************
+ * PEB data structure (472 bytes)
+ */
+typedef struct _SIGHT_PEB
+{
+ BOOLEAN InheritedAddressSpace; /* 00 */
+ BOOLEAN ReadImageFileExecOptions; /* 01 */
+ BOOLEAN BeingDebugged; /* 02 */
+ BOOLEAN SpareBool; /* 03 */
+ HANDLE Mutant; /* 04 */
+ HMODULE ImageBaseAddress; /* 08 */
+ PPEB_LDR_DATA LdrData; /* 0c */
+ RTL_USER_PROCESS_PARAMETERS *ProcessParameters; /* 10 */
+ PVOID SubSystemData; /* 14 */
+ HANDLE ProcessHeap; /* 18 */
+ PRTL_CRITICAL_SECTION FastPebLock; /* 1c */
+ PVOID /*PPEBLOCKROUTINE*/ FastPebLockRoutine; /* 20 */
+ PVOID /*PPEBLOCKROUTINE*/ FastPebUnlockRoutine; /* 24 */
+ ULONG EnvironmentUpdateCount; /* 28 */
+ PVOID KernelCallbackTable; /* 2c */
+ PVOID EventLogSection; /* 30 */
+ PVOID EventLog; /* 34 */
+ PVOID /*PPEB_FREE_BLOCK*/ FreeList; /* 38 */
+ ULONG TlsExpansionCounter; /* 3c */
+ PRTL_BITMAP TlsBitmap; /* 40 */
+ ULONG TlsBitmapBits[2]; /* 44 */
+ PVOID ReadOnlySharedMemoryBase; /* 4c */
+ PVOID ReadOnlySharedMemoryHeap; /* 50 */
+ PVOID *ReadOnlyStaticServerData; /* 54 */
+ PVOID AnsiCodePageData; /* 58 */
+ PVOID OemCodePageData; /* 5c */
+ PVOID UnicodeCaseTableData; /* 60 */
+ ULONG NumberOfProcessors; /* 64 */
+ ULONG NtGlobalFlag; /* 68 */
+ BYTE Spare2[4]; /* 6c */
+ LARGE_INTEGER CriticalSectionTimeout; /* 70 */
+ ULONG HeapSegmentReserve; /* 78 */
+ ULONG HeapSegmentCommit; /* 7c */
+ ULONG HeapDeCommitTotalFreeThreshold; /* 80 */
+ ULONG HeapDeCommitFreeBlockThreshold; /* 84 */
+ ULONG NumberOfHeaps; /* 88 */
+ ULONG MaximumNumberOfHeaps; /* 8c */
+ PVOID *ProcessHeaps; /* 90 */
+ PVOID GdiSharedHandleTable; /* 94 */
+ PVOID ProcessStarterHelper; /* 98 */
+ PVOID GdiDCAttributeList; /* 9c */
+ PVOID LoaderLock; /* a0 */
+ ULONG OSMajorVersion; /* a4 */
+ ULONG OSMinorVersion; /* a8 */
+ ULONG OSBuildNumber; /* ac */
+ ULONG OSPlatformId; /* b0 */
+ ULONG ImageSubSystem; /* b4 */
+ ULONG ImageSubSystemMajorVersion; /* b8 */
+ ULONG ImageSubSystemMinorVersion; /* bc */
+ ULONG ImageProcessAffinityMask; /* c0 */
+ ULONG GdiHandleBuffer[34]; /* c4 */
+ ULONG PostProcessInitRoutine; /* 14c */
+ PRTL_BITMAP TlsExpansionBitmap; /* 150 */
+ ULONG TlsExpansionBitmapBits[32]; /* 154 */
+ ULONG SessionId; /* 1d4 */
+} SIGHT_PEB, *PSIGHT_PEB;
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -141,6 +266,17 @@
#undef NtQuerySystemInformation
#define NtQuerySystemInformation sight_late_NtQuerySystemInformation
+SIGHT_DECLARE_LATE_DLL_FUNC(SYSDLL_NTDLL, NTSTATUS, 1,
+ WINAPI, NtQueryInformationProcess, 0, (
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength),
+ (ProcessHandle, ProcessInformationClass, ProcessInformation,
ProcessInformationLength, ReturnLength));
+#undef NtQueryInformationProcess
+#define NtQueryInformationProcess sight_late_NtQueryInformationProcess
+
SIGHT_DECLARE_LATE_DLL_FUNC(SYSDLL_KERNEL32, BOOL, FALSE,
WINAPI, GetPerformanceInfo, 0, (
PPERFORMACE_INFORMATION pPerformanceInformation,
Modified: trunk/sight/native/os/windows/console.c
===================================================================
--- trunk/sight/native/os/windows/console.c 2007-10-15 11:05:10 UTC (rev 1114)
+++ trunk/sight/native/os/windows/console.c 2007-10-16 16:55:48 UTC (rev 1115)
@@ -282,7 +282,7 @@
if (wLen)
rv = ZSTR_TO_JSTRING(wBuf, wLen);
else
- rv = CSTR_TO_JSTRING(_E, "");
+ rv = CSTR_TO_JSTRING("");
}
cleanup:
Modified: trunk/sight/native/os/windows/main.c
===================================================================
--- trunk/sight/native/os/windows/main.c 2007-10-15 11:05:10 UTC (rev 1114)
+++ trunk/sight/native/os/windows/main.c 2007-10-16 16:55:48 UTC (rev 1115)
@@ -354,5 +354,6 @@
L"Failed setting SeDebugPrivilege",
GetLastError());
}
+
return APR_SUCCESS;
}
Modified: trunk/sight/native/os/windows/process.c
===================================================================
--- trunk/sight/native/os/windows/process.c 2007-10-15 11:05:10 UTC (rev 1114)
+++ trunk/sight/native/os/windows/process.c 2007-10-16 16:55:48 UTC (rev 1115)
@@ -230,52 +230,98 @@
goto cleanup;
}
(*_E)->SetIntArrayRegion(_E, rv, 0, pnum, parr);
+
cleanup:
free(parr);
return rv;
}
-#define PEB_ADDRESS(x) ((char *)0 + (0x00010000 * (1 + (x))))
+#define MAX_ENV_CHARS 2048
-static void read_proc_pages(DWORD pid, HANDLE hProcess,
- sight_str_t *pages, apr_pool_t *pool)
+static DWORD read_proc_peb(HANDLE hProcess, WCHAR **lpCwd,
+ WCHAR **lpCmdLine, WCHAR **lpEnv,
+ apr_pool_t *pool)
{
- int i;
- MEMORY_BASIC_INFORMATION mbi;
- SIZE_T nrd, rdd;
+ DWORD status;
+ PROCESS_BASIC_INFORMATION pbi;
+ SIGHT_PEB peb;
+ RTL_USER_PROCESS_PARAMETERS rtl;
+ DWORD dwSize;
- for (i = 0; i < 2; i++) {
- pages[i].len = 0;
- pages[i].str.w = NULL;
+ memset(&pbi, 0, sizeof(PROCESS_BASIC_INFORMATION));
+ memset(&peb, 0, sizeof(SIGHT_PEB));
+ memset(&rtl, 0, sizeof(RTL_USER_PROCESS_PARAMETERS));
+
+ if ((status = NtQueryInformationProcess(hProcess,
+ ProcessBasicInformation,
+ &pbi,
+ sizeof(PROCESS_BASIC_INFORMATION),
+ &dwSize)) != ERROR_SUCCESS) {
+ return status;
}
- for (i = 0; i < 2; i++) {
- if (!VirtualQueryEx(hProcess, PEB_ADDRESS(i), &mbi, sizeof(mbi)))
- continue;
- nrd = mbi.RegionSize;
- rdd = 0;
- if (nrd > 8192)
- continue;
- pages[i].str.w = apr_palloc(pool, nrd);
- if (!pages[i].str.w) {
- /* If we cannot alloc memory what's the point? */
- return;
+
+ if (!pbi.PebBaseAddress)
+ return EINVAL;
+ if (!ReadProcessMemory(hProcess,
+ pbi.PebBaseAddress,
+ &peb,
+ sizeof(SIGHT_PEB),
+ &dwSize)) {
+ return GetLastError();
+ }
+
+ if (!ReadProcessMemory(hProcess,
+ peb.ProcessParameters,
+ &rtl,
+ sizeof(RTL_USER_PROCESS_PARAMETERS),
+ &dwSize)) {
+ return GetLastError();
+ }
+ /* Read actual data */
+ if (rtl.CurrentDirectory.DosPath.Buffer &&
+ rtl.CurrentDirectory.DosPath.Length) {
+ *lpCwd = apr_pcalloc(pool,
+ rtl.CurrentDirectory.DosPath.Length + sizeof(WCHAR));
+ if (*lpCwd) {
+ if (!ReadProcessMemory(hProcess,
+ rtl.CurrentDirectory.DosPath.Buffer,
+ *lpCwd,
+ rtl.CurrentDirectory.DosPath.Length,
+ NULL))
+ *lpCwd = NULL;
}
- if (!ReadProcessMemory(hProcess,
- PEB_ADDRESS(i),
- pages[i].str.w,
- nrd,
- &rdd)) {
- pages[i].str.w = NULL;
- pages[i].len = 0;
+ }
+ if (rtl.CommandLine.Buffer &&
+ rtl.CommandLine.Length) {
+ *lpCmdLine = apr_pcalloc(pool,
+ rtl.CommandLine.Length + sizeof(WCHAR));
+ if (*lpCmdLine) {
+ if (!ReadProcessMemory(hProcess,
+ rtl.CommandLine.Buffer,
+ *lpCmdLine,
+ rtl.CommandLine.Length,
+ NULL))
+ *lpCmdLine = NULL;
}
- else {
- pages[i].len = (jsize)(rdd / 2);
- /* Make sure we always have double zero at the end */
- pages[i].str.w[pages[i].len - 1] = 0;
- pages[i].str.w[pages[i].len - 2] = 0;
+ }
+ if (rtl.Environment) {
+ MEMORY_BASIC_INFORMATION mbi;
+ if (VirtualQueryEx(hProcess, rtl.Environment, &mbi, sizeof(mbi)))
+ *lpEnv = apr_pcalloc(pool, mbi.RegionSize);
+ else
+ *lpEnv = NULL;
+ if (*lpEnv) {
+ if (!ReadProcessMemory(hProcess,
+ rtl.Environment,
+ *lpEnv,
+ mbi.RegionSize - 4,
+ NULL))
+ *lpEnv = NULL;
}
}
+
+ return ERROR_SUCCESS;
}
static BOOL find_pe32(DWORD pid, PROCESSENTRY32W *ppe32)
@@ -301,53 +347,6 @@
return rv;
}
-
-#define NT32_CWDOFF 164
-#define NT64_CWDOFF 252
-
-#define NT32_OFFSET 294
-#define NT64_OFFSET 382
-
-#define NT32_CWDIFF 130
-
-#define ALIGN_TO_DWORD(A) ((((LPBYTE)(A) - ((LPBYTE)0)) + 3) & ~3)
-
-
-static LPWSTR get_procc_base(LPWSTR mem, SIZE_T len, SIZE_T *off)
-{
- DWORD *base = (DWORD *)mem;
- DWORD *boff = NULL;
- SIZE_T cnt = len / sizeof(DWORD);
- SIZE_T roff = NT32_CWDOFF;
-
- while (!base[roff]) {
- if (roff++ > (cnt - sizeof(DWORD)))
- return NULL;
- }
- if (roff <= NT64_CWDOFF)
- boff = &base[roff];
- else
- roff = NT32_CWDOFF;
- *off = roff;
- return (LPWSTR)boff;
-}
-
-static LPWSTR get_procd_base(LPWSTR mem, SIZE_T len, SIZE_T off)
-{
- DWORD *base = (DWORD *)mem;
- DWORD *boff = NULL;
- SIZE_T cnt = len / sizeof(DWORD);
-
-
- off += NT32_CWDIFF;
- while (!base[off]) {
- if (off++ > (cnt - sizeof(DWORD)))
- return NULL;
- }
- boff = &base[off];
- return (LPWSTR)boff;
-}
-
static void proc_cleanup(int mode, sight_object_t *no)
{
if (no) {
@@ -368,15 +367,13 @@
jchar buf[SIGHT_STYPE_SIZ];
IO_COUNTERS ioc;
FILETIME ft[4];
- sight_str_t ppages[4];
- LPWSTR mproc = NULL;
- SIZE_T mpnrd = 0;
int ppid = -1, tcnt = 0;
PROCESSENTRY32W pe32;
jlong et = 0;
apr_uid_t uid;
apr_gid_t gid;
- int spage = 0;
+ LPWSTR *pargs;
+ int pargc = 0;
if (pid < 0)
return APR_SUCCESS;
@@ -386,6 +383,7 @@
#ifdef SIGHT_DO_STATS
no->clean = proc_cleanup;
#endif
+
SIGHT_LOCAL_TRY(no) {
if (!find_pe32(pid, &pe32)) {
/* System pids have low values */
@@ -448,35 +446,17 @@
/* XXX: Reading process memory is a hack.
*/
if (pid != (jint)GetCurrentProcessId()) {
- read_proc_pages(pid, hProcess, &ppages[0], no->pool);
- if (ppages[0].str.w && (*ppages[0].str.w > 0x003C &&
*ppages[0].str.w < 0x007F)) {
- SET_IFIELD_O(0004, thiz, sight_mw_to_sa(_E, ppages[0].str.w));
- }
- if (ppages[1].str.w) {
- mproc = ppages[spage+1].str.w;
- mpnrd = ppages[spage+1].len;
- }
- if (mproc && mpnrd) {
- SIZE_T pO = NT32_CWDOFF;
- LPWSTR p1, p2, e1;
- int l1, l2;
- if ((p1 = (LPWSTR)get_procc_base(mproc, mpnrd, &pO))) {
- SET_IFIELD_W(0018, thiz, p1);
- }
- /* XXX Might not work on all Windows platforms */
- if ((p1 = (LPWSTR)get_procd_base(mproc, mpnrd, pO))) {
- LPWSTR *args;
- /* p1 Process PATH */
- l1 = lstrlenW(p1) + 1;
- p2 = (LPWSTR)ALIGN_TO_DWORD(p1 + l1);
- /* p2 Process Executable */
- l2 = lstrlenW(p2) + 1;
- e1 = (LPWSTR)ALIGN_TO_DWORD(p2 + l2);
- /* e1 Process Cmdline */
- args = (LPWSTR *)CommandLineToArgvW(e1, &l1);
- if (args) {
- SET_IFIELD_O(0003, thiz, sight_aw_to_sa(_E, args, l1));
- LocalFree(args);
+ WCHAR *lpCwd = NULL, *lpCmdLine = NULL, *lpEnv = NULL;
+ if (read_proc_peb(hProcess, &lpCwd, &lpCmdLine,
+ &lpEnv, no->pool) == ERROR_SUCCESS) {
+ SET_IFIELD_O(0004, thiz, sight_mw_to_sa(_E, lpEnv));
+ SET_IFIELD_W(0018, thiz, lpCwd);
+ if (lpCmdLine) {
+ pargs = (LPWSTR *)CommandLineToArgvW(lpCmdLine,
+ &pargc);
+ if (pargs) {
+ SET_IFIELD_O(0003, thiz, sight_aw_to_sa(_E, pargs, pargc));
+ LocalFree(pargs);
}
}
}
@@ -484,8 +464,6 @@
else {
LPVOID env;
LPWSTR cmdl;
- int pargc;
- LPWSTR *pargs;
if ((env = GetEnvironmentStringsW())) {
SET_IFIELD_O(0004, thiz, sight_mw_to_sa(_E, env));