Esempio n. 1
0
/* Attach to a running process.
   PID is the process ID to attach to, specified by the user
   or a higher layer.  */
static int
win32_attach (unsigned long pid)
{
  HANDLE h;
  winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
  DWORD err;
#ifdef _WIN32_WCE
  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
#else
  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
#endif
  DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);

  h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
  if (h != NULL)
    {
      if (DebugActiveProcess (pid))
	{
	  if (DebugSetProcessKillOnExit != NULL)
	    DebugSetProcessKillOnExit (FALSE);

	  /* win32_wait needs to know we're attaching.  */
	  attaching = 1;
	  do_initial_child_stuff (h, pid, 1);
	  return 0;
	}

      CloseHandle (h);
    }

  err = GetLastError ();
  error ("Attach to process failed (error %d): %s\n",
	 (int) err, strwinerror (err));
}
Esempio n. 2
0
static int __open_proc (RIOW32Dbg *dbg, bool attach) {
	DEBUG_EVENT de;
	int ret = -1;
	HANDLE h_proc = OpenProcess (PROCESS_ALL_ACCESS, FALSE, dbg->pid);

	if (!h_proc) {
		r_sys_perror ("__open_proc/OpenProcess");
		goto att_exit;
	}
	if (attach) {
		/* Attach to the process */
		if (!DebugActiveProcess(dbg->pid)) {
			r_sys_perror ("__open_proc/DebugActiveProcess");
			goto att_exit;
		}
		/* catch create process event */
		if (!WaitForDebugEvent (&de, 10000)) {
			r_sys_perror ("__open_proc/WaitForDebugEvent");
			goto att_exit;
		}
		if (de.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) {
			eprintf ("exception code 0x%04x\n", (ut32)de.dwDebugEventCode);
			goto att_exit;
		}
		dbg->winbase = (ut64)de.u.CreateProcessInfo.lpBaseOfImage;
	}
	dbg->pi.hProcess = h_proc;
	dbg->tid = __w32_first_thread (dbg->pid);
	ret = dbg->pid;
att_exit:
	if (ret == -1 && h_proc) {
		CloseHandle (h_proc);
	}
	return ret;
}
Esempio n. 3
0
// return thread id
static int r_debug_native_attach (RDebug *dbg, int pid) {
#if 0
	if (!dbg || pid == dbg->pid)
		return dbg->tid;
#endif
#if __linux__
	return linux_attach (dbg, pid);
#elif __WINDOWS__ && !__CYGWIN__
	int ret;
	HANDLE process = w32_open_process (PROCESS_ALL_ACCESS, FALSE, pid);
	if (process != (HANDLE)NULL && DebugActiveProcess (pid)) {
		ret = w32_first_thread (pid);
	} else {
		ret = -1;
	}
	ret = w32_first_thread (pid);
	CloseHandle (process);
	return ret;
#elif __CYGWIN__
	#warning "r_debug_native_attach not supported on this platform"
	return -1;
#elif __APPLE__
	return xnu_attach (dbg, pid);
#elif __KFBSD__
	if (ptrace (PT_ATTACH, pid, 0, 0) != -1) perror ("ptrace (PT_ATTACH)");
	return pid;
#else
	int ret = ptrace (PTRACE_ATTACH, pid, 0, 0);
	if (ret != -1) {
		perror ("ptrace (PT_ATTACH)");
	}
	return pid;
#endif
}
Esempio n. 4
0
extern "C" int __declspec(dllexport) AttachPid(DWORD dwVer_bose,DWORD dwPid,CP_HANDLER cp_handler,LOAD_DLL_HANDLER ld_handler,BP_HANDLER bp_handler,CT_HANDLER ct_handler,SS_HANDLER ss_handler,UNLOAD_DLL_HANDLER uld_handler)
{
	HANDLE hProcess;
			
	dwVerbose = dwVer_bose;
	hProcess = OpenProcess(PROCESS_ALL_ACCESS,0,dwPid);
	if (hProcess == 0)
	{
		Log("OpenProcess Failed:%d:%d",dwPid,GetLastError());
		return 0;
	}
	if(!DebugActiveProcess(dwPid))
	{
		Log("DebugActiveProcess Failed:%d:%d",dwPid,GetLastError());
		return 0;
	}
		
	Log("Attached to PID:%d",dwPid);

	load_dll_handler = ld_handler;
	create_process_handler = cp_handler;
	breakpoint_handler = bp_handler;
	createthread_handler = ct_handler;
	singlestep_handler = ss_handler;
	unload_dll_handler = uld_handler;

	EnterDebugging(dwPid);
	// call enter debugging n other init routines....
	return 1;
}
Esempio n. 5
0
static void doChild(int argc, char **argv)
{
    struct child_blackbox blackbox;
    const char *blackbox_file;
    HANDLE parent;
    DWORD ppid;
    BOOL debug;
    BOOL ret;

    blackbox_file = argv[4];
    sscanf(argv[3], "%08x", &ppid);

    parent = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ppid);
    child_ok(!!parent, "OpenProcess failed, last error %#x.\n", GetLastError());

    ret = pCheckRemoteDebuggerPresent(parent, &debug);
    child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
    child_ok(!debug, "Expected debug == 0, got %#x.\n", debug);

    ret = DebugActiveProcess(ppid);
    child_ok(ret, "DebugActiveProcess failed, last error %#x.\n", GetLastError());

    ret = pCheckRemoteDebuggerPresent(parent, &debug);
    child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
    child_ok(debug, "Expected debug != 0, got %#x.\n", debug);

    ret = pDebugActiveProcessStop(ppid);
    child_ok(ret, "DebugActiveProcessStop failed, last error %#x.\n", GetLastError());

    ret = pCheckRemoteDebuggerPresent(parent, &debug);
    child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
    child_ok(!debug, "Expected debug == 0, got %#x.\n", debug);

    ret = CloseHandle(parent);
    child_ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());

    ret = pIsDebuggerPresent();
    child_ok(ret, "Expected ret != 0, got %#x.\n", ret);
    ret = pCheckRemoteDebuggerPresent(GetCurrentProcess(), &debug);
    child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
    child_ok(debug, "Expected debug != 0, got %#x.\n", debug);

    if (pNtCurrentTeb)
    {
        pNtCurrentTeb()->Peb->BeingDebugged = FALSE;

        ret = pIsDebuggerPresent();
        child_ok(!ret, "Expected ret != 0, got %#x.\n", ret);
        ret = pCheckRemoteDebuggerPresent(GetCurrentProcess(), &debug);
        child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
        child_ok(debug, "Expected debug != 0, got %#x.\n", debug);

        pNtCurrentTeb()->Peb->BeingDebugged = TRUE;
    }

    blackbox.failures = child_failures;
    save_blackbox(blackbox_file, &blackbox, sizeof(blackbox));
}
Esempio n. 6
0
BOOL My_DebugActiveProcess()
{
	DWORD dwProcessId=NULL;
	BOOL returnVal_Real = NULL;
	BOOL returnVal_Intercepted = NULL;

	DWORD error_Real = 0;
	DWORD error_Intercepted = 0;
	__try{
	disableInterception();
	returnVal_Real = DebugActiveProcess (dwProcessId);
	error_Real = GetLastError();
	enableInterception();
	returnVal_Intercepted = DebugActiveProcess (dwProcessId);
	error_Intercepted = GetLastError();
	}__except(puts("in filter"), 1){puts("exception caught");}
	return ((returnVal_Real == returnVal_Intercepted) && (error_Real == error_Intercepted));
}
Esempio n. 7
0
File: debug.c Progetto: Disar/Kha
HL_API bool hl_debug_start( int pid ) {
#	if defined(HL_WIN)
	last_pid = -1;
	return (bool)DebugActiveProcess(pid);
#	elif defined(USE_PTRACE)
	return ptrace(PTRACE_ATTACH,pid,0,0) >= 0;
#	else
	return false;
#	endif
}
Esempio n. 8
0
void CDebugger::Attach(DWORD dwProcessId) {
    cout << "[+] Debugger attach to pid:" << dwProcessId << endl;

    m_bActive = DebugActiveProcess(dwProcessId);
    if (m_bActive) {
        bool bSuccess = DebugSetProcessKillOnExit(m_bKillOnExit);
        DebugLoop();
    } else {
        cout << "[-] Attach failed!" << endl;
    }
}
Esempio n. 9
0
void WinDebugger::attach(ProcessId pid) {
    if (process_ != INVALID_HANDLE_VALUE) {
        kill();
    }
    process_ = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
    BOOL ret = DebugActiveProcess(pid);
    if (!ret) {
        std::cerr << "error: attach: " << GetLastError() << std::endl;
        abort();
    }
}
Esempio n. 10
0
static void debugThread(void *arg)
{
    DWORD dwProcessId = (DWORD)(UINT_PTR)arg;

    // attach debuggee
    if (!DebugActiveProcess(dwProcessId)) {
        ErrorMessageBox("DebugActiveProcess: %s", LastErrorMessage());
        return;
    }

    setDumpCallback(appendText);

    SetSymOptions(debug_options.debug_flag);

    DebugMainLoop(&debug_options);
}
Esempio n. 11
0
	void attach(int PID)
	{
		h_process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);

		if (DebugActiveProcess(PID))
		{
			debugger_active = true;
			pid = PID;
			std::cout << "[*] Success DebugActiveProcess()." << std::endl;
		}
		else
		{
			std::cout << "[!] Unable to attach to the process." << std::endl;
			std::cout << "[!] Error Code : " << GetLastError() << std::endl;
		}
	}
