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

📄 i386-stub-win32.c

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

  *ptr++ = 'T'; 				/* notify gdb with signo, PC, FP and SP */
  *ptr++ = hexchars[sigval >> 4];
  *ptr++ = hexchars[sigval & 0xf];

  *ptr++ = hexchars[ESP];
  *ptr++ = ':';
  ptr = mem2hex((char *)&registers[ESP], ptr, 4, 0);	/* SP */
  *ptr++ = ';';

  *ptr++ = hexchars[EBP];
  *ptr++ = ':';
  ptr = mem2hex((char *)&registers[EBP], ptr, 4, 0);	/* FP */
  *ptr++ = ';';

  *ptr++ = hexchars[PC];
  *ptr++ = ':';
  ptr = mem2hex((char *)&registers[PC], ptr, 4, 0); 	/* PC */
  *ptr++ = ';';

  *ptr = '\0';

  putpacket (remcomOutBuffer);

  stepping = 0;

  while (1 == 1)
	{
	  remcomOutBuffer[0] = 0;
	  ptr = getpacket ();

	  switch (*ptr++)
		{
		case '?':
		  remcomOutBuffer[0] = 'S';
		  remcomOutBuffer[1] = hexchars[sigval >> 4];
		  remcomOutBuffer[2] = hexchars[sigval % 16];
		  remcomOutBuffer[3] = 0;
		  break;
		case 'd':
		  remote_debug = !(remote_debug);		/* toggle debug flag */
		  break;
		case 'g':				/* return the value of the CPU registers */
		  mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0);
		  break;
		case 'G':				/* set the value of the CPU registers - return OK */
		  hex2mem (ptr, (char *) registers, NUMREGBYTES, 0);
		  strcpy_s(remcomOutBuffer, BUFMAX, "OK");
		  break;
		case 'P':				/* set the value of a single CPU register - return OK */
		  {
			int regno;

			if (hexToInt (&ptr, &regno) && *ptr++ == '=')
			  if (regno >= 0 && regno < NUMREGS)
				{
				  hex2mem (ptr, (char *) &registers[regno], 4, 0);
				  strcpy_s(remcomOutBuffer, BUFMAX, "OK");
				  break;
				}

			strcpy_s(remcomOutBuffer, BUFMAX, "E01");
			break;
		  }

		  /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
		case 'm':
		  /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
		  if (hexToInt (&ptr, &addr))
			if (*(ptr++) == ',')
			  if (hexToInt (&ptr, &length))
				{
				  ptr = 0;
				  mem_err = 0;
				  mem2hex ((char *) addr, remcomOutBuffer, length, 1);
				  if (mem_err)
					{
					  strcpy_s(remcomOutBuffer, BUFMAX, "E03");
					  debug_error ("memory fault");
					}
				}

		  if (ptr)
			{
			  strcpy_s(remcomOutBuffer, BUFMAX, "E01");
			}
		  break;

		  /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
		case 'M':
		  /* TRY TO READ '%x,%x:'.	IF SUCCEED, SET PTR = 0 */
		  if (hexToInt (&ptr, &addr))
			if (*(ptr++) == ',')
			  if (hexToInt (&ptr, &length))
				if (*(ptr++) == ':')
				  {
					mem_err = 0;
					hex2mem (ptr, (char *) addr, length, 1);

					if (mem_err)
					  {
						strcpy_s(remcomOutBuffer, BUFMAX, "E03");
						debug_error ("memory fault");
					  }
					else
					  {
						strcpy_s(remcomOutBuffer, BUFMAX, "OK");
					  }

					ptr = 0;
				  }
		  if (ptr)
			{
			  strcpy_s(remcomOutBuffer, BUFMAX, "E02");
			}
		  break;

		  /* cAA..AA	Continue at address AA..AA(optional) */
		  /* sAA..AA   Step one instruction from AA..AA(optional) */
		case 's':
		  stepping = 1;
		case 'c':
		  /* try to read optional parameter, pc unchanged if no parm */
		  if (hexToInt (&ptr, &addr))
			registers[PC] = addr;

		  newPC = registers[PC];

		  /* clear the trace bit */
		  registers[PS] &= 0xfffffeff;

		  /* set the trace bit if we're stepping */
		  if (stepping)
			registers[PS] |= 0x100;

#ifdef WIN32 //MF
		  return;
#else
		  _returnFromException ();		/* this is a jump */
#endif
		  break;

		  /* kill the program */
		case 'k':				/* do nothing */
#if 0
		  /* Huh? This doesn't look like "nothing".
			 m68k-stub.c and sparc-stub.c don't have it.  */
		  BREAKPOINT ();
#endif
		  break;
		}						/* switch */

	  /* reply to the request */
	  putpacket (remcomOutBuffer);
	}
}

/* this function is used to set up exception handlers for tracing and
   breakpoints */
void
set_debug_traps (void)
{
#ifndef WIN32 //MF
  stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];

  exceptionHandler (0, _catchException0);
  exceptionHandler (1, _catchException1);
  exceptionHandler (3, _catchException3);
  exceptionHandler (4, _catchException4);
  exceptionHandler (5, _catchException5);
  exceptionHandler (6, _catchException6);
  exceptionHandler (7, _catchException7);
  exceptionHandler (8, _catchException8);
  exceptionHandler (9, _catchException9);
  exceptionHandler (10, _catchException10);
  exceptionHandler (11, _catchException11);
  exceptionHandler (12, _catchException12);
  exceptionHandler (13, _catchException13);
  exceptionHandler (14, _catchException14);
  exceptionHandler (16, _catchException16);
#endif // WIN32

  initialized = 1;
}

