3507620743 发表于 2024-4-8 13:56:17

给定exe文件查看dll依赖以及所用函数

自己用C++实现一个程序,传入exe文件,输出对应dll依赖以及dll文件所用函数

FishC 发表于 2024-4-8 13:56:53

要实现这个功能,你可以使用Windows API来读取exe文件的依赖项和dll文件中所用的函数。

首先,你需要使用`LoadLibraryEx`函数来加载exe文件,并使用`GetModuleHandleEx`函数获取它的模块句柄。然后,你可以使用`EnumProcessModules`函数来获取这个进程所加载的所有模块(包括dll文件)。接下来,你可以使用`GetModuleFileNameEx`函数来获取每个模块的文件名,并使用`GetModuleInformation`函数来获取每个模块的大小等信息。

当你获取到每个dll文件的路径后,你可以使用`LoadLibraryEx`函数加载dll文件,并使用`GetProcAddress`函数获取dll文件中的函数地址。然后,你可以使用`EnumResourceNames`函数或者`EnumResourceTypes`函数来枚举dll文件中的所有资源。

下面是一个简单的示例代码,展示了如何实现这个功能:

#include <windows.h>
#include <iostream>

void listDllDependencies(const char* exeFilePath) {
    HMODULE hExeModule = LoadLibraryExA(exeFilePath, NULL, DONT_RESOLVE_DLL_REFERENCES);
    if (hExeModule == NULL) {
      std::cout << "Failed to load exe." << std::endl;
      return;
    }

    // 获取进程中所有模块
    HMODULE hModules;
    DWORD cbNeeded;
    if (!EnumProcessModules(GetCurrentProcess(), hModules, sizeof(hModules), &cbNeeded)) {
      std::cout << "Failed to enum process modules." << std::endl;
      return;
    }

    std::cout << "DLL Dependencies:" << std::endl;
    for (int i = 0; i < cbNeeded / sizeof(HMODULE); i++) {
      char moduleFilePath;
      GetModuleFileNameExA(GetCurrentProcess(), hModules, moduleFilePath, MAX_PATH);
      
      std::cout << "    " << moduleFilePath << std::endl;
    }
   
    FreeLibrary(hExeModule);
}

void listDllFunctions(const char* dllFilePath) {
    HMODULE hDllModule = LoadLibraryExA(dllFilePath, NULL, DONT_RESOLVE_DLL_REFERENCES);
    if (hDllModule == NULL) {
      std::cout << "Failed to load dll." << std::endl;
      return;
    }

    // 获取dll文件中所有导出的函数
    FARPROC funcAddress;
    DWORD index = 0;
    while ((funcAddress = GetProcAddress(hDllModule, (LPCSTR)index++)) != NULL) {
      std::cout << "    " << (LPVOID)funcAddress << std::endl;
    }

    FreeLibrary(hDllModule);
}

int main() {
    const char* exeFile = "your_exe_file_path.exe";
    const char* dllFile = "your_dll_file_path.dll";

    std::cout << "DLL Dependencies of the exe file:" << std::endl;
    listDllDependencies(exeFile);

    std::cout << "Functions used in the dll file:" << std::endl;
    listDllFunctions(dllFile);

    return 0;
}

请替换`your_exe_file_path.exe`和`your_dll_file_path.dll`为你要查看的相应文件的路径。这个程序会输出exe文件的依赖dll文件列表以及dll文件中导出的函数。

希望能对你有所帮助!如果还有疑问,请随时向我提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

3507620743 发表于 2024-4-8 14:21:21

第15行:EnumProcessModules”: 找不到标识符
第21行: warning C4018: “<”: 有符号/无符号不匹配
第23行: error C3861: “GetModuleFileNameExA”: 找不到标识符

FishC 发表于 2024-4-8 14:21:44

3507620743 发表于 2024-04-08 14:21
第15行:EnumProcessModules”: 找不到标识符
第21行 ...

抱歉,关于第15行的错误,我在代码中漏掉了对Windows API头文件的引用,你需要添加以下头文件:
#include <psapi.h>

