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

📄 module.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

  desc:
    resolve a function address from a hint string
 *****************************************************************************/
DWORD Module::resolve_imp_hint_str(const ModuleList &module_list, DWORD hint, const string &str) const{
  // no rva nothing to resolve
  if(!m_e32.e32_unit[EXP].rva)
    return 0;

  ExpHdr *expptr = (ExpHdr *)rva2ptr(m_e32.e32_unit[EXP].rva);
  DWORD *eatptr = (DWORD *)rva2ptr(expptr->exp_eat);
  WORD *ordptr = (WORD *)rva2ptr(expptr->exp_ordinal);
  char **nameptr = (char **)rva2ptr(expptr->exp_name);
  DWORD ret = 0;

  if(hint >= expptr->exp_namecnt || str != (char *)rva2ptr((DWORD)nameptr[hint]))
    ret = resolve_imp_str(module_list, str);
  else
    ret = addr_from_eat(module_list, eatptr[ordptr[hint]]);

  if(!ret)
    cerr << "Error: Can't find import " << str << " hint " << hint << " in " << m_name << endl;
  
  return ret;
}

/*****************************************************************************
  truncate_o32()

  in:
    none
    
  out:
    boolean value indicating success

  desc:
    truncate a module's o32 data section
 *****************************************************************************/
DWORD Module::truncate_o32(O32 &o32){
  DWORD length = o32.min_size();

  // truncate the data
  BYTE *ptr = (BYTE *)rva2ptr(o32.o32_rva) + length;
  while(length && !*--ptr)
    length--;

  o32.o32_psize = length;

  return o32.o32_psize;
}

/*****************************************************************************
  compress_o32()

  in:
    none
    
  out:
    boolean value indicating success

  desc:
    compress a module's o32 data section
 *****************************************************************************/
DWORD Module::compress_o32(O32 &o32){
  if(o32.is_writable())
    truncate_o32(o32);

  if(!o32.min_size())
    return 0; // skip furthur processing since there is nothing to compress

  // compress the section
  Data compressed_data;
  DWORD compressed_size;

  compressed_size = m_compressor->cecompress((BYTE *)rva2ptr(o32.o32_rva), 
                                             o32.min_size(), 
                                             compressed_data.user_fill(o32.min_size()), 
                                             o32.min_size() - 1, 
                                             1, 
                                             page_size());

  if(compressed_size == -1) // failure, just make sure it's marked as aligned
    o32.o32_flags |= IMAGE_SCN_ALIGN_4BYTES;  // flag is ignored in rest of romimage
  else if(!compressed_size) // compressed to all zeros
    o32.o32_psize = 0;
  else{ // compression worked
    o32.data.set(compressed_data.ptr(), compressed_size); // chose not to use = operator to allow for explicit resize
    o32.o32_flags |= IMAGE_SCN_COMPRESSED;
    o32.o32_psize = compressed_size;
  }

  return o32.o32_psize;
}

/*****************************************************************************
  Module()

  in:
    varies
    
  out:
    none

  desc:
    initializes the class variables
 *****************************************************************************/
Module::Module(const string &file):File(file){
  memset(&m_e32, 0, sizeof(m_e32));
  m_o32_list.clear();

  m_profile.m_function_list.clear();
  memset(&m_profile, 0, sizeof(m_profile));
  
  m_kernel_fixup_list.clear();

  m_file_attributes = FILE_ATTRIBUTE_READONLY;

  set_code_split(true);
  set_module();

  // information for relocation
  m_e32_offset = 0;
  m_o32_offset = 0;
  m_vreloc  = 0;

  // map symbol information
  m_TOC_offset        = 0;
  m_ROM_extensions    = 0;
  m_reset_vector      = 0;
  m_reset_vector_end  = 0;
  m_reset_vector_addr = 0;
}

/*****************************************************************************
  init_kernel()

  in:
    fixup - wether or not we want to fix up the kernel

  out:
    none
    
  desc:
    sets some flags dealing with witch module is the kernel
 *****************************************************************************/
