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

📄 i386-stub-win32.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
SAVE_REGISTERS2();
asm ("pushl $14");
CALL_HOOK();

/*
 * remcomHandler is a front end for handle_exception.  It moves the
 * stack pointer into an area reserved for debugger use.
 */
asm("_remcomHandler:");
asm("           popl %eax");		/* pop off return address	  */
asm("           popl %eax");	  /* get the exception number	*/
asm("		movl _stackPtr, %esp"); /* move to remcom stack area  */
asm("		pushl %eax");	 /* push exception onto stack  */
asm("		call  _handle_exception");	  /* this never returns */


void
_returnFromException ()
{
  return_to_prog ();
}

#endif	// !WIN32


#ifdef _MSC_VER //MF
#define BREAKPOINT() __asm int 3;
#else
#define BREAKPOINT() asm("   int $3");
#endif


#ifdef WIN32 //MF

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

void handle_exception(int exceptionVector);

void win32_exception_handler(EXCEPTION_POINTERS* exc_info)
{
  PCONTEXT ctx = exc_info->ContextRecord;

  registers[EAX] = ctx->Eax;
  registers[ECX] = ctx->Ecx;
  registers[EDX] = ctx->Edx;
  registers[EBX] = ctx->Ebx;
  registers[ESP] = ctx->Esp;
  registers[EBP] = ctx->Ebp;
  registers[ESI] = ctx->Esi;
  registers[EDI] = ctx->Edi;
   registers[PC] = ctx->Eip;
   registers[PS] = ctx->EFlags;
  registers[CS] = ctx->SegCs;
  registers[SS] = ctx->SegSs;
  registers[DS] = ctx->SegDs;
  registers[ES] = ctx->SegEs;
  registers[FS] = ctx->SegFs;
  registers[GS] = ctx->SegGs;

  handle_exception(exc_info->ExceptionRecord->ExceptionCode & 0xFFFF);

  ctx->Eax = registers[EAX];
  ctx->Ecx = registers[ECX];
  ctx->Edx = registers[EDX];
  ctx->Ebx = registers[EBX];
  ctx->Esp = registers[ESP];
  ctx->Ebp = registers[EBP];
  ctx->Esi = registers[ESI];
  ctx->Edi = registers[EDI];
   ctx->Eip = registers[PC];
   ctx->EFlags = registers[PS];
  ctx->SegCs = registers[CS];
  ctx->SegSs = registers[SS];
  ctx->SegDs = registers[DS];
  ctx->SegEs = registers[ES];
  ctx->SegFs = registers[FS];
  ctx->SegGs = registers[GS];
}

#endif // WIN32


int
hex (ch)
	 char ch;
{
  if ((ch >= 'a') && (ch <= 'f'))
	return (ch - 'a' + 10);
  if ((ch >= '0') && (ch <= '9'))
	return (ch - '0');
  if ((ch >= 'A') && (ch <= 'F'))
	return (ch - 'A' + 10);
  return (-1);
}

static char remcomInBuffer[BUFMAX];
static char remcomOutBuffer[BUFMAX];

/* scan for the sequence $<data>#<checksum> 	*/

char *
getpacket (void)
{
  char *buffer = &remcomInBuffer[0];
  unsigned char checksum;
  unsigned char xmitcsum;
  int count;
  char ch;

  while (1)
	{
	  /* wait around for the start character, ignore all other characters */
	  while ((ch = getDebugChar ()) != '$')
		;

	retry:
	  checksum = 0;
	  xmitcsum = -1;
	  count = 0;

	  /* now, read until a # or end of buffer is found */
	  while (count < BUFMAX)
		{
		  ch = getDebugChar ();
		  if (ch == '$')
			goto retry;
		  if (ch == '#')
			break;
		  checksum = checksum + ch;
		  buffer[count] = ch;
		  count = count + 1;
		}
	  buffer[count] = 0;

	  if (ch == '#')
		{
		  ch = getDebugChar ();
		  xmitcsum = hex (ch) << 4;
		  ch = getDebugChar ();
		  xmitcsum += hex (ch);

		  if (checksum != xmitcsum)
			{
			  if (remote_debug)
				{
				  fprintf (stderr,
						   "bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
						   checksum, xmitcsum, buffer);
				}
			  putDebugChar ('-');		/* failed checksum */
			}
		  else
			{
			  putDebugChar ('+');		/* successful transfer */

			  /* if a sequence char is present, reply the sequence ID */
			  if (buffer[2] == ':')
				{
				  putDebugChar (buffer[0]);
				  putDebugChar (buffer[1]);

				  return &buffer[3];
				}

			  return &buffer[0];
			}
		}
	}
}

/* send the packet in buffer.  */

void
putpacket (char *buffer)
{
  unsigned char checksum;
  int count;
  char ch;

  /*  $<packet info>#<checksum>. */
  do
	{
	  putDebugChar ('$');
	  checksum = 0;
	  count = 0;

	  while ((ch = buffer[count]) != 0)
		{
		  putDebugChar (ch);
		  checksum += ch;
		  count += 1;
		}

	  putDebugChar ('#');
	  putDebugChar (hexchars[checksum >> 4]);
	  putDebugChar (hexchars[checksum % 16]);

	}
  while (getDebugChar () != '+');
}