/* This function will generate a breakpoint exception.	It is used at the
   beginning of a program to sync up with a debugger and can be used
   otherwise as a quick means to stop program execution and "break" into
   the debugger. */

void
breakpoint (void)
{
  if (initialized)
	BREAKPOINT ();
}



 //
 // debugger stub implementation for WIN32 applications
 // M. Fuchs, 29.11.2003
 //

#ifdef WIN32

#include <stdlib.h>
#include <errno.h>

#include "utility/utility.h"


int s_initial_breakpoint = 0;


#ifdef DEBUG_SERIAL

FILE* ser_port = NULL;

int init_gdb_connect()
{
		 //TODO: set up connection using serial communication port

		ser_port = fopen("COM1:", "rwb");

		return 1;
}

int getDebugChar()
{
		return fgetc(ser_port);
}

void putDebugChar(int c)
{
		fputc(c, ser_port);
}


#else // DEBUG_SERIAL


static LPTOP_LEVEL_EXCEPTION_FILTER s_prev_exc_handler = 0;


#define I386_EXCEPTION_CNT		17

LONG WINAPI exc_protection_handler(EXCEPTION_POINTERS* exc_info)
{
		int exc_nr = exc_info->ExceptionRecord->ExceptionCode & 0xFFFF;

		if (exc_nr < I386_EXCEPTION_CNT) {
				//LOG(FmtString(TEXT("exc_protection_handler: Exception %x"), exc_nr));

				if (exc_nr==11 || exc_nr==13 || exc_nr==14) {
						if (mem_fault_routine)
								mem_fault_routine();
				}

				++exc_info->ContextRecord->Eip;
		}

		return EXCEPTION_CONTINUE_EXECUTION;
}

LONG WINAPI exc_handler(EXCEPTION_POINTERS* exc_info)
{
		int exc_nr = exc_info->ExceptionRecord->ExceptionCode & 0xFFFF;

		if (exc_nr < I386_EXCEPTION_CNT) {
				//LOG(FmtString("Exception %x", exc_nr));
				//LOG(FmtString("EIP=%08X EFLAGS=%08X", exc_info->ContextRecord->Eip, exc_info->ContextRecord->EFlags));

				 // step over initial breakpoint
				if (s_initial_breakpoint) {
						s_initial_breakpoint = 0;
						++exc_info->ContextRecord->Eip;
				}

				SetUnhandledExceptionFilter(exc_protection_handler);

				win32_exception_handler(exc_info);
				//LOG(FmtString("EIP=%08X EFLAGS=%08X", exc_info->ContextRecord->Eip, exc_info->ContextRecord->EFlags));

				SetUnhandledExceptionFilter(exc_handler);

				return EXCEPTION_CONTINUE_EXECUTION;
		}

		return EXCEPTION_CONTINUE_SEARCH;
}

/* not needed because we use win32_exception_handler() instead of catchExceptionX()
void exceptionHandler(int exc_nr, void* exc_addr)
{
		if (exc_nr>=0 && exc_nr<I386_EXCEPTION_CNT)
				exc_handlers[exc_nr] = exc_addr;
}
*/

void disable_debugging()
{
		if (s_prev_exc_handler) {
				SetUnhandledExceptionFilter(s_prev_exc_handler);
				s_prev_exc_handler = 0;
		}
}


#include <winsock.h>
#ifdef _MSC_VER
#pragma comment(lib, "wsock32")
#endif

static int s_rem_fd = -1;

int init_gdb_connect()
{
		SOCKADDR_IN srv_addr = {0};
		SOCKADDR_IN rem_addr;
		WSADATA wsa_data;
		int srv_socket, rem_len;

		s_prev_exc_handler = SetUnhandledExceptionFilter(exc_handler);

		if (WSAStartup(MAKEWORD(2,2), &wsa_data)) {
				fprintf(stderr, "WSAStartup() failed");
				return 0;
		}

		srv_addr.sin_family = AF_INET;
		srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
		srv_addr.sin_port = htons(9999);

		srv_socket = socket(PF_INET, SOCK_STREAM, 0);
		if (srv_socket == -1) {
				perror("socket()");
				return 0;
		}

		if (bind(srv_socket, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) {
				perror("bind()");
				return 0;
		}

		if (listen(srv_socket, 4) == -1) {
				perror("listen()");
				return 0;
		}

		rem_len = sizeof(rem_addr);

		for(;;) {
				s_rem_fd = accept(srv_socket, (struct sockaddr*)&rem_addr, &rem_len);

				if (s_rem_fd < 0) {
						if (errno == EINTR)
								continue;

						perror("accept()");
						return 0;
				}

				break;
		}

		return 1;
}

#endif // DEBUG_SERIAL


int getDebugChar()
{
		char buffer[1024];
		int r;

		if (s_rem_fd == -1)
				return EOF;

		r = recv(s_rem_fd, buffer, 1, 0);
		if (r == -1) {
				perror("recv()");
				LOG(TEXT("debugger connection broken"));
				s_rem_fd = -1;
				return EOF;
		}

		if (!r)
				return EOF;

		return buffer[0];
}

void putDebugChar(int c)
{
		if (s_rem_fd != -1) {
				const char buffer[] = {c};

				if (!send(s_rem_fd, buffer, 1, 0)) {
						perror("send()");
						LOG(TEXT("debugger connection broken"));
						exit(-1);
				}
		}
}


 // start up GDB stub interface

int initialize_gdb_stub()
{
		if (!init_gdb_connect())
				return 0;

		set_debug_traps();

		s_initial_breakpoint = 1;
		breakpoint();

		return 1;
}

#endif // WIN32

⌨️ 快捷键说明

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