Beispiel #1
0
bool CopyToUser(void* userdst_ptr, const void* ksrc_ptr, size_t count)
{
	uintptr_t userdst = (uintptr_t) userdst_ptr;
	uintptr_t ksrc = (uintptr_t) ksrc_ptr;
	bool result = true;
	Process* process = CurrentProcess();
	assert(IsInProcessAddressSpace(process));
	kthread_mutex_lock(&process->segment_lock);
	while ( count )
	{
		struct segment* segment = FindSegment(process, userdst);
		if ( !segment || !(segment->prot & PROT_WRITE) )
		{
			errno = EFAULT;
			result = false;
			break;
		}
		size_t amount = count;
		size_t segment_available = segment->addr + segment->size - userdst;
		if ( segment_available < amount )
			amount = segment_available;
		memcpy((void*) userdst, (const void*) ksrc, amount);
		userdst += amount;
		ksrc += amount;
		count -= amount;
	}
	kthread_mutex_unlock(&process->segment_lock);
	return result;
}
Beispiel #2
0
// Get process ID via name (must pass name as lowercase)
DWORD Injector::GetProcessIdByName(const std::tstring& Name)
{
	// Grab a new snapshot of the process
	EnsureCloseHandle Snap(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0));
	if (Snap == INVALID_HANDLE_VALUE)
		throw std::runtime_error("Could not get process snapshot.");

	// Search for process
	PROCESSENTRY32 ProcEntry = { sizeof(ProcEntry) };
	bool Found = false;
	BOOL MoreMods = Process32First(Snap, &ProcEntry);
	for (; MoreMods; MoreMods = Process32Next(Snap, &ProcEntry)) 
	{
		std::tstring CurrentProcess(ProcEntry.szExeFile);
        CurrentProcess = toLower(CurrentProcess);
		Found = (CurrentProcess == Name);
		if (Found) break;
	}

	// Check process was found
	if (!Found)
		throw std::runtime_error("Could not find process.");

	// Return PID
	return ProcEntry.th32ProcessID;
}
Beispiel #3
0
/*******************************************************************************
* Function Name  : main.
* Description    : Main routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
int main(void)
{
#ifdef DEBUG
    debug();
#endif

    Set_System();
    Set_USBClock();
    USB_Config();
    USB_Init();
    InitialIO();
    InitialADC();

#ifdef  JOYSTICK
    SSD1303_Init();

    InitialSSD1306_controller();
#endif

    InitialProcTask();

    //WaitConfig();

    InitialDevice(&dev,&SSD1303_Prop,SongSmall5_DrawChar);

    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
    SysTick_SetReload(72000000/20);
    SysTick_CounterCmd(SysTick_Counter_Enable);
    SysTick_ITConfig(ENABLE);

    CurrentProcess = JoystickProcess;
    CurrentSystick = JoystickSystick;
    JoystickUIInit();
    void  HidProcess(void);
    while (1)
    {
        HidProcess();
        continue;
        static u8 lastCamOn = 0;
        if(lastCamOn != bCameraOn) {
            if(bCameraOn) {
                CurrentProcess = TetrisProcess;
                CurrentSystick = TetrisSystick;
                TetrisUIInit();
            } else {
                CurrentProcess = JoystickProcess;
                CurrentSystick = JoystickSystick;
                JoystickUIInit();
            }
        }
        lastCamOn = bCameraOn;
        CurrentProcess();
    }
}
Beispiel #4
0
// NOTE: No overflow can happen here because the user can't make an infinitely
//       long string spanning the entire address space because the user can't
//       control the entire address space.
char* GetStringFromUser(const char* usersrc_str)
{
	uintptr_t usersrc = (uintptr_t) usersrc_str;
	size_t result_length = 0;
	Process* process = CurrentProcess();
	assert(IsInProcessAddressSpace(process));

	kthread_mutex_lock(&process->segment_lock);
	bool done = false;
	while ( !done )
	{
		uintptr_t current_at = usersrc + result_length;
		struct segment* segment = FindSegment(process, current_at);
		if ( !segment || !(segment->prot & PROT_READ) )
		{
			kthread_mutex_unlock(&process->segment_lock);
			return errno = EFAULT, (char*) NULL;
		}
		size_t segment_available = segment->addr + segment->size - current_at;
		volatile const char* str = (volatile const char*) current_at;
		size_t length = 0;
		for ( ; length < segment_available; length++ )
		{
			char c = str[length];
			if ( c == '\0' )
			{
				done = true;
				break;
			}
		}
		result_length += length;
	}

	char* result = new char[result_length + 1];
	if ( !result )
	{
		kthread_mutex_unlock(&process->segment_lock);
		return (char*) NULL;
	}

	memcpy(result, (const char*) usersrc, result_length);
	result[result_length] = '\0';

	// We have transferred a bunch of bytes from user-space and appended a zero
	// byte. This is a string. If no concurrent threads were modifying the
	// memory, this is the intended string. If the memory was modified, we got
	// potential garbage followed by a NUL byte. This is a string, but probably
	// not what was intended. If the garbage itself had a premature unexpected
	// NUL byte, that's okay, the garbage string just got truncated.

	kthread_mutex_unlock(&process->segment_lock);
	return result;
}
void UserCrashHandler(struct interrupt_context* intctx)
{
	Scheduler::SaveInterruptedContext(intctx, &CurrentThread()->registers);

	// Execute this crash handler with preemption on.
	Interrupt::Enable();

	// TODO: Also send signals for other types of user-space crashes.
	if ( intctx->int_no == 14 /* Page fault */ )
	{
		struct sigaction* act = &CurrentProcess()->signal_actions[SIGSEGV];
		kthread_mutex_lock(&CurrentProcess()->signal_lock);
		bool handled = act->sa_handler != SIG_DFL && act->sa_handler != SIG_IGN;
		if ( handled )
			CurrentThread()->DeliverSignalUnlocked(SIGSEGV);
		kthread_mutex_unlock(&CurrentProcess()->signal_lock);
		if ( handled )
		{
			assert(Interrupt::IsEnabled());
			return Signal::DispatchHandler(intctx, NULL);
		}
	}

	// Issue a diagnostic message to the kernel log concerning the crash.
	Log::PrintF("The current process (pid %ji `%s') crashed and was terminated:\n",
	            (intmax_t) CurrentProcess()->pid, CurrentProcess()->program_image_path);
	Log::PrintF("%s exception at ip=0x%zx (cr2=0x%zx, err_code=0x%zx)\n",
	            ExceptionName(intctx), ExceptionLocation(intctx), intctx->cr2,
	            intctx->err_code);

	// Exit the process with the right error code.
	// TODO: Send a SIGINT, SIGBUS, or whatever instead.
	CurrentProcess()->ExitThroughSignal(SIGSEGV);

	// Deliver signals to this thread so it can exit correctly.
	assert(Interrupt::IsEnabled());
	Signal::DispatchHandler(intctx, NULL);
}
Beispiel #6
0
extern unsigned long __GetSystemWideUniqueTID(void)
{
    return(CurrentProcess());
}
Beispiel #7
0
int sys_ppoll(struct pollfd* user_fds, size_t nfds,
              const struct timespec* user_timeout_ts,
              const sigset_t* user_sigmask)
{
	ioctx_t ctx; SetupKernelIOCtx(&ctx);

	struct timespec timeout_ts;
	if ( !FetchTimespec(&timeout_ts, user_timeout_ts) )
		return -1;

	if ( user_sigmask )
		return errno = ENOSYS, -1;

	struct pollfd* fds = CopyFdsFromUser(user_fds, nfds);
	if ( !fds ) { return -1; }

	PollNode* nodes = new PollNode[nfds];
	if ( !nodes ) { delete[] fds; return -1; }

	Process* process = CurrentProcess();

	kthread_mutex_t wakeup_mutex = KTHREAD_MUTEX_INITIALIZER;
	kthread_cond_t wakeup_cond = KTHREAD_COND_INITIALIZER;

	kthread_mutex_lock(&wakeup_mutex);

	int ret = -1;
	bool self_woken = false;
	bool remote_woken = false;
	bool unexpected_error = false;

	Timer timer;
	struct poll_timeout pts;
	if ( timespec_le(timespec_make(0, 1), timeout_ts) )
	{
		timer.Attach(Time::GetClock(CLOCK_MONOTONIC));
		struct itimerspec its;
		its.it_interval = timespec_nul();
		its.it_value = timeout_ts;
		pts.wake_mutex = &wakeup_mutex;
		pts.wake_cond = &wakeup_cond;
		pts.woken = &remote_woken;
		timer.Set(&its, NULL, 0, poll_timeout_callback, &pts);
	}

	size_t reqs;
	for ( reqs = 0; !unexpected_error && reqs < nfds; )
	{
		PollNode* node = nodes + reqs;
		if ( fds[reqs].fd < 0 )
		{
			fds[reqs].revents = POLLNVAL;
			// TODO: Should we set POLLNVAL in node->revents too? Should this
			// system call ignore this error and keep polling, or return to
			// user-space immediately? What if conditions are already true on
			// some of the file descriptors (those we have processed so far?)?
			node->revents = 0;
			reqs++;
			continue;
		}
		Ref<Descriptor> desc = process->GetDescriptor(fds[reqs].fd);
		if ( !desc ) { self_woken = unexpected_error = true; break; }
		node->events = fds[reqs].events | POLL__ONLY_REVENTS;
		node->revents = 0;
		node->wake_mutex = &wakeup_mutex;
		node->wake_cond = &wakeup_cond;
		node->woken = &remote_woken;
		reqs++;
		// TODO: How should errors be handled?
		if ( desc->poll(&ctx, node) == 0 )
			self_woken = true;
		else if ( errno == EAGAIN )
			errno = 0;
		else
			unexpected_error = self_woken = true;
	}

	if ( timeout_ts.tv_sec == 0 && timeout_ts.tv_nsec == 0 )
		self_woken = true;

	while ( !(self_woken || remote_woken) )
	{
		if ( !kthread_cond_wait_signal(&wakeup_cond, &wakeup_mutex) )
			errno = -EINTR,
			self_woken = true;
	}

	kthread_mutex_unlock(&wakeup_mutex);

	for ( size_t i = 0; i < reqs; i++ )
		if ( 0 <= fds[i].fd )
			nodes[i].Cancel();

	if ( timespec_le(timespec_make(0, 1), timeout_ts) )
	{
		timer.Cancel();
		timer.Detach();
	}

	if ( !unexpected_error )
	{
		int num_events = 0;
		for ( size_t i = 0; i < reqs; i++ )
		{
			if ( fds[i].fd < -1 )
				continue;
			if ( (fds[i].revents = nodes[i].revents) )
				num_events++;
		}

		if ( CopyFdsToUser(user_fds, fds, nfds) )
			ret = num_events;
	}

	delete[] nodes;
	delete[] fds;
	return ret;
}