Esempio n. 12
0
/******************************************************************
 *		dbg_attach_debuggee
 *
 * Sets the debuggee to <pid>
 * cofe instructs winedbg what to do when first exception is received
 * (break=FALSE, continue=TRUE)
 * wfe is set to TRUE if dbg_attach_debuggee should also proceed with all debug events
 * until the first exception is received (aka: attach to an already running process)
 */
BOOL dbg_attach_debuggee(DWORD pid, BOOL cofe)
{
    if (!(dbg_curr_process = dbg_add_process(&be_process_active_io, pid, 0))) return FALSE;

    if (!DebugActiveProcess(pid))
    {
        dbg_printf("Can't attach process %04x: error %u\n", pid, GetLastError());
        dbg_del_process(dbg_curr_process);
        return FALSE;
    }
    dbg_curr_process->continue_on_first_exception = cofe;

    SetEnvironmentVariableA("DBGHELP_NOLIVE", NULL);

    dbg_curr_process->active_debuggee = TRUE;
    return TRUE;
}
Esempio n. 13
0
Target::Process *Process::Attach(ProcessId pid) {
  if (pid <= 0)
    return nullptr;

  BOOL result;
  HANDLE handle, threadHandle;
  ThreadId tid;
  ErrorCode error;

  auto process = new Target::Process;

  result = DebugActiveProcess(pid);
  if (!result)
    goto fail;

  handle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
  if (!handle)
    goto fail;

  tid = GetFirstThreadIdForProcess(pid);
  if (tid == kAnyThreadId)
    goto proc_fail;

  threadHandle = OpenThread(THREAD_ALL_ACCESS, false, tid);
  if (!threadHandle)
    goto proc_fail;

  error =
      process->initialize(pid, handle, tid, threadHandle, kFlagAttachedProcess);
  if (error != kSuccess)
    goto init_fail;

  return process;

init_fail:
  process->detach();
  CloseHandle(threadHandle);

proc_fail:
  CloseHandle(handle);

fail:
  delete process;
  return nullptr;
}
Esempio n. 14
0
void AttachConHost(DWORD nConHostPID)
{
	DWORD  nErrCode = 0;
	HANDLE hConHost = GetProcessHandleForDebug(nConHostPID, &nErrCode);

	if (!hConHost)
	{
		_printf("Opening ConHost process handle failed, Code=%u\n", nErrCode);
	}
	else if (!DebugActiveProcess(nConHostPID))
	{
		nErrCode = GetLastError();
		_printf("Attaching to ConHost process handle failed, Code=%u\n", nErrCode);
	}

	if (!nErrCode)
	{
		//TODO: Запустить ConEmuC (требуемой битности) под админом
	}
}
Esempio n. 15
0
BOOL WindowsDebugger::debugger_attach( int nProcessId, BOOL bPause )
{
	if( this->windowsdebugger_token_privilege( SE_DEBUG_NAME, TRUE ) 
		== FALSE ) {
			return FALSE;
	}

	this->bPauseOnAttach = bPause;

	if( DebugActiveProcess( nProcessId ) == FALSE ) {
		WinError::winerror_print_last_error( __FUNCTION__ );
		dprintflvl( 2, "Unable to debug: %d", nProcessId );
		return FALSE;
	}

	this->bAttachedToProcess = TRUE;
	this->nProcessId = nProcessId;

	return TRUE;
}
Esempio n. 16
0
BOOL
CUseDebugger::DebugAttachedProcess()
{
    m_pUI->ShowInfo("Please Enter the PID:\r\n");
    system("taskmgr");

    //get pid
    int argc;
    int pargv[MAXBYTE];
    m_pUI->GetInput(&argc, pargv, g_szBuf, MAXBUF);

    DWORD dwPID = strtoul(g_szBuf, NULL, 10);
    assert(dwPID != 0 && dwPID != ULONG_MAX);

    if (DebugActiveProcess(dwPID))
    {
        this->DebugProcess();
        return TRUE;
    }
    
    return FALSE;
}
int main(int argc,char *argv[]) 
{
	DWORD dwPID;
	
	if(argc!=2)
	{
		printf("Usage:%s pid\n",argv[0]);
		return 1;
	}
	
	//Attach Process
	dwPID=atoi(argv[1]);
	if(!DebugActiveProcess(dwPID))
	{
		printf("DebugActiveProcess(%d) failed!\n","Error code =%d\n",dwPID,GetLastError());
		return 1;
	}
	
	//debug loop
	DebugLoop();
	return 0;
}
Esempio n. 18
0
BOOL CDbgHook::DbgAttatch(DWORD dwPid)
{
	CProcessChecker pck;

	/*
	pck.SetData(dwPid);
	if (!pck.IsProcess())
	return FALSE;
	*/
	if (!DebugActiveProcess(dwPid))
		return FALSE;

	if (!WaitForDebugEvent(&m_de, INFINITE))
		return FALSE;

	if (m_de.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT)
		return FALSE;

	memcpy(&m_cpdi, &m_de.u.CreateProcessInfo, sizeof(CREATE_PROCESS_DEBUG_INFO));

	return TRUE;
}
Esempio n. 19
0
EXPORT
BOOL CreateProcessA(LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation){
	pid_t pid = vfork();
	//printf("Creating process %s %s\n", lpApplicationName, lpCommandLine);
	if(pid == 0){
		char commandline[256];
		strncpy(commandline, lpCommandLine, 255);
		commandline[255] = 0;
//		ptrace(PT_TRACE_ME, 0, 0, 0);
		// parse command line;
		int i=0;
		char *p = strchr(commandline, ' ');
		char *q = commandline;
		char *argv[16];
		while(p){
			*p = 0;
			argv[i++] = q;
			fflush(stdout);
			q = p + 1;
			p = strchr(commandline, ' ');
		}
		argv[i] = q;
		argv[i+1] = 0;
		//printf("Execing %s %s %s", argv[0], argv[1], argv[2]);
		fflush(stdout);
		execv(argv[0], argv);
		perror("Failed to execv!"); 
	} else {
		DebugActiveProcess(pid);
//		ptrace(PT_ATTACH, pid, 0, 0);
//		ptrace(PT_DETACH, pid, 0, 0);
		lpProcessInformation->dwProcessId = pid;
		lpProcessInformation->hProcess = pid;
	}
	return 1;
}
Esempio n. 20
0
int main(int argc, char* argv[])
{
    DWORD dwPID;

    if( argc != 2 )
    {
        printf("\nUSAGE : hookdbg.exe <pid>\n");
        return 1;
    }

    // Attach Process
    dwPID = atoi(argv[1]);
    if( !DebugActiveProcess(dwPID) )
    {
        printf("DebugActiveProcess(%d) failed!!!\n"
               "Error Code = %d\n", dwPID, GetLastError());
        return 1;
    }

    // 디버거 루프
    DebugLoop();

    return 0;
}
Esempio n. 21
0
void *Ploopgrab(LPVOID args)
{
    DEBUG_EVENT  dbg;
    DWORD cont = DBG_CONTINUE, size = 0;
    TCHAR pszFilename[MAX_PATH+1];
    DWORD64 mod;
    struct proc_uc *tmp = args;
    struct ps_prochandle *P = tmp->ps;
    int first_execp = 0;
    BOOL wow = 0;
    char *s;
    DWORD Options = SymGetOptions();

    if (DebugActiveProcess(P->pid) == 0) {
        dprintf( "failed to debug process (%d): %d\n", P->pid, GetLastError() );
        pthread_mutex_lock(&P->mutex);
        P->status = PS_STOP;
        P->flags = CREATE_FAILED;
        if (P->status == PS_STOP)
            pthread_cond_signal(&P->cond);
        pthread_mutex_unlock(&P->mutex);
        return NULL;
    }

    DebugSetProcessKillOnExit(FALSE);

    P->wstat = 0;
    P->exitcode = 0;
    P->event = CreateEvent(NULL,FALSE,FALSE,NULL);
    P->dll_load_order = 1;
    SymSetOptions(Options|SYMOPT_INCLUDE_32BIT_MODULES|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG);

    while (1) {
        if (WaitForDebugEvent(&dbg, INFINITE) == 0) {
            return NULL;
        }

        cont = DBG_CONTINUE;
        pthread_mutex_lock(&P->mutex);

        switch (dbg.dwDebugEventCode) {
        case CREATE_PROCESS_DEBUG_EVENT:
            P->thandle = dbg.u.CreateProcessInfo.hThread;
            P->phandle = dbg.u.CreateProcessInfo.hProcess;
            if ((SymInitialize(P->phandle, 0, FALSE) == FALSE)) {
                dprintf("SymInitialize failed (%d): %d\n", P->pid, GetLastError());
                break;
            }

            s = GetFileNameFromHandle(dbg.u.CreateProcessInfo.hFile, pszFilename);
            addmodule(P, dbg.u.CreateProcessInfo.hFile, s, dbg.u.CreateProcessInfo.lpBaseOfImage, PE_TYPE_EXE, P->dll_load_order);
            size = GetFileSize(dbg.u.CreateProcessInfo.hFile, NULL);
            if (size == INVALID_FILE_SIZE) {
                size = 0;
            }

            if ((mod = SymLoadModuleEx(P->phandle,  dbg.u.CreateProcessInfo.hFile, s, NULL,
                                       (ULONG_PTR) dbg.u.CreateProcessInfo.lpBaseOfImage, size, NULL, 0)) == FALSE) {
                dprintf("SymLoadModule64 Failed for %s: %d\n", s, GetLastError());
                break;
            }

#if __amd64__
            if (Is32bitProcess(P->phandle)) {
                P->model = PR_MODEL_ILP32;
                wow = 1;
            } else
                P->model = PR_MODEL_ILP64;
#else
            P->model = PR_MODEL_ILP32;
#endif

            CloseHandle(dbg.u.CreateProcessInfo.hFile);
            P->status = PS_RUN;
            P->msg.type = 0;
            break;
        case CREATE_THREAD_DEBUG_EVENT:
            P->status = PS_RUN;
            P->msg.type = 0;
            break;
        case LOAD_DLL_DEBUG_EVENT:
            s = GetFileNameFromHandle(dbg.u.LoadDll.hFile, pszFilename);
            if (first_execp) {
                P->dll_load_order++;
            }
            addmodule(P, dbg.u.LoadDll.hFile, s, dbg.u.LoadDll.lpBaseOfDll, PE_TYPE_DLL, P->dll_load_order);
            size = GetFileSize(dbg.u.CreateProcessInfo.hFile, NULL);
            if (size == INVALID_FILE_SIZE) {
                size = 0;
            }
#if __amd64__
            /* Not tracing 64 bit dlls for 32 bit process */
            if (P->model == PR_MODEL_ILP32 && is64bitmodule(dbg.u.LoadDll.lpBaseOfDll, s)) {
                CloseHandle(dbg.u.LoadDll.hFile );
                break;
            }
#endif
            if ((mod = SymLoadModuleEx(P->phandle,  dbg.u.LoadDll.hFile, s, NULL,
                                       (ULONG_PTR) dbg.u.LoadDll.lpBaseOfDll, size, NULL, 0)) == FALSE) {
                dprintf("SymLoadModule64 failed for %s: %d\n", s, GetLastError());
                break;
            }

            CloseHandle(dbg.u.LoadDll.hFile );

            if (first_execp == 0) {
                P->status = PS_RUN;
                P->msg.type = RD_DLACTIVITY;
            } else {
                P->status = PS_STOP;
                P->msg.type = RD_DLACTIVITY;
            }
            break;
        case UNLOAD_DLL_DEBUG_EVENT:
            if (SymUnloadModule64(P->phandle, (ULONG_PTR) dbg.u.UnloadDll.lpBaseOfDll) ==  FALSE) {
                dprintf("SymUnloadModule64 failed-Imagebase %p: %d\n", dbg.u.UnloadDll.lpBaseOfDll, GetLastError());
                break;
            }
            delmodule(P, (ULONG64) dbg.u.UnloadDll.lpBaseOfDll);
            P->status = PS_RUN;
            P->msg.type = RD_DLACTIVITY;
            break;
        case EXIT_PROCESS_DEBUG_EVENT:
            P->exitcode = dbg.u.ExitProcess.dwExitCode;
            P->status = PS_UNDEAD;
            P->msg.type = RD_NONE;
            //SymCleanup(P->phandle);
            break;
        case EXIT_THREAD_DEBUG_EVENT:
            P->status = PS_RUN;
            P->msg.type = 0;
            break;
        case EXCEPTION_DEBUG_EVENT:
            switch(dbg.u.Exception.ExceptionRecord.ExceptionCode) {
            case EXCEPTION_BREAKPOINT:
                if (first_execp++ == 0) {
                    pthread_cond_signal(&P->cond);
                }
                P->status = PS_STOP;
                P->msg.type = 0;

                break;
            default:
                if (dbg.u.Exception.dwFirstChance == 0)
                    P->wstat = dbg.u.Exception.ExceptionRecord.ExceptionCode;
                P->status = PS_RUN;
                cont = DBG_EXCEPTION_NOT_HANDLED;
                break;
            }
            break;
        default:
            P->status = PS_RUN;
            dprintf("Debug Event not processed: %d\n", dbg.dwDebugEventCode);
            break;
        }

        if (P->status != PS_RUN)
            SetEvent(P->event);

        while (P->status == PS_STOP)
            pthread_cond_wait(&P->cond, &P->mutex);
        pthread_mutex_unlock(&P->mutex);

        ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, cont);
    }

}
Esempio n. 22
0
static void doDebugger(int argc, char** argv)
{
    const char* logfile;
    debugger_blackbox_t blackbox;
    HANDLE start_event, done_event, debug_event;

    blackbox.argc=argc;
    logfile=(argc >= 4 ? argv[3] : NULL);
    blackbox.pid=(argc >= 5 ? atol(argv[4]) : 0);

    if (strstr(myARGV[2], "attach"))
    {
        blackbox.attach_rc=DebugActiveProcess(blackbox.pid);
        if (!blackbox.attach_rc)
            blackbox.attach_err=GetLastError();
    }
    else
        blackbox.attach_rc=TRUE;

    debug_event=(argc >= 6 ? (HANDLE)atol(argv[5]) : NULL);
    if (debug_event && strstr(myARGV[2], "event"))
    {
        blackbox.debug_rc=SetEvent(debug_event);
        if (!blackbox.debug_rc)
            blackbox.debug_err=GetLastError();
    }
    else
        blackbox.debug_rc=TRUE;

    get_events(logfile, &start_event, &done_event);
    if (strstr(myARGV[2], "order"))
    {
        trace("debugger: waiting for the start signal...\n");
        WaitForSingleObject(start_event, INFINITE);
    }

    if (strstr(myARGV[2], "nokill"))
    {
        blackbox.nokill_rc=pDebugSetProcessKillOnExit(FALSE);
        if (!blackbox.nokill_rc)
            blackbox.nokill_err=GetLastError();
    }
    else
        blackbox.nokill_rc=TRUE;

    if (strstr(myARGV[2], "detach"))
    {
        blackbox.detach_rc=pDebugActiveProcessStop(blackbox.pid);
        if (!blackbox.detach_rc)
            blackbox.detach_err=GetLastError();
    }
    else
        blackbox.detach_rc=TRUE;

    save_blackbox(logfile, &blackbox, sizeof(blackbox));
    trace("debugger: done debugging...\n");
    SetEvent(done_event);

    /* Just exit with a known value */
    ExitProcess(0xdeadbeef);
}
Esempio n. 23
0
static void test_NtSuspendProcess(char *process_name)
{
    PROCESS_INFORMATION info;
    DEBUG_EVENT ev;
    STARTUPINFOA startup;
    NTSTATUS status;
    HANDLE event;
    char buffer[MAX_PATH];
    ULONG count;
    DWORD ret;

    status = pNtResumeProcess(GetCurrentProcess());
    ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);

    event = CreateEventA(NULL, TRUE, FALSE, "wine_suspend_event");
    ok(!!event, "Failed to create event: %u\n", GetLastError());

    memset(&startup, 0, sizeof(startup));
    startup.cb = sizeof(startup);

    sprintf(buffer, "%s tests/process.c dummy_process wine_suspend_event", process_name);
    ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
    ok(ret, "CreateProcess failed with error %u\n", GetLastError());

    ret = WaitForSingleObject(event, 500);
    ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);

    status = pNtSuspendProcess(info.hProcess);
    ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);

    ResetEvent(event);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);

    status = NtResumeThread(info.hThread, &count);
    ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
    ok(count == 1, "Expected count 1, got %d\n", count);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);

    status = pNtResumeProcess(info.hProcess);
    ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);

    status = pNtSuspendThread(info.hThread, &count);
    ok(status == STATUS_SUCCESS, "NtSuspendThread failed: %x\n", status);
    ok(count == 0, "Expected count 0, got %d\n", count);

    ResetEvent(event);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);

    status = pNtResumeProcess(info.hProcess);
    ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);

    status = pNtSuspendThread(info.hThread, &count);
    ok(status == STATUS_SUCCESS, "NtSuspendThread failed: %x\n", status);
    ok(count == 0, "Expected count 0, got %d\n", count);

    status = pNtSuspendThread(info.hThread, &count);
    ok(status == STATUS_SUCCESS, "NtSuspendThread failed: %x\n", status);
    ok(count == 1, "Expected count 1, got %d\n", count);

    ResetEvent(event);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);

    status = pNtResumeProcess(info.hProcess);
    ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);

    status = pNtResumeProcess(info.hProcess);
    ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);

    ret = DebugActiveProcess(info.dwProcessId);
    ok(ret, "Failed to debug process: %d\n", GetLastError());

    ResetEvent(event);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);

    for (;;)
    {
        ret = WaitForDebugEvent(&ev, INFINITE);
        ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
        if (!ret) break;

        if (ev.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) break;

        ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
        ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
        if (!ret) break;
    }

    ResetEvent(event);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);

    status = pNtResumeProcess(info.hProcess);
    ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);

    status = NtResumeThread(info.hThread, &count);
    ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
    ok(count == 0, "Expected count 0, got %d\n", count);

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);

    ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
    ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());

    ret = WaitForSingleObject(event, 200);
    ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);

    TerminateProcess(info.hProcess, 0);

    CloseHandle(info.hProcess);
    CloseHandle(info.hThread);
}
Esempio n. 24
0
DWORD WINAPI DebugThread(LPVOID lpvParam)
{
	DWORD nWait = WAIT_TIMEOUT;
	//DWORD nExternalExitCode = -1;
	wchar_t szInfo[1024];

	if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
	{
		STARTUPINFO si = {sizeof(si)};
		PROCESS_INFORMATION pi = {};

		if (gpSrv->DbgInfo.bDebugProcessTree)
		{
			SetEnvironmentVariable(ENV_CONEMU_BLOCKCHILDDEBUGGERS_W, ENV_CONEMU_BLOCKCHILDDEBUGGERS_YES);
		}

		if (!CreateProcess(NULL, gpSrv->DbgInfo.pszDebuggingCmdLine, NULL, NULL, FALSE,
			NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|
			DEBUG_PROCESS | (gpSrv->DbgInfo.bDebugProcessTree ? 0 : DEBUG_ONLY_THIS_PROCESS),
			NULL, NULL, &si, &pi))
		{
			DWORD dwErr = GetLastError();

			wchar_t szProc[64]; szProc[0] = 0;
			PROCESSENTRY32 pi = {sizeof(pi)};
			if (GetProcessInfo(gpSrv->dwRootProcess, &pi))
				_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start debugging process. ErrCode=0x%08X\n", dwErr);
			lstrcpyn(szInfo+lstrlen(szInfo), gpSrv->DbgInfo.pszDebuggingCmdLine, 400);
			wcscat_c(szInfo, L"\n");
			_wprintf(szInfo);
			return CERR_CANTSTARTDEBUGGER;
		}

		gpSrv->hRootProcess = pi.hProcess;
		gpSrv->hRootThread = pi.hThread;
		gpSrv->dwRootProcess = pi.dwProcessId;
		gpSrv->dwRootThread = pi.dwThreadId;
		gpSrv->dwRootStartTime = GetTickCount();
	}


	/* ************************* */
	int iDbgIdx = 0, iAttachedCount = 0;
	while (true)
	{
		HANDLE hDbgProcess = NULL;
		DWORD  nDbgProcessID = 0;

		bool bFirstPID = ((iDbgIdx++) == 0);
		if (bFirstPID)
		{
			hDbgProcess = gpSrv->hRootProcess;
			nDbgProcessID = gpSrv->dwRootProcess;
		}
		else
		{
			// Взять из pDebugAttachProcesses
			if (!gpSrv->DbgInfo.pDebugAttachProcesses)
				break;
			if (!gpSrv->DbgInfo.pDebugAttachProcesses->pop_back(nDbgProcessID))
				break;
			hDbgProcess = GetProcessHandleForDebug(nDbgProcessID);
			if (!hDbgProcess)
			{
				_ASSERTE(hDbgProcess!=NULL && "Can't open debugging process handle");
				continue;
			}
		}
	

		_ASSERTE(hDbgProcess!=NULL && "Process handle must be opened");


		// Битность отладчика должна соответствовать битности приложения!
		if (IsWindows64())
		{
			int nBits = GetProcessBits(nDbgProcessID, hDbgProcess);
			if ((nBits == 32 || nBits == 64) && (nBits != WIN3264TEST(32,64)))
			{
				if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
				{
					_printf("Bitness of ConEmuC and debugging program does not match\n");
					if (bFirstPID)
						return CERR_CANTSTARTDEBUGGER;
					else
						continue;
				}

				wchar_t szExe[MAX_PATH+16];
				wchar_t szCmdLine[MAX_PATH*2];
				if (GetModuleFileName(NULL, szExe, countof(szExe)-16))
				{
					wchar_t* pszName = (wchar_t*)PointToName(szExe);
					_wcscpy_c(pszName, 16, (nBits == 32) ? L"ConEmuC.exe" : L"ConEmuC64.exe");
					_wsprintf(szCmdLine, SKIPLEN(countof(szCmdLine))
						L"\"%s\" /DEBUGPID=%u %s", szExe, nDbgProcessID,
						(gpSrv->DbgInfo.nDebugDumpProcess == 1) ? L"/DUMP" :
						(gpSrv->DbgInfo.nDebugDumpProcess == 2) ? L"/MINIDUMP" :
						(gpSrv->DbgInfo.nDebugDumpProcess == 3) ? L"/FULLDUMP" : L"");

					STARTUPINFO si = {sizeof(si)};
					PROCESS_INFORMATION pi = {};
					if (CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
					{
						// Ждать НЕ будем, сразу на выход

						//HANDLE hEvents[2] = {pi.hProcess, ghExitQueryEvent};
						//nWait = WaitForMultipleObjects(countof(hEvents), hEvents, FALSE, INFINITE);
						//if (nWait == WAIT_OBJECT_0)
						//{
						//	//GetExitCodeProcess(pi.hProcess, &nExternalExitCode);
						//	nExternalExitCode = 0;
						//}

						//CloseHandle(pi.hProcess);
						//CloseHandle(pi.hThread);

						//if (nExternalExitCode == 0)
						//{
						//	goto done;
						//}

						// Может там еще процессы в списке на дамп?
						continue;
					}
					else
					{
						DWORD dwErr = GetLastError();
						_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start external debugger '%s'. ErrCode=0x%08X\n",
							szCmdLine, dwErr);
						_wprintf(szInfo);
						if (bFirstPID)
							return CERR_CANTSTARTDEBUGGER;
						else
							continue;
					}
				}


				wchar_t szProc[64]; szProc[0] = 0;
				PROCESSENTRY32 pi = {sizeof(pi)};
				if (GetProcessInfo(nDbgProcessID, &pi))
					_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Bits are incompatible. Can't debug '%s' PID=%i\n",
					szProc[0] ? szProc : L"not found", nDbgProcessID);
				_wprintf(szInfo);
				if (bFirstPID)
					return CERR_CANTSTARTDEBUGGER;
				else
					continue;
			}
		}

		if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL)
		{
			if (!DebugActiveProcess(nDbgProcessID))
			{
				DWORD dwErr = GetLastError();

				wchar_t szProc[64]; szProc[0] = 0;
				PROCESSENTRY32 pi = {sizeof(pi)};
				if (GetProcessInfo(nDbgProcessID, &pi))
					_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't attach debugger to '%s' PID=%i. ErrCode=0x%08X\n",
					szProc[0] ? szProc : L"not found", nDbgProcessID, dwErr);
				_wprintf(szInfo);
				return CERR_CANTSTARTDEBUGGER;
			}
		}

		iAttachedCount++;
	}

	if (iAttachedCount == 0)
	{
		return CERR_CANTSTARTDEBUGGER;
	}
	/* **************** */

	// Дополнительная инициализация, чтобы закрытие дебагера (наш процесс) не привело
	// к закрытию "отлаживаемой" программы
	pfnDebugActiveProcessStop = (FDebugActiveProcessStop)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugActiveProcessStop");
	pfnDebugSetProcessKillOnExit = (FDebugSetProcessKillOnExit)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugSetProcessKillOnExit");

	if (pfnDebugSetProcessKillOnExit)
		pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/);

	gpSrv->DbgInfo.bDebuggerActive = TRUE;
	PrintDebugInfo();
	SetEvent(gpSrv->DbgInfo.hDebugReady);
	

	while (nWait == WAIT_TIMEOUT)
	{
		ProcessDebugEvent();

		if (ghExitQueryEvent)
			nWait = WaitForSingleObject(ghExitQueryEvent, 0);
	}

