Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Finding the Ordinal of an imported function

Finding the Ordinal of an imported function

Scheduled Pinned Locked Moved C / C++ / MFC
jsonquestion
3 Posts 2 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    capricious_001
    wrote on last edited by
    #1

    Hi guys, I was wondering how someone would find the Ordinal of an imported function? I am using an API hook function which is below:

    PVOID HookImportedFunction(const char *Dll, const char *FuncName, int Ordinal, void *Function)
    {
        DWORD oldProtect;
    	void *PrevValue=0;
    
        DWORD image_base = (DWORD)GetModuleHandle(NULL);
        IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)image_base;
        IMAGE_FILE_HEADER *ifh = (IMAGE_FILE_HEADER *)(image_base +
            idh->e_lfanew + sizeof(DWORD));
        IMAGE_OPTIONAL_HEADER *ioh = (IMAGE_OPTIONAL_HEADER *)((DWORD)(ifh) +
            sizeof(IMAGE_FILE_HEADER));
        IMAGE_IMPORT_DESCRIPTOR *iid = (IMAGE_IMPORT_DESCRIPTOR *)(image_base +
            ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    
        VirtualProtect((LPVOID)(image_base +
            ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress),
            ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size, PAGE_READWRITE,
            &oldProtect);
    
        while(iid->Name)
        {
            if(stricmp(Dll, (char *)(image_base + iid->Name)) == 0)
            {
                //trace_printf("Found descriptor: %s\n", dhook->name);
                IMAGE_THUNK_DATA * pThunk = (IMAGE_THUNK_DATA *)
                    ((DWORD)iid->OriginalFirstThunk + image_base);
                IMAGE_THUNK_DATA * pThunk2 = (IMAGE_THUNK_DATA *)
                    ((DWORD)iid->FirstThunk + image_base);
                while(pThunk->u1.AddressOfData)
                {
                    char * name = 0;
                    int ordinal;
                    // Imported by ordinal only:
                    if(pThunk->u1.Ordinal & 0x80000000)
                        ordinal = pThunk->u1.Ordinal & 0xffff;
                    else    // Imported by name, with ordinal hint
                    {
                        IMAGE_IMPORT_BY_NAME * pname = (IMAGE_IMPORT_BY_NAME *)
                            ((DWORD)pThunk->u1.AddressOfData + image_base);
                        ordinal = pname->Hint;
                        name = (char *)pname->Name;
                    }
    
                    if(name != 0 && FuncName && strcmp(name, FuncName) == 0)
                    {
                        //trace_printf("Found entry name: %s\n", ehook->name);
    					PrevValue = (void*)pThunk2->u1.Function;
    #if _MFC_VER == 0x0600
                        pThunk2->u1.Function = (DWORD*)Function;
    #else
                        pThunk2->u1.Function = (DWORD)Function;
    #endif
                    }
                    else if(ordinal == Ordinal)
                    {
                        //trace_printf("Found entry
    
    V 1 Reply Last reply
    0
    • C capricious_001

      Hi guys, I was wondering how someone would find the Ordinal of an imported function? I am using an API hook function which is below:

      PVOID HookImportedFunction(const char *Dll, const char *FuncName, int Ordinal, void *Function)
      {
          DWORD oldProtect;
      	void *PrevValue=0;
      
          DWORD image_base = (DWORD)GetModuleHandle(NULL);
          IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)image_base;
          IMAGE_FILE_HEADER *ifh = (IMAGE_FILE_HEADER *)(image_base +
              idh->e_lfanew + sizeof(DWORD));
          IMAGE_OPTIONAL_HEADER *ioh = (IMAGE_OPTIONAL_HEADER *)((DWORD)(ifh) +
              sizeof(IMAGE_FILE_HEADER));
          IMAGE_IMPORT_DESCRIPTOR *iid = (IMAGE_IMPORT_DESCRIPTOR *)(image_base +
              ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
      
          VirtualProtect((LPVOID)(image_base +
              ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress),
              ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size, PAGE_READWRITE,
              &oldProtect);
      
          while(iid->Name)
          {
              if(stricmp(Dll, (char *)(image_base + iid->Name)) == 0)
              {
                  //trace_printf("Found descriptor: %s\n", dhook->name);
                  IMAGE_THUNK_DATA * pThunk = (IMAGE_THUNK_DATA *)
                      ((DWORD)iid->OriginalFirstThunk + image_base);
                  IMAGE_THUNK_DATA * pThunk2 = (IMAGE_THUNK_DATA *)
                      ((DWORD)iid->FirstThunk + image_base);
                  while(pThunk->u1.AddressOfData)
                  {
                      char * name = 0;
                      int ordinal;
                      // Imported by ordinal only:
                      if(pThunk->u1.Ordinal & 0x80000000)
                          ordinal = pThunk->u1.Ordinal & 0xffff;
                      else    // Imported by name, with ordinal hint
                      {
                          IMAGE_IMPORT_BY_NAME * pname = (IMAGE_IMPORT_BY_NAME *)
                              ((DWORD)pThunk->u1.AddressOfData + image_base);
                          ordinal = pname->Hint;
                          name = (char *)pname->Name;
                      }
      
                      if(name != 0 && FuncName && strcmp(name, FuncName) == 0)
                      {
                          //trace_printf("Found entry name: %s\n", ehook->name);
      					PrevValue = (void*)pThunk2->u1.Function;
      #if _MFC_VER == 0x0600
                          pThunk2->u1.Function = (DWORD*)Function;
      #else
                          pThunk2->u1.Function = (DWORD)Function;
      #endif
                      }
                      else if(ordinal == Ordinal)
                      {
                          //trace_printf("Found entry
      
      V Offline
      V Offline
      Viorel
      wrote on last edited by
      #2

      Maybe the following sample function will give you some ideas? It returns the ordinal number having the handle of the DLL (from LoadLibrary) and the address of the exported function (from GetProcAddress):

      WORD getFunctionOrdinal( HMODULE hModule, FARPROC pFunction)
      {
      	if( hModule == 000 || pFunction == 000) return 0;
      
      	// address of the module's export section
      
      	ULONG export_dir_size;
      	PIMAGE_EXPORT_DIRECTORY pExportDir =
      		(PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(
      		hModule,
      		TRUE,
      		IMAGE_DIRECTORY_ENTRY_EXPORT,
      		&export_dir_size
      		);
      
      	// does this module have export section?
      	if( pExportDir == 000) 
      	{
      		return 0;
      	}
      
      	LPCSTR const charAddress = (LPCSTR)hModule;
      
      	// name of the DLL
      	//LPCSTR const pDllName = charAddress + pExportDir->Name;
      	// starting ordinal value. By default is 1, but is not required to be so
      	WORD const base = (WORD)pExportDir->Base; // (NOTE. It is DWORD)
      	// array function pointers
      	PDWORD const pFunctions = (PDWORD)(charAddress + pExportDir->AddressOfFunctions);
      	// array of function names
      	//PDWORD const pFuncNames = (PDWORD)(charAddress + pExportDir->AddressOfNames);
      	// array of ordinals
      	PWORD const pOrdinals = (PWORD)(charAddress + pExportDir->AddressOfNameOrdinals);
      	// number of entries
      	DWORD const numberOfFunctions = pExportDir->NumberOfFunctions;
      	DWORD const numberOfNames = pExportDir->NumberOfNames; // and numbers of ordinals
      
      	for( DWORD i = 0; i < numberOfFunctions; ++i) 
      	{
      		FARPROC const fp = (FARPROC)(charAddress + pFunctions[i]);
      		if( fp == pFunction) 
      		{
      			return (WORD)(i + base);
      		}
      	}
      
      	return 0; // not found
      }
      

      I hope this helps.

      C 1 Reply Last reply
      0
      • V Viorel

        Maybe the following sample function will give you some ideas? It returns the ordinal number having the handle of the DLL (from LoadLibrary) and the address of the exported function (from GetProcAddress):

        WORD getFunctionOrdinal( HMODULE hModule, FARPROC pFunction)
        {
        	if( hModule == 000 || pFunction == 000) return 0;
        
        	// address of the module's export section
        
        	ULONG export_dir_size;
        	PIMAGE_EXPORT_DIRECTORY pExportDir =
        		(PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(
        		hModule,
        		TRUE,
        		IMAGE_DIRECTORY_ENTRY_EXPORT,
        		&export_dir_size
        		);
        
        	// does this module have export section?
        	if( pExportDir == 000) 
        	{
        		return 0;
        	}
        
        	LPCSTR const charAddress = (LPCSTR)hModule;
        
        	// name of the DLL
        	//LPCSTR const pDllName = charAddress + pExportDir->Name;
        	// starting ordinal value. By default is 1, but is not required to be so
        	WORD const base = (WORD)pExportDir->Base; // (NOTE. It is DWORD)
        	// array function pointers
        	PDWORD const pFunctions = (PDWORD)(charAddress + pExportDir->AddressOfFunctions);
        	// array of function names
        	//PDWORD const pFuncNames = (PDWORD)(charAddress + pExportDir->AddressOfNames);
        	// array of ordinals
        	PWORD const pOrdinals = (PWORD)(charAddress + pExportDir->AddressOfNameOrdinals);
        	// number of entries
        	DWORD const numberOfFunctions = pExportDir->NumberOfFunctions;
        	DWORD const numberOfNames = pExportDir->NumberOfNames; // and numbers of ordinals
        
        	for( DWORD i = 0; i < numberOfFunctions; ++i) 
        	{
        		FARPROC const fp = (FARPROC)(charAddress + pFunctions[i]);
        		if( fp == pFunction) 
        		{
        			return (WORD)(i + base);
        		}
        	}
        
        	return 0; // not found
        }
        

        I hope this helps.

        C Offline
        C Offline
        capricious_001
        wrote on last edited by
        #3

        Thanks Viorel, I'll use that! How do you know so much? ;)

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups