Changeset 81a6048 in nscp


Ignore:
Timestamp:
12/14/11 07:10:26 (18 months ago)
Author:
Michael Medin <michael@…>
Branches:
master, 0.4.0, 0.4.1, 0.4.2
Children:
a87ce04
Parents:
53c1a6e
Message:

Swapped APIs to make command line option for CheckProcess? work with x64...

Location:
include
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • include/EnumProcess.cpp

    re11d494 r81a6048  
    261261  // Open process to get filename 
    262262  DWORD openArgs = PROCESS_QUERY_INFORMATION|PROCESS_VM_READ; 
     263//  if (expand_command_line) 
     264//    openArgs |= PROCESS_VM_OPERATION; 
     265  HANDLE hProc = OpenProcess(openArgs, FALSE, pid); 
     266  if (!hProc) 
     267    throw process_enumeration_exception(GetLastError(), _T("Failed to open process: ") + strEx::itos(pid) + _T(": ")); 
    263268  if (expand_command_line) 
    264     openArgs |= PROCESS_VM_OPERATION; 
    265   HANDLE hProc = OpenProcess(openArgs, FALSE, pid); 
    266   if (!hProc) { 
    267     throw process_enumeration_exception(GetLastError(), _T("Failed to open process: ") + strEx::itos(pid) + _T(": ")); 
    268   } 
    269   if (expand_command_line) { 
    270269    entry.command_line = GetCommandLine(hProc); 
    271   } 
    272270  HMODULE hMod; 
    273271  DWORD size; 
     
    292290} 
    293291 
    294 // Process data block is found in an NT machine. 
    295 // on an Intel system at 0x00020000  which is the 32 
    296 // memory page. At offset 0x0498 is what I believe to be 
    297 // the process' startup directory which is followed by 
    298 // the system's PATH. Next is  process full command 
    299 // followed by the exe name. 
    300 #define PROCESS_DATA_BLOCK_ADDRESS      (LPVOID)0x00020498 
    301 // align pointer 
    302 #define ALIGNMENT(x) ( (x & 0xFFFFFFFC) ? (x & 0xFFFFFFFC) + sizeof(DWORD) : x ) 
    303  
    304 std::wstring CEnumProcess::GetCommandLine(HANDLE hProcess) 
    305 { 
    306   SYSTEM_INFO sysinfo; 
    307   GetSystemInfo (&sysinfo); 
    308  
    309   MEMORY_BASIC_INFORMATION mbi; 
    310   if (VirtualQueryEx (hProcess, PROCESS_DATA_BLOCK_ADDRESS, &mbi, sizeof(mbi) ) == 0) 
    311     throw process_enumeration_exception(_T("VirtualQueryEx failed: ") + error::lookup::last_error()); 
    312   LPBYTE lpBuffer = (LPBYTE)malloc (sysinfo.dwPageSize); 
    313   if (lpBuffer == NULL) 
    314     throw process_enumeration_exception(_T("Failed to allocate buffer")); 
    315   SIZE_T dwBytesRead; 
    316   if (!ReadProcessMemory( hProcess, mbi.BaseAddress, (LPVOID)lpBuffer, sysinfo.dwPageSize, &dwBytesRead)) { 
    317     free(lpBuffer); 
    318     throw process_enumeration_exception(_T("ReadProcessMemory failed: ") + error::lookup::last_error()); 
    319   } 
    320   LPBYTE lpPos = lpPos = lpBuffer + ((DWORD)PROCESS_DATA_BLOCK_ADDRESS - (DWORD)mbi.BaseAddress); 
    321  
    322   // Skip programs current directory and path 
    323   lpPos += (wcslen((LPWSTR)lpPos) + 1) * sizeof(WCHAR); 
    324  
    325   // Aligned on a DWORD boundary skip it, and copy the next string into 
    326   // buffer and null terminate it. 
    327   lpPos = (LPBYTE)ALIGNMENT((DWORD)lpPos); 
    328   lpPos += (wcslen((LPWSTR)lpPos) + 1) * sizeof(WCHAR); 
    329  
    330   // Sometimes there is an extra \0 here 
    331   /* 
    332   if ( *lpPos == '\0' )  
    333     lpPos += sizeof(WCHAR); 
    334   */ 
    335  
    336   DWORD nStrLength = (wcslen((LPWSTR)lpPos) + 1) * sizeof(WCHAR); 
    337   WCHAR *buffer = new TCHAR[nStrLength+2]; 
    338   buffer[0] = L'\0'; 
    339   if(nStrLength > sizeof(WCHAR)) { 
    340     wcsncpy(buffer, (LPWSTR)lpPos, nStrLength); 
    341     buffer[nStrLength] = L'\0'; 
    342   } 
    343   free(lpBuffer); 
    344   std::wstring ret = buffer; 
    345   delete [] buffer; 
     292typedef struct _PROCESS_BASIC_INFORMATION { 
     293  LONG ExitStatus; 
     294  PVOID PebBaseAddress; 
     295  ULONG_PTR AffinityMask; 
     296  LONG BasePriority; 
     297  ULONG_PTR UniqueProcessId; 
     298  ULONG_PTR ParentProcessId; 
     299} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; 
     300 
     301 
     302typedef struct _UNICODE_STRING { 
     303  USHORT Length; 
     304  USHORT MaximumLength; 
     305  PWSTR Buffer; 
     306} UNICODE_STRING, *PUNICODE_STRING; 
     307 
     308PVOID GetPebAddress(HANDLE ProcessHandle) { 
     309  PFNtQueryInformationProcess NtQueryInformationProcess = (PFNtQueryInformationProcess)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess"); 
     310  if (NtQueryInformationProcess == NULL) 
     311    throw CEnumProcess::process_enumeration_exception(_T("Failed to load NtQueryInformationProcess")); 
     312  PROCESS_BASIC_INFORMATION pbi; 
     313  NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(pbi), NULL); 
     314  return pbi.PebBaseAddress; 
     315} 
     316 
     317std::wstring CEnumProcess::GetCommandLine(HANDLE hProcess) { 
     318 
     319  PVOID rtlUserProcParamsAddress; 
     320  UNICODE_STRING commandLine; 
     321  PVOID pebAddress = GetPebAddress(hProcess); 
     322 
     323 
     324#ifdef _WIN64 
     325  if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 0x20, &rtlUserProcParamsAddress, sizeof(PVOID), NULL)) 
     326    throw process_enumeration_exception(_T("Could not read the address of ProcessParameters: ") + error::lookup::last_error()); 
     327#else 
     328  if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 0x10, &rtlUserProcParamsAddress, sizeof(PVOID), NULL)) 
     329    throw process_enumeration_exception(_T("Could not read the address of ProcessParameters: ") + error::lookup::last_error()); 
     330#endif 
     331 
     332#ifdef _WIN64 
     333  if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 0x70, &commandLine, sizeof(commandLine), NULL)) 
     334    throw process_enumeration_exception(_T("Could not read commandline: ") + error::lookup::last_error()); 
     335#else 
     336  if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 0x40, &commandLine, sizeof(commandLine), NULL)) 
     337    throw process_enumeration_exception(_T("Could not read commandline: ") + error::lookup::last_error()); 
     338#endif 
     339 
     340  /* allocate memory to hold the command line */ 
     341  wchar_t *commandLineContents = new wchar_t[commandLine.Length+2]; 
     342  memset(commandLineContents, 0, commandLine.Length); 
     343 
     344  /* read the command line */ 
     345  if (!ReadProcessMemory(hProcess, commandLine.Buffer, commandLineContents, commandLine.Length, NULL)) { 
     346    delete [] commandLineContents; 
     347    throw process_enumeration_exception(_T("Could not read commandline string: ") + error::lookup::last_error()); 
     348  } 
     349 
     350  commandLineContents[(commandLine.Length/sizeof(WCHAR))] = '\0'; 
     351  std::wstring ret = commandLineContents; 
     352  delete [] commandLineContents; 
     353 
    346354  return ret; 
    347355} 
  • include/EnumProcess.h

    re11d494 r81a6048  
    4242typedef BOOL ( WINAPI *TASKENUMPROCEX )(DWORD dwThreadId, WORD hMod16, WORD hTask16, PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ); 
    4343typedef INT (WINAPI *PFVDMEnumTaskWOWEx)(DWORD dwProcessId, TASKENUMPROCEX fp, LPARAM lparam);  
     44typedef LONG (WINAPI *PFNtQueryInformationProcess)(HANDLE ProcessHandle, DWORD ProcessInformationClass, PVOID ProcessInformation, DWORD ProcessInformationLength, PDWORD ReturnLength); 
     45 
    4446#else 
    4547// Functions loaded from PSAPI 
Note: See TracChangeset for help on using the changeset viewer.