//done:
	gbRootAliveLess10sec = FALSE;
	gbInShutdown = TRUE;
	gbAlwaysConfirmExit = FALSE;

	_ASSERTE(gbTerminateOnCtrlBreak==FALSE);

	if (!nExitQueryPlace) nExitQueryPlace = 12+(nExitPlaceStep);

	SetTerminateEvent(ste_DebugThread);
	return 0;
}
Esempio n. 25
0
		static bool Launch()
		{
			return DebugActiveProcess(GetCurrentProcessId()) != FALSE;
		}
Esempio n. 26
0
int wmain(int argc, WCHAR *argv[])
{

	/* Display welcome message */
	printf("handle_monitor %s - Adam Kramer\n", VERSION_NUMBER);

	/* These variables hold configuration options, which can be altered by arguments passed */
	BOOL bIncludeSigned = FALSE;
	BOOL bSuspendProcess = FALSE;
	BOOL bVerbose = FALSE;
	DWORD dNumberCycles = 10;
	DWORD dHandleChangeThreshold = 10;
	DWORD dIterationPause = 1000;

	/* Process arguments */
	if (argc > 1)
	{
		for (int iNumberArgs = 1; iNumberArgs < argc; iNumberArgs++)
		{
			/* /signed - will include signed files in the alerts */
			if (!wcscmp(argv[iNumberArgs], L"/signed"))
			{
				bIncludeSigned = TRUE;
				printf("Info: Will show signed files as well as unsigned\n");
			}
			/* /suspect - will attempt to suspend suspicious processes */
			else if (!wcscmp(argv[iNumberArgs], L"/suspend"))
			{
				bSuspendProcess = TRUE;
				printf("Info: Will attempt to suspend suspicious processes\n");
			}
			/* /verbose - will display details of iterations and hidden results */
			else if (!wcscmp(argv[iNumberArgs], L"/verbose"))
			{
				bVerbose = TRUE;
				printf("Info: Will display verbose status messages\n");
			}
			/* /cycles - allows the user to set cycles completed before analysis */
			else if (WCHAR* wSetCycles = wcsstr(argv[iNumberArgs], L"/cycles="))
			{
				wSetCycles = wcschr(wSetCycles, '=');

				if (!(dNumberCycles = _wtol(++wSetCycles)))
				{
					printf("Error: Invalid /cycles parameter\n");
					return 1;
				}

				printf("Info: Setting number of cycles to %d\n", dNumberCycles);
			}
			/* /threshold - allows the user to set the threshold for minimum number of new handles which are suspicious */
			else if (WCHAR* wSetThreshold = wcsstr(argv[iNumberArgs], L"/threshold="))
			{
				wSetThreshold = wcschr(wSetThreshold, '=');

				if (!(dHandleChangeThreshold = _wtol(++wSetThreshold)))
				{
					printf("Error: Invalid /threshold parameter\n");
					return 1;
				}

				printf("Info: Setting handle threshold to %d\n", dHandleChangeThreshold);
			}
			/* /pause - allows the user to set a pause between cycles (reduce system load, increase window for finding something) */
			else if (WCHAR* wSetPause = wcsstr(argv[iNumberArgs], L"/pause="))
			{
				wSetPause = wcschr(wSetPause, '=');

				dIterationPause = _wtol(++wSetPause);
				printf("Info: Setting pause between cycles to %dms\n", dIterationPause);
			}
		}
		/* End of argument processing */
	}
	else
	{
		/* No argument passed, accordingly display the usage instructions */
		printf("Usage: handle_monitor.exe <optional parameters>\n\n");
		printf("Optional parameters:\n");
		printf("/cycles=X - Set number of cycles before a review [Default: 10]\n");
		printf("/threshold=X - Set suspicion threshold for number of new handles [Default: 10]\n");
		printf("/pause=X - Set pause in milliseconds between cycles [Default: 1000]\n");
		printf("/signed - Include signed executables in review process\n");
		printf("/suspend - Suspend processes identified as suspicious\n");
		printf("/verbose - Display verbose progress messages\n\n");
		printf("Info: No parameters specified, launching monitoring (Ctrl+C to stop)\n");
	}

	/* Import functions manually from NTDLL */
	_NtQuerySystemInformation NtQuerySystemInformation =
		(_NtQuerySystemInformation)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");

	_NtDuplicateObject NtDuplicateObject =
		(_NtDuplicateObject)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtDuplicateObject");

	_NtQueryObject NtQueryObject =
		(_NtQueryObject)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryObject");

	/* Master loop! - This runs forever until a user presses Ctrl+C */
	for (;;)
	{
		/* Update user that process is starting (if /verbose mode activiated) */
		if (bVerbose)
			printf("Verbose Info: Starting sequence\n");

		/* Variables used for retrieving handles */
		NTSTATUS status;
		ULONG handleInfoSize = 0x10000;
		HANDLE processHandle;
		ULONG i;
		PSYSTEM_HANDLE_INFORMATION handleInfo;

		/* Used in each handle iteration to identify the index in iProcessArray of the specific process */
		int iCurrentProcess_ArrayIndex = -1;

		/* Handle array - PROCESS INDEX / HANDLE NUMBER / TEXT OF HANDLE
			This holds all handles which have been found per process */
		auto cHandleArray = new WCHAR[MAX_PROCESSES][MAX_FILE_HANDLES][MAX_PATH]();
		signed int iProcessArray[MAX_PROCESSES][3] = { 0 };

		/* Set process array to -1, which indicates nothing has been set */
		for (int j = 0; j < (MAX_PROCESSES - 1); j++)
			iProcessArray[j][0] = -1;

		/* Loop dNumberCycles [default: 10] times before analysing result */
		for (unsigned int iCycleCounter = 1; iCycleCounter <= dNumberCycles; iCycleCounter++)
		{
			handleInfoSize = 0x10000;
			handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);

			/* NtQuerySystemInformation won't give us the correct buffer size, so we guess by doubling the buffer size. */
			while ((status = NtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
				handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);

			/* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
			if (!NT_SUCCESS(status))
			{
				printf("NtQuerySystemInformation failed!\n");
				return 1;
			}

			/* Loop for each handle on the system, processing it accordingly... */
			for (i = 0; i < handleInfo->HandleCount; i++)
			{
				SYSTEM_HANDLE handle = handleInfo->Handles[i];
				HANDLE dupHandle = NULL;
				POBJECT_TYPE_INFORMATION objectTypeInfo;

				/* Open a handle to the process associated with the handle */
				if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, handle.ProcessId)))
					continue;

				/* Duplicate the handle so we can query it. */
				if (!NT_SUCCESS(NtDuplicateObject(processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, GENERIC_READ, 0, 0)))
				{
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* Query the object type */
				objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
				if (!NT_SUCCESS(NtQueryObject(dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL)))
				{
					free(objectTypeInfo);
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* If it's not a file handle, go to next one (as we're only interested in file handles) */
				if (wcscmp(objectTypeInfo->Name.Buffer, L"File"))
				{
					free(objectTypeInfo);
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* Identify the filename from the handle we're looking at */
				WCHAR* wHandleFileName = new WCHAR[MAX_PATH]();

				if (!GetFileNameFromHandle(dupHandle, wHandleFileName))
				{
					free(objectTypeInfo);
					free(wHandleFileName);
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* This is where we add our findings to the database */
				iCurrentProcess_ArrayIndex = -1;

				/* Check whether we've already got an entry for the process we're looking at */
				for (int j = 0; j < (MAX_PROCESSES - 1); j++)
					if (iProcessArray[j][PROCESS_ARRAY_INDEX] == handle.ProcessId)
						iCurrentProcess_ArrayIndex = j;

				/* If not, create a new entry for the process associated with the current handle */
				if (iCurrentProcess_ArrayIndex == -1)
					for (int j = 0; j < (MAX_PROCESSES - 1); j++)
						if (iProcessArray[j][PROCESS_ARRAY_INDEX] == -1)
						{
							iProcessArray[j][PROCESS_ARRAY_INDEX] = handle.ProcessId;
							iCurrentProcess_ArrayIndex = j;
							break;
						}

				/* If there's more than MAX_PROCESSES, throw an error
					TODO: Tidy this up, identify number of running processes dynamically and set array size accordingly */
				if (iCurrentProcess_ArrayIndex == -1)
				{
					printf("Error: Too many processes running!\n");
					return 1;
				}

				/* Look through the handle array, to see whether the filename can be found */
				WCHAR cCurrentHandleText[MAX_PATH];
				for (int j = 0; j < (MAX_FILE_HANDLES - 1); j++)
				{
					/* If we hit NULL, there are no more to find, so add ours */
					swprintf_s(cCurrentHandleText, MAX_PATH, L"%ls", wHandleFileName);

					if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], L"")){
						wcscpy_s(cHandleArray[iCurrentProcess_ArrayIndex][j], cCurrentHandleText);
						break;
					}
					/* If we find ours, then stop searching */
					else if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], cCurrentHandleText))
						break;
				}

				/* If it's the first (or last) cycle, tally how many entries in the handle array for this
					particular process we have so far */

				if (iCycleCounter == 1)
					for (int j = 0; j < (MAX_FILE_HANDLES - 1); j++)
						if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], L"")){
							iProcessArray[iCurrentProcess_ArrayIndex][PROCESS_ARRAY_COUNT_START_CYCLE] = (j - 1);
							break;
						}

				if (iCycleCounter == dNumberCycles)
					for (int j = 0; j < (MAX_FILE_HANDLES - 1); j++)
						if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], L"")) {
							iProcessArray[iCurrentProcess_ArrayIndex][PROCESS_ARRAY_COUNT_END_CYCLE] = (j - 1);
							break;
						}

				free(objectTypeInfo);
				free(wHandleFileName);
				CloseHandle(dupHandle);
				CloseHandle(processHandle);
			}
			free(handleInfo);

			/* If the iteration pause is not 0, sleep for the requested time [Default: 1000ms] */
			if (dIterationPause)
				Sleep(dIterationPause);

			/* If /verbose active - inform user which cycle we are on */
			if (bVerbose)
				if (iCycleCounter == 1)
					printf("Verbose Info: Completed cycle %d", iCycleCounter);
				else if (iCycleCounter == dNumberCycles)
					printf(" %d\n", iCycleCounter);
				else
					printf(" %d", iCycleCounter);
		}

		/* If /verbose active - inform user we are now starting a review */
		if (bVerbose)
			printf("Verbose Info: Cycles completed, beginning review\n");

		/* Check if any of them met threshold*/
		for (int j = 0; j < (MAX_PROCESSES - 1); j++)
		{
			if (iProcessArray[j][PROCESS_ARRAY_COUNT_END_CYCLE] < iProcessArray[j][PROCESS_ARRAY_COUNT_START_CYCLE])
				continue;

			/* dHandleDelta is the difference between number of handles for a process from first cycle to the last one  */
			DWORD dHandleDelta = (iProcessArray[j][PROCESS_ARRAY_COUNT_END_CYCLE] - iProcessArray[j][PROCESS_ARRAY_COUNT_START_CYCLE]);

			/* Check whether the delta is equal or above the threshold */
			if (dHandleDelta >= dHandleChangeThreshold)
			{
				HANDLE pHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, iProcessArray[j][PROCESS_ARRAY_INDEX]);
				TCHAR tProcessName[MAX_PATH];
				GetModuleFileNameEx(pHandle, 0, tProcessName, MAX_PATH);
				CloseHandle(pHandle);

				/* If we don't want signed, yet it is signed, skip... */
				if (!bIncludeSigned && (is_signed(tProcessName) == 0))
				{
					if (bVerbose)
						wprintf(L"Verbose Info: Skipping alert on %s (%d) despite trigger, as it is signed (use /signed to alert on signed executables too)\n", tProcessName, iProcessArray[j][PROCESS_ARRAY_INDEX]);
					continue;
				}

				/* Inform the user if we have a suspicious process */
				wprintf(L"Alert! Process: %s (%d) has had a suspicious number of handles (%d) created in the last cycle\nNew handles created during this cycle:\n", tProcessName, iProcessArray[j][PROCESS_ARRAY_INDEX], dHandleDelta);

				for (DWORD k = 1; k <= dHandleDelta; k++)
					wprintf(L"%s\n", cHandleArray[j][iProcessArray[j][PROCESS_ARRAY_COUNT_START_CYCLE] + k]);

				if (bSuspendProcess)
				{

					printf("Info: Attempting to suspend process %d\n", iProcessArray[j][PROCESS_ARRAY_INDEX]);

					/* Attach debugger to process (freeze it!)*/
					if (!DebugActiveProcess(iProcessArray[j][PROCESS_ARRAY_INDEX]))
					{
						printf("Info: Could not attach to process %d as a debugger\n", iProcessArray[j][PROCESS_ARRAY_INDEX]);
					}
					else
					{
						DebugSetProcessKillOnExit(FALSE);

						printf("Info: Successfully attached to process %d as debugger\n", iProcessArray[j][PROCESS_ARRAY_INDEX]);
						printf("Info: It will remain frozen until this process is terminated\n");
					}
				}

				printf("------------------------------------------------------------------------------\n");

			}
		}

		if (bVerbose)
			printf("Verbose Info: Review complete\n");

		free(cHandleArray);

	}

	return 0;
}
Esempio n. 27
0
void
stAttachDebugger(
    DWORD           processId,
    std::string     fnIncludes,
    std::string     fnExcludes,
    bool            activeProcess = true)
