Example #1
0
void VDMInject32(HANDLE hProcess, unsigned int hwnd, const GUID* from)
{
	TCHAR szPath[MAX_PATH] = {0};
	GetPreferredModuleName(g_hModule, true, szPath);
	
	// construct arguments
	auto shared = VirtualAllocEx(hProcess, nullptr, sizeof(VDM::Shared32), MEM_COMMIT, PAGE_READWRITE);
	WriteProcessMemory(hProcess, RVA(shared, AddressOf(VDM::Shared32, hwnd)), &hwnd, sizeof(HWND), nullptr);
	WriteProcessMemory(hProcess, RVA(shared, AddressOf(VDM::Shared32, guid)), from, sizeof(*from), nullptr);

	MODULEINFO kernel32;
	GetRemoteModuleInfo(hProcess, _T("kernel32.dll"), &kernel32, true);
	auto fnLoadLibrary = GetRemoteProcAddress(hProcess, (HMODULE)kernel32.lpBaseOfDll, "LoadLibraryW", true);
	auto remote = VirtualAllocEx(hProcess, nullptr, _countof(szPath), MEM_COMMIT, PAGE_READWRITE);
	WriteProcessMemory(hProcess, remote, szPath, _countof(szPath), nullptr);
	CallOnRemoteThread(hProcess, fnLoadLibrary, remote);

	MODULEINFO vdmhelper;
	GetRemoteModuleInfo(hProcess, _T("VDMHelper32.dll"), &vdmhelper, true);
	auto fnVDMProcess = GetRemoteProcAddress(hProcess, (HMODULE)vdmhelper.lpBaseOfDll, "VDMProcess", true);
	CallOnRemoteThread(hProcess, fnVDMProcess, shared);

	auto fnFreeLibrary = GetRemoteProcAddress(hProcess, (HMODULE)kernel32.lpBaseOfDll, "FreeLibrary", true);
	CallOnRemoteThread(hProcess, fnFreeLibrary, vdmhelper.lpBaseOfDll);

	VirtualFreeEx(hProcess, remote, 0, MEM_RELEASE);
	VirtualFreeEx(hProcess, shared, 0, MEM_RELEASE);
}
Example #2
0
NTSTATUS
NTAPI
LdrPEProcessImportDirectoryEntry(PVOID DriverBase,
                                 PLOADER_MODULE LoaderModule,
                                 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory)
{
    PVOID* ImportAddressList;
    PULONG FunctionNameList;

    if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
    {
        return STATUS_UNSUCCESSFUL;
    }

    /* Get the import address list. */
    ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk);

    /* Get the list of functions to import. */
    if (ImportModuleDirectory->OriginalFirstThunk != 0)
    {
        FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk);
    }
    else
    {
        FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
    }

    /* Walk through function list and fixup addresses. */
    while (*FunctionNameList != 0L)
    {
        if ((*FunctionNameList) & 0x80000000)
        {
            DbgPrint("Failed to import ordinal from %s\n", LoaderModule->String);
            return STATUS_UNSUCCESSFUL;
        }
        else
        {
            IMAGE_IMPORT_BY_NAME *pe_name;
            pe_name = RVA(DriverBase, *FunctionNameList);
            *ImportAddressList = LdrPEGetExportByName((PVOID)LoaderModule->ModStart, pe_name->Name, pe_name->Hint);

            /* Fixup the address to be virtual */
            *ImportAddressList = (PVOID)(ULONG_PTR)*ImportAddressList + (ULONG_PTR)KernelBase - (ULONG_PTR)KernelMemory;


            //DbgPrint("Looked for: %s and found: %x\n", pe_name->Name, *ImportAddressList);
            if ((*ImportAddressList) == NULL)
            {
                DbgPrint("Failed to import %s from %s\n", pe_name->Name, LoaderModule->String);
                return STATUS_UNSUCCESSFUL;
            }
        }
        ImportAddressList++;
        FunctionNameList++;
    }
    return STATUS_SUCCESS;
}
Example #3
0
void eterm_show(int m, cmulti **x, func_t *fF, int bmax, int kappa)
{
  int kmax,k,db=64;
  int *b=NULL,tau;
  func_t *fJ=NULL;
  cmulti **y=NULL;
  rmulti **e=NULL,**eps=NULL,**em=NULL,**r=NULL,*rmax=NULL,**p=NULL;
  
  kmax=(bmax-64)/db; if(kmax<0){ kmax=2; }
  tau=cvec_get_exp_max(m,x);
  printf("tau=%d\n",tau);

  fJ=func_grad(func_retain(fF),func_var1_list(m));
  CVA(y,m); RVA(e,kmax); RVA(eps,kmax); RVA(em,kmax); RVA(r,kmax); RVA(p,kmax); RA(rmax);

  b=ivec_allocate(kmax);

  b[0]=53;
  for(k=1; k<kmax; k++){ b[k]=(k-1)*db+64; }

  for(k=0; k<kmax; k++){
    printf("b=%4d ",b[k]);
    set_default_prec(b[k]);
    rset_d(eps[k],1); rmul_2exp(eps[k],eps[k],-b[k]+tau);
    mpfr_printf("2^(-b+tau)=%8.1Re ",eps[k]);
    cvec_round(m,y,b[k]);
    csolve_newton_map(m,y,x,fF,fJ);
    csolve_newton_e_norm(e[k],m,y,x,fF,fJ,bmax*4);
    if(rgt(eps[k],e[k])){ printf("> "); }else{ printf("< "); }
    mpfr_printf("e=%8.1Re ",e[k]);
    rset_d(em[k],1); rmul_2exp(em[k],em[k],-b[k]+tau+kappa);
    if(rgt(e[k],em[k])){ printf("> "); }else{ printf("< "); }
    mpfr_printf("em=%8.1Re ",em[k]);

    rlog2(p[k],e[k]); rsub_d1(p[k],tau,p[k]); rsub_d1(p[k],b[k],p[k]);
    mpfr_printf("b-tau+log2(e)=%+6.2Rf ",p[k]);


    rlog2(r[k],e[k]); rsub_d1(r[k],tau,r[k]); rdiv_d2(r[k],r[k],b[k]); rsub_d1(r[k],1,r[k]);
    mpfr_printf("κ=1-(tau-log2(e))/b=%+.10Rf ",r[k]);
    printf("\n");
  }
  rvec_max(rmax,kmax,p);
  mpfr_printf("cancel bits=%+.2Rf\n",rmax);
  rvec_max(rmax,kmax,r);
  mpfr_printf("κ_max=%+.10Rf\n",rmax);
  

  // done
  fJ=func_del(fJ);
  b=ivec_free(b);
  CVF(y,m); RVF(e,kmax); RVF(eps,kmax); RVF(em,kmax); RVF(r,kmax); RVF(p,kmax); RF(rmax);
}
Example #4
0
const char * PE_FindNearFunctionName(
	WINE_MODREF *wm,
	FARPROC funcAddr )
{
	unsigned short			* ordinal;
	unsigned long			* function;
	unsigned char			** name;
	const char *ename = NULL;
	int				i, j;
	PE_MODREF			*pem = &(wm->binfmt.pe);
	IMAGE_EXPORT_DIRECTORY 		*exports = pem->pe_export;
	unsigned int			load_addr = wm->module;
	unsigned long			rva_start, rva_end, addr;
	char				* forward;
	if (!exports) {
		/* Not a fatal problem, some apps do
		 * GetProcAddress(0,"RegisterPenApp") which triggers this
		 * case.
		 */
		WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,pem);
		return NULL;
	}
	ordinal= (unsigned short*)  RVA(exports->AddressOfNameOrdinals);
	function= (unsigned long*)   RVA(exports->AddressOfFunctions);
	name	= (unsigned char **) RVA(exports->AddressOfNames);
	forward = NULL;
	rva_start = PE_HEADER(wm->module)->OptionalHeader
		.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
	rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader
		.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
	void *last_func = 0;
	
	for (j = 0; j < exports->NumberOfNames; j++)
	{
		int index = ordinal[j];
		//printf("%p %p %s\n", function[index], funcAddr, RVA(name[j]));
		if(((void*)last_func >= funcAddr-load_addr ) && ((void*)function[index] < funcAddr-load_addr ) ) 
		return  (char*)RVA(name[j-1]);
		last_func = function[index];
	}
	//printf("PE_FindFunctionName: could not resolve %p\n", funcAddr);
  return 0;
}
Example #5
0
static void
dump_exports (HMODULE hModule)
{
#if 0
  char *Module;
  int i, j;
  u_short *ordinal;
  u_long *function, *functions;
  u_char **name;
  unsigned int load_addr = hModule;

  DWORD rva_start =
      PE_HEADER (hModule)->
      OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  DWORD rva_end =
      rva_start +
      PE_HEADER (hModule)->
      OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
  IMAGE_EXPORT_DIRECTORY *pe_exports =
      (IMAGE_EXPORT_DIRECTORY *) RVA (rva_start);

  Module = (char *) RVA (pe_exports->Name);
  TRACE ("*******EXPORT DATA*******\n");
  TRACE ("Module name is %s, %ld functions, %ld names\n",
      Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames);
  ordinal = (u_short *) RVA (pe_exports->AddressOfNameOrdinals);
  functions = function = (u_long *) RVA (pe_exports->AddressOfFunctions);
  name = (u_char **) RVA (pe_exports->AddressOfNames);

  TRACE (" Ord    RVA     Addr   Name\n");
  for (i = 0; i < pe_exports->NumberOfFunctions; i++, function++) {
    if (!*function)
      continue;
    if (TRACE_ON (win32)) {
      DPRINTF ("%4ld %08lx %p", i + pe_exports->Base, *function,
          RVA (*function));

      for (j = 0; j < pe_exports->NumberOfNames; j++)
        if (ordinal[j] == i) {
          DPRINTF ("  %s", (char *) RVA (name[j]));
          break;
        }
      if ((*function >= rva_start) && (*function <= rva_end))
        DPRINTF (" (forwarded -> %s)", (char *) RVA (*function));
      DPRINTF ("\n");
    }
  }
#endif
}
Example #6
0
static const void *get_dir_and_size(unsigned int idx, unsigned int *size)
{
    if(PE_nt_headers->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
    {
        const IMAGE_OPTIONAL_HEADER64 *opt = (const IMAGE_OPTIONAL_HEADER64*)&PE_nt_headers->OptionalHeader;
        if (idx >= opt->NumberOfRvaAndSizes)
            return NULL;
        if(size)
            *size = opt->DataDirectory[idx].Size;
        return RVA(opt->DataDirectory[idx].VirtualAddress,
                   opt->DataDirectory[idx].Size);
    }
    else
    {
        const IMAGE_OPTIONAL_HEADER32 *opt = (const IMAGE_OPTIONAL_HEADER32*)&PE_nt_headers->OptionalHeader;
        if (idx >= opt->NumberOfRvaAndSizes)
            return NULL;
        if(size)
            *size = opt->DataDirectory[idx].Size;
        return RVA(opt->DataDirectory[idx].VirtualAddress,
                   opt->DataDirectory[idx].Size);
    }
}
Example #7
0
static void
do_relocations (unsigned int load_addr, IMAGE_BASE_RELOCATION * r)
{
  int delta = load_addr - PE_HEADER (load_addr)->OptionalHeader.ImageBase;
  int hdelta = (delta >> 16) & 0xFFFF;
  int ldelta = delta & 0xFFFF;

  if (delta == 0)

    return;
  while (r->VirtualAddress) {
    char *page = (char *) RVA (r->VirtualAddress);
    int count = (r->SizeOfBlock - 8) / 2;
    int i;

    /*
       TRACE_(fixup)("%x relocations for page %lx\n",
       count, r->VirtualAddress);
     */
    for (i = 0; i < count; i++) {
      int offset = r->TypeOffset[i] & 0xFFF;
      int type = r->TypeOffset[i] >> 12;
      //TRACE_(fixup)("patching %x type %x\n", offset, type);
      switch (type) {
        case IMAGE_REL_BASED_ABSOLUTE:
          break;
        case IMAGE_REL_BASED_HIGH:
          *(short *) (page + offset) += hdelta;
          break;
        case IMAGE_REL_BASED_LOW:
          *(short *) (page + offset) += ldelta;
          break;
        case IMAGE_REL_BASED_HIGHLOW:
          *(int *) (page + offset) += delta;

          break;
        case IMAGE_REL_BASED_HIGHADJ:
          FIXME ("Don't know what to do with IMAGE_REL_BASED_HIGHADJ\n");
          break;
        case IMAGE_REL_BASED_MIPS_JMPADDR:
          FIXME ("Is this a MIPS machine ???\n");
          break;
        default:
          FIXME ("Unknown fixup type\n");
          break;
      }
    }
    r = (IMAGE_BASE_RELOCATION *) ((char *) r + r->SizeOfBlock);
  }
}
Example #8
0
static tCLIFile* LoadPEFile(void *pData) {
	tCLIFile *pRet = TMALLOC(tCLIFile);

	unsigned char *pMSDOSHeader = (unsigned char*)&(((unsigned char*)pData)[0]);
	unsigned char *pPEHeader;
	unsigned char *pPEOptionalHeader;
	unsigned char *pPESectionHeaders;
	unsigned char *pCLIHeader;
	unsigned char *pRawMetaData;

	int i;
	unsigned int lfanew;
	unsigned short machine;
	int numSections;
	unsigned int imageBase;
	int fileAlignment;
	unsigned int cliHeaderRVA, cliHeaderSize;
	unsigned int metaDataRVA, metaDataSize;
	tMetaData *pMetaData;

	pRet->pRVA = RVA();
	pRet->pMetaData = pMetaData = MetaData();

	lfanew = *(unsigned int*)&(pMSDOSHeader[0x3c]);
	pPEHeader = pMSDOSHeader + lfanew + 4;
	pPEOptionalHeader = pPEHeader + 20;
	pPESectionHeaders = pPEOptionalHeader + 224;

	machine = *(unsigned short*)&(pPEHeader[0]);
	if (machine != DOT_NET_MACHINE) {
		return NULL;
	}
	numSections = *(unsigned short*)&(pPEHeader[2]);

	imageBase = *(unsigned int*)&(pPEOptionalHeader[28]);
	fileAlignment = *(int*)&(pPEOptionalHeader[36]);

	for (i=0; i<numSections; i++) {
		unsigned char *pSection = pPESectionHeaders + i * 40;
		RVA_Create(pRet->pRVA, pData, pSection);
	}

	cliHeaderRVA = *(unsigned int*)&(pPEOptionalHeader[208]);
	cliHeaderSize = *(unsigned int*)&(pPEOptionalHeader[212]);

	pCLIHeader = RVA_FindData(pRet->pRVA, cliHeaderRVA);

	metaDataRVA = *(unsigned int*)&(pCLIHeader[8]);
	metaDataSize = *(unsigned int*)&(pCLIHeader[12]);
	pRet->entryPoint = *(unsigned int*)&(pCLIHeader[20]);
	pRawMetaData = RVA_FindData(pRet->pRVA, metaDataRVA);

	// Load all metadata
	{
		unsigned int versionLen = *(unsigned int*)&(pRawMetaData[12]);
		unsigned int ofs, numberOfStreams;
		void *pTableStream = NULL;
		unsigned int tableStreamSize;
		pRet->pVersion = &(pRawMetaData[16]);
		log_f(1, "CLI version: %s\n", pRet->pVersion);
		ofs = 16 + versionLen;
		numberOfStreams = *(unsigned short*)&(pRawMetaData[ofs + 2]);
		ofs += 4;

		for (i=0; i<(signed)numberOfStreams; i++) {
			unsigned int streamOffset = *(unsigned int*)&pRawMetaData[ofs];
			unsigned int streamSize = *(unsigned int*)&pRawMetaData[ofs+4];
			unsigned char *pStreamName = &pRawMetaData[ofs+8];
			void *pStream = pRawMetaData + streamOffset;
			ofs += (unsigned int)((strlen(pStreamName)+4) & (~0x3)) + 8;
			if (strcasecmp(pStreamName, "#Strings") == 0) {
				MetaData_LoadStrings(pMetaData, pStream, streamSize);
			} else if (strcasecmp(pStreamName, "#US") == 0) {
				MetaData_LoadUserStrings(pMetaData, pStream, streamSize);
			} else if (strcasecmp(pStreamName, "#Blob") == 0) {
				MetaData_LoadBlobs(pMetaData, pStream, streamSize);
			} else if (strcasecmp(pStreamName, "#GUID") == 0) {
				MetaData_LoadGUIDs(pMetaData, pStream, streamSize);
			} else if (strcasecmp(pStreamName, "#~") == 0) {
				pTableStream = pStream;
				tableStreamSize = streamSize;
			}
		}
		// Must load tables last
		if (pTableStream != NULL) {
			MetaData_LoadTables(pMetaData, pRet->pRVA, pTableStream, tableStreamSize);
		}
	}

	// Mark all generic definition types and methods as such
	for (i=pMetaData->tables.numRows[MD_TABLE_GENERICPARAM]; i>0; i--) {
		tMD_GenericParam *pGenericParam;
		IDX_TABLE ownerIdx;

		pGenericParam = (tMD_GenericParam*)MetaData_GetTableRow
			(pMetaData, MAKE_TABLE_INDEX(MD_TABLE_GENERICPARAM, i));
		ownerIdx = pGenericParam->owner;
		switch (TABLE_ID(ownerIdx)) {
			case MD_TABLE_TYPEDEF:
				{
					tMD_TypeDef *pTypeDef = (tMD_TypeDef*)MetaData_GetTableRow(pMetaData, ownerIdx);
					pTypeDef->isGenericDefinition = 1;
				}
				break;
			case MD_TABLE_METHODDEF:
				{
					tMD_MethodDef *pMethodDef = (tMD_MethodDef*)MetaData_GetTableRow(pMetaData, ownerIdx);
					pMethodDef->isGenericDefinition = 1;
				}
				break;
			default:
				Crash("Wrong generic parameter owner: 0x%08x", ownerIdx);
		}
	}

	// Mark all nested classes as such
	for (i=pMetaData->tables.numRows[MD_TABLE_NESTEDCLASS]; i>0; i--) {
		tMD_NestedClass *pNested;
		tMD_TypeDef *pParent, *pChild;

		pNested = (tMD_NestedClass*)MetaData_GetTableRow(pMetaData, MAKE_TABLE_INDEX(MD_TABLE_NESTEDCLASS, i));
		pParent = (tMD_TypeDef*)MetaData_GetTableRow(pMetaData, pNested->enclosingClass);
		pChild = (tMD_TypeDef*)MetaData_GetTableRow(pMetaData, pNested->nestedClass);
		pChild->pNestedIn = pParent;
	}

	return pRet;
}
Example #9
0
/***********************************************************************
 *           LoadLibraryExA   (KERNEL32)
 */
HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
{
	WINE_MODREF *wm = 0;
	char* listpath[] = { "", "", "/usr/lib/win32", "/usr/local/lib/win32", 0 };
	extern char* def_path;
	char path[512];
	char checked[2000];
        int i = -1;

        checked[0] = 0;
	if(!libname)
	{
		SetLastError(ERROR_INVALID_PARAMETER);
		return 0;
	}

	wm=MODULE_FindModule(libname);
	if(wm) return wm->module;

//	if(fs_installed==0)
//	    install_fs();

	while (wm == 0 && listpath[++i])
	{
	    if (i < 2)
	    {
		if (i == 0)
		    /* check just original file name */
		    strncpy(path, libname, 511);
                else
		    /* check default user path */
		    strncpy(path, def_path, 300);
	    }
	    else if (strcmp(def_path, listpath[i]))
                /* path from the list */
		strncpy(path, listpath[i], 300);
	    else
		continue;

	    if (i > 0)
	    {
		strcat(path, "/");
		strncat(path, libname, 100);
	    }
	    path[511] = 0;
	    wm = MODULE_LoadLibraryExA( path, hfile, flags );

	    if (!wm)
	    {
		if (checked[0])
		    strcat(checked, ", ");
		strcat(checked, path);
                checked[1500] = 0;

	    }
	}
	if ( wm )
	{
		if ( !MODULE_DllProcessAttach( wm, NULL ) )
		{
			WARN_(module)("Attach failed for module '%s', \n", libname);
			MODULE_FreeLibrary(wm);
			SetLastError(ERROR_DLL_INIT_FAILED);
			MODULE_RemoveFromList(wm);
			wm = NULL;
		}
	}

	if (!wm)
	    printf("Win32 LoadLibrary failed to load: %s\n", checked);

#define RVA(x) ((char *)wm->module+(unsigned int)(x))
	if (strstr(libname,"vp31vfw.dll") && wm)
	{
	    int i;

	  // sse hack moved from patch dll into runtime patching
          if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==RVA(0x1000)) {
	    fprintf(stderr, "VP3 DLL found\n");
	    for (i=0;i<18;i++) RVA(0x4bd6)[i]=0x90;
	  }
	}

        // remove a few divs in the VP codecs that make trouble
        if (strstr(libname,"vp5vfw.dll") && wm)
        {
          int i;
          if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==RVA(0x3930)) {
            for (i=0;i<3;i++) RVA(0x4e86)[i]=0x90;
            for (i=0;i<3;i++) RVA(0x5a23)[i]=0x90;
            for (i=0;i<3;i++) RVA(0x5bff)[i]=0x90;
          } else {
            fprintf(stderr, "Unsupported VP5 version\n");
            return 0;
          }
        }

        if (strstr(libname,"vp6vfw.dll") && wm)
        {
          int i;
          if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==RVA(0x3ef0)) {
            // looks like VP 6.1.0.2
            for (i=0;i<6;i++) RVA(0x7268)[i]=0x90;
            for (i=0;i<6;i++) RVA(0x7e83)[i]=0x90;
            for (i=0;i<6;i++) RVA(0x806a)[i]=0x90;
          } else if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==RVA(0x4120)) {
            // looks like VP 6.2.0.10
            for (i=0;i<6;i++) RVA(0x7688)[i]=0x90;
            for (i=0;i<6;i++) RVA(0x82c3)[i]=0x90;
            for (i=0;i<6;i++) RVA(0x84aa)[i]=0x90;
            for (i=0;i<6;i++) RVA(0x1d2cc)[i]=0x90;
            for (i=0;i<6;i++) RVA(0x2179d)[i]=0x90;
            for (i=0;i<6;i++) RVA(0x1977f)[i]=0x90;
          } else if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==RVA(0x3e70)) {
            // looks like VP 6.0.7.3
            for (i=0;i<6;i++) RVA(0x7559)[i]=0x90;
            for (i=0;i<6;i++) RVA(0x81c3)[i]=0x90;
            for (i=0;i<6;i++) RVA(0x839e)[i]=0x90;
          } else {
            fprintf(stderr, "Unsupported VP6 version\n");
            return 0;
          }
        }

        // Windows Media Video 9 Advanced
        if (strstr(libname,"wmvadvd.dll") && wm)
        {
          // The codec calls IsRectEmpty with coords 0,0,0,0 => result is 0
          // but it really wants the rectangle to be not empty
          if (PE_FindExportedFunction(wm, "CreateInstance", TRUE)==RVA(0xb812)) {
            // Dll version is 10.0.0.3645
            *RVA(0x8b0f)=0xeb; // Jump always, ignoring IsRectEmpty result
          } else {
            fprintf(stderr, "Unsupported WMVA version\n");
            return 0;
          }
        }

	if (strstr(libname,"QuickTime.qts") && wm)
	{
	    void** ptr;
	    void *dispatch_addr;
	    int i;

//	    dispatch_addr = GetProcAddress(wm->module, "theQuickTimeDispatcher", TRUE);
	    dispatch_addr = PE_FindExportedFunction(wm, "theQuickTimeDispatcher", TRUE);
	    if (dispatch_addr == RVA(0x124c30))
	    {
	        fprintf(stderr, "QuickTime5 DLLs found\n");
		ptr = (void **)RVA(0x375ca4); // dispatch_ptr
	        for (i=0;i<5;i++)  RVA(0x19e842)[i]=0x90; // make_new_region ?
	        for (i=0;i<28;i++) RVA(0x19e86d)[i]=0x90; // call__call_CreateCompatibleDC ?
		for (i=0;i<5;i++)  RVA(0x19e898)[i]=0x90; // jmp_to_call_loadbitmap ?
	        for (i=0;i<9;i++)  RVA(0x19e8ac)[i]=0x90; // call__calls_OLE_shit ?
	        for (i=0;i<106;i++) RVA(0x261b10)[i]=0x90; // disable threads
#if 0
		/* CreateThread callers */
		for (i=0;i<5;i++) RVA(0x1487c5)[i]=0x90;
		for (i=0;i<5;i++) RVA(0x14b275)[i]=0x90;
		for (i=0;i<5;i++) RVA(0x1a24b1)[i]=0x90;
		for (i=0;i<5;i++) RVA(0x1afc5a)[i]=0x90;
		for (i=0;i<5;i++) RVA(0x2f799c)[i]=0x90;
		for (i=0;i<5;i++) RVA(0x2f7efe)[i]=0x90;
		for (i=0;i<5;i++) RVA(0x2fa33e)[i]=0x90;
#endif

#if 0
		/* TerminateQTML fix */
		for (i=0;i<47;i++) RVA(0x2fa3b8)[i]=0x90; // terminate thread
		for (i=0;i<47;i++) RVA(0x2f7f78)[i]=0x90; // terminate thread
		for (i=0;i<77;i++) RVA(0x1a13d5)[i]=0x90;
		RVA(0x08e0ae)[0] = 0xc3; // font/dc remover
		for (i=0;i<24;i++) RVA(0x07a1ad)[i]=0x90; // destroy window
#endif
	    } else if (dispatch_addr == RVA(0x13b330))
	    {
    		fprintf(stderr, "QuickTime6 DLLs found\n");
		ptr = (void **)RVA(0x3b9524); // dispatcher_ptr
		for (i=0;i<5;i++)  RVA(0x2730cc)[i]=0x90; // make_new_region
		for (i=0;i<28;i++) RVA(0x2730f7)[i]=0x90; // call__call_CreateCompatibleDC
		for (i=0;i<5;i++)  RVA(0x273122)[i]=0x90; // jmp_to_call_loadbitmap
		for (i=0;i<9;i++)  RVA(0x273131)[i]=0x90; // call__calls_OLE_shit
		for (i=0;i<96;i++) RVA(0x2ac852)[i]=0x90; // disable threads
	    } else if (dispatch_addr == RVA(0x13c3e0))
	    {
    		fprintf(stderr, "QuickTime6.3 DLLs found\n");
		ptr = (void **)RVA(0x3ca01c); // dispatcher_ptr
		for (i=0;i<5;i++)  RVA(0x268f6c)[i]=0x90; // make_new_region
		for (i=0;i<28;i++) RVA(0x268f97)[i]=0x90; // call__call_CreateCompatibleDC
		for (i=0;i<5;i++)  RVA(0x268fc2)[i]=0x90; // jmp_to_call_loadbitmap
		for (i=0;i<9;i++)  RVA(0x268fd1)[i]=0x90; // call__calls_OLE_shit
		for (i=0;i<96;i++) RVA(0x2b4722)[i]=0x90; // disable threads
	    } else
	    {
	        fprintf(stderr, "Unsupported QuickTime version (%p)\n",
		    dispatch_addr);
		return 0;
	    }

	    fprintf(stderr,"QuickTime.qts patched!!! old entry=%p\n",ptr[0]);

#ifdef EMU_QTX_API
	    report_entry = report_func;
	    report_ret   = report_func_ret;
	    wrapper_target=ptr[0];
	    ptr[0]=wrapper;
#endif
	}