bool Module::init_kernel(bool fixup, const Memory &ram_section){
  if(name() == "nk.exe"){
    m_flags |= FLAG_KERNEL;
    if(fixup) 
      m_flags |= FLAG_KERNEL_FIXUP;

    memory_iterator()->init_kernel();
  }
  else{
    cerr << "Warning: No kernel module found" << endl;
  }
 
  assert(ram_section.type() == RAM_TYPE);

  memset(&s_romhdr, 0, sizeof(s_romhdr));
  s_romhdr.ulRAMStart = ram_section.address();
  s_romhdr.ulRAMFree  = ram_section.address();
  s_romhdr.ulRAMEnd   = ram_section.address() + ram_section.length();
  
  return s_romhdr.ulRAMStart != 0 || s_romhdr.ulRAMEnd != 0;
}

/*****************************************************************************
  sync_names()

  in:
    none

  out:
    boolean value indicating success
    
  desc:
    check if path name and file name are different: 
    
      m_name = nk.bin, m_release_path = d:\nk32.bin
      optional m_build_path = public\projects\nkexe\SH3_rel\
      
    if so, copy nk32.bin to nk.bin and copy the pdb and map file also.
 *****************************************************************************/
bool Module::sync_names(bool profile, bool copy_files){
  // check to see if the names differ
  if(is_kernel() && profile){
    m_release_path = lowercase(m_release_path);
    
    if(m_release_path.find("nk.exe") != string::npos ||
       m_release_path.find("nknodbg.exe") != string::npos)
      m_release_path = m_release_path.substr(0, m_release_path.rfind("\\") + 1) + "nkprof.exe";
  }
  
  if(!copy_files)
    return true;
  
  if(m_name != m_release_path.substr(m_release_path.rfind("\\") + 1)){
    string t_to = m_release_path.substr(0, m_release_path.rfind("\\") + 1) + m_name;  // replace with short name
    string t_from = m_release_path;

    cout << "Copying " << t_from << " to " << t_to << " for debugger\n";
    
    m_release_path = t_to;  // update the qualified path with the new name
    if(!CopyFile(t_from.c_str(), t_to.c_str(), false)){
      cerr << "Error: Failed copying " << t_from << " to " << t_to << endl;
      return false;
    }

    t_to.replace(t_to.rfind('.'), 4, ".pdb");
    t_from.replace(t_from.rfind('.'), 4, ".pdb");
    if(t_from != t_to && !CopyFile(t_from.c_str(), t_to.c_str(), false)){
//      cerr << "Warning: Failed copying " << t_from << " to " << t_to << endl;
    }

    t_to.replace(t_to.rfind('.'), 4, ".map");
    t_from.replace(t_from.rfind('.'), 4, ".map");
    if(t_from != t_to && !CopyFile(t_from.c_str(), t_to.c_str(), false)){
//      cerr << "Warning: Failed copying " << t_from << " to " << t_to << endl;
    }

    t_to.replace(t_to.rfind('.'), 4, ".rel");
    t_from.replace(t_from.rfind('.'), 4, ".rel");
    if(t_from != t_to && !CopyFile(t_from.c_str(), t_to.c_str(), false)){
//      cerr << "Warning: Failed copying " << t_from << " to " << t_to << endl;
    }
  }

  if(fixup_like_kernel()){
    string reloc_file = m_release_path;  // replace with short name
    reloc_file.replace(reloc_file.rfind('.'), 4, ".rel");
    
    if(GetFileAttributes(reloc_file.c_str()) == -1){
      cerr << "Error: Module " << m_name << " reqested kernel fixup and couldn't find required .rel file\n";
      return false;
    }
  }    

  return true;
}

/*****************************************************************************
  add_sig_files()

  in:

  out:

  desc:
 *****************************************************************************/

bool Module::add_sig_files(FileList &file_list){
  if(!needs_signing())
    return true;

  // add a signature file for this module, named in the form
  // "module-suffix.sig"
  string sig_name = name();
  string release_path;
  int pos = sig_name.rfind('.');

  if(pos != string::npos)
    sig_name[pos] = '-';
  
  sig_name += ".sig";
  release_path = m_release_path.substr(0, m_release_path.rfind("\\") + 1) + sig_name;

  if(GetFileAttributes(release_path.c_str()) == -1){
    ofstream sig_file(release_path.c_str(), ios::trunc);
    if(sig_file.bad()){
      cerr << "Error: Could not open '" << release_path << "' for writing\n";
      return false;
    }
  
    sig_file << "This is a place holder for sig info";
    sig_file.flush();
    sig_file.close();
  }

  File file;

  if(!file.set(sig_name, release_path, FILE_ATTRIBUTE_READONLY, memory_iterator(), m_compressor))
    return false;

  file_list.push_back(file);

  m_signature_file = file_list.end();
  m_signature_file--;

  return true;
}

