Пример #1
0
    void GenerateUpperTriangularMatrices(NekDouble values[], NekDouble scale,
        boost::shared_ptr<NekMatrix<NekDouble, StandardMatrixTag> >& m1,
        boost::shared_ptr<NekMatrix<NekMatrix<NekDouble>, ScaledMatrixTag> >& m2,
        boost::shared_ptr<NekMatrix<NekMatrix<NekDouble>, BlockMatrixTag> >& m3)
    {
        m1 = MakePtr(new NekMatrix<NekDouble, StandardMatrixTag>(4, 4, values, eUPPER_TRIANGULAR));
        
        double inner_values[10];
        std::transform(values, values+10, inner_values, boost::bind(std::divides<NekDouble>(), _1, scale));

        boost::shared_ptr<NekMatrix<NekDouble> > inner(
            new NekMatrix<NekDouble>(4, 4, inner_values, eUPPER_TRIANGULAR)); 
        m2 = MakePtr(new NekMatrix<NekMatrix<NekDouble>, ScaledMatrixTag>(scale, inner));
        
        double block_1_values[] = {values[0], 0.0,
                                   values[1], values[2]};
        double block_2_values[] = {values[3], values[4],
                                   values[6], values[7]};
        double block_4_values[] = {values[5], 0.0,
                                   values[8], values[9]};
        boost::shared_ptr<NekMatrix<NekDouble> > block1(new NekMatrix<NekDouble>(2, 2, block_1_values));
        boost::shared_ptr<NekMatrix<NekDouble> > block2(new NekMatrix<NekDouble>(2, 2, block_2_values));
        boost::shared_ptr<NekMatrix<NekDouble> > block4(new NekMatrix<NekDouble>(2, 2, block_4_values));
        
        m3 = MakePtr(new NekMatrix<NekMatrix<NekDouble>, BlockMatrixTag>(2, 2, 2, 2));
        m3->SetBlock(0,0, block1);
        m3->SetBlock(0,1, block2);
        m3->SetBlock(1,1, block4);
    }
Пример #2
0
void DumpFirstLinkerMember(PVOID p)
{
    DWORD cSymbols = *(PDWORD)p;
    PDWORD pMemberOffsets = MakePtr( PDWORD, p, 4 );
    PSTR pSymbolName;
    unsigned i;

    cSymbols = ConvertBigEndian(cSymbols);
    pSymbolName = MakePtr( PSTR, pMemberOffsets, 4 * cSymbols );
    
    printf("First Linker Member:\n");
    printf( "  Symbols:         %08X\n", cSymbols );
    printf( "  MbrOffs   Name\n  --------  ----\n" );
        
    for ( i = 0; i < cSymbols; i++ )
    {
        DWORD offset;
        
        offset = ConvertBigEndian( *pMemberOffsets );
        
        printf("  %08X  %s\n", offset, pSymbolName);
        
        pMemberOffsets++;
        pSymbolName += strlen(pSymbolName) + 1;
    }
}
static PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportModule)
{
	PIMAGE_DOS_HEADER pDOSHeader;
	PIMAGE_NT_HEADERS pNTHeader;
	PIMAGE_IMPORT_DESCRIPTOR pImportDesc;

	if ((szImportModule == NULL) || (hModule == NULL))
		return NULL;
	pDOSHeader = (PIMAGE_DOS_HEADER) hModule;
	if (IsBadReadPtr(pDOSHeader, sizeof(IMAGE_DOS_HEADER)) || (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)) {
		return NULL;
	}
	pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDOSHeader, pDOSHeader->e_lfanew);
	if (IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) || (pNTHeader->Signature != IMAGE_NT_SIGNATURE))
		return NULL;
	if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0)
		return NULL;
	pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDOSHeader, pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
	while (pImportDesc->Name) {
		PSTR szCurrMod = MakePtr(PSTR, pDOSHeader, pImportDesc->Name);
		if (_stricmp(szCurrMod, szImportModule) == 0)
			break;
		pImportDesc++;
	}
	if (pImportDesc->Name == (DWORD)0)
		return NULL;
	return pImportDesc;
}
Пример #4
0
void DumpSecondLinkerMember(PVOID p)
{
    DWORD cArchiveMembers = *(PDWORD)p;
    PDWORD pMemberOffsets = MakePtr( PDWORD, p, 4 );
    DWORD cSymbols;
    PSTR pSymbolName;
    PWORD pIndices;
    unsigned i;

    cArchiveMembers = cArchiveMembers;

    // The number of symbols is in the DWORD right past the end of the
    // member offset array.
    cSymbols = pMemberOffsets[cArchiveMembers];

    pIndices = MakePtr( PWORD, p, 4 + cArchiveMembers * sizeof(DWORD) + 4 );

    pSymbolName = MakePtr( PSTR, pIndices, cSymbols * sizeof(WORD) );
    
    printf("Second Linker Member:\n");
    
    printf( "  Archive Members: %08X\n", cArchiveMembers );
    printf( "  Symbols:         %08X\n", cSymbols );
    printf( "  MbrOffs   Name\n  --------  ----\n" );

    for ( i = 0; i < cSymbols; i++ )
    {
        printf("  %08X  %s\n", pMemberOffsets[pIndices[i] - 1], pSymbolName);
        pSymbolName += strlen(pSymbolName) + 1;
    }
}
Пример #5
0
    void GenerateFullMatrices(double values[], double scale,
        boost::shared_ptr<NekMatrix<NekDouble, StandardMatrixTag> >& m1,
        boost::shared_ptr<NekMatrix<NekMatrix<NekDouble>, ScaledMatrixTag> >& m2,
        boost::shared_ptr<NekMatrix<NekMatrix<NekDouble>, BlockMatrixTag> >& m3)
    {
        m1 = MakePtr(new NekMatrix<NekDouble, StandardMatrixTag>(4, 4, values));
        
        double inner_values[16];
        std::transform(values, values+16, inner_values, boost::bind(std::divides<NekDouble>(), _1, scale));

        boost::shared_ptr<NekMatrix<NekDouble> > inner(
            new NekMatrix<NekDouble>(4, 4, inner_values)); 
        m2 = MakePtr(new NekMatrix<NekMatrix<NekDouble>, ScaledMatrixTag>(scale, inner));
        
        double block_1_values[] = {values[0], values[1], 
                            values[4], values[5]};
        double block_2_values[] = {values[2], values[3],
                            values[6], values[7]};
        double block_3_values[] = {values[8], values[9], 
                            values[12], values[13]};
        double block_4_values[] = {values[10], values[11],
                            values[14], values[15]};
        boost::shared_ptr<NekMatrix<NekDouble> > block1(new NekMatrix<NekDouble>(2, 2, block_1_values));
        boost::shared_ptr<NekMatrix<NekDouble> > block2(new NekMatrix<NekDouble>(2, 2, block_2_values));
        boost::shared_ptr<NekMatrix<NekDouble> > block3(new NekMatrix<NekDouble>(2, 2, block_3_values));
        boost::shared_ptr<NekMatrix<NekDouble> > block4(new NekMatrix<NekDouble>(2, 2, block_4_values));
        
        m3 = MakePtr(new NekMatrix<NekMatrix<NekDouble>, BlockMatrixTag>(2, 2, 2, 2));
        m3->SetBlock(0,0, block1);
        m3->SetBlock(1,0, block2);
        m3->SetBlock(0,1, block3);
        m3->SetBlock(1,1, block4);
    }
