VC PE导出/输入表演示(进程版)

本文介绍了一个用于读取Windows进程中导出表和导入表信息的C++程序。该程序通过调用NtQueryInformationProcess函数获取指定进程的基本信息,并进一步读取其内存中的PE文件结构来解析导出表和导入表。此工具对于逆向工程和调试非常有用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// GetProcessTable.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "stdio.h"

typedef LONG NTSTATUS;
#define STATUS_SUCCESS (0)
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef struct _PROCESS_BASIC_INFORMATION
{
    PVOID Reserved1;
    //PPEB PebBaseAddress;
 ULONG PebBaseAddress;
    PVOID Reserved2[2];
    ULONG UniqueProcessId;
    PVOID Reserved3;
} PROCESS_BASIC_INFORMATION,*PPROCESS_BASIC_INFORMATION;;

typedef NTSTATUS
(WINAPI *NTQUERYINFORMATIONPROCESS)(
 HANDLE ProcessHandle,
 ULONG ProcessInformationClass,
 PVOID ProcessInformation,
 ULONG ProcessInformationLength,
 PULONG ReturnLength
);
NTQUERYINFORMATIONPROCESS NtQueryInformationProcess;

VOID PrintImportTable(DWORD dwProcessId);
VOID PrintExportTable(DWORD dwProcessId);
LPSTR GetProcessPath(DWORD dwProcessId);

ULONG muBase=0;

int main(int argc, char* argv[])
{
 HMODULE hMod = LoadLibrary("ntdll.dll");
 if (argc==1)
  return 0;
 NtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS)GetProcAddress(hMod,"NtQueryInformationProcess");
 FreeLibrary(hMod);
 printf("进程路径是:%s/n/n",GetProcessPath(atoi(argv[1])));
 printf("导出表信息:/n/n");
 PrintExportTable(atoi(argv[1]));
 printf("/n");
 printf("----------------------------------------------/n/n");
 printf("输入表信息:/n/n");
 PrintImportTable(atoi(argv[1]));
 return 0;
}


LPSTR GetProcessPath(DWORD dwProcessId)
{
 DWORD dwAddr=0;
 WCHAR strPath[260];
 char strTmp[260];
 PPROCESS_BASIC_INFORMATION pInfo=(PPROCESS_BASIC_INFORMATION)new BYTE[sizeof(PROCESS_BASIC_INFORMATION)];
 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
 if (!hProcess)
  return "";
 if (NtQueryInformationProcess(hProcess,0,pInfo,sizeof(PROCESS_BASIC_INFORMATION),NULL)>=0)
 {
  ReadProcessMemory(hProcess,(PVOID)(pInfo->PebBaseAddress + 0xC),&dwAddr,4,NULL);
  ReadProcessMemory(hProcess,(PVOID)(dwAddr + 0xC), &dwAddr, 4, NULL);
  ReadProcessMemory(hProcess,(PVOID)(dwAddr + 0x18), &muBase, 4, NULL);
  //printf("模块基地址是:0x%x",muBase);
        ReadProcessMemory(hProcess,(PVOID)(dwAddr + 0x28), &dwAddr, 4, NULL);
        ReadProcessMemory(hProcess,(PVOID)dwAddr, strPath, sizeof(strPath), NULL);
  //printf("模块路径是:%S",strPath);
  sprintf(strTmp,"%S",strPath);
  CloseHandle(hProcess);
  return &strTmp[0];
 }
 CloseHandle(hProcess);
 return "";
}