#undef RVA

	return wm ? wm->module : 0;
}
Example #10
0
static BOOLEAN
WinLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead,
                      IN PVOID DllBase,
                      IN PVOID ImageBase,
                      IN PIMAGE_THUNK_DATA ThunkData,
                      IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
                      IN ULONG ExportSize,
                      IN BOOLEAN ProcessForwards,
                      IN PCSTR DirectoryPath)
{
    ULONG Ordinal;
    PULONG NameTable, FunctionTable;
    PUSHORT OrdinalTable;
    LONG High, Low, Middle, Result;
    ULONG Hint;
    PIMAGE_IMPORT_BY_NAME ImportData;
    PCHAR ExportName, ForwarderName;
    BOOLEAN Success;

    //TRACE("WinLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X, ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n",
    //    DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize, ProcessForwards);

    /* Check passed DllBase param */
    if(DllBase == NULL)
    {
        WARN("DllBase == NULL!\n");
        return FALSE;
    }

    /* Convert all non-critical pointers to PA from VA */
    ThunkData = VaToPa(ThunkData);

    /* Is the reference by ordinal? */
    if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards)
    {
        /* Yes, calculate the ordinal */
        Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) - (UINT32)ExportDirectory->Base);
        //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal);
    }
    else
    {
        /* It's reference by name, we have to look it up in the export directory */
        if (!ProcessForwards)
        {
            /* AddressOfData in thunk entry will become a virtual address (from relative) */
            //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD was %p\n", ThunkData->u1.AddressOfData);
            ThunkData->u1.AddressOfData =
                (ULONG_PTR)RVA(ImageBase, ThunkData->u1.AddressOfData);
            //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD became %p\n", ThunkData->u1.AddressOfData);
        }

        /* Get the import name */
        ImportData = VaToPa((PVOID)ThunkData->u1.AddressOfData);

        /* Get pointers to Name and Ordinal tables (RVA -> VA) */
        NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
        OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));

        //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n",
        //    NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals);

        /* Get the hint, convert it to a physical pointer */
        Hint = ((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint;
        //TRACE("HintIndex %d\n", Hint);

        /* Get the export name from the hint */
        ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));

        /* If Hint is less than total number of entries in the export directory,
           and import name == export name, then we can just get it from the OrdinalTable */
        if ((Hint < ExportDirectory->NumberOfNames) &&
            (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
        {
            Ordinal = OrdinalTable[Hint];
            //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal);
        }
        else
        {
            /* It's not the easy way, we have to lookup import name in the name table.
               Let's use a binary search for this task. */

            //TRACE("WinLdrpBindImportName() looking up the import name using binary search...\n");

            /* Low boundary is set to 0, and high boundary to the maximum index */
            Low = 0;
            High = ExportDirectory->NumberOfNames - 1;

            /* Perform a binary-search loop */
            while (High >= Low)
            {
                /* Divide by 2 by shifting to the right once */
                Middle = (Low + High) / 2;

                /* Get the name from the name table */
                ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));

                /* Compare the names */
                Result = strcmp(ExportName, (PCHAR)ImportData->Name);

                /*TRACE("Binary search: comparing Import '__', Export '%s'\n",*/
                    /*VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),*/
                    /*(PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));*/

                /*TRACE("TE->u1.AOD %p, fulladdr %p\n",
                    ThunkData->u1.AddressOfData,
                    ((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name );*/


                /* Depending on result of strcmp, perform different actions */
                if (Result > 0)
                {
                    /* Adjust top boundary */
                    High = Middle - 1;
                }
                else if (Result < 0)
                {
                    /* Adjust bottom boundary */
                    Low = Middle + 1;
                }
                else
                {
                    /* Yay, found it! */
                    break;
                }
            }

            /* If high boundary is less than low boundary, then no result found */
            if (High < Low)
            {
                //Print(L"Error in binary search\n");
                ERR("Did not find export '%s'!\n", (PCHAR)ImportData->Name);
                return FALSE;
            }

            /* Everything alright, get the ordinal */
            Ordinal = OrdinalTable[Middle];

            //TRACE("WinLdrpBindImportName() found Ordinal %d\n", Ordinal);
        }
    }

    /* Check ordinal number for validity! */
    if (Ordinal >= ExportDirectory->NumberOfFunctions)
    {
        ERR("Ordinal number is invalid!\n");
        return FALSE;
    }

    /* Get a pointer to the function table */
    FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions));

    /* Save a pointer to the function */
    ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);

    /* Is it a forwarder? (function pointer is within the export directory) */
    ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
    if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
        ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
    {
        PLDR_DATA_TABLE_ENTRY DataTableEntry;
        CHAR ForwardDllName[255];
        PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
        ULONG RefExportSize;
        TRACE("WinLdrpBindImportName(): ForwarderName %s\n", ForwarderName);

        /* Save the name of the forward dll */
        RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));

        /* Strip out the symbol name */
        *strrchr(ForwardDllName,'.') = '\0';

        /* Check if the target image is already loaded */
        if (!WinLdrCheckForLoadedDll(ModuleListHead, ForwardDllName, &DataTableEntry))
        {
            /* Check if the forward dll name has an extension */
            if (strchr(ForwardDllName, '.') == NULL)
            {
                /* Name does not have an extension, append '.dll' */
                strcat(ForwardDllName, ".dll");
            }

            /* Now let's try to load it! */
            Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead,
                                                      DirectoryPath,
                                                      ForwardDllName,
                                                      &DataTableEntry);
            if (!Success)
            {
                ERR("WinLdrpLoadAndScanReferencedDll() failed to load forwarder dll.\n");
                return Success;
            }
        }

        /* Get pointer to the export directory of loaded DLL */
        RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
            RtlImageDirectoryEntryToData(VaToPa(DataTableEntry->DllBase),
            TRUE,
            IMAGE_DIRECTORY_ENTRY_EXPORT,
            &RefExportSize);

        /* Fail if it's NULL */
        if (RefExportDirectory)
        {
            UCHAR Buffer[128];
            IMAGE_THUNK_DATA RefThunkData;
            PIMAGE_IMPORT_BY_NAME ImportByName;
            PCHAR ImportName;

            /* Get pointer to the import name */
            ImportName = strrchr(ForwarderName, '.') + 1;

            /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
            ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;

            /* Fill the name with the import name */
            RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);

            /* Set Hint to 0 */
            ImportByName->Hint = 0;

            /* And finally point ThunkData's AddressOfData to that structure */
            RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;

            /* And recursively call ourselves */
            Success = WinLdrpBindImportName(ModuleListHead,
                                            DataTableEntry->DllBase,
                                            ImageBase,
                                            &RefThunkData,
                                            RefExportDirectory,
                                            RefExportSize,
                                            TRUE,
                                            DirectoryPath);

            /* Fill out the ThunkData with data from RefThunkData */
            ThunkData->u1 = RefThunkData.u1;

            /* Return what we got from the recursive call */
            return Success;
        }
        else
        {
            /* Fail if ExportDirectory is NULL */
            return FALSE;
        }
    }

    /* Success! */
    return TRUE;
}
Example #11
0
BOOLEAN
WinLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead,
                                IN PCCH DirectoryPath,
                                IN PLDR_DATA_TABLE_ENTRY ScanDTE)
{
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    PIMAGE_IMPORT_DESCRIPTOR ImportTable;
    ULONG ImportTableSize;
    PCH ImportName;
    BOOLEAN Success;

    /* Get a pointer to the import table of this image */
    ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
        TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);

    {
        UNICODE_STRING BaseName;
        BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
        BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
        BaseName.Length = ScanDTE->BaseDllName.Length;
        TRACE("WinLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
            &BaseName, ImportTable);
    }

    /* If image doesn't have any import directory - just return success */
    if (ImportTable == NULL)
        return TRUE;

    /* Loop through all entries */
    for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++)
    {
        /* Get pointer to the name */
        ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
        TRACE("WinLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);

        /* In case we get a reference to ourselves - just skip it */
        if (WinLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
            continue;

        /* Load the DLL if it is not already loaded */
        if (!WinLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
        {
            Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead,
                                                      DirectoryPath,
                                                      ImportName,
                                                      &DataTableEntry);
            if (!Success)
            {
                ERR("WinLdrpLoadAndScanReferencedDll() failed\n");
                return Success;
            }
        }

        /* Scan its import address table */
        Success = WinLdrpScanImportAddressTable(ModuleListHead,
                                                DataTableEntry->DllBase,
                                                ScanDTE->DllBase,
                                                (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
                                                DirectoryPath);

        if (!Success)
        {
            ERR("WinLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
                ImportName, DirectoryPath);
            return Success;
        }
    }

    return TRUE;
}
Example #12
0
/**********************************************************************
 *                 PE_CreateModule
 *
 * Create WINE_MODREF structure for loaded HMODULE32, link it into
 * process modref_list, and fixup all imports.
 *
 * Note: hModule must point to a correctly allocated PE image,
 *       with base relocations applied; the 16-bit dummy module
 *       associated to hModule must already exist.
 *
 * Note: This routine must always be called in the context of the
 *       process that is to own the module to be created.
 */
WINE_MODREF *PE_CreateModule( HMODULE hModule,
                              LPCSTR filename, DWORD flags, WIN_BOOL builtin )
{
    DWORD load_addr = (DWORD)hModule;
    IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
    IMAGE_DATA_DIRECTORY *dir;
    IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL;
    IMAGE_EXPORT_DIRECTORY *pe_export = NULL;
    IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL;
    WINE_MODREF *wm;




    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
    if (dir->Size)
        pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress);

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT;
    if (dir->Size)
        pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(dir->VirtualAddress);

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
    if (dir->Size)
        pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(dir->VirtualAddress);

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXCEPTION;
    if (dir->Size) FIXME("Exception directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_SECURITY;
    if (dir->Size) FIXME("Security directory ignored\n" );




    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DEBUG;
    if (dir->Size) TRACE("Debug directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COPYRIGHT;
    if (dir->Size) FIXME("Copyright string ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_GLOBALPTR;
    if (dir->Size) FIXME("Global Pointer (MIPS) ignored\n" );



    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG;
    if (dir->Size) FIXME("Load Configuration directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT;
    if (dir->Size) TRACE("Bound Import directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IAT;
    if (dir->Size) TRACE("Import Address Table directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT;
    if (dir->Size)
    {
		TRACE("Delayed import, stub calls LoadLibrary\n" );
		/*
		 * Nothing to do here.
		 */

#ifdef ImgDelayDescr
		/*
		 * This code is useful to observe what the heck is going on.
		 */
		{
		ImgDelayDescr *pe_delay = NULL;
        pe_delay = (PImgDelayDescr)RVA(dir->VirtualAddress);
        TRACE_(delayhlp)("pe_delay->grAttrs = %08x\n", pe_delay->grAttrs);
        TRACE_(delayhlp)("pe_delay->szName = %s\n", pe_delay->szName);
        TRACE_(delayhlp)("pe_delay->phmod = %08x\n", pe_delay->phmod);
        TRACE_(delayhlp)("pe_delay->pIAT = %08x\n", pe_delay->pIAT);
        TRACE_(delayhlp)("pe_delay->pINT = %08x\n", pe_delay->pINT);
        TRACE_(delayhlp)("pe_delay->pBoundIAT = %08x\n", pe_delay->pBoundIAT);
        TRACE_(delayhlp)("pe_delay->pUnloadIAT = %08x\n", pe_delay->pUnloadIAT);
        TRACE_(delayhlp)("pe_delay->dwTimeStamp = %08x\n", pe_delay->dwTimeStamp);
        }
#endif
	}

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR;
    if (dir->Size) FIXME("Unknown directory 14 ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+15;
    if (dir->Size) FIXME("Unknown directory 15 ignored\n" );




    wm = (WINE_MODREF *)HeapAlloc( GetProcessHeap(),
                                   HEAP_ZERO_MEMORY, sizeof(*wm) );
    wm->module = hModule;

    if ( builtin )
        wm->flags |= WINE_MODREF_INTERNAL;
    if ( flags & DONT_RESOLVE_DLL_REFERENCES )
        wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS;
    if ( flags & LOAD_LIBRARY_AS_DATAFILE )
        wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE;

    wm->type = MODULE32_PE;
    wm->binfmt.pe.pe_export = pe_export;
    wm->binfmt.pe.pe_import = pe_import;
    wm->binfmt.pe.pe_resource = pe_resource;
    wm->binfmt.pe.tlsindex = -1;

    wm->filename = malloc(strlen(filename)+1);
    strcpy(wm->filename, filename );
    wm->modname = strrchr( wm->filename, '\\' );
    if (!wm->modname) wm->modname = wm->filename;
    else wm->modname++;

    if ( pe_export )
        dump_exports( hModule );

    /* Fixup Imports */

    if (    pe_import
         && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE )
         && !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
         && fixup_imports( wm ) )
    {
        /* remove entry from modref chain */
         return NULL;
    }

    return wm;
}
Example #13
0
BOOLEAN
WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead,
                             IN PCCH BaseDllName,
                             IN PCCH FullDllName,
                             IN PVOID BasePA,
                             OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
{
    PVOID BaseVA = PaToVa(BasePA);
    PWSTR Buffer;
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    PIMAGE_NT_HEADERS NtHeaders;
    USHORT Length;
    TRACE("WinLdrAllocateDataTableEntry(, '%s', '%s', %p)\n",
       BaseDllName, FullDllName, BasePA);

    /* Allocate memory for a data table entry, zero-initialize it */
    DataTableEntry = (PLDR_DATA_TABLE_ENTRY)FrLdrHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY),
                                                           TAG_WLDR_DTE);
    if (DataTableEntry == NULL)
        return FALSE;
    RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));

    /* Get NT headers from the image */
    NtHeaders = RtlImageNtHeader(BasePA);

    /* Initialize corresponding fields of DTE based on NT headers value */
    DataTableEntry->DllBase = BaseVA;
    DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
    DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
    DataTableEntry->SectionPointer = 0;
    DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;

    /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
       by simple conversion - copying each character */
    Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
    if (Buffer == NULL)
    {
        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
        return FALSE;
    }
    RtlZeroMemory(Buffer, Length);

    DataTableEntry->BaseDllName.Length = Length;
    DataTableEntry->BaseDllName.MaximumLength = Length;
    DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
    while (*BaseDllName != 0)
    {
        *Buffer++ = *BaseDllName++;
    }

    /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
       using the same method */
    Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
    if (Buffer == NULL)
    {
        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
        return FALSE;
    }
    RtlZeroMemory(Buffer, Length);

    DataTableEntry->FullDllName.Length = Length;
    DataTableEntry->FullDllName.MaximumLength = Length;
    DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
    while (*FullDllName != 0)
    {
        *Buffer++ = *FullDllName++;
    }

    /* Initialize what's left - LoadCount which is 1, and set Flags so that
       we know this entry is processed */
    DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
    DataTableEntry->LoadCount = 1;

    /* Insert this DTE to a list in the LPB */
    InsertTailList(ModuleListHead, &DataTableEntry->InLoadOrderLinks);
    TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n", DataTableEntry,
          DataTableEntry->BaseDllName.Length / 2,
          VaToPa(DataTableEntry->BaseDllName.Buffer),
          DataTableEntry->DllBase);

    /* Save pointer to a newly allocated and initialized entry */
    *NewEntry = DataTableEntry;

    /* Return success */
    return TRUE;
}
Example #14
0
static DWORD fixup_imports( WINE_MODREF *wm )
{
    IMAGE_IMPORT_DESCRIPTOR	*pe_imp;
    PE_MODREF			*pem;
    unsigned int load_addr	= wm->module;
    int				i,characteristics_detection=1;
    char			*modname;

    assert(wm->type==MODULE32_PE);
    pem = &(wm->binfmt.pe);
    if (pem->pe_export)
    	modname = (char*) RVA(pem->pe_export->Name);
    else
        modname = "<unknown>";


    TRACE("Dumping imports list\n");


    pe_imp = pem->pe_import;
    if (!pe_imp) return 0;

    /* We assume that we have at least one import with !0 characteristics and
     * detect broken imports with all characteristsics 0 (notably Borland) and
     * switch the detection off for them.
     */
    for (i = 0; pe_imp->Name ; pe_imp++) {
	if (!i && !pe_imp->u.Characteristics)
		characteristics_detection = 0;
	if (characteristics_detection && !pe_imp->u.Characteristics)
		break;
	i++;
    }
    if (!i) return 0;


    wm->nDeps = i;
    wm->deps  = HeapAlloc( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) );

    /* load the imported modules. They are automatically
     * added to the modref list of the process.
     */

    for (i = 0, pe_imp = pem->pe_import; pe_imp->Name ; pe_imp++) {
	IMAGE_IMPORT_BY_NAME	*pe_name;
	PIMAGE_THUNK_DATA	import_list,thunk_list;
 	char			*name = (char *) RVA(pe_imp->Name);

	if (characteristics_detection && !pe_imp->u.Characteristics)
		break;

        /* FIXME: here we should fill imports */
        TRACE("Loading imports for %s.dll\n", name);

	if (pe_imp->u.OriginalFirstThunk != 0) {
	    TRACE("Microsoft style imports used\n");
	    import_list =(PIMAGE_THUNK_DATA) RVA(pe_imp->u.OriginalFirstThunk);
	    thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);

	    while (import_list->u1.Ordinal) {
		if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) {
		    int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal);

//		    TRACE("--- Ordinal %s,%d\n", name, ordinal);

		    thunk_list->u1.Function=LookupExternal(name, ordinal);
		} else {
		    pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData);
//		    TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint);
		    thunk_list->u1.Function=LookupExternalByName(name, pe_name->Name);
		}
		import_list++;
		thunk_list++;
	    }
	} else {
	    TRACE("Borland style imports used\n");
	    thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);
	    while (thunk_list->u1.Ordinal) {
		if (IMAGE_SNAP_BY_ORDINAL(thunk_list->u1.Ordinal)) {

		    int ordinal = IMAGE_ORDINAL(thunk_list->u1.Ordinal);

		    TRACE("--- Ordinal %s.%d\n",name,ordinal);
		    thunk_list->u1.Function=LookupExternal(
		      name, ordinal);
		} else {
		    pe_name=(PIMAGE_IMPORT_BY_NAME) RVA(thunk_list->u1.AddressOfData);
		    TRACE("--- %s %s.%d\n",
		   		  pe_name->Name,name,pe_name->Hint);
		    thunk_list->u1.Function=LookupExternalByName(
		      name, pe_name->Name);
		}
		thunk_list++;
	    }
	}
    }
    return 0;
}
Example #15
0
/**********************************************************************
 *			PE_LoadImage
 * Load one PE format DLL/EXE into memory
 *
 * Unluckily we can't just mmap the sections where we want them, for
 * (at least) Linux does only support offsets which are page-aligned.
 *
 * BUT we have to map the whole image anyway, for Win32 programs sometimes
 * want to access them. (HMODULE32 point to the start of it)
 */