Пример #6
0
void init_core_dll()
{
    PIMAGE_DOS_HEADER        dos;
    PIMAGE_NT_HEADERS32      nt;
    PIMAGE_EXPORT_DIRECTORY  exp;

    dos =  (PIMAGE_DOS_HEADER)LOAD_BASE;
    nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);

    list_initialize(&core_dll.link);

    core_dll.img_base = LOAD_BASE;
    core_dll.img_size = nt->OptionalHeader.SizeOfImage;
    core_dll.img_md   = NULL;

    core_dll.img_hdr  = nt;
    core_dll.img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
    core_dll.img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
                        nt->OptionalHeader.DataDirectory[0].VirtualAddress);
    core_dll.img_name = strupr(MakePtr(char*, LOAD_BASE, exp->Name));

    dll_slab = slab_cache_create(sizeof(dll_t), 16,NULL,NULL,SLAB_CACHE_MAGDEFERRED);

    DBG("%s base %x size %x sections %d exports %x\n",
        core_dll.img_name, core_dll.img_base,
        core_dll.img_size, nt->FileHeader.NumberOfSections,
        core_dll.img_exp );
};
Пример #7
0
GLOBAL void InitTypes()
{ 
  TypeNames[Uchar] = "unsigned char";
  TypeNames[Schar] = "signed char";
  TypeNames[Char] = "char";
  TypeNames[Sshort] = "short";
  TypeNames[Ushort] = "unsigned short";
  TypeNames[Sint] = "int";
  TypeNames[Uint] = "unsigned";
  TypeNames[Int_ParseOnly] = "int";
  TypeNames[Slong] = "long";
  TypeNames[Ulong] = "unsigned long";
  TypeNames[Slonglong] = "long long";
  TypeNames[Ulonglong] = "unsigned long long";
  TypeNames[Float] = "float";
  TypeNames[Double] = "double";
  TypeNames[Longdouble] = "long double";
  TypeNames[Void] = "void";
  TypeNames[Ellipsis] = "...";

  EllipsisNode = MakePrim(EMPTY_TQ, Ellipsis);
  Undeclared   = MakeDecl("undeclared!", EMPTY_TQ, NULL, NULL, NULL);

  PrimVoid     = MakePrim(EMPTY_TQ, Void);
  PrimChar     = MakePrim(EMPTY_TQ, Char);
  PrimSchar    = MakePrim(EMPTY_TQ, Schar);
  PrimUchar    = MakePrim(EMPTY_TQ, Uchar);
  PrimSshort   = MakePrim(EMPTY_TQ, Sshort);
  PrimUshort   = MakePrim(EMPTY_TQ, Ushort);
  PrimSint     = MakePrim(EMPTY_TQ, Sint);
  PrimUint     = MakePrim(EMPTY_TQ, Uint);
  PrimSlong    = MakePrim(EMPTY_TQ, Slong);
  PrimUlong    = MakePrim(EMPTY_TQ, Ulong);
  PrimSlonglong= MakePrim(EMPTY_TQ, Slonglong);
  PrimUlonglong= MakePrim(EMPTY_TQ, Ulonglong);
  PrimFloat    = MakePrim(EMPTY_TQ, Float);
  PrimDouble   = MakePrim(EMPTY_TQ, Double);
  PrimLongdouble= MakePrim(EMPTY_TQ, Longdouble);
  StaticString = MakePtr(EMPTY_TQ, MakePrim(T_STATIC, Char));

  /* Make some standard zeros */
  SintZero   = MakeConstSint(0);
  UintZero   = MakeConstUint(0);
  SlongZero  = MakeConstSlong(0);
  UlongZero  = MakeConstUlong(0);
  FloatZero  = MakeConstFloat(0.0);
  DoubleZero = MakeConstDouble(0.0);

  /* Make some standard ones */
  SintOne    = MakeConstSint(1);
  UintOne    = MakeConstUint(1);
  SlongOne   = MakeConstSlong(1);
  UlongOne   = MakeConstUlong(1);
  FloatOne   = MakeConstFloat(1.0);
  DoubleOne  = MakeConstDouble(1.0);

  PtrVoid = MakePtr(EMPTY_TQ, PrimVoid);
  PtrNull = MakeConstPtr(0);
}
static BOOL HookImportFunction(HMODULE hModule, LPCSTR szImportModule, LPCSTR szFunc, PROC paHookFuncs, PROC* paOrigFuncs)
{
	PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
	PIMAGE_THUNK_DATA pOrigThunk;
	PIMAGE_THUNK_DATA pRealThunk;

	if (!IsNT() && ((size_t)hModule >= 0x80000000))
		return FALSE;
	pImportDesc = GetNamedImportDescriptor(hModule, szImportModule);
	if (pImportDesc == NULL)
		return FALSE;
	pOrigThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->OriginalFirstThunk);
	pRealThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->FirstThunk);
	while (pOrigThunk->u1.Function) {
		if (IMAGE_ORDINAL_FLAG != (pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)) {
			PIMAGE_IMPORT_BY_NAME pByName = MakePtr(PIMAGE_IMPORT_BY_NAME, hModule, pOrigThunk->u1.AddressOfData);
			BOOL bDoHook;
			// When hook EditPlus, read pByName->Name[0] will case this dll terminate, so call IsBadReadPtr() here.
			if (IsBadReadPtr(pByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
				pOrigThunk++;
				pRealThunk++;
				continue;				
			}
			if ('\0' == pByName->Name[0]) {
				pOrigThunk++;
				pRealThunk++;
				continue;
			}
			bDoHook = FALSE;
			if ((szFunc[0] == pByName->Name[0]) && (_strcmpi(szFunc, (char*)pByName->Name) == 0)) {
				if (paHookFuncs)
					bDoHook = TRUE;
			}
			if (bDoHook) {
				MEMORY_BASIC_INFORMATION mbi_thunk;
				DWORD dwOldProtect;

				VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
				VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect);
				if (paOrigFuncs)
					*paOrigFuncs = (PROC)pRealThunk->u1.Function;
				pRealThunk->u1.Function = (DWORD)paHookFuncs;

				VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect, &dwOldProtect);
				return TRUE;
			}
		}
		pOrigThunk++;
		pRealThunk++;
	}
	return FALSE;
}
Пример #9
0
//===========================================================================
// Top level routine to find the EXE's imports, and redirect them
bool HookAPICalls( SDLLHook* Hook )
{
    if ( !Hook )
        return false;

    HMODULE hModEXE = GetModuleHandle( 0 );

    PIMAGE_NT_HEADERS pExeNTHdr = PEHeaderFromHModule( hModEXE );
    
    if ( !pExeNTHdr )
        return false;

    DWORD importRVA = pExeNTHdr->OptionalHeader.DataDirectory
                        [IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    if ( !importRVA )
        return false;

    // Convert imports RVA to a usable pointer
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MakePtr( PIMAGE_IMPORT_DESCRIPTOR,
                                                    hModEXE, importRVA );

    // Save off imports address in a global for later use
    g_pFirstImportDesc = pImportDesc;   

	bool returnVal = false;

    // Iterate through each import descriptor, and redirect if appropriate
    while ( pImportDesc->FirstThunk )
    {
        PSTR pszImportModuleName = MakePtr( PSTR, hModEXE, pImportDesc->Name);

		OutputDebugString( "Checking:  " );
		OutputDebugString( pszImportModuleName );
        OutputDebugString( "...\n" );

        if ( lstrcmpi( pszImportModuleName, Hook->Name ) == 0 )
        {
            OutputDebugString( "Found " );
            OutputDebugString( Hook->Name );
            OutputDebugString( "...\n" );

            RedirectIAT( Hook, pImportDesc, (PVOID)hModEXE );

			returnVal = true;
        }
        
        pImportDesc++;  // Advance to next import descriptor
    }

    return returnVal;
}
Пример #10
0
void* HAPIHook::InterceptDllMember(HMODULE hModule,char *szDllName,char *szFunctionName,DWORD pNewFunction)
{
	EnterCriticalSection(&m_cs);
	PIMAGE_DOS_HEADER pDosHeader;
	PIMAGE_NT_HEADERS pNTHeader;
	PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
	PIMAGE_THUNK_DATA pThunk;
	DWORD dwOldProtect;
	DWORD dwOldProtect2;
	void *pOldFunction;

	if(!(pOldFunction = GetProcAddress(GetModuleHandle(szDllName),szFunctionName)))
		return 0;

	pDosHeader = (PIMAGE_DOS_HEADER)hModule;
	if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
		return(NULL);

	pNTHeader = MakePtr(PIMAGE_NT_HEADERS,pDosHeader,pDosHeader->e_lfanew);
	if(pNTHeader->Signature != IMAGE_NT_SIGNATURE
		|| ( pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR,pDosHeader,pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)) == (PIMAGE_IMPORT_DESCRIPTOR )pNTHeader)
		return(NULL);

	while(pImportDesc->Name)
	{
		char *szModuleName = MakePtr(char *,pDosHeader,pImportDesc->Name);
		if(!stricmp(szModuleName,szDllName))
			break;
		pImportDesc++;
	}
	if(pImportDesc->Name == NULL)
		return(NULL);

	pThunk = MakePtr(PIMAGE_THUNK_DATA,pDosHeader,pImportDesc->FirstThunk);
	while(pThunk->u1.Function)
	{
		if(pThunk->u1.Function == (DWORD)pOldFunction)
		{
			VirtualProtect((void*)&pThunk->u1.Function,sizeof(DWORD),PAGE_EXECUTE_READWRITE,&dwOldProtect);
			pThunk->u1.Function = pNewFunction;
			VirtualProtect((void*)&pThunk->u1.Function,sizeof(DWORD),dwOldProtect,&dwOldProtect2 );
			return(pOldFunction);
		}
		pThunk++;
	}
	LeaveCriticalSection(&m_cs);
	return(NULL);
}
Пример #11
0
//
// Do a hexadecimal dump of the raw data for all the sections.  You
// could just dump one section by adjusting the PIMAGE_SECTION_HEADER
// and cSections parameters
//
void DumpRawSectionData(PIMAGE_SECTION_HEADER section,
                        PVOID base,
                        unsigned cSections)
{
    unsigned i;
    char name[IMAGE_SIZEOF_SHORT_NAME + 1];

    printf("Section Hex Dumps\n");
    
    for ( i=1; i <= cSections; i++, section++ )
    {
        // Make a copy of the section name so that we can ensure that
        // it's null-terminated
        memcpy(name, section->Name, IMAGE_SIZEOF_SHORT_NAME);
        name[IMAGE_SIZEOF_SHORT_NAME] = 0;

        // Don't dump sections that don't exist in the file!
        if ( section->PointerToRawData == 0 )
            continue;
        
        printf( "section %02X (%s)  size: %08X  file offs: %08X\n",
                i, name, section->SizeOfRawData, section->PointerToRawData);

        HexDump( MakePtr(PBYTE, base, section->PointerToRawData),
                 section->SizeOfRawData );
        printf("\n");
    }
}
Пример #12
0
srv_t* __fastcall load_pe_driver(const char *path)
{
    PIMAGE_DOS_HEADER     dos;
    PIMAGE_NT_HEADERS32   nt;

    drv_entry_t   *drv_entry;
    addr_t        *img_base ;
    srv_t         *srv;

    img_base = load_image(path);

    if( ! img_base )
        return 0;

    if( link_image( img_base ) )
    {
        dos = (PIMAGE_DOS_HEADER)img_base;
        nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);

        drv_entry = MakePtr(drv_entry_t*, img_base,
                            nt->OptionalHeader.AddressOfEntryPoint);

        srv = drv_entry(1);

        if(srv != NULL)
            srv->entry = nt->OptionalHeader.AddressOfEntryPoint + img_base;

        return srv;
    }
    else
    {
Пример #13
0
ULONG peDumpExports(HMODULE mod, BOOL noname)
{
  if (!mod)
  {
    return ERROR_INVALID_PARAMETER;
  }

  PBYTE pImageBase = (PBYTE)mod;
  PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)pImageBase;

  // get pointers to 32 and 64 bit versions of the header.
  PIMAGE_NT_HEADERS32 pNTHeader = MakePtr( PIMAGE_NT_HEADERS32, dosHeader, dosHeader->e_lfanew );
  PIMAGE_NT_HEADERS64 pNTHeader64 = (PIMAGE_NT_HEADERS64)pNTHeader;
  BOOL is64 = ( pNTHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC );

  ULONG gle;
  if (is64)
  {
    gle = peDumpExportsInternal((PBYTE)mod,pNTHeader64,noname);
  }
  else
  {
    gle = peDumpExportsInternal((PBYTE)mod,pNTHeader,noname);
  }
  return gle;  
}
Пример #14
0
FARPROC GetRemoteProcAddress(unsigned long pId, char *module, char *func)
{
   HMODULE remoteMod = GetRemoteModuleHandle(pId, module);
   HMODULE localMod = GetModuleHandle(module);

   //   Account for potential differences in base address
   //   of modules in different processes.
   unsigned long delta = MakeDelta(unsigned long, remoteMod, localMod);
   return MakePtr(FARPROC, GetProcAddress(localMod, func), delta);
}
Пример #15
0
HRESULT CPEFile::Open(LPCTSTR pszFile, BOOL bReadOnly)
{
  HRESULT hr = S_OK;
  Close();

  m_hFile = CreateFile(pszFile, GENERIC_READ | ((bReadOnly == FALSE) ? GENERIC_WRITE: 0), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (m_hFile == INVALID_HANDLE_VALUE)
  {
    hr = HRESULT_FROM_WIN32(GetLastError());
  }
  else
  {
    m_hMap = CreateFileMapping(m_hFile, NULL, (bReadOnly == TRUE) ? PAGE_READONLY:PAGE_READWRITE, 0, 0, NULL);
    if (!m_hMap)
    {
      hr = HRESULT_FROM_WIN32(GetLastError());
    }
    else
    {
      m_pBase = (PIMAGE_DOS_HEADER)MapViewOfFile(m_hMap, FILE_MAP_READ | ((bReadOnly == FALSE) ? FILE_MAP_WRITE:0), 0, 0, 0);
      if (!m_pBase)
      {
        hr = HRESULT_FROM_WIN32(GetLastError());
      }
    }
  }

  if (SUCCEEDED(hr))
  {
    PIMAGE_FILE_HEADER pImageHeader = (PIMAGE_FILE_HEADER)m_pBase;
    if (m_pBase->e_magic != IMAGE_DOS_SIGNATURE)
    {
      hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
    }

    m_pNTHeader = MakePtr(PIMAGE_NT_HEADERS, m_pBase, m_pBase->e_lfanew);
    if (IsBadReadPtr(m_pNTHeader, sizeof(m_pNTHeader->Signature)))
    {
      hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
    }
    else
    {
      if (m_pNTHeader->Signature != IMAGE_NT_SIGNATURE)
      {
        hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
      }
    }
    m_bIs64Bit = (m_pNTHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC);
  }

  if (FAILED(hr)) Close();

  return hr;
}
Пример #16
0
bool DumpDbgFile( MPanelItem *pRoot, PIMAGE_SEPARATE_DEBUG_HEADER pImageSepDbgHeader )
{
    DumpImageDbgHeader(pRoot, pImageSepDbgHeader);
    pRoot->printf("\n");
    
    DumpSectionTable( pRoot, (PIMAGE_SECTION_HEADER)(pImageSepDbgHeader+1),
                        pImageSepDbgHeader->NumberOfSections, TRUE);
                    
    DumpDebugDirectory(
        pRoot, MakePtr(PIMAGE_DEBUG_DIRECTORY,
        pImageSepDbgHeader, sizeof(IMAGE_SEPARATE_DEBUG_HEADER) +
        (pImageSepDbgHeader->NumberOfSections * sizeof(IMAGE_SECTION_HEADER))
        + pImageSepDbgHeader->ExportedNamesSize),
        pImageSepDbgHeader->DebugDirectorySize,
        (PBYTE)pImageSepDbgHeader);
    
    pRoot->printf("\n");
    
    if ( g_pCOFFHeader )
	{
        DumpCOFFHeader( pRoot, g_pCOFFHeader );
    
		pRoot->printf("\n");

		g_pCOFFSymbolTable = new COFFSymbolTable(
			MakePtr( PVOID, g_pCOFFHeader, g_pCOFFHeader->LvaToFirstSymbol),
			g_pCOFFHeader->NumberOfSymbols );


		DumpCOFFSymbolTable( pRoot, g_pCOFFSymbolTable );

		delete g_pCOFFSymbolTable;
	}
	
	if ( g_pCVHeader )
	{
		DumpCVSymbolTable( pRoot, (PBYTE)g_pCVHeader, g_pMappedFileBase );
	}
	return true;
}
Пример #17
0
bool MapSections(HANDLE hProcess, void *moduleBase, void *dllBin, IMAGE_NT_HEADERS *ntHd)
{
   IMAGE_SECTION_HEADER *header = IMAGE_FIRST_SECTION(ntHd);
   unsigned int nBytes = 0;
   unsigned int virtualSize = 0;
   unsigned int n = 0;

   //   Loop through the list of sections
   for(unsigned int i = 0; ntHd->FileHeader.NumberOfSections; i++)
   {
      //   Once we've reached the SizeOfImage, the rest of the sections
      //   don't need to be mapped, if there are any.
      if(nBytes >= ntHd->OptionalHeader.SizeOfImage)
         break;
     
      WriteProcessMemory(hProcess,
         MakePtr(LPVOID, moduleBase, header->VirtualAddress),
         MakePtr(LPCVOID, dllBin, header->PointerToRawData),
         header->SizeOfRawData,
         (LPDWORD)&n);

      virtualSize = header->VirtualAddress;
      header++;
      virtualSize = header->VirtualAddress - virtualSize;
      nBytes += virtualSize;

      //   Set the proper page protections for this section.
      //   This really could be skipped, but it's not that
      //   hard to implement and it makes it more like a
      //   real loader.
      VirtualProtectEx(hProcess,
         MakePtr(LPVOID, moduleBase, header->VirtualAddress),
         virtualSize,
         header->Characteristics & 0x00FFFFFF,
         NULL);
   }

   return true;
}
Пример #18
0
BOOL CRemoteLoader::ProcessSection( BYTE* Name, PVOID BaseAddress, PVOID RemoteAddress, ULONG RawData, ULONG VirtualAddress, ULONG RawSize, ULONG VirtualSize, ULONG ProtectFlag )
{
	DebugShout( "[ProcessSection] ProcessSection( %s, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X )",
		Name, BaseAddress, RemoteAddress, RawData, VirtualAddress, RawSize, VirtualSize, ProtectFlag );

	HANDLE hProcess = GetProcess();

	if( hProcess == INVALID_HANDLE_VALUE )
	{
		hProcess = GetCurrentProcess();
	}

	if( WriteProcessMemory( hProcess,
		MakePtr( PVOID, RemoteAddress, VirtualAddress ),
		MakePtr( PVOID, BaseAddress, RawData ),
		RawSize,
		NULL ) == FALSE )
	{
		DebugShout( "[ProcessSection] Failed to write memory for (%s) -> (%s)", Name, LastErrorString() );

		return FALSE;
	}

	DWORD dwOldProtect = NULL;

	if( VirtualProtectEx( hProcess,
		MakePtr( PVOID, RemoteAddress, VirtualAddress ),
		VirtualSize,
		ProtectFlag,
		&dwOldProtect ) == FALSE )
	{
		DebugShout( "[ProcessSection] Failed to protect memory for (%s) -> (%s)", Name, LastErrorString() );

		return FALSE;
	}

	return TRUE;
}
Пример #19
0
int validate_pe(void *raw, size_t raw_size, int is_exec)
{
    PIMAGE_DOS_HEADER     dos;
    PIMAGE_NT_HEADERS32   nt;

    dos = (PIMAGE_DOS_HEADER)raw;

    if( !raw || raw_size < sizeof(IMAGE_DOS_HEADER) )
        return 0;

    if( dos->e_magic != IMAGE_DOS_SIGNATURE || dos->e_lfanew <= 0)
        return 0;

    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);

    if( (uint32_t)nt < (uint32_t)raw)
        return 0;

    if(nt->Signature != IMAGE_NT_SIGNATURE)
        return 0;

    if(nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
        return 0;

    if(is_exec && (nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
        return 0;

    if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
        return 0;

    if( is_exec && nt->OptionalHeader.ImageBase != 0)
        return 0;

    if(nt->OptionalHeader.SectionAlignment < 4096)
    {
        if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment)
            return 0;
    }
    else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment)
        return 0;

    if(!IsPowerOf2(nt->OptionalHeader.SectionAlignment) ||
       !IsPowerOf2(nt->OptionalHeader.FileAlignment))
        return 0;

    if(nt->FileHeader.NumberOfSections > 96)
        return 0;

    return 1;
}
Пример #20
0
EXE_FILE::EXE_FILE( PSTR pszFileName ) : MEMORY_MAPPED_FILE( pszFileName )
{
    m_errorType = errEXE_FILE_FILE_NOT_FOUND;
    m_secondaryHeaderOffset = -1;   // A bogus value to catch bugs
    m_exeType = exeType_Invalid;

    if ( FALSE == MEMORY_MAPPED_FILE::IsValid() )
        return;     // m_errorType already set to errEXE_FILE_FILE_NOT_FOUND

    // If we get here, the file exists, and was mapped.  We're still not
    // sure that it's a valid EXE though
    m_errorType = errEXE_FILE_INVALID_FORMAT;

    if ( GetFileSize() < sizeof(IMAGE_DOS_HEADER) )
        return;
    
    PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)GetBase();
    if ( IMAGE_DOS_SIGNATURE != pDosHdr->e_magic )
        return;

    // If we get here, it's at least a DOS 'MZ' file
    m_errorType = errEXE_FILE_NO_ERROR;

    if ( pDosHdr->e_lfarlc < 0x40 ) // Theoretically, this field must be >=
    {                               // 0x40 for it to be a non-DOS executable
        m_exeType = exeType_DOS;
        return;
    }

    // Sanity check.  Make sure the "new header" offset isn't past the end
    // of the file
    if ( pDosHdr->e_lfanew > (LONG)GetFileSize() )
        return;

    // Make a pointer to the secondary header   
    m_secondaryHeaderOffset = pDosHdr->e_lfanew;
    PWORD pSecondHdr = MakePtr( PWORD, GetBase(), m_secondaryHeaderOffset );

    // Decide what type of EXE, based on the start of the secondary header
    switch ( *pSecondHdr )
    {
        case IMAGE_OS2_SIGNATURE: m_exeType = exeType_NE; break;
        case IMAGE_VXD_SIGNATURE: m_exeType = exeType_VXD; break;
        case 0x4558: m_exeType = exeType_LX; break;     // OS/2 2.X
    }
    
    if ( *(PDWORD)pSecondHdr == IMAGE_NT_SIGNATURE )
        m_exeType = exeType_PE;
}
Пример #21
0
// Main function 
// see description of PPGIParamsBlock in unpack.h
// return TRUE if this pluging can handle the source
// __declspec(dllexport)
BOOL __stdcall PexPreloadImage(PPGIParamsBlock pPGI)
{
	CString str;	
	DWORD id = pPGI->dwInterface;
	PDWORD base = (DWORD *) pPGI->pInBuff;
	
	(pPGI->pCallBack)(id, 0, "Executing...");
	
	PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER) base;
    PIMAGE_NT_HEADERS pSecondHdr = MakePtr( PIMAGE_NT_HEADERS, base, pDosHdr->e_lfanew );
	PBYTE NTbase = (PBYTE) GetSectionPtr( pSecondHdr, (DWORD) base);
	
	if ( NTbase > ((PBYTE) base + pPGI->dwInSize)) 
	{
//		str.Format("%s: Error in EXE file", PIABV);
//		(pPGI->pCallBack)(id, 0, str);  // 
		return FALSE;
	}
	if (NTbase)
	{ // NTbase + 24
		if (*(NTbase + 2) == 0xE9)
			str.Format("%s: File compressed with Aspack ver 2.11", PIABV);
		else if (*(PWORD)(NTbase + 0x3B2) == 0x01B8)
			str.Format("%s: File compressed with Aspack ver 2.12/2.12a/2.12b", PIABV);
		else if (*(PWORD)(NTbase + 0x3B3) == 0x01B8)
			str.Format("%s: File compressed with Aspack ver ??", PIABV);
		else if (*(PWORD)(NTbase + 0x4F4) == 0x01B8)
			str.Format("%s: File compressed with Aspack 2000", PIABV);
		else if (*(PWORD)(NTbase + 0x4F6) == 0x01B8)
			str.Format("%s: File compressed with Aspack 2001", PIABV);
		else if (*(PWORD)(NTbase + 0x4F6) == 0x01B8 && *(NTbase + 0x4DF) == 0x000443A02)
			str.Format("%s: File compressed with Aspack ver 2.1", PIABV);
		else if (*(PWORD)(NTbase + 0x4F6) == 0x01B8 && *(NTbase + 0x4DF) == 0x0004439FD)
			str.Format("%s: File compressed with Aspack ver ??", PIABV);
		else if (*(PWORD)(NTbase + 0x3BA) == 0x7561)
			str.Format("%s: File compressed with Aspack ver ??", PIABV);
		else if (*(NTbase + 2) == 0xE8)
			str.Format("%s: File compressed with Aspack ver 2.11c/d", PIABV);
		else return FALSE;
	} else return FALSE;
	(pPGI->pCallBack)(id, 0, str);  // 

	//void *p = (pPGI->pMemAllocator)(DWORD len);	// Memory allocator for the returned Image
	// if (p) pPGI->pOutBuff = (LPVOID) p;			// Initialize output buffer pointer
	// pPGI->dwOutSize = len;						// Set output buffer size
	return TRUE;

}
Пример #22
0
//    Given a process ID, file pointer, NT header, and start of .idata, fix the imports
bool FixImports(unsigned long pId, void *base, IMAGE_NT_HEADERS *ntHd, IMAGE_IMPORT_DESCRIPTOR *impDesc)
{
   char *module;

    //   Loop through all the required modules
    while((module = (char *)GetPtrFromRVA((DWORD)(impDesc->Name), ntHd, (PBYTE)base)))
    {
        //   If the library is already loaded(like kernel32.dll or ntdll.dll) LoadLibrary will
        //   just return the handle to that module.
        //    A neat alternative would be to load them all again.  This will help ensure
        //    we have a working copy for our own function calls which is hidden :O
        HMODULE localMod = LoadLibraryA(module);

        //   If the module isn't loaded in the remote process, we recursively call the
        //   module mapping code.  This has the added benefit of ensuring that any of
        //   the current modules dependencies will be just as invisible as this one.
        if(!GetRemoteModuleHandle(pId, module))
            MapRemoteModule(pId, module);        
        
        // fix the time/date stamp
        impDesc->TimeDateStamp = ntHd->FileHeader.TimeDateStamp;

        //   Lookup the first import thunk for this module
        //   NOTE: It is possible this module could forward functions...which is something
        //   that I really should handle.  Maybe I'll add support for forward functions
        //   a little bit later.
        IMAGE_THUNK_DATA *itd =
            (IMAGE_THUNK_DATA *)GetPtrFromRVA((DWORD)(impDesc->FirstThunk), ntHd, (PBYTE)base);

        while(itd->u1.AddressOfData)
        {
            IMAGE_IMPORT_BY_NAME *iibn;
            iibn = (IMAGE_IMPORT_BY_NAME *)GetPtrFromRVA((DWORD)(itd->u1.AddressOfData), ntHd, (PBYTE)base);

                 itd->u1.Function = MakePtr(DWORD, GetRemoteProcAddress(pId,
                     module,
                     (char *)iibn->Name), 0);

            ++itd;
        }
        ++impDesc;
    }

    return true;
}
Пример #23
0
void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
  {
  PPOOLHEADER pph;                           /* Points on area header. */

  if (!memp)
    /*******************************************************************/
    /*  Allocation is to be done in the Sarea.                         */
    /*******************************************************************/
    memp = g->Sarea;

//size = ((size + 3) / 4) * 4;       /* Round up size to multiple of 4 */
  size = ((size + 7) / 8) * 8;       /* Round up size to multiple of 8 */
  pph = (PPOOLHEADER)memp;

#if defined(DEBUG2) || defined(DEBUG3)
 htrc("SubAlloc in %p size=%d used=%d free=%d\n",
  memp, size, pph->To_Free, pph->FreeBlk);
#endif

  if ((uint)size > pph->FreeBlk) {   /* Not enough memory left in pool */
    char     *pname = "Work";

    sprintf(g->Message,
      "Not enough memory in %s area for request of %u (used=%d free=%d)",
                          pname, (uint) size, pph->To_Free, pph->FreeBlk);

#if defined(DEBUG2) || defined(DEBUG3)
 htrc("%s\n", g->Message);
#endif

    longjmp(g->jumper[g->jump_level], 1);
    } /* endif size OS32 code */

  /*********************************************************************/
  /*  Do the suballocation the simplest way.                           */
  /*********************************************************************/
  memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block  */
  pph->To_Free += size;               /* New offset of pool free block */
  pph->FreeBlk -= size;               /* New size   of pool free block */
#if defined(DEBUG2) || defined(DEBUG3)
 htrc("Done memp=%p used=%d free=%d\n",
  memp, pph->To_Free, pph->FreeBlk);
#endif
  return (memp);
  } /* end of PlugSubAlloc */
