コード例 #1
0
ファイル: SleshLibrary.cpp プロジェクト: robot-aquila/wquik
SleshLibrary::SleshLibrary(const char* moduleName) {
	find_module_path(moduleName);
	hmod = NULL;
	string error;
	ULONG retadr = 0;
	DWORD rb;
	HANDLE hFile;
	IMAGE_DOS_HEADER DosHeader;
	IMAGE_NT_HEADERS PeHeader;
	IMAGE_SECTION_HEADER Section[MAX_SECTIONS];
	char tmp[1024];

	// откроем файл на чтение
	string path = find_module_path(moduleName);
	hFile = CreateFileA(path.c_str(),
		GENERIC_READ, FILE_SHARE_READ,
		0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if ( hFile == INVALID_HANDLE_VALUE ) {
		getLastError(error, "CreateFile");
		error += ": ";
		error += moduleName;
		throw DllException(error.c_str());
	}

	// считаем DOS заголовок
	if ( ReadFile(hFile, &DosHeader, sizeof(IMAGE_DOS_HEADER), &rb, 0) == 0 ) {
		getLastError(error, "ReadFile");
		CloseHandle(hFile);
		throw DllException(error.c_str());
	}

	if (DosHeader.e_magic == IMAGE_DOS_SIGNATURE) { // проверим сигнатуру
		// если есть какимето данные между DOS заголовком и PE 
		// то считаем их. В MS компиляторах это часто Rich данные
		if (sizeof(IMAGE_DOS_HEADER) < DosHeader.e_lfanew) {
			if ( ReadFile(hFile, &tmp[0], DosHeader.e_lfanew -
				sizeof(IMAGE_DOS_HEADER), &rb, 0) == 0 )
			{
				getLastError(error, "ReadFile");
				CloseHandle(hFile);
				throw DllException(error.c_str());
			}
		}
		// установим указатель в файле на PE заголовок
		if ( SetFilePointer(hFile, DosHeader.e_lfanew, 0, FILE_BEGIN) ==
			INVALID_SET_FILE_POINTER )
		{
			getLastError(error, "SetFilePointer");
			CloseHandle(hFile);
			throw DllException(error.c_str());
		}
		// считаем заголовок
		if ( ReadFile(hFile, &PeHeader, sizeof(IMAGE_NT_HEADERS), &rb, 0) == 0 ) {
			getLastError(error, "ReadFile");
			CloseHandle(hFile);
			throw DllException(error.c_str());
		}

		if ( PeHeader.Signature == IMAGE_NT_SIGNATURE ) { // проверим сигнатуру
			// считаем 10 секций
			if ( ReadFile(hFile, &Section[0], sizeof(IMAGE_SECTION_HEADER) *
				PeHeader.FileHeader.NumberOfSections, &rb, 0) == 0 ) 
			{
				getLastError(error, "ReadFile");
				CloseHandle(hFile);
				throw DllException(error.c_str());
			}
			// выделим память столько, сколько указано в SIZE OF BASE
			retadr = (ULONG)VirtualAlloc(0, PeHeader.OptionalHeader.SizeOfImage,
				MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
			if ( retadr == NULL ) {
				getLastError(error, "VirtualAlloc");
				CloseHandle(hFile);
				throw DllException(error.c_str());
			}
			
			// скопируем туда DOS заголовок
			memcpy((void*) retadr, &DosHeader, sizeof(IMAGE_DOS_HEADER));
			// скопируем туда PE заголовок
			memcpy((void*)(retadr + DosHeader.e_lfanew), &PeHeader,
				sizeof(IMAGE_NT_HEADERS));
			// скопируем туда таблицу секций
			memcpy((void*)(retadr + DosHeader.e_lfanew + sizeof(IMAGE_NT_HEADERS)),
				&Section[0], sizeof(IMAGE_SECTION_HEADER) *
				PeHeader.FileHeader.NumberOfSections);
			// если есть Rich данные то и их тоже скопируем
			if ( sizeof(IMAGE_DOS_HEADER) < DosHeader.e_lfanew )  {
				memcpy((void*)(retadr + sizeof(IMAGE_DOS_HEADER)), &tmp[0],
					DosHeader.e_lfanew - sizeof(IMAGE_DOS_HEADER));
			}
			// обработаем каждую секцию
			for ( int i = 0; i < PeHeader.FileHeader.NumberOfSections; i++ ){
				// установим указатель в файле не начало секции в файле
				if ( SetFilePointer(hFile, Section[i].PointerToRawData, 0, FILE_BEGIN) ==
					INVALID_SET_FILE_POINTER )
				{
					getLastError(error, "SetFilePointer");
					CloseHandle(hFile);
					VirtualFree((LPVOID)retadr, 0, MEM_RELEASE); // очищаем память
					throw DllException(error.c_str());
				}
				// считаем всё секцию
				if ( ReadFile(hFile, (void*)(retadr + Section[i].VirtualAddress),
					Section[i].SizeOfRawData, &rb,0) == 0 )
				{
					getLastError(error, "ReadFile");
					CloseHandle(hFile);
					VirtualFree((LPVOID)retadr, 0, MEM_RELEASE);
					throw DllException(error.c_str());
				}
			}

			CloseHandle(hFile);

			// Обработаем релоки
			try {
				progressReloc(retadr);
				progressImport(retadr);
			} catch ( DllException e ) {
				VirtualFree((LPVOID)retadr, 0, MEM_RELEASE);
				throw DllException(e.what());
			}

			__asm {
				mov eax, PeHeader.OptionalHeader.AddressOfEntryPoint
				add eax, retadr // EAX = ENTRY POINT
				push 0
				push DLL_PROCESS_ATTACH // ставим флаг что подгрузили DLL
				push retadr
				call eax // передадим управление на точку входа в DLL 
			}
			hmod = (HMODULE)retadr;
		}
	}
}
コード例 #2
0
ファイル: modmgr.c プロジェクト: ErisBlastar/osfree
unsigned long OpenModule(char *          pszName,
                         unsigned long   cbName,
                         char const *    pszModname,
			 char            exeflag,
                         unsigned long * phmod)
{
#ifdef L4API_l4v2
  l4_addr_t pageaddr, addr2;
#endif
  #define buf_size 4096
  char buf[buf_size+1];
  char *p_buf = (char *) &buf;
  //char *orig_name = NULL;
  struct module_rec *prev;
  IXFModule *ixfModule, *ixf;
  IXFSYSDEP *ixfSysDep, *sd;
  slist_t *s, *s0, *r;
  l4exec_section_t *section;
  void *addr;
  unsigned long size;
  int  rc, t, n, i;

  // Check input arguments
  if ((phmod==NULL)||
      (pszModname==NULL)||
      (pszName==NULL)) return 87 /*ERROR_INVALID_PARAMETER*/;

  // Initialize return vars
  *pszName=0;
  *phmod=0;

  // @todo extract filename only because can be fullname with path

  char *mname = get_fname(pszModname);

  
  // Specail case - EMXWRAP.DLL. Read more in docs\os2\sub32.txt
  if (!exeflag && !strcasecmp(mname, "EMXWRAP"))
  {
    if (options.debugmodmgr) LOG("ModLoadModule: EXMWRAP module replaced by SUB32 module.");
    //mname="SUB32";
    pszModname="SUB32.DLL";
  }

  if (options.debugmodmgr) LOG("ModLoadModule: Loading module %s...", mname);

  ////
  //if (!exeflag)
    if (!(t = getrec(mname, &prev)))
    {
      if (!exeflag)
      {
        // @todo use handles here
        *phmod=(unsigned long)prev->module_struct;
        LOG("already loaded");
        return 0/*NO_ERROR*/;
      }
    }
    else if (t == -1)
    {
      LOG("mod not loaded!");
      *phmod=NULL;
      if (cbName<=strlen(mname)) return 8 /*ERROR_NOT_ENOUGH_MEMORY*/;
      strcpy(pszName, mname);
      return 5 /*ERROR_ACCESS_DENIED*/; // @todo Need more accurate code
    }

  // Ok. No module found. Try to load file
  LOG("open: %s", pszModname);
  // Consider fully-qualified name specified.
  rc=io_load_file(pszModname, &addr, &size);
  if (rc)
  {
    // Searches for module name and returns the full path in the buffer p_buf.
    LOG("io_load_file1: rc=%u", rc);

    if (!exeflag)
      rc = find_module_path(pszModname, p_buf);
    else
      rc = find_path(pszModname, p_buf);

    LOG("find_module_path: rc=%u, p_buf=%s", rc, p_buf);
    if (!rc) rc=io_load_file(p_buf, &addr, &size);
  }
  else
    LOG("successful");
  
  if (rc)
  {
    LOG("io_load_file2: rc=%u", rc);
    strcpy(pszName, pszModname);
    *phmod=NULL;
    return rc;
  }

  ixfModule = (IXFModule *)malloc(sizeof(IXFModule));
#ifdef L4API_l4v2
  ixfSysDep = (IXFSYSDEP *)malloc(sizeof(IXFSYSDEP));

  if (!t && exeflag)
  {
    // 1st instance IXFModule structure
    ixf = (IXFModule *)(prev->module_struct);
    memmove(ixfModule, ixf, sizeof(IXFModule));

    sd = (IXFSYSDEP *)(ixf->hdlSysDep);
    memmove(ixfSysDep, sd, sizeof(IXFSYSDEP));
    ixfModule->hdlSysDep = (unsigned int)ixfSysDep;

    for (i = 0, r = 0, s0 = sd->seclist; 
         s0; i++, r = s, s0 = s0->next)
    {
      s = (slist_t *)malloc(sizeof(slist_t));
      if (i == 0) // 1st loop iteration
        ixfSysDep->seclist = s;
      else
      {
        r->next = s;
	s->next = 0;
      }
      section = (l4exec_section_t *)malloc(sizeof(l4exec_section_t));
      s->section = section;
      memmove(section, s0->section, sizeof(l4exec_section_t));
      // create Copy-On-Write copy of original dataspace
      rc = l4dm_copy(&s0->section->ds, L4DM_COW, 
                     "os2exec section", &section->ds);
      if (rc)
        LOG("dataspace copy rc=%d", rc);
    }
    // @todo use handles here
    *phmod=(unsigned long)ixfModule;
    ModRegister(mname, ixfModule, exeflag);
    LOG("copy created");
    return 0/*NO_ERROR*/;
  }
  else
  {
    ixfModule->hdlSysDep = (unsigned int)ixfSysDep;
    // initialize section number to zero
    ixfSysDep->secnum = 0;
    ixfSysDep->seclist = 0;
  }
#else
  // other hosts
  // ...
#endif

  rc=IXFIdentifyModule(addr, size, ixfModule);
  if (rc)
  {
    LOG("IXFIdentifyModule: rc=%u", rc);
    strcpy(pszName, pszModname);
    *phmod=NULL;
    free((void *)(ixfModule->hdlSysDep));
    free(ixfModule);
    return rc;
  }

//save addr and size into the structure
  ixfModule->addr = addr;
  ixfModule->size = size;
  ixfModule->name = (char *)malloc(strlen(pszModname) + 1);
  strcpy(ixfModule->name, pszModname);
  ixfModule->exec = exeflag;
  //@todo use handle table
  *phmod=(unsigned long)ixfModule;

  return rc;
}