HMODULE PE_LoadImage( int handle, LPCSTR filename, WORD *version )
{
    HMODULE	hModule;
    HANDLE	mapping;

    IMAGE_NT_HEADERS *nt;
    IMAGE_SECTION_HEADER *pe_sec;
    IMAGE_DATA_DIRECTORY *dir;
//    BY_HANDLE_FILE_INFORMATION bhfi;
    int	i, rawsize, lowest_va, vma_size, file_size = 0;
    DWORD load_addr = 0, aoep, reloc = 0;
//    struct get_read_fd_request *req = get_req_buffer();
    int unix_handle = handle;
    int page_size = getpagesize();


//    if ( GetFileInformationByHandle( hFile, &bhfi ) )
//    	file_size = bhfi.nFileSizeLow;
    file_size=lseek(handle, 0, SEEK_END);
    lseek(handle, 0, SEEK_SET);

    // fix CreateFileMappingA
    mapping = CreateFileMappingA( handle, NULL, PAGE_READONLY | SEC_COMMIT,
                                    0, 0, NULL );
    if (!mapping)
    {
        WARN("CreateFileMapping error %ld\n", GetLastError() );
        return 0;
    }
//    hModule = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
    hModule=(HMODULE)mapping;
//    CloseHandle( mapping );
    if (!hModule)
    {
        WARN("MapViewOfFile error %ld\n", GetLastError() );
        return 0;
    }
    if ( *(WORD*)hModule !=IMAGE_DOS_SIGNATURE)
    {
        WARN("%s image doesn't have DOS signature, but 0x%04x\n", filename,*(WORD*)hModule);
        goto error;
    }

    nt = PE_HEADER( hModule );


    if ( nt->Signature != IMAGE_NT_SIGNATURE )
    {
        WARN("%s image doesn't have PE signature, but 0x%08lx\n", filename, nt->Signature );
        goto error;
    }


    if ( nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 )
    {
        dbg_printf("Trying to load PE image for unsupported architecture (");
        switch (nt->FileHeader.Machine)
        {
        case IMAGE_FILE_MACHINE_UNKNOWN: dbg_printf("Unknown"); break;
        case IMAGE_FILE_MACHINE_I860:    dbg_printf("I860"); break;
        case IMAGE_FILE_MACHINE_R3000:   dbg_printf("R3000"); break;
        case IMAGE_FILE_MACHINE_R4000:   dbg_printf("R4000"); break;
        case IMAGE_FILE_MACHINE_R10000:  dbg_printf("R10000"); break;
        case IMAGE_FILE_MACHINE_ALPHA:   dbg_printf("Alpha"); break;
        case IMAGE_FILE_MACHINE_POWERPC: dbg_printf("PowerPC"); break;
        default: dbg_printf("Unknown-%04x", nt->FileHeader.Machine); break;
        }
        dbg_printf(")\n");
        goto error;
    }


    pe_sec = PE_SECTIONS( hModule );
    rawsize = 0; lowest_va = 0x10000;
    for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
    {
        if (lowest_va > pe_sec[i].VirtualAddress)
           lowest_va = pe_sec[i].VirtualAddress;
    	if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
	    continue;
	if (pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData > rawsize)
	    rawsize = pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData;
    }


    if ( file_size && file_size < rawsize )
    {
        ERR("PE module is too small (header: %d, filesize: %d), "
                    "probably truncated download?\n",
                    rawsize, file_size );
        goto error;
    }


    aoep = nt->OptionalHeader.AddressOfEntryPoint;
    if (aoep && (aoep < lowest_va))
        FIXME("VIRUS WARNING: '%s' has an invalid entrypoint (0x%08lx) "
                      "below the first virtual address (0x%08x) "
                      "(possibly infected by Tchernobyl/SpaceFiller virus)!\n",
                       filename, aoep, lowest_va );


    /* FIXME:  Hack!  While we don't really support shared sections yet,
     *         this checks for those special cases where the whole DLL
     *         consists only of shared sections and is mapped into the
     *         shared address space > 2GB.  In this case, we assume that
     *         the module got mapped at its base address. Thus we simply
     *         check whether the module has actually been mapped there
     *         and use it, if so.  This is needed to get Win95 USER32.DLL
     *         to work (until we support shared sections properly).
     */

    if ( nt->OptionalHeader.ImageBase & 0x80000000 &&
        !strstr(filename, "xanlib.dll"))
    {
        HMODULE sharedMod = (HMODULE)nt->OptionalHeader.ImageBase;
        IMAGE_NT_HEADERS *sharedNt = (PIMAGE_NT_HEADERS)
               ( (LPBYTE)sharedMod + ((LPBYTE)nt - (LPBYTE)hModule) );

        /* Well, this check is not really comprehensive,
           but should be good enough for now ... */
        if (    !IsBadReadPtr( (LPBYTE)sharedMod, sizeof(IMAGE_DOS_HEADER) )
             && memcmp( (LPBYTE)sharedMod, (LPBYTE)hModule, sizeof(IMAGE_DOS_HEADER) ) == 0
             && !IsBadReadPtr( sharedNt, sizeof(IMAGE_NT_HEADERS) )
             && memcmp( sharedNt, nt, sizeof(IMAGE_NT_HEADERS) ) == 0 )
        {
            UnmapViewOfFile( (LPVOID)hModule );
            return sharedMod;
        }
    }



    load_addr = nt->OptionalHeader.ImageBase;
    vma_size = calc_vma_size( hModule );

    load_addr = (DWORD)VirtualAlloc( (void*)load_addr, vma_size,
                                     MEM_RESERVE | MEM_COMMIT,
                                     PAGE_EXECUTE_READWRITE );
    if (load_addr == 0)
    {

        FIXME("We need to perform base relocations for %s\n", filename);
	dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BASERELOC;
        if (dir->Size)
            reloc = dir->VirtualAddress;
        else
        {
            FIXME( "FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n",
                   filename,
                   (nt->FileHeader.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)?
                   "stripped during link" : "unknown reason" );
            goto error;
        }

        /* FIXME: If we need to relocate a system DLL (base > 2GB) we should
         *        really make sure that the *new* base address is also > 2GB.
         *        Some DLLs really check the MSB of the module handle :-/
         */
        if ( nt->OptionalHeader.ImageBase & 0x80000000 )
            ERR( "Forced to relocate system DLL (base > 2GB). This is not good.\n" );

        load_addr = (DWORD)VirtualAlloc( NULL, vma_size,
					 MEM_RESERVE | MEM_COMMIT,
					 PAGE_EXECUTE_READWRITE );
	if (!load_addr) {
            FIXME_(win32)(
                   "FATAL: Couldn't load module %s (out of memory, %d needed)!\n", filename, vma_size);
            goto error;
	}
    }

    TRACE("Load addr is %lx (base %lx), range %x\n",
          load_addr, nt->OptionalHeader.ImageBase, vma_size );
    TRACE_(segment)("Loading %s at %lx, range %x\n",
                    filename, load_addr, vma_size );

#if 0

    *(PIMAGE_DOS_HEADER)load_addr = *(PIMAGE_DOS_HEADER)hModule;
    *PE_HEADER( load_addr ) = *nt;
    memcpy( PE_SECTIONS(load_addr), PE_SECTIONS(hModule),
            sizeof(IMAGE_SECTION_HEADER) * nt->FileHeader.NumberOfSections );


    memcpy( load_addr, hModule, lowest_fa );
#endif

    if ((void*)FILE_dommap( handle, (void *)load_addr, 0, nt->OptionalHeader.SizeOfHeaders,
                     0, 0, PROT_EXEC | PROT_WRITE | PROT_READ,
                     MAP_PRIVATE | MAP_FIXED ) != (void*)load_addr)
    {
        ERR_(win32)( "Critical Error: failed to map PE header to necessary address.\n");
        goto error;
    }


    pe_sec = PE_SECTIONS( hModule );
    for (i = 0; i < nt->FileHeader.NumberOfSections; i++, pe_sec++)
    {
        if (!pe_sec->SizeOfRawData || !pe_sec->PointerToRawData) continue;
        TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n",
              filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress),
              pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize );
        if ((void*)FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress),
                         0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData,
                         PROT_EXEC | PROT_WRITE | PROT_READ,
                         MAP_PRIVATE | MAP_FIXED ) != (void*)RVA(pe_sec->VirtualAddress))
        {

            ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n");
            goto error;
        }
        if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) &&
            (pe_sec->SizeOfRawData & (page_size-1)))
        {
            DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size;
            if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize;
            TRACE("clearing %p - %p\n",
                  RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData,
                  RVA(pe_sec->VirtualAddress) + end );
            memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0,
                    end - pe_sec->SizeOfRawData );
        }
    }


    if ( reloc )
        do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) );


    *version =   ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 )
               |   (nt->OptionalHeader.MinorSubsystemVersion & 0xff);


    UnmapViewOfFile( (LPVOID)hModule );
    return (HMODULE)load_addr;

