⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssp.c

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2000, 2001, 2002 Red Hat, Inc. * *     This program is free software; you can redistribute it and/or modify *     it under the terms of the GNU General Public License as published by *     the Free Software Foundation; either version 2 of the License, or *     (at your option) any later version. * *     A copy of the GNU General Public License can be found at *     http://www.gnu.org/ * * Written by DJ Delorie <dj@redhat.com> * */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <time.h>#include <ctype.h>#include <windows.h>#include <getopt.h>static const char version[] = "$Revision: 1.6 $";static char *prog_name;static struct option longopts[] ={  {"console-trace", no_argument, NULL, 'c' },  {"disable", no_argument, NULL, 'd' },  {"enable", no_argument, NULL, 'e' },  {"help", no_argument, NULL, 'h' },  {"dll", no_argument, NULL, 'l' },  {"sub-threads", no_argument, NULL, 's' },  {"trace-eip", no_argument, NULL, 't' },  {"verbose", no_argument, NULL, 'v' },  {"version", no_argument, NULL, 'V' },  {NULL, 0, NULL, 0}};static char opts[] = "cdehlstvV";#define KERNEL_ADDR 0x77000000#define TRACE_SSP 0#define VERBOSE	1#define TIMES	1000/* from winsup/gmon.h */struct gmonhdr {	unsigned long	lpc;	/* base pc address of sample buffer */	unsigned long	hpc;	/* max pc address of sampled buffer */	int	ncnt;		/* size of sample buffer (plus this header) */	int	version;	/* version number */	int	profrate;	/* profiling clock rate */	int	spare[3];	/* reserved */};#define GMONVERSION	0x00051879#define HISTCOUNTER unsigned shorttypedef struct {  unsigned int base_address;  int pcount;  int scount;  char *name;} DllInfo;typedef struct {  unsigned int address;  unsigned char real_byte;} PendingBreakpoints;unsigned low_pc=0, high_pc=0;unsigned last_pc=0, pc, last_sp=0, sp;int total_cycles, count;HANDLE hProcess;PROCESS_INFORMATION procinfo;STARTUPINFO startup;CONTEXT context;HISTCOUNTER *hits=0;struct gmonhdr hdr;int running = 1, profiling = 1;char dll_name[1024], *dll_ptr, *cp;int eip;unsigned opcode_count = 0;int stepping_enabled = 1;int tracing_enabled = 0;int trace_console = 0;int trace_all_threads = 0;int dll_counts = 0;int verbose = 0;#define MAXTHREADS 100DWORD active_thread_ids[MAXTHREADS];HANDLE active_threads[MAXTHREADS];DWORD thread_step_flags[MAXTHREADS];DWORD thread_return_address[MAXTHREADS];int num_active_threads = 0;int suspended_count=0;#define MAXDLLS 100DllInfo dll_info[MAXDLLS];int num_dlls=0;#define MAXPENDS 100PendingBreakpoints pending_breakpoints[MAXPENDS];int num_breakpoints=0;static voidadd_breakpoint (unsigned int address){  int i;  DWORD rv;  static char int3[] = { 0xcc };  for (i=0; i<num_breakpoints; i++)    {      if (pending_breakpoints[i].address == address)	return;      if (pending_breakpoints[i].address == 0)	break;    }  if (i == MAXPENDS)    return;  pending_breakpoints[i].address = address;  ReadProcessMemory (hProcess,		    (void *)address,		    &(pending_breakpoints[i].real_byte),		    1, &rv);  WriteProcessMemory (hProcess,		     (void *)address,		     (LPVOID)int3, 1, &rv);  if (i >= num_breakpoints)    num_breakpoints = i+1;}static intremove_breakpoint (unsigned int address){  int i;  DWORD rv;  for (i=0; i<num_breakpoints; i++)    {      if (pending_breakpoints[i].address == address)	{	  pending_breakpoints[i].address = 0;	  WriteProcessMemory (hProcess,			     (void *)address,			     &(pending_breakpoints[i].real_byte),			     1, &rv);	  return 1;	}    }  return 0;}static HANDLElookup_thread_id (DWORD threadId, int *tix){  int i;  for (i=0; i<num_active_threads; i++)    if (active_thread_ids[i] == threadId)      {	if (tix) *tix = i;	return active_threads[i];      }  return 0;}static voidset_step_threads (int threadId, int trace){  int rv, tix;  HANDLE thread = lookup_thread_id (threadId, &tix);  rv = GetThreadContext (thread, &context);  if (rv != -1)    {      thread_step_flags[tix] = trace;      if (trace)	context.EFlags |= 0x100; /* TRAP (single step) flag */      else	context.EFlags &= ~0x100; /* TRAP (single step) flag */      SetThreadContext (thread, &context);    }}static voidset_steps (){  int i, s;  for (i=0; i<num_active_threads; i++)    {      GetThreadContext (active_threads[i], &context);      s = context.EFlags & 0x0100;      if (!s && thread_step_flags[i])	{	  set_step_threads (active_thread_ids[i], 1);	}    }}static intdll_sort (const void *va, const void *vb){  DllInfo *a = (DllInfo *)va;  DllInfo *b = (DllInfo *)vb;  if (a->base_address < b->base_address)    return -1;  return 1;}static char *addr2dllname (unsigned int addr){  int i;  for (i=num_dlls-1; i>=0; i--)    {      if (dll_info[i].base_address < addr)	{	  return dll_info[i].name;	}    }  return (char *)"";}static voiddump_registers (HANDLE thread){  context.ContextFlags = CONTEXT_FULL;  GetThreadContext (thread, &context);  printf ("eax %08lx ebx %08lx ecx %08lx edx %08lx eip\n",	  context.Eax, context.Ebx, context.Ecx, context.Edx);  printf ("esi %08lx edi %08lx ebp %08lx esp %08lx %08lx\n",	  context.Esi, context.Esi, context.Ebp, context.Esp, context.Eip);}typedef struct Edge {  struct Edge *next;  unsigned int from_pc;  unsigned int to_pc;  unsigned int count;} Edge;Edge *edges[4096];voidstore_call_edge (unsigned int from_pc, unsigned int to_pc){  Edge *e;  unsigned int h = ((from_pc + to_pc)>>4) & 4095;  for (e=edges[h]; e; e=e->next)    if (e->from_pc == from_pc && e->to_pc == to_pc)      break;  if (!e)    {      e = (Edge *)malloc (sizeof (Edge));      e->next = edges[h];      edges[h] = e;      e->from_pc = from_pc;      e->to_pc = to_pc;      e->count = 0;    }  e->count++;}voidwrite_call_edges (FILE *f){  int h;  Edge *e;  for (h=0; h<4096; h++)    for (e=edges[h]; e; e=e->next)      fwrite (&(e->from_pc), 1, 3*sizeof (unsigned int), f);}char *wide_strdup (char *cp){  unsigned short *s = (unsigned short *)cp;  int len;  char *rv;  for (len=0; s[len]; len++);  rv = (char *)malloc (len+1);  for (len=0; s[len]; len++)    rv[len] = s[len];  rv[len] = 0;  return rv;}voidrun_program (char *cmdline){  FILE *tracefile = 0;  int tix, i;  HANDLE hThread;  char *string;  memset (&startup, 0, sizeof (startup));  startup.cb = sizeof (startup);  if (!CreateProcess (0, cmdline, 0, 0, 0,		     CREATE_NEW_PROCESS_GROUP		     | CREATE_SUSPENDED		     | DEBUG_PROCESS		     | DEBUG_ONLY_THIS_PROCESS,		     0, 0, &startup, &procinfo))    {      fprintf (stderr, "Can't create process: error %ld\n", GetLastError ());      exit (1);    }  hProcess = procinfo.hProcess;#if 0  printf ("procinfo: %08x %08x %08x %08x\n",	 hProcess, procinfo.hThread, procinfo.dwProcessId, procinfo.dwThreadId);#endif  active_threads[0] = procinfo.hThread;  active_thread_ids[0] = procinfo.dwThreadId;  thread_step_flags[0] = stepping_enabled;  num_active_threads = 1;  dll_info[0].base_address = 0;  dll_info[0].pcount = 0;  dll_info[0].scount = 0;  dll_info[0].name = cmdline;  num_dlls = 1;  SetThreadPriority (procinfo.hThread, THREAD_PRIORITY_IDLE);  context.ContextFlags = CONTEXT_FULL;  ResumeThread (procinfo.hThread);  total_cycles = 0;  if (tracing_enabled)    {      tracefile = fopen ("trace.ssp", "w");      if (!tracefile)	{	  tracing_enabled = 0;	  perror ("trace.ssp");	}    }  running = 1;  while (running)    {      int src, dest;      DWORD rv;      DEBUG_EVENT event;      int contv = DBG_CONTINUE;      event.dwDebugEventCode = -1;      if (!WaitForDebugEvent (&event, INFINITE))	{	  printf ("idle...\n");	}      hThread = lookup_thread_id (event.dwThreadId, &tix);#if 0      printf ("DE: %x/%d %d %d ",	     hThread, tix,	     event.dwDebugEventCode, num_active_threads);      for (src=0; src<num_active_threads; src++)	{	  int sc = SuspendThread (active_threads[src]);	  int rv = GetThreadContext (active_threads[src], &context);	  ResumeThread (active_threads[src]);	  printf (" [%x,%x,%x]",		 active_threads[src], context.Eip, active_thread_ids[src]);	}      printf ("\n");#endif      switch (event.dwDebugEventCode)	{	case CREATE_PROCESS_DEBUG_EVENT:	  break;	case CREATE_THREAD_DEBUG_EVENT:	  if (verbose)	    printf ("create thread %08lx at %08x %s\n",		   event.dwThreadId,		   (int)event.u.CreateThread.lpStartAddress,		   addr2dllname ((unsigned int)event.u.CreateThread.lpStartAddress));	  active_thread_ids[num_active_threads] = event.dwThreadId;	  active_threads[num_active_threads] = event.u.CreateThread.hThread;	  thread_return_address[num_active_threads] = 0;	  num_active_threads++;	  if (trace_all_threads && stepping_enabled)	    {	      thread_step_flags[num_active_threads-1] = stepping_enabled;	      add_breakpoint ((int)event.u.CreateThread.lpStartAddress);	    }	  break;	case EXIT_THREAD_DEBUG_EVENT:	  if (verbose)	    printf ("exit thread %08lx, code=%ld\n",		   event.dwThreadId,		   event.u.ExitThread.dwExitCode);	  for (src=0, dest=0; src<num_active_threads; src++)	    if (active_thread_ids[src] != event.dwThreadId)	      {		active_thread_ids[dest] = active_thread_ids[src];		active_threads[dest] = active_threads[src];		dest++;	      }	  num_active_threads = dest;	  break;	case EXCEPTION_DEBUG_EVENT:	  rv = GetThreadContext (hThread, &context);	  switch (event.u.Exception.ExceptionRecord.ExceptionCode)	    {	    case STATUS_BREAKPOINT:	      if (remove_breakpoint ((int)event.u.Exception.ExceptionRecord.ExceptionAddress))		{		  context.Eip --;		  if (!rv)		    SetThreadContext (hThread, &context);		  if (ReadProcessMemory (hProcess, (void *)context.Esp, &rv, 4, &rv))		      thread_return_address[tix] = rv;		}	      set_step_threads (event.dwThreadId, stepping_enabled);	    case STATUS_SINGLE_STEP:	      opcode_count++;	      pc = (unsigned int)event.u.Exception.ExceptionRecord.ExceptionAddress;	      sp = (unsigned int)context.Esp;	      if (tracing_enabled)		fprintf (tracefile, "%08x %08lx\n", pc, event.dwThreadId);	      if (trace_console)		{		  printf ("%d %08x\n", tix, pc);		  fflush (stdout);		}	      if (dll_counts)		{		  int i;		  for (i=num_dlls-1; i>=0; i--)		    {		      if (dll_info[i].base_address < context.Eip)			{			  if (hThread == procinfo.hThread)			    dll_info[i].pcount++;			  else			    dll_info[i].scount++;			  break;			}		    }		}	      if (pc < last_pc || pc > last_pc+10)		{		  static int ncalls=0;		  static int qq=0;		  if (++qq % 100 == 0)		    fprintf (stderr, " %08x %d %d \r",			    pc, ncalls, opcode_count);		  if (sp == last_sp-4)		    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -