def add_tracked_pid(self, pid): #Initiate driver's state and communication mecanisms BytesReturned = DWORD(0) pid = DWORD(pid) success = KERNEL32.DeviceIoControl(self.hdevice, IOCTL_ADD_TRACKED, ctypes.byref(pid), ctypes.sizeof(pid), NULL, 0, ctypes.byref(BytesReturned), 0) if not (success): self.log.error("DeviceIoControl failed") raise UnpackerException("DeviceIoControl failed")
def run(self): """Run capturing of usage info. @return: operation status. """ meminfo = MEMORYSTATUSEX() meminfo.dwLength = sizeof(MEMORYSTATUSEX) phquery = PVOID() PDH.PdhOpenQuery(None, None, byref(phquery)) buflen = DWORD() buflen.value = 0 PDH.PdhExpandWildCardPathA(None, "\\Processor(*)\\% Processor Time", None, byref(buflen), 0) buf = create_string_buffer(buflen.value + 1) PDH.PdhExpandWildCardPathA(None, "\\Processor(*)\\% Processor Time", buf, byref(buflen), 0) counters = buf.raw.rstrip(b"\x00").split(b"\x00") counter_handles = [] for counter in counters: if b"_Total" in counter: continue phcounter = PVOID() PDH.PdhAddCounterA(phquery, counter, None, byref(phcounter)) counter_handles.append(phcounter) nf = NetlogFile() nf.init("aux/usage.log") PDH.PdhCollectQueryData(phquery) while self.do_run: time.sleep(2) PDH.PdhCollectQueryData(phquery) usage = PDH_FMT_COUNTERVALUE() bigfloat = 0.0 for counter_handle in counter_handles: PDH.PdhGetFormattedCounterValue(counter_handle, PDH_FMT_DOUBLE, None, byref(usage)) if usage.doubleValue > bigfloat: bigfloat = usage.doubleValue KERNEL32.GlobalMemoryStatusEx(byref(meminfo)) usagedata = b"%d %d\n" % (meminfo.dwMemoryLoad, round(bigfloat)) nf.send(usagedata) for counter_handle in counter_handles: PDH.PdhRemoveCounter(counter_handle) PDH.PdhCloseQuery(phquery) nf.close() return True
def run(self): """Run capturing of usage info. @return: operation status. """ meminfo = MEMORYSTATUSEX() meminfo.dwLength = sizeof(MEMORYSTATUSEX) phquery = PVOID() PDH.PdhOpenQuery(None, None, byref(phquery)) buflen = DWORD() buflen.value = 0 PDH.PdhExpandWildCardPathA(None, "\\Processor(*)\\% Processor Time", None, byref(buflen), 0) buf = create_string_buffer(buflen.value + 1) PDH.PdhExpandWildCardPathA(None, "\\Processor(*)\\% Processor Time", buf, byref(buflen), 0) counters = buf.raw.rstrip("\x00").split("\x00") counter_handles = [] for counter in counters: if "_Total" in counter: continue phcounter = PVOID() PDH.PdhAddCounterA(phquery, counter, None, byref(phcounter)) counter_handles.append(phcounter) nf = NetlogFile("aux/usage.log") PDH.PdhCollectQueryData(phquery) while self.do_run: time.sleep(2) PDH.PdhCollectQueryData(phquery) usage = PDH_FMT_COUNTERVALUE() bigfloat = 0.0 for counter_handle in counter_handles: PDH.PdhGetFormattedCounterValue(counter_handle, PDH_FMT_DOUBLE, None, byref(usage)) if usage.doubleValue > bigfloat: bigfloat = usage.doubleValue KERNEL32.GlobalMemoryStatusEx(byref(meminfo)) usagedata = "%d %d\n" % (meminfo.dwMemoryLoad, round(bigfloat)) nf.sock.sendall(usagedata) for counter_handle in counter_handles: PDH.PdhRemoveCounter(counter_handle) PDH.PdhCloseQuery(phquery) nf.close() return True
def run(self, waiting_time): # Open driver device self.hdevice = KERNEL32.CreateFileA(self.device_name, GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, None) if self.hdevice == INVALID_HANDLE_VALUE: self.log.error("CreateFileA failed with error : 0x%x" % KERNEL32.GetLastError()) quit() self.log.info("Driver device file opened, handle = %x" % self.hdevice) #todo : build command line self.process = Process(self.command_line, self.log) self.process.create_suspended() self.pre_run() self.log.info("Target process handle value is 0x%x" % self.process.process_handle) self.thread_running = True thread = Thread(target=self.pipe_reader_thread, args=()) #Create an unpack event which will be signaled when the self.hUnpackEvent = KERNEL32.CreateEventA(NULL, 0, 0, "DaEvent") self.UserlandNotidyEvent = KERNEL32.CreateEventA( NULL, 0, 0, "UserlandNotidyEvent") #Struct sent to the driver MyPidStruct = PID_STRUCT() MyPidStruct.do_log = self.kernel_log MyPidStruct.RWEPolicy = self.rwe_policy MyPidStruct.InitialNXState = self.initial_nx_state MyPidStruct.UserlandNotidyEvent = self.UserlandNotidyEvent MyPidStruct.TargetProcessHandle = self.process.process_handle #Initiate driver's state and communication mecanisms BytesReturned = DWORD(0) success = KERNEL32.DeviceIoControl(self.hdevice, IOCTL_SETUP_STUFF, ctypes.byref(MyPidStruct), ctypes.sizeof(MyPidStruct), NULL, 0, ctypes.byref(BytesReturned), 0) if not (success): self.log.error("DeviceIoControl failed") raise UnpackerException("DeviceIoControl failed") thread.start() #Resume main process thtread self.process.resume() self.log.info("Main thread resumed") #Wait for unpacking to terminate r = KERNEL32.WaitForSingleObject(self.hUnpackEvent, self.max_unpack_time) if (r == WAIT_ABANDONED): self.log.error("Wait abandoned, something went wrong") raise UnpackerException("Wait abandoned, something went wrong") if (r == WAIT_TIMEOUT): self.log.info("Wait timed out") self.log.info("Thread suspended") if (r == WAIT_OBJECT_0): self.log.info("Event signaled") BytesReturned = DWORD(0) success = KERNEL32.DeviceIoControl(self.hdevice, IOCTL_SUSPEND_TRACKED, NULL, 0, NULL, 0, ctypes.byref(BytesReturned), 0) if not (success): self.log.error("DeviceIoControl failed") raise UnpackerException("DeviceIoControl failed") self.thread_running = False result = self.post_treatment() BytesReturned = DWORD(0) success = KERNEL32.DeviceIoControl(self.hdevice, IOCTL_UNTRACK_AND_RESUME_PROCESSES, NULL, 0, NULL, 0, ctypes.byref(BytesReturned), 0) if not (success): self.log.error("DeviceIoControl failed") raise UnpackerException("DeviceIoControl failed") BytesReturned = DWORD(0) success = KERNEL32.DeviceIoControl(self.hdevice, IOCTL_CLEANUP, NULL, 0, NULL, 0, ctypes.byref(BytesReturned), 0) if not (success): self.log.error("DeviceIoControl failed") raise UnpackerException("DeviceIoControl failed") KERNEL32.CloseHandle(self.hdevice) KERNEL32.CloseHandle(self.UserlandNotidyEvent) self.process.terminate() KERNEL32.ExitProcess(0)
def pipe_reader_thread(self): evt_header = EVENT_HEADER() nbRead = DWORD(0) while (self.thread_running): valid_object = True #Wait for the driver to signal an event is ready for retrieval r = KERNEL32.WaitForSingleObject(self.UserlandNotidyEvent, INFINITE) if (r == WAIT_OBJECT_0): #An event has arrived, request it to the driver ReceiveBuffer = ctypes.create_string_buffer(1024) BytesReturned = DWORD(0) success = KERNEL32.DeviceIoControl( self.hdevice, IOCTL_RETRIEVE_EXCEPTION, NULL, 0, ctypes.byref(ReceiveBuffer), ctypes.sizeof(ReceiveBuffer), ctypes.byref(BytesReturned), 0) if not (success): self.log.error("DeviceIoControl failed") raise UnpackerException("DeviceIoControl failed") header_size = ctypes.sizeof(EVENT_HEADER) #Ensure there is a header if (BytesReturned.value < header_size): self.log.error( "Did not receive enough data from driver (%d bytes)" % BytesReturned.value) continue #Copy the data in a EVENT_HEADER object ctypes.memmove(ctypes.addressof(evt_header), ReceiveBuffer[0:header_size], header_size) #Ensure it is a known event if not (Events.has_key(evt_header.event_type)): self.log.error("Received unknown event with type : %d" % evt_header.event_type) continue #Ensure the object fits in the buffer n_remaining_bytes = BytesReturned.value - header_size event_class = Events[evt_header.event_type] if (n_remaining_bytes != ctypes.sizeof(event_class)): self.log.error( "Wrong event size. Received %d bytes, expected %d bytes" % (n_remaining_bytes, ctypes.sizeof(event_class))) continue event_obj = event_class() # "cast" the buffer in the appropriate event class ctypes.memmove(ctypes.addressof(event_obj), ReceiveBuffer[header_size:], ctypes.sizeof(event_class)) #call the user defined event handler result = self.event_handler(evt_header.event_type, event_obj) if (result == 0): self.stop() return