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

📄 dumper.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* dumper.cc   Copyright 1999, 2001, 2002 Red Hat Inc.   Written by Egor Duda <deo@logos-m.ru>   This file is part of Cygwin.   This software is a copyrighted work licensed under the terms of the   Cygwin license.  Please consult the file "CYGWIN_LICENSE" for   details. */#include <bfd.h>#include <elf/common.h>#include <elf/external.h>#include <sys/procfs.h>#include <sys/cygwin.h>#include <getopt.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <windows.h>#include "dumper.h"#define NOTE_NAME_SIZE 16typedef struct _note_header  {    Elf_External_Note elf_note_header;    char name[NOTE_NAME_SIZE - 1];	/* external note contains first byte of data */  }#ifdef __GNUC____attribute__ ((packed))#endif  note_header;static const char version[] = "$Revision: 1.9 $";BOOL verbose = FALSE;int deb_printf (const char *format,...){  if (!verbose)    return 0;  va_list va;  va_start (va, format);  int ret_val = vprintf (format, va);  va_end (va);  return ret_val;}dumper::dumper (DWORD pid, DWORD tid, const char *file_name){  this->file_name = strdup (file_name);  this->pid = pid;  this->tid = tid;  core_bfd = NULL;  excl_list = new exclusion (20);  list = last = NULL;  status_section = NULL;  memory_num = module_num = thread_num = 0;  hProcess = OpenProcess (PROCESS_ALL_ACCESS,			  FALSE,	/* no inheritance */			  pid);  if (!hProcess)    {      fprintf (stderr, "Failed to open process #%lu, error %ld\n", pid, GetLastError ());      return;    }  init_core_dump ();  if (!sane ())    dumper_abort ();}dumper::~dumper (){  close ();  free (file_name);}voiddumper::dumper_abort (){  close ();  unlink (file_name);}voiddumper::close (){  if (core_bfd)    bfd_close (core_bfd);  if (excl_list)    delete excl_list;  if (hProcess)    CloseHandle (hProcess);  core_bfd = NULL;  hProcess = NULL;  excl_list = NULL;}intdumper::sane (){  if (hProcess == NULL || core_bfd == NULL || excl_list == NULL)    return 0;  return 1;}voidprint_section_name (bfd* abfd, asection* sect, PTR obj){  deb_printf (" %s", bfd_get_section_name (abfd, sect));}voiddumper::print_core_section_list (){  deb_printf ("current sections:");  bfd_map_over_sections (core_bfd, &print_section_name, NULL);  deb_printf ("\n");}process_entity *dumper::add_process_entity_to_list (process_entity_type type){  if (!sane ())    return NULL;  process_entity *new_entity = (process_entity *) malloc (sizeof (process_entity));  if (new_entity == NULL)    return NULL;  new_entity->next = NULL;  new_entity->section = NULL;  if (last == NULL)    list = new_entity;  else    last->next = new_entity;  last = new_entity;  return new_entity;}intdumper::add_thread (DWORD tid, HANDLE hThread){  if (!sane ())    return 0;  CONTEXT *pcontext;  process_entity *new_entity = add_process_entity_to_list (pr_ent_thread);  if (new_entity == NULL)    return 0;  new_entity->type = pr_ent_thread;  thread_num++;  new_entity->u.thread.tid = tid;  new_entity->u.thread.hThread = hThread;  pcontext = &(new_entity->u.thread.context);  pcontext->ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;  if (!GetThreadContext (hThread, pcontext))    {      deb_printf ("Failed to read thread context (tid=%x), error %ld\n", tid, GetLastError ());      return 0;    }  deb_printf ("added thread %u\n", tid);  return 1;}intdumper::add_mem_region (LPBYTE base, DWORD size){  if (!sane ())    return 0;  if (base == NULL || size == 0)    return 1;			// just ignore empty regions  process_entity *new_entity = add_process_entity_to_list (pr_ent_memory);  if (new_entity == NULL)    return 0;  new_entity->type = pr_ent_memory;  memory_num++;  new_entity->u.memory.base = base;  new_entity->u.memory.size = size;  deb_printf ("added memory region %08x-%08x\n", (DWORD) base, (DWORD) base + size);  return 1;}/* split_add_mem_region scans list of regions to be excluded from dumping process   (excl_list) and removes all "excluded" parts from given region. */intdumper::split_add_mem_region (LPBYTE base, DWORD size){  if (!sane ())    return 0;  if (base == NULL || size == 0)    return 1;			// just ignore empty regions  LPBYTE last_base = base;  for (process_mem_region * p = excl_list->region;       p < excl_list->region + excl_list->last;       p++)    {      if (p->base >= base + size || p->base + p->size <= base)	continue;      if (p->base <= base)	{	  last_base = p->base + p->size;	  continue;	}      add_mem_region (last_base, p->base - last_base);      last_base = p->base + p->size;    }  if (last_base < base + size)    add_mem_region (last_base, base + size - last_base);  return 1;}intdumper::add_module (LPVOID base_address){  if (!sane ())    return 0;  char *module_name = psapi_get_module_name (hProcess, (DWORD) base_address);  if (module_name == NULL)    return 1;  process_entity *new_entity = add_process_entity_to_list (pr_ent_module);  if (new_entity == NULL)    return 0;  new_entity->type = pr_ent_module;  module_num++;  new_entity->u.module.base_address = base_address;  new_entity->u.module.name = module_name;  parse_pe (module_name, excl_list);  deb_printf ("added module %08x %s\n", base_address, module_name);  return 1;}#define PAGE_BUFFER_SIZE 4096intdumper::collect_memory_sections (){  if (!sane ())    return 0;  LPBYTE current_page_address;  LPBYTE last_base = (LPBYTE) 0xFFFFFFFF;  DWORD last_size = 0;  DWORD done;  char mem_buf[PAGE_BUFFER_SIZE];  MEMORY_BASIC_INFORMATION mbi;  if (hProcess == NULL)    return 0;  for (current_page_address = 0; current_page_address < (LPBYTE) 0xFFFF0000;)    {      if (!VirtualQueryEx (hProcess, current_page_address, &mbi, sizeof (mbi)))	break;      int skip_region_p = 0;      if (mbi.Protect & (PAGE_NOACCESS | PAGE_GUARD) ||	  mbi.State != MEM_COMMIT)	skip_region_p = 1;      if (!skip_region_p)	{	  /* just to make sure that later we'll be able to read it.	     According to MS docs either region is all-readable or	     all-nonreadable */	  if (!ReadProcessMemory (hProcess, current_page_address, mem_buf, sizeof (mem_buf), &done))	    {	      DWORD err = GetLastError ();	      const char *pt[10];	      pt[0] = (mbi.Protect & PAGE_READONLY) ? "RO " : "";	      pt[1] = (mbi.Protect & PAGE_READWRITE) ? "RW " : "";	      pt[2] = (mbi.Protect & PAGE_WRITECOPY) ? "WC " : "";	      pt[3] = (mbi.Protect & PAGE_EXECUTE) ? "EX " : "";	      pt[4] = (mbi.Protect & PAGE_EXECUTE_READ) ? "EXRO " : "";	      pt[5] = (mbi.Protect & PAGE_EXECUTE_READWRITE) ? "EXRW " : "";	      pt[6] = (mbi.Protect & PAGE_EXECUTE_WRITECOPY) ? "EXWC " : "";	      pt[7] = (mbi.Protect & PAGE_GUARD) ? "GRD " : "";	      pt[8] = (mbi.Protect & PAGE_NOACCESS) ? "NA " : "";	      pt[9] = (mbi.Protect & PAGE_NOCACHE) ? "NC " : "";	      char buf[10 * 6];	      buf[0] = '\0';	      for (int i = 0; i < 10; i++)		strcat (buf, pt[i]);	      deb_printf ("warning: failed to read memory at %08x-%08x (protect = %s), error %ld.\n",			  (DWORD) current_page_address,			  (DWORD) current_page_address + mbi.RegionSize,			  buf, err);	      skip_region_p = 1;	    }	}      if (!skip_region_p)	{	  if (last_base + last_size == current_page_address)	    last_size += mbi.RegionSize;	  else	    {	      split_add_mem_region (last_base, last_size);	      last_base = (LPBYTE) mbi.BaseAddress;	      last_size = mbi.RegionSize;	    }	}      else	{	  split_add_mem_region (last_base, last_size);	  last_base = NULL;	  last_size = 0;	}      current_page_address += mbi.RegionSize;    }  /* dump last sections, if any */  split_add_mem_region (last_base, last_size);  return 1;};intdumper::dump_memory_region (asection * to, process_mem_region * memory){  if (!sane ())    return 0;  DWORD size = memory->size;  DWORD todo;  DWORD done;  LPBYTE pos = memory->base;  DWORD sect_pos = 0;  if (to == NULL || memory == NULL)    return 0;  char mem_buf[PAGE_BUFFER_SIZE];  while (size > 0)    {      todo = min (size, PAGE_BUFFER_SIZE);      if (!ReadProcessMemory (hProcess, pos, mem_buf, todo, &done))	{	  deb_printf ("Failed to read process memory at %x(%x), error %ld\n", pos, todo, GetLastError ());	  return 0;	}      size -= done;      pos += done;      if (!bfd_set_section_contents (core_bfd, to, mem_buf, sect_pos, done))	{	  bfd_perror ("writing memory region to bfd");	  dumper_abort ();	  return 0;	};      sect_pos += done;    }  return 1;}intdumper::dump_thread (asection * to, process_thread * thread){  if (!sane ())    return 0;  if (to == NULL || thread == NULL)    return 0;  win32_pstatus thread_pstatus;  note_header header;  bfd_putl32 (NOTE_NAME_SIZE, header.elf_note_header.namesz);  bfd_putl32 (sizeof (thread_pstatus), header.elf_note_header.descsz);  bfd_putl32 (NT_WIN32PSTATUS, header.elf_note_header.type);  strncpy ((char *) &header.elf_note_header.name, "win32thread", NOTE_NAME_SIZE);  thread_pstatus.data_type = NOTE_INFO_THREAD;  thread_pstatus.data.thread_info.tid = thread->tid;  if (tid == 0)    {      /* this is a special case. we don't know, which thread         was active when exception occured, so let's blame         the first one */      thread_pstatus.data.thread_info.is_active_thread = TRUE;      tid = (DWORD) - 1;    }  else if (tid > 0 && thread->tid == tid)    thread_pstatus.data.thread_info.is_active_thread = TRUE;  else    thread_pstatus.data.thread_info.is_active_thread = FALSE;  memcpy (&(thread_pstatus.data.thread_info.thread_context),	  &(thread->context),	  sizeof (thread->context));  if (!bfd_set_section_contents (core_bfd, to, &header,				 0,				 sizeof (header)) ||      !bfd_set_section_contents (core_bfd, to, &thread_pstatus,				 sizeof (header),				 sizeof (thread_pstatus)))    {      bfd_perror ("writing thread info to bfd");      dumper_abort ();      return 0;    };  return 1;}

⌨️ 快捷键说明

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