/*****************************************************************************
  load()

  in:
    none

  out:
    boolean value indicating success

  desc:
    reads in the e32 structure, the o32 structures, the o32 data areas (if 
    any), and possible debuf fixup tables if we're the kernel

    does a couple basic checks on the data also
 *****************************************************************************/
bool Module::load(){
  DWORD e32_ptr;
  DWORD debug_offset;
  
  ifstream file(m_release_path.c_str(), ios::in | ios::binary);
  if(file.bad()){
    cerr << "Error: Could not open '" << m_release_path << "' for reading\n";
    return false;
  }

  file.seekg(0x3c); // e32 pointer offset
  file.read((char *)&e32_ptr, sizeof(e32_ptr));
  if(file.fail()){
    cerr << "Error: Failed reading e32 pointer in module " << m_name << endl;
    return false;
  }

  file.seekg(e32_ptr);
  file.read((char *)&m_e32, sizeof(m_e32));
  if(file.fail()){
    cerr << "Error: Failed reading e32 structure in module " << m_name << endl;
    return false;
  }

  if(!m_e32.e32_objalign){
    cerr << "Warning: Page Size is zero, forcing to " << s_page_size << " in module " << m_name << endl;
    m_e32.e32_objalign = s_page_size;
  }

  if(m_e32.e32_objalign != s_page_size){
    cerr << "Error: only 4k page alignments supported at this time, found in module " << m_name << endl;
    return false;
  }

  if(!m_e32.e32_vsize){
    cerr << "Error: Invalid size specification (e32_vsize == 0) in module " << m_name << endl;
    return false;
  }

  // might as well be thorough
  if(m_e32.e32_magic[0] != 'P'  ||
     m_e32.e32_magic[1] != 'E'  ||
     m_e32.e32_magic[2] != '\0' ||
     m_e32.e32_magic[3] != '\0' ){
    cerr << "Error: Image signature invalid: found '" << m_e32.e32_magic 
         << "' where '" << "PE" << "' expected in module " << m_name << endl;
    return false;
  }

  bool resource_only = true;

  // read all objects
  for(int i = 0; i < m_e32.e32_objcnt; i++){
    O32 o32;
    
    file.seekg(e32_ptr + sizeof(m_e32) + i * sizeof(o32_obj));
    file.read((char *)&o32, sizeof(o32_obj));
    if(file.fail()){
      cerr << "Error: Failed reading o32 structure in module " << m_name << endl;
      return false;
    }

    if(o32.o32_rva <= m_e32.e32_unit[DEB].rva && m_e32.e32_unit[DEB].rva < o32.o32_rva + o32.o32_vsize)
      debug_offset = o32.o32_dataptr - o32.o32_rva + m_e32.e32_unit[DEB].rva;

    if(o32.o32_dataptr && o32.o32_psize){
      file.seekg(o32.o32_dataptr);
      file.read((char *)o32.data.user_fill(o32.o32_psize), o32.o32_psize);
      if(file.fail()){
        cerr << "Error: Failed reading o32 data in module " << m_name << endl;
        return false;
      }
    }

    if(o32.name() == ".rsrc")
      o32.o32_flags &= ~IMAGE_SCN_MEM_WRITE;
    else
      resource_only = false;

    if(m_flags & IMAGE_SCN_MEM_NOT_PAGED)
      o32.o32_flags |= IMAGE_SCN_MEM_NOT_PAGED;

    m_o32_list.push_back(o32);
  }

  if(resource_only){
    fprintf(stderr, "Found a resource only dll %s\n", m_name.c_str());
    m_flags |= FLAG_RESOURCE_ONLY;
  }

  // read in debugging info for kernel fixups, if appropriate
  if(!s_cpu_id){

⌨️ 快捷键说明

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