ULONG64 GetOSVersion() { ULONG32 osMajorVersion, osMinorVersion; ULONG64 address = GetPebAddress(); if (IsTarget64()) { if (GetFieldValue(address, "ntdll!_PEB", "OSMajorVersion", osMajorVersion) != 0) { dprintf("read OSMajorVersion failed\n"); return 0; } if (GetFieldValue(address, "ntdll!_PEB", "OSMinorVersion", osMinorVersion) != 0) { dprintf("read OSMinorVersion failed\n"); return 0; } } else { ULONG cb; if (!READMEMORY(address + 0xa4, osMajorVersion)) { dprintf("read OSMajorVersion failed\n"); return 0; } if (!READMEMORY(address + 0xa8, osMinorVersion)) { dprintf("read OSMinorVersion failed\n"); return 0; } } return (((ULONG64)osMajorVersion << 32) | osMinorVersion); }
ULONG64 GetPebAddress() { if (!IsTarget64() && IsPtr64()) { // WOW64 ULONG64 teb; GetTebAddress(&teb); ULONG cb; ULONG32 teb32; if (!READMEMORY(teb, teb32)) { dprintf("read TEB32 at %p failed\n", teb); return NULL; } ULONG32 peb32; // _TEB::ProcessEnvironmentBlock if (!READMEMORY(teb32 + 0x30, peb32)) { dprintf("read PEB32 at %p failed\n", teb32 + 0x30); return NULL; } return peb32; } else { ULONG64 address; GetPebAddress(NULL, &address); return address; } }
static WCHAR * GetProcessCommandLine(HANDLE pHandle, DWORD *exitTag, DWORD *lastErrorCode) { PVOID rtlurp; UNICODE_STRING cmdln; PVOID peba = GetPebAddress(pHandle); // Get the address of ProcessParameters. if (!ReadProcessMemory(pHandle, (PCHAR)peba + FIELD_OFFSET(PEB, ProcessParameters), &rtlurp, sizeof(rtlurp), NULL)) { // Could not read the address of ProcessParameters. *exitTag = 1; *lastErrorCode = GetLastError(); return NULL; } // Read the CommandLine UNICODE_STRING structure. if (!ReadProcessMemory(pHandle, (PCHAR)rtlurp + FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, CommandLine), &cmdln, sizeof(cmdln), NULL)) { // Could not read the address of CommandLine. *exitTag = 2; *lastErrorCode = GetLastError(); return NULL; } // Allocate memory to hold the command line. WCHAR *cmdlncnts = malloc(cmdln.Length); if (NULL == cmdlncnts) { *exitTag = 3; return NULL; } // Read the command line contents. if (!ReadProcessMemory(pHandle, cmdln.Buffer, cmdlncnts, cmdln.Length, NULL)) { // Could not read the command line string. *exitTag = 4; *lastErrorCode = GetLastError(); free(cmdlncnts); cmdlncnts = NULL; return NULL; } WCHAR *result = malloc(cmdln.Length + 2); if(result == NULL) { *exitTag = 5; *lastErrorCode = GetLastError(); free(cmdlncnts); cmdlncnts = NULL; return NULL; } memcpy(result, cmdlncnts, cmdln.Length); // ... plus two bytes (size of WCHAR) for a nul-terminator. *(WCHAR*)((char*)result + cmdln.Length) = 0x0000L; free(cmdlncnts); cmdlncnts = NULL; return result; }
int GetProcessCommandLine(int pid) { HANDLE processHandle; PVOID pebAddress; PVOID rtlUserProcParamsAddress; UNICODE_STRING commandLine; WCHAR *commandLineContents; if ((processHandle = OpenProcess( PROCESS_QUERY_INFORMATION | /* required for NtQueryInformationProcess */ PROCESS_VM_READ, /* required for ReadProcessMemory */ FALSE, pid)) == 0) { printf("Could not open process!\n"); return GetLastError(); } pebAddress = GetPebAddress(processHandle); /* get the address of ProcessParameters */ if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 0x10, &rtlUserProcParamsAddress, sizeof(PVOID), NULL)) { printf("Could not read the address of ProcessParameters!\n"); return GetLastError(); } /* read the CommandLine UNICODE_STRING structure */ if (!ReadProcessMemory(processHandle, (PCHAR)rtlUserProcParamsAddress + 0x40, &commandLine, sizeof(commandLine), NULL)) { printf("Could not read CommandLine!\n"); return GetLastError(); } /* allocate memory to hold the command line */ commandLineContents = (WCHAR *)malloc(commandLine.Length); /* read the command line */ if (!ReadProcessMemory(processHandle, commandLine.Buffer, commandLineContents, commandLine.Length, NULL)) { printf("Could not read the command line string!\n"); return GetLastError(); } /* print it */ /* the length specifier is in characters, but commandLine.Length is in bytes */ /* a WCHAR is 2 bytes */ printf("%.*S\n", commandLine.Length / 2, commandLineContents); CloseHandle(processHandle); free(commandLineContents); return 1; }
NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath ) { PDEVICE_OBJECT pdo = NULL; NTSTATUS s = STATUS_SUCCESS; UNICODE_STRING usDriverName, usDosDeviceName; RtlInitUnicodeString( &usDriverName, DRIVER_NAME ); RtlInitUnicodeString( &usDosDeviceName, DEVICE_NAME ); s = IoCreateDevice( pDriverObject, 0, &usDriverName, \ FILE_DRIVER_SSDT, FILE_DEVICE_SECURE_OPEN, \ FALSE, &pdo ); if( STATUS_SUCCESS == s ) { pDriverObject->MajorFunction[IRP_MJ_CREATE] = SSDTCreate; pDriverObject->MajorFunction[IRP_MJ_CLOSE]=SSDTClose; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] \ = SSDTDeviceIoCtl; pDriverObject->DriverUnload = SSDTUnload; IoCreateSymbolicLink( &usDosDeviceName, &usDriverName ); } MUTEX_INIT(LogMutex); // GetProcessNameOffset(); Log = ExAllocatePool(NonPagedPool,sizeof(LOG_BUF)); if(Log == NULL) { s = STATUS_INSUFFICIENT_RESOURCES; } else { Log->Length = 0; Log->Next = NULL; //pCurrentLog = Log; NumLog = 1; } pSystem = PsGetCurrentProcess(); DbgPrint("pSystem %0x",pSystem); pebAddress = GetPebAddress(); pObjectTypeProcess = *(PULONG)((ULONG)pSystem - OBJECT_HEADER_SIZE +OBJECT_TYPE_OFFSET); MyPspTerminateThreadByPointer =GetUndocumentFunctionAdress(); GetProcessNameOffset(); DbgPrint( "SSDT: Load Success!" ); return s; }
char *getcmdlinefrompid(int pid) { HANDLE processHandle; PVOID pebAddress; PVOID rtlUserProcParamsAddress; UNICODE_STRING commandLine; WCHAR *commandLineContents; if ((processHandle = OpenProcess( PROCESS_QUERY_INFORMATION | /* required for NtQueryInformationProcess */ PROCESS_VM_READ, /* required for ReadProcessMemory */ FALSE, pid)) == 0) { printf("Could not open process!\n"); return ""; } pebAddress = GetPebAddress(processHandle); /* get the address of ProcessParameters */ if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 0x10, &rtlUserProcParamsAddress, sizeof(PVOID), NULL)) { printf("Could not read the address of ProcessParameters!\n"); return ""; } /* read the CommandLine UNICODE_STRING structure */ if (!ReadProcessMemory(processHandle, (PCHAR)rtlUserProcParamsAddress + 0x40, &commandLine, sizeof(commandLine), NULL)) { printf("Could not read CommandLine!\n"); return ""; } /* allocate memory to hold the command line */ commandLineContents = (WCHAR *)malloc(commandLine.Length); /* read the command line */ if (!ReadProcessMemory(processHandle, commandLine.Buffer, commandLineContents, commandLine.Length, NULL)) { printf("Could not read the command line string!\n"); return ""; } CloseHandle(processHandle); static char ascii[1024]; memset(ascii,0,sizeof(ascii)); wcstombs(ascii,commandLineContents,commandLine.Length<sizeof(ascii)?commandLine.Length:sizeof(ascii)); return ascii; }
ULONG32 GetNtGlobalFlag() { ULONG32 ntGlobalFlag; ULONG64 address = GetPebAddress(); if (IsTarget64()) { if (GetFieldValue(address, "ntdll!_PEB", "NtGlobalFlag", ntGlobalFlag) != 0) { dprintf("read NtGlobalFlag failed\n"); return 0; } } else { ULONG cb; if (!READMEMORY(address + 0x68, ntGlobalFlag)) { dprintf("read NtGlobalFlag failed\n"); return 0; } } return ntGlobalFlag; }
std::vector<ModuleInfo> GetLoadedModules() { std::vector<ModuleInfo> info; ULONG cb; ULONG64 pebAddress = GetPebAddress(); if (IsTarget64()) { ULONG64 ldr; if (GetFieldValue(pebAddress, "ntdll!_PEB", "Ldr", ldr) != 0) { dprintf("read Ldr failed\n"); goto ERROR_EXIT; } ULONG offset; if (GetFieldOffset("ntdll!_PEB_LDR_DATA", "InMemoryOrderModuleList", &offset) != 0) { dprintf("GetFieldOffset(_PEB_LDR_DATA::InMemoryOrderModuleList) failed\n"); goto ERROR_EXIT; } ULONG64 headAddress = ldr + offset; LIST_ENTRY64 inMemoryOrderModuleList; if (GetFieldValue(ldr, "ntdll!_PEB_LDR_DATA", "InMemoryOrderModuleList", inMemoryOrderModuleList) != 0) { dprintf("read InMemoryOrderModuleList failed\n"); goto ERROR_EXIT; } LIST_ENTRY64 entry = inMemoryOrderModuleList; while (entry.Flink != headAddress) { ModuleInfo moduleInfo; ULONG64 address = entry.Flink; if (!READMEMORY(address, entry)) { dprintf("read entry at %p failed\n", address); goto ERROR_EXIT; } // LDR_DATA_TABLE_ENTRY at address - sizeof(entry) ULONG64 dllBase, sizeOfImage; if (GetFieldValue(address - sizeof(entry), "ntdll!_LDR_DATA_TABLE_ENTRY", "DllBase", dllBase) != 0) { dprintf("read DllBase around %p failed\n", address - sizeof(entry)); goto ERROR_EXIT; } moduleInfo.DllBase = dllBase; if (GetFieldValue(address - sizeof(entry), "ntdll!_LDR_DATA_TABLE_ENTRY", "SizeOfImage", sizeOfImage) != 0) { dprintf("read SizeOfImage around %p failed\n", address - sizeof(entry)); goto ERROR_EXIT; } moduleInfo.SizeOfImage = sizeOfImage; // UNICODE_STRING struct { USHORT Length; USHORT MaximumLength; ULONG64 Buffer; } fullDllName; if (GetFieldValue(address - sizeof(entry), "ntdll!_LDR_DATA_TABLE_ENTRY", "FullDllName", fullDllName) != 0) { dprintf("read FullDllName around %p failed\n", address - sizeof(entry)); goto ERROR_EXIT; } std::vector<wchar_t> unicode; unicode.resize(fullDllName.Length / sizeof(wchar_t)); if (!ReadMemory(fullDllName.Buffer, &unicode[0], fullDllName.Length, &cb) || cb != fullDllName.Length) { dprintf("read unicode at %p %d failed\n", fullDllName.Buffer, (int)fullDllName.Length); goto ERROR_EXIT; } int written = WideCharToMultiByte(CP_ACP, 0, &unicode[0], fullDllName.Length / sizeof(wchar_t), moduleInfo.FullDllName, sizeof(moduleInfo.FullDllName), NULL, NULL); if (written < 0 || written >= sizeof(moduleInfo.FullDllName)) { dprintf("WideCharToMultiByte returns %d\n", written); goto ERROR_EXIT; } moduleInfo.FullDllName[written] = '\0'; info.push_back(moduleInfo); } return info; } else { ULONG32 ldr; if (!READMEMORY(pebAddress + 0xc, ldr)) { dprintf("read Ldr failed\n"); goto ERROR_EXIT; } ULONG64 headAddress = ldr + 0x14; LIST_ENTRY32 inMemoryOrderModuleList; if (!READMEMORY(headAddress, inMemoryOrderModuleList)) { dprintf("read InMemoryOrderModuleList failed\n"); goto ERROR_EXIT; } LIST_ENTRY32 entry = inMemoryOrderModuleList; while (entry.Flink != headAddress) { ModuleInfo moduleInfo; ULONG64 address = entry.Flink; if (!READMEMORY(address, entry)) { dprintf("read entry at %p failed\n", address); goto ERROR_EXIT; } // LDR_DATA_TABLE_ENTRY at address - sizeof(entry) ULONG32 dllBase, sizeOfImage; if (!READMEMORY(address - sizeof(entry) + 0x18, dllBase)) { dprintf("read DllBase at %p failed\n", address - sizeof(entry) + 0x18); goto ERROR_EXIT; } moduleInfo.DllBase = dllBase; if (!READMEMORY(address - sizeof(entry) + 0x20, sizeOfImage)) { dprintf("read SizeOfImage at %p failed\n", address - sizeof(entry) + 0x20); goto ERROR_EXIT; } moduleInfo.SizeOfImage = sizeOfImage; // UNICODE_STRING struct { USHORT Length; USHORT MaximumLength; ULONG32 Buffer; } fullDllName; if (!READMEMORY(address - sizeof(entry) + 0x24, fullDllName)) { dprintf("read FullDllName at %p failed\n", address - sizeof(entry) + 0x24); goto ERROR_EXIT; } std::vector<wchar_t> unicode; unicode.resize(fullDllName.Length / sizeof(wchar_t)); if (!ReadMemory(fullDllName.Buffer, &unicode[0], fullDllName.Length, &cb) || cb != fullDllName.Length) { dprintf("read unicode at %p %d failed\n", (ULONG64)fullDllName.Buffer, (int)fullDllName.Length); goto ERROR_EXIT; } int written = WideCharToMultiByte(CP_ACP, 0, &unicode[0], fullDllName.Length / sizeof(wchar_t), moduleInfo.FullDllName, sizeof(moduleInfo.FullDllName), NULL, NULL); if (written < 0 || written >= sizeof(moduleInfo.FullDllName)) { dprintf("WideCharToMultiByte returns %d\n", written); goto ERROR_EXIT; } moduleInfo.FullDllName[written] = '\0'; info.push_back(moduleInfo); } return info; } ERROR_EXIT: info.clear(); return info; }
/* * returns a Python list representing the arguments for the process * with given pid or NULL on error. */ PyObject* get_arg_list(long pid) { int nArgs, i; LPWSTR *szArglist; HANDLE hProcess; PVOID pebAddress; PVOID rtlUserProcParamsAddress; UNICODE_STRING commandLine; WCHAR *commandLineContents; PyObject *arg = NULL; PyObject *arg_from_wchar = NULL; PyObject *argList = NULL; hProcess = handle_from_pid(pid); if(hProcess == NULL) { return NULL; } pebAddress = GetPebAddress(hProcess); /* get the address of ProcessParameters */ #ifdef _WIN64 if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 32, &rtlUserProcParamsAddress, sizeof(PVOID), NULL)) #else if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 0x10, &rtlUserProcParamsAddress, sizeof(PVOID), NULL)) #endif { ////printf("Could not read the address of ProcessParameters!\n"); PyErr_SetFromWindowsErr(0); CloseHandle(hProcess); return NULL; } /* read the CommandLine UNICODE_STRING structure */ #ifdef _WIN64 if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 112, &commandLine, sizeof(commandLine), NULL)) #else if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 0x40, &commandLine, sizeof(commandLine), NULL)) #endif { ////printf("Could not read CommandLine!\n"); CloseHandle(hProcess); PyErr_SetFromWindowsErr(0); return NULL; } /* allocate memory to hold the command line */ commandLineContents = (WCHAR *)malloc(commandLine.Length+1); /* read the command line */ if (!ReadProcessMemory(hProcess, commandLine.Buffer, commandLineContents, commandLine.Length, NULL)) { ////printf("Could not read the command line string!\n"); CloseHandle(hProcess); PyErr_SetFromWindowsErr(0); free(commandLineContents); return NULL; } /* print the commandline */ ////printf("%.*S\n", commandLine.Length / 2, commandLineContents); // null-terminate the string to prevent wcslen from returning incorrect length // the length specifier is in characters, but commandLine.Length is in bytes commandLineContents[(commandLine.Length/sizeof(WCHAR))] = '\0'; // attemempt tp parse the command line using Win32 API, fall back on string // cmdline version otherwise szArglist = CommandLineToArgvW(commandLineContents, &nArgs); if (NULL == szArglist) { // failed to parse arglist // encode as a UTF8 Python string object from WCHAR string arg_from_wchar = PyUnicode_FromWideChar(commandLineContents, commandLine.Length / 2); #if PY_MAJOR_VERSION >= 3 argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar)); #else argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar)); #endif } else { // arglist parsed as array of UNICODE_STRING, so convert each to Python // string object and add to arg list argList = Py_BuildValue("[]"); for(i=0; i<nArgs; i++) { ////printf("%d: %.*S (%d characters)\n", i, wcslen(szArglist[i]), // szArglist[i], wcslen(szArglist[i])); arg_from_wchar = PyUnicode_FromWideChar(szArglist[i], wcslen(szArglist[i]) ); #if PY_MAJOR_VERSION >= 3 arg = PyUnicode_FromObject(arg_from_wchar); #else arg = PyUnicode_AsUTF8String(arg_from_wchar); #endif Py_XDECREF(arg_from_wchar); PyList_Append(argList, arg); Py_XDECREF(arg); } } LocalFree(szArglist); free(commandLineContents); CloseHandle(hProcess); return argList; }
static ULONG64 GetHeapAddress(ULONG index) { const bool isTarget64 = IsTarget64(); ULONG64 address = GetPebAddress(); ULONG cb; ULONG32 numberOfHeaps; if (isTarget64) { if (GetFieldValue(address, "ntdll!_PEB", "NumberOfHeaps", numberOfHeaps) != 0) { dprintf("read NumberOfHeaps failed\n"); return 0; } } else { if (!READMEMORY(address + 0x88, numberOfHeaps)) { dprintf("read NumberOfHeaps failed\n"); return 0; } } if (index >= numberOfHeaps) { return 0; } ULONG64 processHeaps; if (isTarget64) { if (GetFieldValue(address, "ntdll!_PEB", "ProcessHeaps", processHeaps) != 0) { dprintf("read ProcessHeaps failed\n"); return 0; } } else { ULONG32 value; if (!READMEMORY(address + 0x90, value)) { dprintf("read ProcessHeaps failed\n"); return 0; } processHeaps = value; } ULONG64 heap; if (isTarget64) { if (!READMEMORY((ULONG64)processHeaps + 8 * index, heap)) { dprintf("read heap address failed\n"); return 0; } } else { ULONG32 value; if (!READMEMORY((ULONG64)processHeaps + 4 * index, value)) { dprintf("read heap address failed\n"); return 0; } heap = value; } return heap; }