/*++

Routine Description:
    
    Our mini-debugger implementation. It does following
    things:
    - Attach to a running process
    - On first breakpoint, inject the IAT patching DLL into target
    - Print information of any exception in target process
    - Print the debug spew from target process

Arguments:

    processId - PID of the process to attach
    
    fnIncludes - List of include filters

    fnExclude - List of exclude filters

    activeProcess - If we are attaching to an already running process
        then we pass activeProcess = true, this causes us to call
        DebugActiveProcess and not wait for process creation event

--*/
{
    int threadCount = 0;
    bool processInfected = false;

    if (activeProcess)
    {
        if (!DebugActiveProcess(processId))
        {
            gView->PrintError(L"\nCould not attach to the process (PID = %d).", processId);
            stHandleError(GetLastError());
            goto funcExit;
        }
    }

    HMODULE hMod = GetModuleHandle(L"Kernel32.dll");

    if (hMod)
    {
        PFNDEBUGSETPROCESSKILLONEXIT pfnDebugSetProcessKillOnExit =
                (PFNDEBUGSETPROCESSKILLONEXIT)GetProcAddress(hMod, "DebugSetProcessKillOnExit");

        if (pfnDebugSetProcessKillOnExit)
        {
            pfnDebugSetProcessKillOnExit(FALSE);
        }
    }

    gProcessId = processId;

    DEBUG_EVENT debugEvent;
    DWORD       dwContinueStatus = DBG_CONTINUE;

    bool keepAlive = true;

    while(keepAlive)
    {
        WaitForDebugEvent(&debugEvent, INFINITE);
        dwContinueStatus = DBG_CONTINUE;

        if (debugEvent.dwProcessId == processId)
        {
            switch (debugEvent.dwDebugEventCode)
            {
                case EXCEPTION_DEBUG_EVENT:
                {
                    switch (debugEvent.u.Exception.ExceptionRecord.ExceptionCode)
                    {
                        case EXCEPTION_BREAKPOINT:
                        {
                            //IHU_DBG_LOG(TRC_STRACE, HX_LEVEL_INFO, (L"EXCEPTION_BREAKPOINT\n"));

                            if (!processInfected)
                            {
                                if (gRemovePatchOnExit)
                                {
                                    HRSRC       hRes;
                                    HGLOBAL     hResG;
                                    LPVOID      pRes;
                                    DWORD       dwResSize;

                                    hRes = FindResource(
                                                    NULL,
                                                    MAKEINTRESOURCE(IDR_BIN_DLL),
                                                    L"BIN");

                                    hResG       = LoadResource(NULL, hRes);
                                    pRes        = LockResource(hResG);
                                    dwResSize   = SizeofResource(NULL, hRes);

                                    wchar_t tempPath[MAX_PATH];
                                    wchar_t tempFile[MAX_PATH];
                                    GetTempPath(MAX_PATH, tempPath);
                                    GetTempFileName(tempPath, L"", 0, tempFile);

                                    gInjectorDllPath = tempFile;

                                    HANDLE oFile = CreateFile(
                                                        gInjectorDllPath.c_str(),
                                                        GENERIC_READ | GENERIC_WRITE,
                                                        0,
                                                        NULL,
                                                        CREATE_ALWAYS,
                                                        FILE_ATTRIBUTE_NORMAL,
                                                        NULL);

                                    if (oFile == INVALID_HANDLE_VALUE)
                                    {
                                        gView->PrintError(
                                                L"Failed to create the temporary DLL [%s]. Error code = %x\n",
                                                gInjectorDllPath.c_str(),
                                                GetLastError());
                                        return;
                                    }

                                    DWORD bytesWritten;

                                    if (!WriteFile(
                                                oFile,
                                                pRes,
                                                dwResSize,
                                                &bytesWritten,
                                                NULL))
                                    {
                                        gView->PrintError(
                                                L"Failed to write the temporary DLL. Error code = %x\n",
                                                GetLastError());
                                        return;
                                    }
                                    
                                    CloseHandle(oFile);
                                }
                                else
                                {
                                    wchar_t exePath[MAX_PATH];

                                    if (GetModuleFileName(
                                                        NULL,
                                                        exePath,
                                                        MAX_PATH))
                                    {
                                        std::wstring dllPath = exePath;
                                        int slashPos = dllPath.find_last_of(L'\\');
                                        if (slashPos != -1)
                                        {
                                            dllPath = dllPath.substr(0, slashPos + 1);
                                        }
                                        dllPath += L"stserum.dll";

                                        gInjectorDllPath = dllPath;
                                    }
                                }

                                ihiInjectDll(
                                            ghProcess,
                                            (LPCWSTR)gInjectorDllPath.c_str(),
                                            (LPCSTR)fnIncludes.c_str(),
                                            (LPCSTR)fnExcludes.c_str());

                                processInfected = true;
                            }

                            break;
                        }
                        default:
                        {
                            if (debugEvent.u.Exception.dwFirstChance)
                            {
                                gView->PrintWarning(L"Exception = %x, Address = %x (first-chance!)\n",
                                    debugEvent.u.Exception.ExceptionRecord.ExceptionCode,
                                    debugEvent.u.Exception.ExceptionRecord.ExceptionAddress);
                            }
                            else
                            {
                                gView->PrintError(L"Exception = %x, Address = %x (second-chance!)\n",
                                    debugEvent.u.Exception.ExceptionRecord.ExceptionCode,
                                    debugEvent.u.Exception.ExceptionRecord.ExceptionAddress);
                            }

                            //
                            // If this was a second chance exception, it will cause
                            // the process to terminate
                            //
                            dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
                            break;
                        }
                    }

                    break;
                }
                case CREATE_THREAD_DEBUG_EVENT:
                {
                    ++threadCount;
                    break;
                }
                case CREATE_PROCESS_DEBUG_EVENT:
                {
                    if (ghProcess == INVALID_HANDLE_VALUE)
                    {
                        ghProcess = debugEvent.u.CreateProcessInfo.hProcess;
                    }
                    //IHU_DBG_LOG(TRC_STRACE, HX_LEVEL_INFO, (L"Create Process\n"));                    
                    break;
                }
                case EXIT_THREAD_DEBUG_EVENT:
                {
                    --threadCount;
                    break;
                }
                case EXIT_PROCESS_DEBUG_EVENT:
                {
                    gView->PrintMessage(
                        L"Target process has been terminated. Exit Code = %d.\n",
                        debugEvent.u.ExitProcess.dwExitCode);

                    keepAlive = false;
                    break;
                }
                case LOAD_DLL_DEBUG_EVENT:
                {
                    break;
                }
                case UNLOAD_DLL_DEBUG_EVENT:
                {
                    break;
                }
                case OUTPUT_DEBUG_STRING_EVENT:
                {
                    DWORD cbRead = 0;

                    ReadProcessMemory(  ghProcess,
                                        debugEvent.u.DebugString.lpDebugStringData,
                                        gDbgString,
                                        debugEvent.u.DebugString.nDebugStringLength,
                                        &cbRead);

                    if (debugEvent.u.DebugString.fUnicode)
                    {
                        if (gDbgString[0] == L'$')
                        {   
                            gView->PrintTrace(L"%ws", &gDbgString[1]);
                        }
                        else if (gDbgString[0] == L'#')
                        {
                            gView->PrintError(L"%ws", &gDbgString[1]);
                        }
                        else
                        {
                            gView->PrintTraceOrig(L"%ws", gDbgString);
                        }
                        
                    }
                    else
                    {
                        if (gDbgString[0] == L'$')
                        {   
                            gView->PrintTraceA("%s", &gDbgString[1]);
                        }
                        else if (gDbgString[0] == L'#')
                        {
                            gView->PrintErrorA("%s", &gDbgString[1]);
                        }
                        else
                        {
                            gView->PrintTraceOrigA("%s", gDbgString);
                        }
                    }

                    break;
                }
            }
        }

        ContinueDebugEvent( debugEvent.dwProcessId,
                            debugEvent.dwThreadId,
                            dwContinueStatus);
    }

    //
    // If we need to remove the patching on exit, it means we created a
    // temporary injector dll, we should delete that now
    //
    if (gRemovePatchOnExit)
    {
        DeleteFile(gInjectorDllPath.c_str());
    }

    //IHU_DBG_LOG(TRC_STRACE, HX_LEVEL_INFO, (L"Total thread count = %d\n", threadCount));

funcExit:

    return;
}
Esempio n. 28
0
void debug(DWORD processId)
{
	DebugActiveProcess(processId);
}
static int NaClDebugExceptionHandlerStandaloneMain(int argc, char **argv) {
  int target_pid;
  NaClHandle socket;
  char *rest1;
  char *rest2;
  void *info;
  size_t info_size;
  HANDLE process_handle;
  DWORD written;

  if (argc != 3) {
    NaClLog(LOG_FATAL, "NaClDebugExceptionHandlerStandaloneMain: "
            "Expected 3 arguments: target_pid, socket, data\n");
  }

  target_pid = strtol(argv[0], &rest1, 0);
  socket = (NaClHandle)(uintptr_t) strtol(argv[1], &rest2, 0);
  if (*rest1 != '\0' || *rest2 != '\0') {
    NaClLog(LOG_FATAL, "NaClDebugExceptionHandlerStandaloneMain: "
            "Bad string argument\n");
  }

  info_size = strlen(argv[2]);
  if (info_size % 2 != 0) {
    NaClLog(LOG_FATAL, "NaClDebugExceptionHandlerStandaloneMain: "
            "Odd string length\n");
  }
  info_size /= 2;
  info = malloc(info_size);
  if (info == NULL) {
    NaClLog(LOG_FATAL, "NaClDebugExceptionHandlerStandaloneMain: "
            "malloc() failed\n");
  }
  DecodeHexString((uint8_t *) info, argv[2], info_size);

  if (!DebugActiveProcess(target_pid)) {
    NaClLog(LOG_FATAL, "NaClDebugExceptionHandlerStandaloneMain: "
            "Failed to attach with DebugActiveProcess()\n");
  }

  process_handle = OpenProcess(PROCESS_QUERY_INFORMATION |
                               PROCESS_SUSPEND_RESUME |
                               PROCESS_TERMINATE |
                               PROCESS_VM_OPERATION |
                               PROCESS_VM_READ |
                               PROCESS_VM_WRITE |
                               PROCESS_DUP_HANDLE |
                               SYNCHRONIZE,
                               /* bInheritHandle= */ FALSE,
                               target_pid);
  if (process_handle == NULL) {
    NaClLog(LOG_FATAL, "NaClDebugExceptionHandlerStandaloneMain: "
            "Failed to get process handle with OpenProcess()\n");
  }

  /* Send message to indicate that we attached to the process successfully. */
  if (!WriteFile(socket, "k", 1, &written, NULL) || written != 1) {
    NaClLog(LOG_FATAL, "NaClDebugExceptionHandlerStandaloneMain: "
            "Failed to send reply\n");
  }

  NaClDebugExceptionHandlerRun(process_handle, info, info_size);
  return 0;
}
Esempio n. 30
0
static void test_debug_loop(int argc, char **argv)
{
    const char *arguments = " debugger child ";
    struct child_blackbox blackbox;
    char blackbox_file[MAX_PATH];
    PROCESS_INFORMATION pi;
    STARTUPINFOA si;
    BOOL debug;
    DWORD pid;
    char *cmd;
    BOOL ret;

    if (!pDebugActiveProcessStop || !pCheckRemoteDebuggerPresent)
    {
        win_skip("DebugActiveProcessStop or CheckRemoteDebuggerPresent not available, skipping test.\n");
        return;
    }

    pid = GetCurrentProcessId();
    ret = DebugActiveProcess(pid);
    ok(!ret, "DebugActiveProcess() succeeded on own process.\n");

    get_file_name(blackbox_file);
    cmd = HeapAlloc(GetProcessHeap(), 0, strlen(argv[0]) + strlen(arguments) + strlen(blackbox_file) + 10);
    sprintf(cmd, "%s%s%08x %s", argv[0], arguments, pid, blackbox_file);

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    ret = CreateProcessA(NULL, cmd, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi);
    ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError());

    HeapFree(GetProcessHeap(), 0, cmd);

    ret = pCheckRemoteDebuggerPresent(pi.hProcess, &debug);
    ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
    ok(debug, "Expected debug != 0, got %#x.\n", debug);

    for (;;)
    {
        DEBUG_EVENT ev;

        ret = WaitForDebugEvent(&ev, INFINITE);
        ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
        if (!ret) break;

        if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break;

        ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
        ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
        if (!ret) break;
    }

    ret = CloseHandle(pi.hThread);
    ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
    ret = CloseHandle(pi.hProcess);
    ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());

    load_blackbox(blackbox_file, &blackbox, sizeof(blackbox));
    ok(!blackbox.failures, "Got %d failures from child process.\n", blackbox.failures);

    ret = DeleteFileA(blackbox_file);
    ok(ret, "DeleteFileA failed, last error %#x.\n", GetLastError());
}