error:
    if (unix_handle != -1) close( unix_handle );
    if (load_addr)
    VirtualFree( (LPVOID)load_addr, 0, MEM_RELEASE );
    UnmapViewOfFile( (LPVOID)hModule );
    return 0;
}
Example #16
0
/* Look up the specified function or ordinal in the exportlist:
 * If it is a string:
 * 	- look up the name in the Name list.
 *	- look up the ordinal with that index.
 *	- use the ordinal as offset into the functionlist
 * If it is a ordinal:
 *	- use ordinal-pe_export->Base as offset into the functionlist
 */
FARPROC PE_FindExportedFunction(
	WINE_MODREF *wm,
	LPCSTR funcName,
        WIN_BOOL snoop )
{
	unsigned short			* ordinals;
	unsigned long			* function;
	unsigned char			** name;
	const char *ename = NULL;
	int				i, ordinal;
	PE_MODREF			*pem = &(wm->binfmt.pe);
	IMAGE_EXPORT_DIRECTORY 		*exports = pem->pe_export;
	unsigned int			load_addr = wm->module;
	unsigned long			rva_start, rva_end, addr;
	char				* forward;

	if (HIWORD(funcName))
		TRACE("(%s)\n",funcName);
	else
		TRACE("(%d)\n",(int)funcName);
	if (!exports) {
		/* Not a fatal problem, some apps do
		 * GetProcAddress(0,"RegisterPenApp") which triggers this
		 * case.
		 */
		WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,pem);
		return NULL;
	}
	ordinals= (unsigned short*)  RVA(exports->AddressOfNameOrdinals);
	function= (unsigned long*)   RVA(exports->AddressOfFunctions);
	name	= (unsigned char **) RVA(exports->AddressOfNames);
	forward = NULL;
	rva_start = PE_HEADER(wm->module)->OptionalHeader
		.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
	rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader
		.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;

	if (HIWORD(funcName))
        {

            int min = 0, max = exports->NumberOfNames - 1;
            while (min <= max)
            {
                int res, pos = (min + max) / 2;
		ename = (const char*) RVA(name[pos]);
		if (!(res = strcmp( ename, funcName )))
                {
                    ordinal = ordinals[pos];
                    goto found;
                }
                if (res > 0) max = pos - 1;
                else min = pos + 1;
            }

	    for (i = 0; i < exports->NumberOfNames; i++)
            {
		ename = (const char*) RVA(name[i]);
                if (!strcmp( ename, funcName ))
                {
		    ERR( "%s.%s required a linear search\n", wm->modname, funcName );
                    ordinal = ordinals[i];
                    goto found;
                }
            }
            return NULL;
	}
        else
        {
            ordinal = LOWORD(funcName) - exports->Base;
            if (snoop && name)
            {
                for (i = 0; i < exports->NumberOfNames; i++)
                    if (ordinals[i] == ordinal)
                    {
                        ename = RVA(name[i]);
                        break;
                    }
            }
	}

 found:
        if (ordinal >= exports->NumberOfFunctions)
        {
            TRACE("	ordinal %ld out of range!\n", ordinal + exports->Base );
            return NULL;
        }
        addr = function[ordinal];
        if (!addr) return NULL;
        if ((addr < rva_start) || (addr >= rva_end))
        {
            FARPROC proc = RVA(addr);
            if (snoop)
            {
                if (!ename) ename = "@";
//                proc = SNOOP_GetProcAddress(wm->module,ename,ordinal,proc);
		TRACE("SNOOP_GetProcAddress n/a\n");

            }
            return proc;
        }
        else
        {
                WINE_MODREF *wm;
                char *forward = RVA(addr);
		char module[256];
		char *end = strchr(forward, '.');

		if (!end) return NULL;
                if (end - forward >= sizeof(module)) return NULL;
                memcpy( module, forward, end - forward );
		module[end-forward] = 0;
                if (!(wm = MODULE_FindModule( module )))
                {
                    ERR("module not found for forward '%s'\n", forward );
                    return NULL;
                }
		return MODULE_GetProcAddress( wm->module, end + 1, snoop );
	}
}
Example #17
0
void AlignChimeLocal3(const string &Q3, const string &A3, const string &B3,
  const string &QLabel, const string &ALabel, const string &BLabel,
  ChimeHit2 &Hit)
	{
	Hit.Clear();

	const byte *Q3Seq = (const byte *) Q3.c_str();
	const byte *A3Seq = (const byte *) A3.c_str();
	const byte *B3Seq = (const byte *) B3.c_str();

	const unsigned ColCount = SIZE(Q3);
	asserta(SIZE(A3) == ColCount && SIZE(B3) == ColCount);

	vector<float> ColScoresA(ColCount, 0.0f);
	vector<float> ColScoresB(ColCount, 0.0f);

	float ScoreN = -(float) opt_xn;
	unsigned QL = 0;
	for (unsigned Col = 0; Col < ColCount; ++Col)
		{
		char q = Q3Seq[Col];
		char a = A3Seq[Col];
		char b = B3Seq[Col];

		if (!isgap(q))
			++QL;

		if (q == a && q == b && a == b)
			continue;

		if (isgap(q) || isgap(a) || isgap(b))
			continue;

		if (Col > 0 && (isgap(Q3Seq[Col-1]) || isgap(A3Seq[Col-1]) || isgap(B3Seq[Col-1])))
			continue;

		if (Col + 1 < ColCount && (isgap(Q3Seq[Col+1]) || isgap(A3Seq[Col+1]) || isgap(B3Seq[Col+1])))
			continue;

		if (q == a && q != b)
			ColScoresA[Col] = 1;
		else
			ColScoresA[Col] = ScoreN;

		if (q == b && q != a)
			ColScoresB[Col] = 1;
		else
			ColScoresB[Col] = ScoreN;
		}

	vector<float> LVA(ColCount, 0.0f);
	vector<float> LVB(ColCount, 0.0f);

	LVA[0] = ColScoresA[0];
	LVB[0] = ColScoresB[0];
	for (unsigned Col = 1; Col < ColCount; ++Col)
		{
		LVA[Col] = max(LVA[Col-1], 0.0f) + ColScoresA[Col];
		LVB[Col] = max(LVB[Col-1], 0.0f) + ColScoresB[Col];
		}

	vector<float> RVA(ColCount, 0.0f);
	vector<float> RVB(ColCount, 0.0f);

	RVA[ColCount-1] = ColScoresA[ColCount-1];
	RVB[ColCount-1] = ColScoresB[ColCount-1];
	for (int Col = ColCount-2; Col >= 0; --Col)
		{
		RVA[Col] = max(RVA[Col+1], 0.0f) + ColScoresA[Col];
		RVB[Col] = max(RVB[Col+1], 0.0f) + ColScoresB[Col];
		}

	bool FirstA = true;
	float MaxSum = 0.0;
	unsigned ColX = UINT_MAX;
	for (unsigned Col = 1; Col < ColCount-1; ++Col)
		{
		float Sum = LVA[Col] + RVB[Col+1];
		if (Sum > MaxSum)
			{
			FirstA = true;
			MaxSum = Sum;
			ColX = Col;
			}
		}

	for (unsigned Col = 1; Col < ColCount-1; ++Col)
		{
		float Sum = LVB[Col] + RVA[Col+1];
		if (Sum > MaxSum)
			{
			FirstA = false;
			MaxSum = Sum;
			ColX = Col;
			}
		}
	if (ColX == UINT_MAX)
		return;

	unsigned ColLo = UINT_MAX;
	unsigned ColHi = UINT_MAX;
	if (FirstA)
		{
		float Sum = 0.0f;
		for (int Col = ColX; Col >= 0; --Col)
			{
			Sum += ColScoresA[Col];
			if (Sum >= LVA[ColX])
				{
				ColLo = Col;
				break;
				}
			}
		asserta(Sum >= LVA[ColX]);
		Sum = 0.0f;
		for (unsigned Col = ColX+1; Col < ColCount; ++Col)
			{
			Sum += ColScoresB[Col];
			if (Sum >= RVB[ColX])
				{
				ColHi = Col;
				break;
				}
			}
		asserta(Sum >= RVB[ColX]);
		}
	else
		{
		float Sum = 0.0f;
		for (int Col = ColX; Col >= 0; --Col)
			{
			Sum += ColScoresB[Col];
			if (Sum >= LVB[ColX])
				{
				ColLo = Col;
				break;
				}
			}
		asserta(Sum >= LVB[ColX]);
		Sum = 0.0f;
		for (unsigned Col = ColX+1; Col < ColCount; ++Col)
			{
			Sum += ColScoresA[Col];
			if (Sum >= RVA[ColX])
				{
				ColHi = Col;
				break;
				}
			}
		asserta(Sum >= RVA[ColX]);
		}

	unsigned ColXHi = ColX;
	for (unsigned Col = ColX + 1; Col < ColCount; ++Col)
		{
		char q = Q3Seq[Col];
		char a = A3Seq[Col];
		char b = B3Seq[Col];
		
		if (q == a && q == b && !isgap(q))
			ColXHi = Col;
		else
			break;
		}

	unsigned ColXLo = ColX;
	for (int Col = (int) ColX - 1; Col >= 0; --Col)
		{
		char q = Q3Seq[Col];
		char a = A3Seq[Col];
		char b = B3Seq[Col];
		
		if (q == a && q == b && !isgap(q))
			ColXLo = Col;
		else
			break;
		}

	unsigned IdQA = 0;
	unsigned IdQB = 0;
	unsigned IdAB = 0;
	unsigned NQA = 0;
	unsigned NQB = 0;
	unsigned NAB = 0;
	for (unsigned Col = 0; Col < ColCount; ++Col)
		{
		char q = Q3Seq[Col];
		char a = A3Seq[Col];
		char b = B3Seq[Col];

		if (!isgap(q) && !isgap(a))
			{
			++NQA;
			if (q == a)
				++IdQA;
			}

		if (!isgap(q) && !isgap(b))
			{
			++NQB;
			if (q == b)
				++IdQB;
			}

		if (!isgap(a) && !isgap(b))
			{
			++NAB;
			if (a == b)
				++IdAB;
			}
		}

	Hit.PctIdQA = Pct(IdQA, NQA);
	Hit.PctIdQB = Pct(IdQB, NQB);
	Hit.PctIdAB = Pct(IdAB, NAB);

	unsigned LIdQA = 0;
	unsigned LIdQB = 0;
	for (unsigned Col = ColLo; Col < ColXLo; ++Col)
		{
		char q = Q3Seq[Col];
		char a = A3Seq[Col];
		char b = B3Seq[Col];

		if (!isgap(q) && !isgap(a))
			{
			if (q == a)
				++LIdQA;
			}

		if (!isgap(q) && !isgap(b))
			{
			if (q == b)
				++LIdQB;
			}
		}

	unsigned RIdQA = 0;
	unsigned RIdQB = 0;
	for (unsigned Col = ColXHi+1; Col <= ColHi; ++Col)
		{
		char q = Q3Seq[Col];
		char a = A3Seq[Col];
		char b = B3Seq[Col];

		if (!isgap(q) && !isgap(a))
			{
			if (q == a)
				++RIdQA;
			}

		if (!isgap(q) && !isgap(b))
			{
			if (q == b)
				++RIdQB;
			}
		}

	unsigned IdDiffL = max(LIdQA, LIdQB) - min(LIdQA, LIdQB);
	unsigned IdDiffR = max(RIdQA, RIdQB) - min(RIdQA, RIdQB);
	unsigned MinIdDiff = min(IdDiffL, IdDiffR);
	unsigned ColRange = ColHi - ColLo + 1;
	if (opt_queryfract > 0.0f && float(ColRange)/float(QL) < opt_queryfract)
		return;

//	double Div = Pct(MinIdDiff, QSD.L);

#if	TRACE
	{
	Log("  Col  A Q B   ScoreA   ScoreB      LVA      LVB      RVA      RVB\n");
	Log("-----  - - -  -------  -------  -------  -------  -------  -------\n");
	for (unsigned Col = 0; Col < ColCount; ++Col)
		{
		if (ColScoresA[Col] == 0.0 && ColScoresB[Col] == 0.0)
			continue;

		char q = Q3Seq[Col];
		char a = A3Seq[Col];
		char b = B3Seq[Col];
		Log("%5u  %c %c %c", Col, a, q, b);

		if (ColScoresA[Col] == 0.0)
			Log("  %7.7s", "");
		else
			Log("  %7.1f", ColScoresA[Col]);

		if (ColScoresB[Col] == 0.0)
			Log("  %7.7s", "");
		else
			Log("  %7.1f", ColScoresB[Col]);

		Log("  %7.1f  %7.1f  %7.1f  %7.1f", LVA[Col], LVB[Col], RVA[Col], RVB[Col]);

		Log("\n");
		}
	Log("\n");
	Log("MaxSum %.1f, ColLo %u, ColXLo %u, ColX %u, ColXHi %u, ColHi %u, AF %c\n",
	  MaxSum, ColLo, ColXLo, ColX, ColXHi, ColHi, tof(FirstA));
	Log("  LIdQA %u, LIdQB %u, RIdQA %u, RIdQB %u\n", LIdQA, LIdQB, RIdQA, RIdQB);
	}
#endif

	string Q3L;
	string A3L;
	string B3L;
	for (unsigned Col = ColLo; Col <= ColHi; ++Col)
		{
		char q = Q3[Col];
		char a = A3[Col];
		char b = B3[Col];

		Q3L += q;
		A3L += a;
		B3L += b;
		}

	AlignChimeGlobal3(Q3L, A3L, B3L, QLabel, ALabel, BLabel, Hit);

#if	0
// CS SNPs
	Hit.CS_LY = 0;
	Hit.CS_LN = 0;
	Hit.CS_RY = 0;
	Hit.CS_RN = 0;
	Hit.CS_LA = 0;
	Hit.CS_RA = 0;
	for (unsigned Col = ColLo; Col <= ColHi; ++Col)
		{
		char q = Q3Seq[Col];
		char a = A3Seq[Col];
		char b = B3Seq[Col];
		if (q == a && q == b && a == b)
			continue;
		if (isgap(q) || isgap(a) || isgap(b))
			continue;
		if (Col > 0 && (isgap(Q3Seq[Col-1]) || isgap(A3Seq[Col-1]) || isgap(B3Seq[Col-1])))
			continue;
		if (Col + 1 < ColCount && (isgap(Q3Seq[Col+1]) || isgap(A3Seq[Col+1]) || isgap(B3Seq[Col+1])))
			continue;

		if (!FirstA)
			swap(a, b);

		if (Col < ColXLo)
			{
			if (q == a && q != b)
				++Hit.CS_LY;
			else if (q == b && q != a)
				++Hit.CS_LN;
			else
				++Hit.CS_LA;
			}
		else if (Col > ColXHi)
			{
			if (q == b && q != a)
				++Hit.CS_RY;
			else if (q == a && q != b)
				++Hit.CS_RN;
			else
				++Hit.CS_RA;
			}
		}

	double ScoreL = GetScore2(Hit.CS_LY, Hit.CS_LN, Hit.CS_LA);
	double ScoreR = GetScore2(Hit.CS_RY, Hit.CS_RN, Hit.CS_RA);
	Hit.Score = ScoreL*ScoreR;

	//Hit.QSD = QSD;
	//if (FirstA)
	//	{
	//	Hit.ASD = ASD;
	//	Hit.BSD = BSD;
	//	Hit.PathQA = PathQA;
	//	Hit.PathQB = PathQB;
	//	}
	//else
	//	{
	//	Hit.ASD = BSD;
	//	Hit.BSD = ASD;
	//	}

	//Hit.ColLo = ColLo;
	//Hit.ColXLo = ColXLo;
	//Hit.ColXHi = ColXHi;
	//Hit.ColHi = ColHi;
	//Hit.Div = Div;

//	Hit.LogMe();
#endif
	}
