首页
社区
课程
招聘
[求助]64位win10读取导出函数
发表于: 2016-4-21 08:48 4715

[求助]64位win10读取导出函数

2016-4-21 08:48
4715
刚开始学习PE结构,在32位xp、win7,64位win8下读取导出表都正常,64位win10能正常遍历导出函数名,但拿到的函数地址不对,下面贴出源码:

#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>
#include <DbgHelp.h>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
  string strErr;
  HANDLE hFileMapping;
  LPBYTE lpFileBase;
  PIMAGE_NT_HEADERS pNtHeaders;
  PIMAGE_DOS_HEADER pDosHeader;
  PIMAGE_SECTION_HEADER pFirstSection;
  PIMAGE_SECTION_HEADER  pSection;
  PIMAGE_EXPORT_DIRECTORY pExportTable;
  PDWORD pFunctions;
  PWORD pOrdinals;
  PDWORD pNames;
  BOOL hasNames;
  const char* szFuncName;
  unsigned char* szCode;
  char szLog[4096]={0};
  string strDebug;

  HANDLE hFile = CreateFile("C:\\Windows\\System32\\ntdll.dll",
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
  
  if (hFile == INVALID_HANDLE_VALUE)
  {
    strErr = GetLastError();
    OutputDebugStringA(strErr.c_str());
    return -1;
  }

  hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  if (hFileMapping == NULL || hFileMapping == INVALID_HANDLE_VALUE)
  {
    strErr = GetLastError();
    OutputDebugStringA(strErr.c_str());
    CloseHandle(hFile);
    return -1;
  }

  lpFileBase = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
  if (lpFileBase == NULL)
  {
    strErr = GetLastError();
    CloseHandle(hFile);
    CloseHandle(hFileMapping);
    return -1;
  }

  pDosHeader=(PIMAGE_DOS_HEADER)lpFileBase;
  pNtHeaders=(PIMAGE_NT_HEADERS)(lpFileBase+pDosHeader->e_lfanew);
  
  pFirstSection=IMAGE_FIRST_SECTION(pNtHeaders);
  for(int i=0; i<pNtHeaders->FileHeader.NumberOfSections; i++)
  {
    if(pFirstSection[i].VirtualAddress<=pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress&&
      (pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress<pFirstSection[i].VirtualAddress+pFirstSection[i].Misc.VirtualSize))
    {
      pSection=&pFirstSection[i];
      //break;
    }
  }
  pExportTable=(PIMAGE_EXPORT_DIRECTORY)(lpFileBase+pSection->PointerToRawData+pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress-pSection->VirtualAddress);
  pFunctions = (PDWORD)(lpFileBase+pExportTable->AddressOfFunctions+pSection->PointerToRawData-pSection->VirtualAddress);
  pOrdinals = (PWORD)(lpFileBase+pExportTable->AddressOfNameOrdinals+pSection->PointerToRawData-pSection->VirtualAddress);
  pNames = (PDWORD)(lpFileBase+pExportTable->AddressOfNames+pSection->PointerToRawData-pSection->VirtualAddress);

  //pExportTable=(PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa(pNtHeaders, lpFileBase, pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress, NULL);
  //pFunctions = (PDWORD)ImageRvaToVa(pNtHeaders, lpFileBase, pExportTable->AddressOfFunctions, NULL);
  //pOrdinals = (PWORD)ImageRvaToVa(pNtHeaders, lpFileBase, pExportTable->AddressOfNameOrdinals, NULL);
  //pNames = (PDWORD)ImageRvaToVa(pNtHeaders, lpFileBase, pExportTable->AddressOfNames, NULL);//(lpFileBase+pExportTable->AddressOfNames);
  hasNames = (pExportTable->AddressOfNames !=0);

  for(int i=0; i<pExportTable->NumberOfNames; i++)
  {
    //szFuncName=(const char*)ImageRvaToVa(pNtHeaders, lpFileBase, pNames[i], NULL);
    szFuncName=(const char*)(lpFileBase+pNames[i]+pSection->PointerToRawData-pSection->VirtualAddress);
    if(!_stricmp(szFuncName, "ZwQuerySystemInformation"))
    {
      DWORD res=pOrdinals[i]+pExportTable->Base-1;
      szCode = (unsigned char*)(lpFileBase+pFunctions[res]+pSection->PointerToRawData-pSection->VirtualAddress);
      for(int i=0; i<15; i++)
      {
        sprintf(szLog, "%02X ", szCode[i]);
        strDebug+=szLog;
        if(i&&((i+1)%5==0))
        {
          strDebug+="\r\n";
          OutputDebugStringA(strDebug.c_str());
          strDebug="";
        }
      }
    }
  }
  return 0;
}


代码打印拷贝指令


OD查看内存API指令


百思不得其解,虚心向各位大神请教~

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 364
活跃值: (1741)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
pSection->PointerToRawData-pSection->VirtualAddress 是什么东西? AddressOfFunctions 这个不好用吗?
2016-4-21 10:26
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
PE文件映射到到内存节表填充的长度,是读的文件映射所以不能直接用AddressOfFunctions。
2016-4-21 11:25
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
何必要思呢?这么简单的代码调试一下不就知道哪里出错了
2016-4-22 00:47
0
雪    币: 112
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
for(int i=0; i<pNtHeaders->FileHeader.NumberOfSections; i++)
{
if(pFirstSection.VirtualAddress<=pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress&&
(pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress<pFirstSection.VirtualAddress+pFirstSection.Misc.VirtualSize))
{
pSection=&pFirstSection;
//break;
}
}

这段的依据是什么,一眼没瞅明白,另外,
CreateFileMapping, PAGE_READONLY| SEC_IMAGE。不是很方便吗?
2016-4-25 15:52
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这个是计算导出表在哪个节表内,SEC_IMAGE果然好用,非常感谢!
2016-4-26 14:30
0
游客
登录 | 注册 方可回帖
返回
//