而关于第21行的警告,它是因为返回的是一个unsigned int类型的值。你可以对返回的值做强制类型转换或者忽略这个警告,例如:
(DWORD_PTR)moduleBase

下面是更新后的示例代码:
#include <iostream>
#include <Windows.h>
#include <psapi.h>

void listDllDependencies(const char* exeFilePath) {
    HMODULE hExeModule = LoadLibraryExA(exeFilePath, NULL, DONT_RESOLVE_DLL_REFERENCES);
    if (hExeModule == NULL) {
      std::cout << "Failed to load the input exe file." << std::endl;
      return;
    }

    HMODULE moduleHandles;
    DWORD cbNeeded;
    if (!EnumProcessModules(GetCurrentProcess(), moduleHandles, sizeof(moduleHandles), &cbNeeded)) {
      std::cout << "Failed to enumerate process modules." << std::endl;
      return;
    }

    for (int i = 0; i < (cbNeeded / sizeof(HMODULE)); ++i) {
      char moduleName;
      if (GetModuleFileNameExA(GetCurrentProcess(), moduleHandles, moduleName, MAX_PATH)) {
            std::cout << "Module: " << moduleName << std::endl;

            MODULEINFO moduleInfo;
            if (GetModuleInformation(GetCurrentProcess(), moduleHandles, &moduleInfo, sizeof(moduleInfo))) {
                std::cout << "Base Address: 0x" << std::hex << (DWORD_PTR)moduleInfo.lpBaseOfDll << std::endl;
                std::cout << "Size: " << std::dec << moduleInfo.SizeOfImage << std::endl;
            }
      }
    }

    FreeLibrary(hExeModule);
}

int main() {
    const char* exeFilePath = "C:\\path\\to\\your\\exe\\file.exe";
    listDllDependencies(exeFilePath);

    return 0;
}

请记住,这只是一个简单的示例代码,你可能需要根据实际需求进行适当的修改和完善。另外,这段代码默认使用的是ASCII字符集的路径,如果你使用的是Unicode字符集,请在函数名后面加上`W`,例如`LoadLibraryExW`、`GetModuleFileNameExW`等。希望能帮到你!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

人造人 发表于 2024-4-10 19:50:26

这段时间有点忙,现在才写完
第一点写完了,第二点写了一半
我就不用代码去查找dll的位置了,我直接把依赖的dll复制到当前目录
而且这只是一次扫描,后面再有新的dll也不管了
剩下的代码你自己写吧,我感兴趣的那部分,我已经写了

$ ls
KERNEL32.dllmain.cppmain.exesteam_api64.dlltest.exe
$ cat main.cpp
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <iterator>
#include <cstdint>
#include <utility>
#include <sstream>
#include <iomanip>
#include <stdexcept>
#include <exception>
#include <windows.h>

using std::vector, std::string, std::pair;
using std::ifstream, std::istreambuf_iterator;
using std::cout, std::endl;
using std::stringstream, std::hex, std::setw, std::setfill;
using std::exception, std::runtime_error;

string string_from_file(const string &filename) {
    ifstream in(filename);
    istreambuf_iterator<char> beg(in), end;
    return string(beg, end);
}

ULONGLONG file_offset(const IMAGE_NT_HEADERS *inh, ULONG rva) {
    const IMAGE_SECTION_HEADER *ish = (const IMAGE_SECTION_HEADER *)(inh + 1);
    for(size_t i = 0; i < inh->FileHeader.NumberOfSections; ++i) {
      if(ish.VirtualAddress <= rva && rva < ish.VirtualAddress + ish.SizeOfRawData) {
            return ish.PointerToRawData + rva - ish.VirtualAddress;
      }
    }
    throw runtime_error("invalid rva");
}

const void *obj_addr(const IMAGE_DOS_HEADER *idh, ULONGLONG offset) {
    return (const uint8_t *)idh + offset;
}