VOID PrintImportTable(DWORD dwProcessId)
{
 PIMAGE_DOS_HEADER pDosHeader=(PIMAGE_DOS_HEADER)new BYTE[sizeof(IMAGE_DOS_HEADER)];
 PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)new BYTE[sizeof(IMAGE_NT_HEADERS)];
 PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)new BYTE[sizeof(IMAGE_IMPORT_DESCRIPTOR)];
 PIMAGE_THUNK_DATA pThunk=(PIMAGE_THUNK_DATA)new BYTE[sizeof(IMAGE_THUNK_DATA)];
 DWORD dwStup=0,dwStup1=0;
 char strName[130];
 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
 if (!hProcess)
  return ;
 //获取IMAGE_DOS_HEADER
 ReadProcessMemory(hProcess,(PVOID)muBase, pDosHeader, sizeof(IMAGE_DOS_HEADER), NULL);
 //获取IMAGE_NT_HEADERS
 ReadProcessMemory(hProcess,(PVOID)(muBase + pDosHeader->e_lfanew), pNtHeaders, sizeof(IMAGE_NT_HEADERS), NULL); 
 while (TRUE)
 {
  //获取IMAGE_IMPORT_DESCRIPTOR
  ReadProcessMemory(hProcess,(PVOID)(muBase + pNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress + dwStup * sizeof(IMAGE_IMPORT_DESCRIPTOR)), pImport, sizeof(IMAGE_IMPORT_DESCRIPTOR), NULL);
  if (pImport->OriginalFirstThunk==0 && pImport->FirstThunk==0) break;
  ReadProcessMemory(hProcess,(PVOID)(muBase + pImport->Name), strName, sizeof(strName), NULL);
  printf("模块:%s/n",strName);
  dwStup1=0;
  do
  {
   if (pImport->OriginalFirstThunk!=0)
    ReadProcessMemory(hProcess,(PVOID)(muBase + pImport->OriginalFirstThunk + dwStup1 * 4), pThunk, sizeof(IMAGE_THUNK_DATA), NULL);
   else
    ReadProcessMemory(hProcess,(PVOID)(muBase + pImport->FirstThunk + dwStup1 * 4), pThunk, sizeof(IMAGE_THUNK_DATA), NULL);
   if (pThunk->u1.AddressOfData==0) break;
   memset(strName,0,130);
   ReadProcessMemory(hProcess,(PVOID)(muBase + (ULONG)pThunk->u1.AddressOfData->Name), strName, sizeof(strName), NULL);
   printf("/t函数:%s/n",strName);
   dwStup1++;
  } while (pThunk->u1.AddressOfData!=0);
  dwStup++;
 };
 delete []pDosHeader;
 delete []pImport;
 delete []pNtHeaders;
 delete []pThunk;
 CloseHandle(hProcess);
}

VOID PrintExportTable(DWORD dwProcessId)
{
 PIMAGE_DOS_HEADER pDosHeader=(PIMAGE_DOS_HEADER)new BYTE[sizeof(IMAGE_DOS_HEADER)];
 PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)new BYTE[sizeof(IMAGE_NT_HEADERS)];
 PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)new BYTE[sizeof(IMAGE_EXPORT_DIRECTORY)];
 DWORD dwStup=0,dwOffset=0;
 char strName[130];
 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
 if (!hProcess)
  return ;
 //获取IMAGE_DOS_HEADER
 ReadProcessMemory(hProcess,(PVOID)muBase, pDosHeader, sizeof(IMAGE_DOS_HEADER), NULL);
 //获取IMAGE_NT_HEADERS
 ReadProcessMemory(hProcess,(PVOID)(muBase + pDosHeader->e_lfanew), pNtHeaders, sizeof(IMAGE_NT_HEADERS), NULL); 
 if (pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress==0)
 {
  printf("没有导出表信息!!/n");
  return ;
 }
 ReadProcessMemory(hProcess,(PVOID)(muBase + pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress), pExport, sizeof(IMAGE_EXPORT_DIRECTORY), NULL);
 ReadProcessMemory(hProcess,(PVOID)(muBase + pExport->Name), strName, sizeof(strName), NULL); 
 printf("模块:%s/n",strName);
 ULONG uStup=0;
 do
 {
  ReadProcessMemory(hProcess,(PVOID)(muBase + pExport->AddressOfNames + uStup * sizeof(uStup)), &dwOffset, sizeof(dwOffset), NULL);
  if (dwOffset==0) break;
  ReadProcessMemory(hProcess,(PVOID)(muBase + dwOffset), &dwOffset, sizeof(dwOffset), NULL);
  if (dwOffset==0) break;
  memset(strName,0,130);
  ReadProcessMemory(hProcess,(PVOID)(muBase + dwOffset), strName, sizeof(strName), NULL);
  printf("/t函数:%s/n",strName);
  uStup ++;
 } while (dwOffset!=0);
 delete []pDosHeader;
 delete []pExport;
 delete []pNtHeaders;
 CloseHandle(hProcess);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值