Пример #24
0
FARPROC GetRemoteProcAddress(const char *module, const char *func, short nPID)
{
	HMODULE remoteMod = GetRemoteModuleHandle(module, nPID);
	HMODULE localMod = GetModuleHandle(module);

	//	If the module isn't already loaded, we load it, but since many of the 
	//	modules we'll probably be loading will do nasty things like modify
	//	memory and hook functions, we use the DONT_RESOLVE_DLL_REFERENCES flag,
	//	so that LoadLibraryEx only loads the dll, but doesn't execute it.
	if(!localMod) localMod = LoadLibraryEx(module, NULL, DONT_RESOLVE_DLL_REFERENCES);

	//	Account for potential differences in base address
	//	of modules in different processes.
	int delta = MakeDelta(int, remoteMod, localMod);

	FARPROC LocalFunctionAddress = GetProcAddress(localMod, func);

	return MakePtr(FARPROC, LocalFunctionAddress, delta);
}
Пример #25
0
/*----------------------------------------------------------------------
* DumpObjFile --
*
*	Dump an object file--either a full listing or just the exported
*	symbols.
*----------------------------------------------------------------------
*/
void DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full)
{
    PIMAGE_SYMBOL PCOFFSymbolTable;
    DWORD COFFSymbolCount;

    //PCOFFSymbolTable = (PIMAGE_SYMBOL)LongToPtr(
    //((DWORD)PtrToLong( pImageFileHeader ) + pImageFileHeader->PointerToSymbolTable) );
    PCOFFSymbolTable = MakePtr(PIMAGE_SYMBOL, pImageFileHeader,	pImageFileHeader->PointerToSymbolTable);
    COFFSymbolCount = pImageFileHeader->NumberOfSymbols;

    if (full)
    {
        DumpSymbolTable(PCOFFSymbolTable, fout, COFFSymbolCount);
    }
    else
    {
        DumpExternals(PCOFFSymbolTable, fout, COFFSymbolCount);
    }
}
Пример #26
0
void TestExeFile( const char *pFilename, PIMAGE_DOS_HEADER dosHeader )
{
	PIMAGE_NT_HEADERS pNTHeader;
	
	pNTHeader = MakePtr( PIMAGE_NT_HEADERS, dosHeader,
								dosHeader->e_lfanew );

	// First, verify that the e_lfanew field gave us a reasonable
	// pointer, then verify the PE signature.
	if ( IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) ||
	     pNTHeader->Signature != IMAGE_NT_SIGNATURE )
	{
		printf("Unhandled EXE type, or invalid .EXE (%s)\n", pFilename);
		return;
	}

	if ( HasSection( (PIMAGE_SECTION_HEADER)(pNTHeader+1), pNTHeader->FileHeader.NumberOfSections, "ValveDBG" ) )
	{
		printf("%s is a debug build\n", pFilename);
	}
}
Пример #27
0
void NTHeader::parsePEFile(const char* fileName)
{
	hFile_ = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if (hFile_ == INVALID_HANDLE_VALUE)
		throw std::exception("Unable to open file!");

	hFileMapping_ = CreateFileMapping(hFile_, NULL, PAGE_READONLY, 0, 0, NULL);
	if (hFileMapping_ == 0 )
	{
		CloseHandle(hFile_);
		throw std::exception("Unable to create file mapping!");
	}

	mappedView_ = (PBYTE)MapViewOfFile(hFileMapping_, FILE_MAP_READ, 0, 0, 0);
	if (mappedView_ == 0)
	{
		CloseHandle(hFileMapping_);
		CloseHandle(hFile_);
		throw std::exception("Unable to map view of file!");
	}

	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mappedView_;	
	pNTHeader_ = MakePtr(PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew);
}
/*----------------------------------------------------------------------
FUNCTION        :   GetNamedImportDescriptor
DISCUSSION      :
    Gets the import descriptor for the requested module.  If the module
is not imported in hModule, NULL is returned.
    This is a potential useful function in the future.
PARAMETERS      :
    hModule      - The module to hook in.
    szImportMod  - The module name to get the import descriptor for.
RETURNS         :
    NULL  - The module was not imported or hModule is invalid.
    !NULL - The import descriptor.
----------------------------------------------------------------------*/
PIMAGE_IMPORT_DESCRIPTOR
                     GetNamedImportDescriptor ( HMODULE hModule     ,
                                                LPCSTR  szImportMod  )
{
    // Always check parameters.
    ASSERT ( NULL != szImportMod ) ;
    ASSERT ( NULL != hModule     ) ;
    if ( ( NULL == szImportMod ) || ( NULL == hModule ) )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( NULL ) ;
    }

    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)hModule ;

    // Is this the MZ header?
    if ( ( TRUE == IsBadReadPtr ( pDOSHeader                  ,
                                 sizeof ( IMAGE_DOS_HEADER )  ) ) ||
         ( IMAGE_DOS_SIGNATURE != pDOSHeader->e_magic           )   )
    {
        ASSERT ( FALSE ) ;
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( NULL ) ;
    }

    // Get the PE header.
    PIMAGE_NT_HEADERS pNTHeader = MakePtr ( PIMAGE_NT_HEADERS       ,
                                            pDOSHeader              ,
                                            pDOSHeader->e_lfanew     ) ;

    // Is this a real PE image?
    if ( ( TRUE == IsBadReadPtr ( pNTHeader ,
                                  sizeof ( IMAGE_NT_HEADERS ) ) ) ||
         ( IMAGE_NT_SIGNATURE != pNTHeader->Signature           )   )
    {
        ASSERT ( FALSE ) ;
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( NULL ) ;
    }

    // If there is no imports section, leave now.
    if ( 0 == pNTHeader->OptionalHeader.
                         DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].
                                                      VirtualAddress   )
    {
        return ( NULL ) ;
    }

    // Get the pointer to the imports section.
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc
     = MakePtr ( PIMAGE_IMPORT_DESCRIPTOR ,
                 pDOSHeader               ,
                 pNTHeader->OptionalHeader.
                         DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].
                                                      VirtualAddress ) ;

    // Loop through the import module descriptors looking for the
    //  module whose name matches szImportMod.
    while ( NULL != pImportDesc->Name )
    {
        PSTR szCurrMod = MakePtr ( PSTR              ,
                                   pDOSHeader        ,
                                   pImportDesc->Name  ) ;
        if ( 0 == _stricmp ( szCurrMod , szImportMod ) )
        {
            // Found it.
            break ;
        }
        // Look at the next one.
        pImportDesc++ ;
    }

    // If the name is NULL, then the module is not imported.
    if ( NULL == pImportDesc->Name )
    {
        return ( NULL ) ;
    }

    // All OK, Jumpmaster!
    return ( pImportDesc ) ;

}
BOOL BUGSUTIL_DLLINTERFACE __stdcall
        HookImportedFunctionsByName ( HMODULE         hModule     ,
                                      LPCSTR          szImportMod ,
                                      UINT            uiCount     ,
                                      LPHOOKFUNCDESCA paHookArray ,
                                      PROC *          paOrigFuncs ,
                                      LPDWORD         pdwHooked    )
{
    // Double check the parameters.
    ASSERT ( NULL != szImportMod ) ;
    ASSERT ( 0 != uiCount ) ;
    ASSERT ( FALSE == IsBadReadPtr ( paHookArray ,
                                     sizeof (HOOKFUNCDESC) * uiCount ));
#ifdef _DEBUG
    if ( NULL != paOrigFuncs )
    {
        ASSERT ( FALSE == IsBadWritePtr ( paOrigFuncs ,
                                          sizeof ( PROC ) * uiCount ) );
    }
    if ( NULL != pdwHooked )
    {
        ASSERT ( FALSE == IsBadWritePtr ( pdwHooked , sizeof ( UINT )));
    }

    // Check each function name in the hook array.
    {
        for ( UINT i = 0 ; i < uiCount ; i++ )
        {
            ASSERT ( NULL != paHookArray[ i ].szFunc  ) ;
            ASSERT ( '\0' != *paHookArray[ i ].szFunc ) ;
            // If the proc is not NULL, then it is checked.
            if ( NULL != paHookArray[ i ].pProc )
            {
                ASSERT ( FALSE == IsBadCodePtr ( paHookArray[i].pProc));
            }
        }
    }
#endif
    // Do the parameter validation for real.
    if ( ( 0    == uiCount      )                                 ||
         ( NULL == szImportMod  )                                 ||
         ( TRUE == IsBadReadPtr ( paHookArray ,
                                  sizeof (HOOKFUNCDESC) * uiCount ) ) )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }
    if ( ( NULL != paOrigFuncs )                                &&
         ( TRUE == IsBadWritePtr ( paOrigFuncs ,
                                   sizeof ( PROC ) * uiCount ) )  )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }
    if ( ( NULL != pdwHooked )                                    &&
         ( TRUE == IsBadWritePtr ( pdwHooked , sizeof ( UINT ) ) )  )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }

    // Is this a system DLL, which Windows95 will not let you patch
    //  since it is above the 2GB line?
    if ( ( FALSE == IsNT ( ) ) && ( (DWORD)hModule >= 0x80000000 ) )
    {
        SetLastErrorEx ( ERROR_INVALID_HANDLE , SLE_ERROR ) ;
        return ( FALSE ) ;
    }


    // TODO TODO
    //  Should each item in the hook array be checked in release builds?

    if ( NULL != paOrigFuncs )
    {
        // Set all the values in paOrigFuncs to NULL.
        memset ( paOrigFuncs , NULL , sizeof ( PROC ) * uiCount ) ;
    }
    if ( NULL != pdwHooked )
    {
        // Set the number of functions hooked to zero.
        *pdwHooked = 0 ;
    }

    // Get the specific import descriptor.
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc =
                     GetNamedImportDescriptor ( hModule , szImportMod );
    if ( NULL == pImportDesc )
    {
        // The requested module was not imported.  This is not an error.
        return ( TRUE ) ;
    }

    // Get the original thunk information for this DLL.  I cannot use
    //  the thunk information stored in the pImportDesc->FirstThunk
    //  because the that is the array that the loader has already
    //  bashed to fix up all the imports.  This pointer gives us acess
    //  to the function names.
    PIMAGE_THUNK_DATA pOrigThunk =
                        MakePtr ( PIMAGE_THUNK_DATA       ,
                                  hModule                 ,
                                  pImportDesc->OriginalFirstThunk  ) ;
    // Get the array pointed to by the pImportDesc->FirstThunk.  This is
    //  where I will do the actual bash.
    PIMAGE_THUNK_DATA pRealThunk = MakePtr ( PIMAGE_THUNK_DATA       ,
                                             hModule                 ,
                                             pImportDesc->FirstThunk  );

    // Loop through and look for the one that matches the name.
    while ( NULL != pOrigThunk->u1.Function )
    {
        // Only look at those that are imported by name, not ordinal.
        if (  IMAGE_ORDINAL_FLAG !=
                        ( pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG ))
        {
            // Look get the name of this imported function.
            PIMAGE_IMPORT_BY_NAME pByName ;

            pByName = MakePtr ( PIMAGE_IMPORT_BY_NAME    ,
                                hModule                  ,
                                pOrigThunk->u1.AddressOfData  ) ;

            // If the name starts with NULL, then just skip out now.
            if ( '\0' == pByName->Name[ 0 ] )
            {
                continue ;
            }

            // Determines if we do the hook.
            BOOL bDoHook = FALSE ;

            // TODO TODO
            //  Might want to consider bsearch here.

            // See if the particular function name is in the import
            //  list.  It might be good to consider requiring the
            //  paHookArray to be in sorted order so bsearch could be
            //  used so the lookup will be faster.  However, the size of
            //  uiCount coming into this function should be rather
            //  small but it is called for each function imported by
            //  szImportMod.
            for ( UINT i = 0 ; i < uiCount ; i++ )
            {
                if ( ( paHookArray[i].szFunc[0] ==
                                                pByName->Name[0] ) &&
                     ( 0 == _strcmpi ( paHookArray[i].szFunc ,
                                      (char*)pByName->Name   )   )    )
                {
                    // If the proc is NULL, kick out, otherwise go
                    //  ahead and hook it.
                    if ( NULL != paHookArray[ i ].pProc )
                    {
                        bDoHook = TRUE ;
                    }
                    break ;
                }
            }

            if ( TRUE == bDoHook )
            {
                // I found it.  Now I need to change the protection to
                //  writable before I do the blast.  Note that I am now
                //  blasting into the real thunk area!
                MEMORY_BASIC_INFORMATION mbi_thunk ;

                VirtualQuery ( pRealThunk                          ,
                               &mbi_thunk                          ,
                               sizeof ( MEMORY_BASIC_INFORMATION )  ) ;

                VERIFY ( VirtualProtect ( mbi_thunk.BaseAddress ,
                                          mbi_thunk.RegionSize  ,
                                          PAGE_READWRITE        ,
                                          &mbi_thunk.Protect     ) ) ;

                // Save the original address if requested.
                if ( NULL != paOrigFuncs )
                {
                    paOrigFuncs[i] = (PROC)pRealThunk->u1.Function ;
                }
                // Do the actual hook.
                pRealThunk->u1.Function = (DWORD)paHookArray[i].pProc ;

                DWORD dwOldProtect ;

                // Change the protection back to what it was before I
                //  blasted.
                VERIFY ( VirtualProtect ( mbi_thunk.BaseAddress ,
                                          mbi_thunk.RegionSize  ,
                                          mbi_thunk.Protect     ,
                                          &dwOldProtect          ) ) ;

                if ( NULL != pdwHooked )
                {
                    // Increment the total number hooked.
                    *pdwHooked += 1 ;
                }
            }
        }
        // Increment both tables.
        pOrigThunk++ ;
        pRealThunk++ ;
    }

    // All OK, JumpMaster!
    SetLastError ( ERROR_SUCCESS ) ;
    return ( TRUE ) ;
}
Пример #30
0
bool RedirectIAT( SDLLHook* DLLHook, PIMAGE_IMPORT_DESCRIPTOR pImportDesc, PVOID pBaseLoadAddr )
{
    PIMAGE_THUNK_DATA pIAT;     // Ptr to import address table
    PIMAGE_THUNK_DATA pINT;     // Ptr to import names table
    PIMAGE_THUNK_DATA pIteratingIAT;

    // Figure out which OS platform we're on
    OSVERSIONINFO osvi; 
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    GetVersionEx( &osvi );

    // If no import names table, we can't redirect this, so bail
    if ( pImportDesc->OriginalFirstThunk == 0 )
        return false;

    pIAT = MakePtr( PIMAGE_THUNK_DATA, pBaseLoadAddr, pImportDesc->FirstThunk );
    pINT = MakePtr( PIMAGE_THUNK_DATA, pBaseLoadAddr, pImportDesc->OriginalFirstThunk );

    // Count how many entries there are in this IAT.  Array is 0 terminated
    pIteratingIAT = pIAT;
    unsigned cFuncs = 0;
    while ( pIteratingIAT->u1.Function )
    {
        cFuncs++;
        pIteratingIAT++;
    }

    if ( cFuncs == 0 )  // If no imported functions, we're done!
        return false;

    // These next few lines ensure that we'll be able to modify the IAT,
    // which is often in a read-only section in the EXE.
    DWORD flOldProtect, flNewProtect, flDontCare;
    MEMORY_BASIC_INFORMATION mbi;
    
    // Get the current protection attributes                            
    VirtualQuery( pIAT, &mbi, sizeof(mbi) );
    
    // remove ReadOnly and ExecuteRead attributes, add on ReadWrite flag
    flNewProtect = mbi.Protect;
    flNewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ);
    flNewProtect |= (PAGE_READWRITE);
    
    if ( !VirtualProtect(   pIAT, sizeof(PVOID) * cFuncs,
                            flNewProtect, &flOldProtect) )
    {
        return false;
    }

    // If the Default hook is enabled, build an array of redirection stubs in the processes memory.
    DLPD_IAT_STUB * pStubs = 0;
    if ( DLLHook->UseDefault )
    {
        // Allocate memory for the redirection stubs.  Make one extra stub at the
        // end to be a sentinel
        pStubs = new DLPD_IAT_STUB[ cFuncs + 1];
        if ( !pStubs )
            return false;
    }

    // Scan through the IAT, completing the stubs and redirecting the IAT
    // entries to point to the stubs
    pIteratingIAT = pIAT;

    while ( pIteratingIAT->u1.Function )
    {
        void* HookFn = 0;  // Set to either the SFunctionHook or pStubs.

        if ( !IMAGE_SNAP_BY_ORDINAL( pINT->u1.Ordinal ) )  // import by name
        {
            PIMAGE_IMPORT_BY_NAME pImportName = MakePtr( PIMAGE_IMPORT_BY_NAME, pBaseLoadAddr, pINT->u1.AddressOfData );

            // Iterate through the hook functions, searching for this import.
            SFunctionHook* FHook = DLLHook->Functions;
            while ( FHook->Name )
            {
                if ( lstrcmpi( FHook->Name, (char*)pImportName->Name ) == 0 )
                {
                    OutputDebugString( "Hooked function: " );
                    OutputDebugString( (char*)pImportName->Name );
                    OutputDebugString( "\n" );

                    // Save the old function in the SFunctionHook structure and get the new one.
                    FHook->OrigFn = (void*)pIteratingIAT->u1.Function; // cyber / cast as void*
                    HookFn = FHook->HookFn;
                    break;
                }

                FHook++;
            }

            // If the default function is enabled, store the name for the user.
            if ( DLLHook->UseDefault )
                pStubs->pszNameOrOrdinal = (DWORD)&pImportName->Name;
        }
        else
        {
            // If the default function is enabled, store the ordinal for the user.
            if ( DLLHook->UseDefault )
                pStubs->pszNameOrOrdinal = pINT->u1.Ordinal;
        }

        // If the default function is enabled, fill in the fields to the stub code.
        if ( DLLHook->UseDefault )
        {
            pStubs->data_call = (DWORD)(PDWORD)DLLHook->DefaultFn
                                - (DWORD)(PDWORD)&pStubs->instr_JMP;
            pStubs->data_JMP = *(PDWORD)pIteratingIAT - (DWORD)(PDWORD)&pStubs->count;

            // If it wasn't manually hooked, use the Stub function.
            if ( !HookFn )
                HookFn = (void*)pStubs;
        }

        // Replace the IAT function pointer if we have a hook.
        if ( HookFn )
        {
            // Cheez-o hack to see if what we're importing is code or data.
            // If it's code, we shouldn't be able to write to it
            if ( IsBadWritePtr( (PVOID)pIteratingIAT->u1.Function, 1 ) )
            {
                pIteratingIAT->u1.Function = (DWORD)HookFn; // cyber / made PDWORD into DWORD
            }
            else if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
            {
                // Special hack for Win9X, which builds stubs for imported
                // functions in system DLLs (Loaded above 2GB).  These stubs are
                // writeable, so we have to explicitly check for this case
                if ( pIteratingIAT->u1.Function > (DWORD)0x80000000 ) // cyber / made PDWORD into DWORD
                    pIteratingIAT->u1.Function = (DWORD)HookFn; // cyber / made PDWORD into DWORD
            }
        }

        if ( DLLHook->UseDefault )
            pStubs++;           // Advance to next stub

        pIteratingIAT++;    // Advance to next IAT entry
        pINT++;             // Advance to next INT entry
    }

    if ( DLLHook->UseDefault )
        pStubs->pszNameOrOrdinal = 0;   // Final stub is a sentinel

    // Put the page attributes back the way they were.
    VirtualProtect( pIAT, sizeof(PVOID) * cFuncs, flOldProtect, &flDontCare);
    
    return true;
}