const string string_hex(ULONGLONG value) {
    stringstream ss;
    ss << hex << setw(16) << setfill('0') << value;
    return ss.str();
}

const vector<pair<string, vector<string>>> parse_import_descriptor(const string &filename) {
    vector<pair<string, vector<string>>> result;
    string pe_file = string_from_file(filename);
    const IMAGE_DOS_HEADER *idh = (const IMAGE_DOS_HEADER *)pe_file.data();
    if(idh->e_magic != IMAGE_DOS_SIGNATURE) throw runtime_error("idh->e_magic != IMAGE_DOS_SIGNATURE");
    const IMAGE_NT_HEADERS *inh = (const IMAGE_NT_HEADERS *)obj_addr(idh, idh->e_lfanew);
    if(inh->Signature != IMAGE_NT_SIGNATURE) throw runtime_error("inh->Signature != IMAGE_NT_SIGNATURE");
    //const IMAGE_FILE_HEADER *ifh = &inh->FileHeader;
    const IMAGE_OPTIONAL_HEADER *ioh = &inh->OptionalHeader;
    if(!ioh->DataDirectory.Size) return result;
    const IMAGE_IMPORT_DESCRIPTOR *iid = (const IMAGE_IMPORT_DESCRIPTOR *)
      obj_addr(idh, file_offset(inh, ioh->DataDirectory.VirtualAddress));
    for(size_t i = 0; ; ++i) {
      if(!iid.Characteristics) break;
      const char *name = (const char *)obj_addr(idh, file_offset(inh, iid.Name));
      result.push_back(pair<string, vector<string>>(string(name), vector<string>()));
      const IMAGE_THUNK_DATA *itd = (const IMAGE_THUNK_DATA *)obj_addr(idh, file_offset(inh, iid.OriginalFirstThunk));
      for(size_t i = 0; ; ++i) {
            if(!itd.u1.Ordinal) break;
            string name;
            if(itd.u1.Ordinal & IMAGE_ORDINAL_FLAG) {
                name = string("ordinal: ") + string_hex(itd.u1.Ordinal & ~IMAGE_ORDINAL_FLAG);
            } else {
                const IMAGE_IMPORT_BY_NAME *iibn = (const IMAGE_IMPORT_BY_NAME *)
                  obj_addr(idh, file_offset(inh, itd.u1.Ordinal));
                name = string((const char *)iibn->Name);
            }
            result.back().second.push_back(name);
      }
    }
    return result;
}

void print_result(const string &filename, const vector<pair<string, vector<string>>> &v) {
    cout << filename << endl;
    for(const auto &i: v) {
      cout << "    " << i.first << std::endl;
      for(const auto &i: i.second) {
            cout << "      " << i << std::endl;
      }
    }
}

