English 中文(简体)
Differences in code between Windows 32 bits and 64 bits
原标题:

I was experimenting with the following code to simulate GetProcAddress.

// Retrieve NT header from base address.
IMAGE_NT_HEADERS *GetNtHeaderFromBase( void *pBaseAddr )
{
 IMAGE_DOS_HEADER       *pDosHeader;
 IMAGE_NT_HEADERS       *pNtHeaders;

 pDosHeader = ((IMAGE_DOS_HEADER *)pBaseAddr);
 if(pDosHeader->e_magic != 0x5A4D)
  return NULL;

 pNtHeaders = ((IMAGE_NT_HEADERS *)((DWORD)pBaseAddr + pDosHeader->e_lfanew));
 if(pNtHeaders->Signature != 0x4550)
  return NULL;

 return ((pNtHeaders == NULL) ? NULL : pNtHeaders);
}


// This emulates GetProcAddress.
void *GetFuncAddr( DWORD pBaseAddr, char *lpszFuncName ) 
{
 IMAGE_NT_HEADERS       *pNtHeaders;
 IMAGE_DATA_DIRECTORY   *pDataDir;
 IMAGE_EXPORT_DIRECTORY *pExportDir;
 const char      **lpszNames;
 DWORD       *lpdwFuncs, dwIndex;

 pNtHeaders = GetNtHeaderFromBase((void *)pBaseAddr);
 if(pNtHeaders == NULL)
  return NULL;

 pDataDir = ((IMAGE_DATA_DIRECTORY *)(pNtHeaders->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT));
 if(pDataDir == NULL)
  return NULL;

 pExportDir = ((IMAGE_EXPORT_DIRECTORY *)(pBaseAddr + pDataDir->VirtualAddress));
 if(pExportDir == NULL)
  return NULL;

 lpdwFuncs  = ((DWORD *)(pBaseAddr + pExportDir->AddressOfFunctions));
 lpszNames  = ((const char **)(pBaseAddr + pExportDir->AddressOfNames));
 if(lpdwFuncs == NULL || lpszNames == NULL)
  return NULL;

 for(dwIndex = 0; dwIndex < pExportDir->NumberOfFunctions; dwIndex++)
 { 
  // decrypt funcname and get the address
  if(!cmpstr(((char *)(pBaseAddr + lpszNames[dwIndex])), lpszFuncName))
   return (void*)(pBaseAddr + lpdwFuncs[dwIndex]);
 }

 return NULL;
}

But when I run the program on a Windows Vista x64 I get an access violation. I thought it was the numbers on GetNtHeaderFromBase (the numbers passed on IMAGE_DOS_HEADER and IMAGE_NET_HEADER) but i can t find any reference anywhere as to what it might be on a x64 bit binary.

Anyone has any idea what changes do I need to make to this code to make it work under 64 bit Windows? Or, a better way to achieve a getprocaddress-like function that works on both x32 and x64?

Thank you for the help and the code.

jess.

最佳回答

The reason why is that you re storing a pointer sized value in a DWORD for the pBaseAddr method. Pointer values are 8 bytes on 64 bit windows while a DWORD is only 4 bytes. You need to do one of the following

  1. Pass pBaseAddr as a pointer (preferred approach)
  2. Pass it as a size_t which will correctly be 4 bytes on 32 bit windows and 8 bytes on 64 bit windows.
问题回答

I m not sure if it s your only problem, but DWORD is 32 bits, even on 64-bit platforms. You re casting pointers to this, and on 64 bit that results in truncation. If you want a pointer-sized integer you should use DWORD_PTR or ULONG_PTR.

I would also check that your structures are 64-bit safe in that regard.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签