void debug_error (char* format/*, char* parm*/)
{
  if (remote_debug)
    fprintf (stderr, format/*, parm*/);
}

/* Address of a routine to RTE to if we get a memory fault.  */
static void (*volatile mem_fault_routine) () = NULL;

/* Indicate to caller of mem2hex or hex2mem that there has been an
   error.  */
static volatile int mem_err = 0;

void
set_mem_err (void)
{
  mem_err = 1;
}

/* These are separate functions so that they are so short and sweet
   that the compiler won't save any registers (if there is a fault
   to mem_fault, they won't get restored, so there better not be any
   saved).	*/
int
get_char (char *addr)
{
  return *addr;
}

void
set_char (char *addr, int val)
{
  *addr = val;
}

/* convert the memory pointed to by mem into hex, placing result in buf */
/* return a pointer to the last char put in buf (null) */
/* If MAY_FAULT is non-zero, then we should set mem_err in response to
   a fault; if zero treat a fault like any other fault in the stub.  */
char *
mem2hex (mem, buf, count, may_fault)
	 char *mem;
	 char *buf;
	 int count;
	 int may_fault;
{
  int i;
  unsigned char ch;

#ifdef WIN32 //MF
  if (IsBadReadPtr(mem, count))
	return mem;
#else
  if (may_fault)
	mem_fault_routine = set_mem_err;
#endif
  for (i = 0; i < count; i++)
	{
	  ch = get_char (mem++);
	  if (may_fault && mem_err)
		return (buf);
	  *buf++ = hexchars[ch >> 4];
	  *buf++ = hexchars[ch % 16];
	}
  *buf = 0;
#ifndef WIN32 //MF
  if (may_fault)
	mem_fault_routine = NULL;
#endif
  return (buf);
}

/* convert the hex array pointed to by buf into binary to be placed in mem */
/* return a pointer to the character AFTER the last byte written */
char *
hex2mem (buf, mem, count, may_fault)
	 char *buf;
	 char *mem;
	 int count;
	 int may_fault;
{
  int i;
  unsigned char ch;

#ifdef WIN32 //MF
   // MinGW does not support structured exception handling, so let's
   // go safe and make memory writable by default
  DWORD old_protect;

  VirtualProtect(mem, count, PAGE_EXECUTE_READWRITE, &old_protect);
#else
  if (may_fault)
	mem_fault_routine = set_mem_err;
#endif

  for (i = 0; i < count; i++)
	{
	  ch = hex (*buf++) << 4;
	  ch = ch + hex (*buf++);
	  set_char (mem++, ch);
	  if (may_fault && mem_err)
		return (mem);
	}

#ifndef WIN32 //MF
  if (may_fault)
	mem_fault_routine = NULL;
#endif

  return (mem);
}

/* this function takes the 386 exception vector and attempts to
   translate this number into a unix compatible signal value */
int
computeSignal (int exceptionVector)
{
  int sigval;
  switch (exceptionVector)
	{
	case 0:
	  sigval = 8;
	  break;					/* divide by zero */
	case 1:
	  sigval = 5;
	  break;					/* debug exception */
	case 3:
	  sigval = 5;
	  break;					/* breakpoint */
	case 4:
	  sigval = 16;
	  break;					/* into instruction (overflow) */
	case 5:
	  sigval = 16;
	  break;					/* bound instruction */
	case 6:
	  sigval = 4;
	  break;					/* Invalid opcode */
	case 7:
	  sigval = 8;
	  break;					/* coprocessor not available */
	case 8:
	  sigval = 7;
	  break;					/* double fault */
	case 9:
	  sigval = 11;
	  break;					/* coprocessor segment overrun */
	case 10:
	  sigval = 11;
	  break;					/* Invalid TSS */
	case 11:
	  sigval = 11;
	  break;					/* Segment not present */
	case 12:
	  sigval = 11;
	  break;					/* stack exception */
	case 13:
	  sigval = 11;
	  break;					/* general protection */
	case 14:
	  sigval = 11;
	  break;					/* page fault */
	case 16:
	  sigval = 7;
	  break;					/* coprocessor error */
	default:
	  sigval = 7;				/* "software generated" */
	}
  return (sigval);
}

/**********************************************/
/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
/* RETURN NUMBER OF CHARS PROCESSED 		  */
/**********************************************/
int
hexToInt (char **ptr, int *intValue)
{
  int numChars = 0;
  int hexValue;

  *intValue = 0;

  while (**ptr)
	{
	  hexValue = hex (**ptr);
	  if (hexValue >= 0)
		{
		  *intValue = (*intValue << 4) | hexValue;
		  numChars++;
		}
	  else
		break;

	  (*ptr)++;
	}

  return (numChars);
}

/*
 * This function does all command procesing for interfacing to gdb.
 */
void
handle_exception (int exceptionVector)
{
  int sigval, stepping;
  int addr, length;
  char *ptr;
  int newPC;

#ifndef WIN32 //MF
  gdb_i386vector = exceptionVector;
#endif

  if (remote_debug)
	{
	  printf ("vector=%d, sr=0x%x, pc=0x%x\n",
			  exceptionVector, registers[PS], registers[PC]);
	}

  /* reply to host that an exception has occurred */
  sigval = computeSignal (exceptionVector);

  ptr = remcomOutBuffer;

⌨️ 快捷键说明

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