int main() {
    string filename = "test.exe";
    vector<pair<string, vector<string>>> v = parse_import_descriptor(filename);
    print_result(filename, v);
    for(const auto &i: v) {
      try {
            vector<pair<string, vector<string>>> v = parse_import_descriptor(i.first);
            print_result(i.first, v);
      } catch(const exception &e) {
            cout << i.first << ": " << e.what() << endl;
      }
    }
    return 0;
}
$ ./main
test.exe
    WINMM.dll
      midiInOpen
      midiInStart
      midiInClose
      midiInGetErrorTextA
      midiInGetNumDevs
      midiInGetID
      midiInStop
      midiInGetDevCapsA
      timeBeginPeriod
      timeGetTime
      timeEndPeriod
    OPENGL32.dll
      wglGetProcAddress
      wglDeleteContext
      wglMakeCurrent
      wglCreateContext
    KERNEL32.dll
      GetLastError
      GetCurrentThread
      QueryPerformanceFrequency
      CloseHandle
      GetNativeSystemInfo
      GetSystemInfo
      LoadLibraryW
      GetLocalTime
      GetProcAddress
      GlobalLock
      GetCurrentProcessId
      SystemTimeToFileTime
      CreateProcessW
      FreeLibrary
      GetConsoleWindow
      GetSystemTime
      QueryPerformanceCounter
      GlobalUnlock
      LoadLibraryExW
      GetExitCodeProcess
      LoadLibraryA
      GetSystemPowerStatus
      SetConsoleTextAttribute
      MultiByteToWideChar
      FlushFileBuffers
      GetFileSizeEx
      GetTimeZoneInformation
      ReadConsoleW
      SetFilePointerEx
      HeapReAlloc
      CreatePipe
      GetFileAttributesExW
      EnumSystemLocalesW
      GetUserDefaultLCID
      IsValidLocale
      GetLocaleInfoW
      LCMapStringW
      CompareStringW
      GetCommandLineA
      WriteFile
      RemoveDirectoryW
      MoveFileExW
      FileTimeToSystemTime
      SystemTimeToTzSpecificLocalTime
      PeekNamedPipe
      GetFileInformationByHandle
      GetDriveTypeW
      CreateFileW
      FormatMessageW
      FreeLibraryAndExitThread
      ExitThread
      CreateThread
      ReadFile
      GetFileType
      SetStdHandle
      DuplicateHandle
      TlsFree
      TlsSetValue
      TlsGetValue
      TlsAlloc
      RtlUnwind
      RaiseException
      RtlPcToFileHeader
      RtlUnwindEx
      GetStartupInfoW
      IsDebuggerPresent
      InitializeSListHead
      IsProcessorFeaturePresent
      SetUnhandledExceptionFilter
      UnhandledExceptionFilter
      RtlVirtualUnwind
      RtlLookupFunctionEntry
      RtlCaptureContext
      CreateEventW
      ResetEvent
      InitializeCriticalSectionAndSpinCount
      GetCPInfo
      GetStringTypeW
      LCMapStringEx
      DecodePointer
      EncodePointer
      GetModuleHandleW
      GetConsoleMode
      Sleep
      LCIDToLocaleName
      GetModuleHandleA
      WaitForSingleObject
      GetEnvironmentVariableW
      SetThreadPriority
      GetUserDefaultUILanguage
      GetLocaleInfoEx
      SetEnvironmentVariableW
      GetModuleFileNameW
      TerminateProcess
      OutputDebugStringA
      GetStdHandle
      GetCurrentProcess
      SetPriorityClass
      GetSystemTimeAsFileTime
      SetLastError
      GetConsoleScreenBufferInfo
      SetConsoleCtrlHandler
      WideCharToMultiByte
      LocalFree
      GlobalAlloc
      GetCommandLineW
      GetConsoleOutputCP
      GetFullPathNameW
      IsValidCodePage
      GetACP
      GetOEMCP
      GetEnvironmentStringsW
      FreeEnvironmentStringsW
      GetModuleHandleExW
      WriteConsoleW
      SetEndOfFile
      EnterCriticalSection
      LeaveCriticalSection
      InitializeCriticalSection
      DeleteCriticalSection
      FindNextFileW
      FindClose
      CreateSemaphoreA
      CreateEventA
      VirtualFree
      CreateMutexA
      ReleaseMutex
      HeapFree
      GetTickCount64
      HeapAlloc
      GetProcessHeap
      ReleaseSemaphore
      SetEvent
      TryEnterCriticalSection
      ReplaceFileW
      CreateDirectoryW
      GetVolumeInformationW
      GetLogicalDrives
      FindFirstFileExW
      GetFileAttributesW
      DeleteFileW
      GetCurrentDirectoryW
      SetCurrentDirectoryW
      GetTempFileNameW
      GetDiskFreeSpaceExA
      ExitProcess
      InitializeSRWLock
      ReleaseSRWLockExclusive
      AcquireSRWLockExclusive
      InitializeCriticalSectionEx
      GetCurrentThreadId
      InitializeConditionVariable
      WakeConditionVariable
      WakeAllConditionVariable
      SleepConditionVariableCS
      SleepConditionVariableSRW
      WaitForSingleObjectEx
      GetExitCodeThread
      HeapSize
    ole32.dll
      CoInitialize
      CoCreateInstance
      PropVariantClear
      CoTaskMemFree
    USER32.dll
      GetDC
      GetRawInputDeviceInfoA
      GetRawInputDeviceList
      DefWindowProcW
      AdjustWindowRectEx
      GetKeyState
      GetMessageExtraInfo
      AllowSetForegroundWindow
      CallWindowProcW
      CloseTouchInputHandle
      GetTouchInputInfo
      GetWindowRect
      LoadCursorA
      IsWindowVisible
      SetWindowPos
      MessageBoxW
      MonitorFromWindow
      SetWindowRgn
      EnumDisplayMonitors
      CreateWindowExW
      GetKeyboardLayoutNameA
      ScreenToClient
      GetSystemMetrics
      SetWindowTextW
      RegisterClassExW
      ShowWindow
      OpenClipboard
      DispatchMessageW
      SetTimer
      DestroyIcon
      RegisterTouchWindow
      CreateIconIndirect
      ClientToScreen
      CloseClipboard
      EmptyClipboard
      PeekMessageW
      GetKeyboardLayoutList
      GetRawInputData
      TrackMouseEvent
      GetKeyboardLayout
      CreateIconFromResource
      MessageBoxA
      MoveWindow
      SetFocus
      RegisterRawInputDevices
      TranslateMessage
      GetClipboardData
      ClipCursor
      SendMessageA
      SetCapture
      SetClipboardData
      SetCursor
      LoadIconA
      FlashWindowEx
      SystemParametersInfoA
      GetClientRect
      IsClipboardFormatAvailable
      GetWindowLongPtrA
      ActivateKeyboardLayout
      KillTimer
      SetWindowLongPtrA
      ReleaseCapture
      SetForegroundWindow
      IsIconic
      SetCursorPos
      ReleaseDC
      GetCursorPos
    GDI32.dll
      GetObjectA
      ChoosePixelFormat
      SetPixelFormat
      SwapBuffers
      DeleteObject
      CreateBitmap
      SetTextColor
      BitBlt
      CreateCompatibleBitmap
      SelectObject
      CreateCompatibleDC
      CreatePolygonRgn
      GetDeviceCaps
      CreateRectRgn
      DeleteDC
      SetBkColor
    SHELL32.dll
      DragQueryFileW
      CommandLineToArgvW
      ShellExecuteW
      SHGetKnownFolderPath
      SHFileOperationW
      DragAcceptFiles
    ADVAPI32.dll
      GetCurrentHwProfileA
      RegOpenKeyExW
      RegCloseKey
      RegQueryValueExW
    DINPUT8.dll
      DirectInput8Create
    IMM32.dll
      ImmReleaseContext
      ImmGetContext
      ImmAssociateContext
      ImmSetCompositionWindow
    AVRT.dll
      AvSetMmThreadCharacteristicsA
      AvSetMmThreadPriority
    dwmapi.dll
      DwmIsCompositionEnabled
      DwmEnableBlurBehindWindow
      DwmFlush
    IPHLPAPI.DLL
      GetBestInterfaceEx
      GetAdaptersAddresses
    SHLWAPI.dll
      PathFileExistsW
    WSOCK32.dll
      ordinal: 0000000000000074
      ordinal: 0000000000000097
      ordinal: 000000000000000d
      ordinal: 0000000000000009
      ordinal: 000000000000000f
      ordinal: 0000000000000003
      ordinal: 0000000000000013
      ordinal: 0000000000000006
      ordinal: 0000000000000008
      ordinal: 000000000000000e
      ordinal: 000000000000006f
      ordinal: 0000000000000015
      ordinal: 0000000000000004
      ordinal: 0000000000000017
      ordinal: 0000000000000014
      ordinal: 000000000000000a
      ordinal: 0000000000000002
      ordinal: 0000000000000010
      ordinal: 0000000000000012
      ordinal: 000000000000000c
      ordinal: 0000000000000011
      ordinal: 0000000000000073
      ordinal: 0000000000000001
    WS2_32.dll
      freeaddrinfo
      getnameinfo
      inet_pton
      WSAConnect
      getaddrinfo
    bcrypt.dll
      BCryptGenRandom
    steam_api64.dll
      SteamAPI_UnregisterCallback
      SteamGameServer_Shutdown
      SteamInternal_ContextInit
      SteamAPI_Shutdown
      SteamInternal_FindOrCreateGameServerInterface
      SteamAPI_GetHSteamUser
      SteamAPI_ReleaseCurrentThreadMemory
      SteamAPI_IsSteamRunning
      SteamInternal_GameServer_Init
      SteamAPI_RegisterCallResult
      SteamAPI_RegisterCallback
      SteamGameServer_GetHSteamUser
      SteamAPI_RestartAppIfNecessary
      SteamAPI_Init
      SteamAPI_UnregisterCallResult
      SteamInternal_FindOrCreateUserInterface
      SteamAPI_RunCallbacks