FARPROC WINAPI
__delayLoadHelper2(
    PCImgDelayDescr     pidd,
    FARPROC *           ppfnIATEntry
    ) {

    // Set up some data we use for the hook procs but also useful for
    // our own use
    //
    InternalImgDelayDescr   idd = {
        pidd->grAttrs,
        PFromRva<LPCSTR>(pidd->rvaDLLName),
        PFromRva<HMODULE*>(pidd->rvaHmod),
        PFromRva<PImgThunkData>(pidd->rvaIAT),
        PFromRva<PCImgThunkData>(pidd->rvaINT),
        PFromRva<PCImgThunkData>(pidd->rvaBoundIAT),
        PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT),
        pidd->dwTimeStamp
        };

    DelayLoadInfo   dli = {
        sizeof DelayLoadInfo,
        pidd,
        ppfnIATEntry,
        idd.szName,
        { 0 },
        0,
        0,
        0
        };

    if (0 == (idd.grAttrs & dlattrRva)) {
        PDelayLoadInfo  rgpdli[1] = { &dli };

        RaiseException(
            VcppException(ERROR_SEVERITY_ERROR, ERROR_INVALID_PARAMETER),
            0,
            1,
            PULONG_PTR(rgpdli)
            );
        return 0;
        }

    HMODULE hmod = *idd.phmod;

    // Calculate the index for the IAT entry in the import address table
    // N.B. The INT entries are ordered the same as the IAT entries so
    // the calculation can be done on the IAT side.
    //
    const unsigned  iIAT = IndexFromPImgThunkData(PCImgThunkData(ppfnIATEntry), idd.pIAT);
    const unsigned  iINT = iIAT;

    PCImgThunkData  pitd = &(idd.pINT[iINT]);

    dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal);

    if (dli.dlp.fImportByName) {
        dli.dlp.szProcName = LPCSTR(PFromRva<PIMAGE_IMPORT_BY_NAME>(RVA(UINT_PTR(pitd->u1.AddressOfData)))->Name);
        }
    else {
        dli.dlp.dwOrdinal = DWORD(IMAGE_ORDINAL(pitd->u1.Ordinal));
        }

    // Call the initial hook.  If it exists and returns a function pointer,
    // abort the rest of the processing and just return it for the call.
    //
    FARPROC pfnRet = NULL;

    if (__pfnDliNotifyHook2) {
        pfnRet = ((*__pfnDliNotifyHook2)(dliStartProcessing, &dli));

        if (pfnRet != NULL) {
            goto HookBypass;
            }
        }

    // Check to see if we need to try to load the library.
    //
    if (hmod == 0) {
        if (__pfnDliNotifyHook2) {
            hmod = HMODULE(((*__pfnDliNotifyHook2)(dliNotePreLoadLibrary, &dli)));
            }
        if (hmod == 0) {
            hmod = ::LoadLibraryEx(dli.szDll, NULL, 0);
            }
        if (hmod == 0) {
            dli.dwLastError = ::GetLastError();
            if (__pfnDliFailureHook2) {
                // when the hook is called on LoadLibrary failure, it will
                // return 0 for failure and an hmod for the lib if it fixed
                // the problem.
                //
                hmod = HMODULE((*__pfnDliFailureHook2)(dliFailLoadLib, &dli));
                }

            if (hmod == 0) {
                PDelayLoadInfo  rgpdli[1] = { &dli };

                RaiseException(
                    VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND),
                    0,
                    1,
                    PULONG_PTR(rgpdli)
                    );
                
                // If we get to here, we blindly assume that the handler of the exception
                // has magically fixed everything up and left the function pointer in 
                // dli.pfnCur.
                //
                return dli.pfnCur;
                }
            }

        // Store the library handle.  If it is already there, we infer
        // that another thread got there first, and we need to do a
        // FreeLibrary() to reduce the refcount
        //
        HMODULE hmodT = HMODULE(InterlockedExchangePointer((PVOID *) idd.phmod, PVOID(hmod)));
        if (hmodT == hmod) {
            ::FreeLibrary(hmod);
            }
        }

    // Go for the procedure now.
    //
    dli.hmodCur = hmod;
    if (__pfnDliNotifyHook2) {
        pfnRet = (*__pfnDliNotifyHook2)(dliNotePreGetProcAddress, &dli);
        }
    if (pfnRet == 0) {
        if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
            // bound imports exist...check the timestamp from the target image
            //
            PIMAGE_NT_HEADERS   pinh(PinhFromImageBase(hmod));

            if (pinh->Signature == IMAGE_NT_SIGNATURE &&
                TimeStampOfImage(pinh) == idd.dwTimeStamp &&
                FLoadedAtPreferredAddress(pinh, hmod)) {

                // Everything is good to go, if we have a decent address
                // in the bound IAT!
                //
                pfnRet = FARPROC(UINT_PTR(idd.pBoundIAT[iIAT].u1.Function));
                if (pfnRet != 0) {
                    goto SetEntryHookBypass;
                    }
                }
            }

        pfnRet = ::GetProcAddress(hmod, dli.dlp.szProcName);
        }

    if (pfnRet == 0) {
        dli.dwLastError = ::GetLastError();
        if (__pfnDliFailureHook2) {
            // when the hook is called on GetProcAddress failure, it will
            // return 0 on failure and a valid proc address on success
            //
            pfnRet = (*__pfnDliFailureHook2)(dliFailGetProc, &dli);
            }
        if (pfnRet == 0) {
            PDelayLoadInfo  rgpdli[1] = { &dli };

            RaiseException(
                VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND),
                0,
                1,
                PULONG_PTR(rgpdli)
                );

            // If we get to here, we blindly assume that the handler of the exception
            // has magically fixed everything up and left the function pointer in 
            // dli.pfnCur.
            //
            pfnRet = dli.pfnCur;
            }
        }

