难以理解通过序数解析函数名的c++函数

  • 本文关键字:函数 c++ 序数 c++ winapi
  • 更新时间 :
  • 英文 :


我正在学习恶意软件分析课程。我发现这个代码让我感到困惑。前两部分是有意义的,但if语句的开头部分对我来说很难理解。这个";如果";语句应该通过序数解析函数名。我已经在评论中提出了我的问题。

FARPROC WINAPI myGetProcAddress(HMODULE hMod, char * sProcName) {
char * pBaseAddress = (char *) hMod;
// get pointers to main headers/structures
IMAGE_DOS_HEADER * pDosHdr = (IMAGE_DOS_HEADER *) pBaseAddress;
IMAGE_NT_HEADERS * pNTHdr = (IMAGE_NT_HEADERS *) (pBaseAddress + pDosHdr->e_lfanew);
IMAGE_OPTIONAL_HEADER * pOptionalHdr = &pNTHdr->OptionalHeader;
IMAGE_DATA_DIRECTORY * pDataDir = (IMAGE_DATA_DIRECTORY *) (&pOptionalHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
IMAGE_EXPORT_DIRECTORY * pExportDirAddr = (IMAGE_EXPORT_DIRECTORY *) (pBaseAddress + pDataDir->VirtualAddress);
// resolve addresses to Export Address Table, table of function names and "table of ordinals"
DWORD * pEAT = (DWORD *) (pBaseAddress + pExportDirAddr->AddressOfFunctions);
DWORD * pFuncNameTbl = (DWORD *) (pBaseAddress + pExportDirAddr->AddressOfNames);
WORD * pHintsTbl = (WORD *) (pBaseAddress + pExportDirAddr->AddressOfNameOrdinals);
// function address we're looking for
void *pProcAddr = NULL;
// resolve function by ordinal
if (((DWORD_PTR)sProcName >> 16) == 0) { // why shift by 16
WORD ordinal = (WORD) sProcName & 0xFFFF;   // why & 0xFFFF
DWORD Base = pExportDirAddr->Base;          
if (ordinal < Base || ordinal >= Base + pExportDirAddr->NumberOfFunctions)
return NULL;
// not sure what this part does
pProcAddr = (FARPROC) (pBaseAddress + (DWORD_PTR) pEAT[ordinal - Base]);
}
...
...
...
}

我非常感谢你的解释。

这允许您使用位操作将数字(此处为双字或双字(拆分为两部分,例如:

0x12345678 >> 16 = 0x1234 (hi order word)
0x12345678 & 0xFFFF = 0x5678 (lo order word)

为什么代码会这样做?它是用GetProcAddress的lpProcName参数记录的:

函数或变量名,或函数的序数。如果此参数是一个序数值,它必须在低位单词中;高阶字必须为零。

最新更新