WINMM.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
OPENGL32.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
KERNEL32.dll
ole32.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
USER32.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
GDI32.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
SHELL32.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
ADVAPI32.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
DINPUT8.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
IMM32.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
AVRT.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
dwmapi.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
IPHLPAPI.DLL: idh->e_magic != IMAGE_DOS_SIGNATURE
SHLWAPI.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
WSOCK32.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
WS2_32.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
bcrypt.dll: idh->e_magic != IMAGE_DOS_SIGNATURE
steam_api64.dll
    KERNEL32.dll
      TlsAlloc
      TlsGetValue
      TlsSetValue
      TlsFree
      LoadLibraryExW
      OpenProcess
      GetExitCodeProcess
      InitializeCriticalSection
      EnterCriticalSection
      LeaveCriticalSection
      DeleteCriticalSection
      InitializeCriticalSectionAndSpinCount
      LoadLibraryExA
      GetModuleFileNameW
      GetModuleHandleA
      GetModuleHandleExW
      GetCommandLineW
      GetEnvironmentVariableA
      SetEnvironmentVariableA
      OutputDebugStringA
      GetFileAttributesW
      MultiByteToWideChar
      WideCharToMultiByte
      GetLastError
      FreeLibrary
      CloseHandle
      GetProcAddress
      SetEndOfFile
      ReadConsoleW
      SetEvent
      ResetEvent
      WaitForSingleObjectEx
      CreateEventW
      GetModuleHandleW
      RtlCaptureContext
      RtlLookupFunctionEntry
      RtlVirtualUnwind
      IsDebuggerPresent
      UnhandledExceptionFilter
      SetUnhandledExceptionFilter
      GetStartupInfoW
      IsProcessorFeaturePresent
      QueryPerformanceCounter
      GetCurrentProcessId
      GetCurrentThreadId
      GetSystemTimeAsFileTime
      InitializeSListHead
      RtlPcToFileHeader
      RaiseException
      RtlUnwindEx
      InterlockedFlushSList
      SetLastError
      EncodePointer
      GetCurrentProcess
      TerminateProcess
      ExitProcess
      GetModuleFileNameA
      HeapFree
      HeapAlloc
      GetACP
      GetStdHandle
      GetFileType
      GetStringTypeW
      LCMapStringW
      FindClose
      FindFirstFileExA
      FindNextFileA
      IsValidCodePage
      GetOEMCP
      GetCPInfo
      GetCommandLineA
      GetEnvironmentStringsW
      FreeEnvironmentStringsW
      GetProcessHeap
      SetStdHandle
      FlushFileBuffers
      WriteFile
      GetConsoleCP
      GetConsoleMode
      CreateFileW
      HeapSize
      HeapReAlloc
      SetFilePointerEx
      WriteConsoleW
      ReadFile
    ADVAPI32.dll
      RegOpenKeyExW
      RegCloseKey
      RegQueryValueExW
    SHELL32.dll
      ShellExecuteW
$
页: [1]
查看完整版本: 给定exe文件查看dll依赖以及所用函数