SetEntryHookBypass:
    *ppfnIATEntry = pfnRet;

HookBypass:
    if (__pfnDliNotifyHook2) {
        dli.dwLastError = 0;
        dli.hmodCur = hmod;
        dli.pfnCur = pfnRet;
        (*__pfnDliNotifyHook2)(dliNoteEndProcessing, &dli);
        }
    return pfnRet;
    }
Example #19
0
MODULE_HEADERS *
ExecPE(char *lpszName)
{
	static void *BaseAddress;

	IMAGE_DOS_HEADER DosHeader;
 	PIMAGE_SECTION_HEADER pSectionHeaders;
	PIMAGE_NT_HEADERS pNTHeader;
	static int nNTHeader;
	int i,len;
	int index = nNTHeader;
	char *bp;
	int ret;
	HFILE hFile;

	bp = lpszName;
	while(*bp) {
		*bp = tolower(*bp);
		bp++;
	}
	for(i=0;i<nNTHeader;i++) {
		if(strcmp(NTModules[i].modulename,lpszName) == 0) {
			return &NTModules[i];
		}
	}

    	hFile = _lopen(lpszName,READ);
	if(hFile == -1) {
		char lpszFileName[256];

		strcpy(lpszFileName,dirname);	
		strcat(lpszFileName,"/");	
		strcat(lpszFileName,lpszName);	

		hFile = _lopen(lpszFileName,READ);

		if(hFile == -1) {
			logstr(LF_ERROR,"cannot open file %s\n",lpszFileName);
			return 0;
		}		
	}

	/* read the dos image header first */
        ret = _lread(hFile,&DosHeader,sizeof(IMAGE_DOS_HEADER));

	if(DosHeader.e_magic == IMAGE_DOS_SIGNATURE)	{

		/* now read in the nt header */
    		_llseek(hFile,DosHeader.e_lfanew,0);

		pNTHeader = &NTHeader[nNTHeader];

		ret = _lread(hFile,pNTHeader, sizeof(IMAGE_NT_HEADERS));

		/* yes, it is a win32 header */
		if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) {
			_lclose(hFile);
			return 0;
		}
		

		bp = strrchr(lpszName,'/');
		if(bp)
			bp++;
		else 
			bp = lpszName;

		BaseAddress = VirtualAlloc(
			(void *) pNTHeader->OptionalHeader.ImageBase,
			pNTHeader->OptionalHeader.SizeOfImage,
			MEM_COMMIT,
			PAGE_EXECUTE_READWRITE);

		logstr(lf_console,"Load File: %s %p\n",lpszName,BaseAddress);

		NTModules[nNTHeader].modulename = bp; 		
		NTModules[nNTHeader].pNTHeader = pNTHeader; 		
		NTModules[nNTHeader].BaseAddress = BaseAddress; 		
		nNTHeader++;

		if (nNTHeader == 1 && usebuiltins) {
			NTModules[nNTHeader++].modulename = "user32.dll";
			NTModules[nNTHeader++].modulename = "gdi32.dll";
			NTModules[nNTHeader++].modulename = "kernel32.dll";
			NTModules[nNTHeader++].modulename = "shell32.dll";
			NTModules[nNTHeader++].modulename = "comctl32.dll";
			NTModules[nNTHeader++].modulename = "comdlg32.dll";
			NTModules[nNTHeader++].modulename = "rpcrt4.dll";
			NTModules[nNTHeader++].modulename = "advapi32.dll";
		}

		/* show the NT header */
	 	//if (index == 0)
		   DumpHeader(&pNTHeader->FileHeader);

		/* show the Optional header */
	 	//if (index == 0)
		   DumpOptionalHeader((PIMAGE_OPTIONAL_HEADER) 
			&pNTHeader->OptionalHeader);

		pSectionHeaders = (PIMAGE_SECTION_HEADER)((void *)BaseAddress + sizeof(IMAGE_NT_HEADERS));

		/* now read the section headers */
		ret = _lread( hFile, pSectionHeaders, sizeof(IMAGE_SECTION_HEADER)*
			pNTHeader->FileHeader.NumberOfSections);

		for(i=0; i < pNTHeader->FileHeader.NumberOfSections; i++) {
			void *LoadAddress;

			LoadAddress = 
				RVA(BaseAddress,pSectionHeaders->VirtualAddress);
			//if (index == 0) 
			{
			   DumpSectionTable( LoadAddress,pSectionHeaders,i);
			}

			/* load only non-BSS segments */
			if(!(pSectionHeaders->Characteristics &
				IMAGE_SCN_CNT_UNINITIALIZED_DATA)) 
		        {
			    _llseek(hFile,pSectionHeaders->PointerToRawData,SEEK_SET);
			    len = _lread(hFile,(char*) LoadAddress, 
				pSectionHeaders->SizeOfRawData);

			    if( len != pSectionHeaders->SizeOfRawData)
			    {
				logstr(LF_ERROR,"Failed to load section %x %x\n", i,len);
				exit(0);
			    }
			    pSectionHeaders++;
			}
			
			/* not needed, memory is zero */
			if(strcmp(pSectionHeaders[i].Name, ".bss") == 0)
			    memset((void *)LoadAddress, 0,
				   pSectionHeaders[i].Misc.VirtualSize ?
				   pSectionHeaders[i].Misc.VirtualSize :
				   pSectionHeaders[i].SizeOfRawData);
		}

		_lclose(hFile);

		// we are dependent on other modules, go get and load those
		//if (index == 0)
		   LoadImportsSection(BaseAddress, pNTHeader,lpszName);

		if (index == 0) 
		{
			logstr(lf_header,"   %32s   PE Header  BaseAddress\n",
				"FileName");
			for(i=0;i<nNTHeader;i++) {
			   logstr(lf_header,"%.4d: %32s %p %p\n",
				i,
				NTModules[i].modulename,
				NTModules[i].pNTHeader,
				NTModules[i].BaseAddress);
			}	
        		
		}

		if (index == 0)
		   LoadExportsTable(&NTModules[0],pNTHeader,lpszName);

		if (index == 0)
		   ExecEntryPoint(
			NTModules[0].BaseAddress, 
			NTModules[0].pNTHeader, 
			lpszName);

		return &NTModules[index]; 		
	}
	return 0;
}
Example #20
0
PVOID
NTAPI
LdrPEGetExportByName(PVOID BaseAddress,
                     PUCHAR SymbolName,
                     USHORT Hint)
{
    PIMAGE_EXPORT_DIRECTORY ExportDir;
    PULONG * ExFunctions;
    PULONG * ExNames;
    USHORT * ExOrdinals;
    PVOID ExName;
    ULONG Ordinal;
    PVOID Function;
    LONG minn, maxn, mid, res;
    ULONG ExportDirSize;

    /* HAL and NTOS use a virtual address, switch it to physical mode */
    if ((ULONG_PTR)BaseAddress & 0x80000000)
    {
        BaseAddress = (PVOID)((ULONG_PTR)BaseAddress - KSEG0_BASE + (ULONG)KernelMemory);
    }

    ExportDir = (PIMAGE_EXPORT_DIRECTORY)
        RtlImageDirectoryEntryToData(BaseAddress,
                                     TRUE,
                                     IMAGE_DIRECTORY_ENTRY_EXPORT,
                                     &ExportDirSize);
    if (!ExportDir)
    {
        DbgPrint("LdrPEGetExportByName(): no export directory!\n");
        return NULL;
    }

    /* The symbol names may be missing entirely */
    if (!ExportDir->AddressOfNames)
    {
        DbgPrint("LdrPEGetExportByName(): symbol names missing entirely\n");
        return NULL;
    }

    /*
    * Get header pointers
    */
    ExNames = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfNames);
    ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
    ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions);

    /*
    * Check the hint first
    */
    if (Hint < ExportDir->NumberOfNames)
    {
        ExName = RVA(BaseAddress, ExNames[Hint]);
        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
        {
            Ordinal = ExOrdinals[Hint];
            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
            {
                Function = LdrPEFixupForward((PCHAR)Function);
                if (Function == NULL)
                {
                    DbgPrint("LdrPEGetExportByName(): failed to find %s\n", Function);
                }
                return Function;
            }

            if (Function != NULL) return Function;
        }
    }

    /*
    * Binary search
    */
    minn = 0;
    maxn = ExportDir->NumberOfNames - 1;
    while (minn <= maxn)
    {
        mid = (minn + maxn) / 2;

        ExName = RVA(BaseAddress, ExNames[mid]);
        res = strcmp(ExName, (PCHAR)SymbolName);
        if (res == 0)
        {
            Ordinal = ExOrdinals[mid];
            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
            {
                Function = LdrPEFixupForward((PCHAR)Function);
                if (Function == NULL)
                {
                    DbgPrint("1: failed to find %s\n", Function);
                }
                return Function;
            }
            if (Function != NULL)
            {
                return Function;
            }
        }
        else if (res > 0)
        {
            maxn = mid - 1;
        }
        else
        {
            minn = mid + 1;
        }
    }

    /* Fall back on unsorted */
    minn = 0;
    maxn = ExportDir->NumberOfNames - 1;
    while (minn <= maxn)
    {
        ExName = RVA(BaseAddress, ExNames[minn]);
        res = strcmp(ExName, (PCHAR)SymbolName);
        if (res == 0)
        {
            Ordinal = ExOrdinals[minn];
            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
            {
                Function = LdrPEFixupForward((PCHAR)Function);
                if (Function == NULL)
                {
                    DbgPrint("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
                }
                return Function;
            }
	    if (Function != NULL)
	    {
		return Function;
	    }
	    DbgPrint("Failed to get function %s\n", SymbolName);
	}
	minn++;
    }

    DbgPrint("2: failed to find %s\n",SymbolName);
    return (PVOID)NULL;
}