就像VC提供的Depends那样?

解决方案 »

  1.   

    自己修改系统api函数所在的dll,重写所有的api函数,截获api函数的调用,然后自己调用原来的dll重的对应函数。
      

  2.   

    分析应用程序的导入表,去察看一下pe文件的格式
    pe文件的导入表中记载其装载dll的名字和api的名字。
      

  3.   

    //老毛子写的程序,拿来参考。#include <windows.h>#define MakePtr(base, offset) ((LPSTR)(base) + offset)//@//////////////////////////////////////////////////////////////////////////
    // §¤§&Yacute;§à§&Ograve;§&Ntilde;§&Yacute;§&icirc;§&szlig;§í§&Ouml; §á§&Ouml;§&acirc;§&Ouml;§&THORN;§&Ouml;§&szlig;§&szlig;§í§&Ouml;static BOOL     g_bUnicodeOS = FALSE;
    static HMODULE  g_hModuleUnicows = NULL;
    static LPWORD   g_pdwOrd = NULL;
    static LPDWORD  g_pdwAddrs = NULL;
    static LPDWORD  g_pdwNames = NULL;
    static DWORD    g_dwNames = 0;//@//////////////////////////////////////////////////////////////////////////
    // §&pound;§&atilde;§á§à§&THORN;§à§&Ocirc;§&Ntilde;§&auml;§&Ouml;§&Yacute;§&icirc;§&szlig;§&Ntilde;§&ntilde; §&aelig;§&aring;§&szlig;§&Uuml;§è§&Uacute;§&ntilde;, §&Oacute;§à§&Ugrave;§&Oacute;§&acirc;§&Ntilde;§&euml;§&Ntilde;§&Ouml;§&auml; §&Ntilde;§&Otilde;§&acirc;§&Ouml;§&atilde; §&aelig;§&aring;§&szlig;§&Uuml;§è§&Uacute;§&Uacute; §&Uacute;§&Ugrave; unicows.dll
    // §&atilde; §&aring;§&Uuml;§&Ntilde;§&Ugrave;§&Ntilde;§&szlig;§&szlig;§í§&THORN; §&Uacute;§&THORN;§&Ouml;§&szlig;§&Ouml;§&THORN;, §&Ouml;§&atilde;§&Yacute;§&Uacute; §&auml;§&Ntilde;§&Uuml;§&Ntilde;§&ntilde; §&Uacute;§&THORN;§&Ouml;§&Ouml;§&auml;§&atilde;§&ntilde;static LPDWORD GetFunctionAddress(LPCSTR azName)
    {
    DWORD dwName = 0; 
        while (dwName < g_dwNames)
        {
            if (0 == ::lstrcmpiA(MakePtr( g_hModuleUnicows, g_pdwNames[dwName]), azName))
                return (LPDWORD)MakePtr(g_hModuleUnicows, g_pdwAddrs[g_pdwOrd[dwName]]);
    dwName ++;
        }    return NULL;
    }BOOL _UnicowsInit(LPCSTR szLib)
    {
    /* int i = ::GetVersion();
        if (0 == (0x80000000 & ::GetVersion()))
        {
            // WinNT/2k/XP: §&acute;§&aring;§&auml; §&szlig;§&Ntilde;§&THORN; §&Otilde;§&Ouml;§&Yacute;§&Ntilde;§&auml;§&icirc; §&szlig;§&Ouml;§é§&Ouml;§&Ocirc;§à
            g_bUnicodeOS = TRUE;
            return ::SetLastError(0), TRUE;
        }    */
        g_hModuleUnicows = ::LoadLibraryA(szLib);
        if (!g_hModuleUnicows)
            return FALSE; // §°§ê§&Uacute;§&Ograve;§&Uuml;§&Ntilde; §á§&acirc;§&Uacute; §&Ugrave;§&Ntilde;§&Ocirc;§&acirc;§&aring;§&Ugrave;§&Uuml;§&Ouml; Unicows.dll    // §&macr;§&Ntilde;§&ccedil;§à§&Otilde;§&Uacute;§&THORN; §&auml;§&Ntilde;§&Ograve;§&Yacute;§&Uacute;§è§&aring; §&iuml;§&Uuml;§&atilde;§á§à§&acirc;§&auml;§&Ntilde;
        PIMAGE_DOS_HEADER pDosHeader = PIMAGE_DOS_HEADER(g_hModuleUnicows);    if (::IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER))
                || IMAGE_DOS_SIGNATURE != pDosHeader->e_magic)
            return ::SetLastError(ERROR_INVALID_PARAMETER), FALSE;    PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)
            MakePtr(g_hModuleUnicows, pDosHeader->e_lfanew);
        
        if (::IsBadReadPtr(pNTHeaders, sizeof(IMAGE_NT_HEADERS))
                || IMAGE_NT_SIGNATURE != pNTHeaders->Signature)
            return ::SetLastError(ERROR_INVALID_PARAMETER), FALSE;    IMAGE_DATA_DIRECTORY& expDir =
            pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
        PIMAGE_EXPORT_DIRECTORY pExpDir = (PIMAGE_EXPORT_DIRECTORY )
            MakePtr(g_hModuleUnicows, expDir.VirtualAddress);    // §&copy;§&Ntilde;§á§à§&szlig;§&Uacute;§&THORN;§&Ntilde;§&Ouml;§&THORN; §&auml;§&Ntilde;§&Ograve;§&Yacute;§&Uacute;§è§&aring; §&Uacute;§&THORN;§&Ouml;§&szlig; §&Uacute; §&Ntilde;§&Otilde;§&acirc;§&Ouml;§&atilde;§à§&Oacute;
        g_pdwOrd = (LPWORD)MakePtr(g_hModuleUnicows, pExpDir->AddressOfNameOrdinals);
        g_pdwNames = (LPDWORD)MakePtr(g_hModuleUnicows, pExpDir->AddressOfNames);
        g_pdwAddrs = (LPDWORD)MakePtr(g_hModuleUnicows, pExpDir->AddressOfFunctions);
        g_dwNames = pExpDir->NumberOfNames;    return TRUE;
    }static LPCSTR GetNameFromOrdinal(HMODULE hModule,DWORD dwOrdinal)
    {
        if (!hModule)
            return FALSE; // §&macr;§&Ouml;§&auml; §&auml;§&Ntilde;§&Uuml;§à§&Ocirc;§à §&THORN;§à§&Otilde;§&aring;§&Yacute;§&ntilde;
        
        // §&macr;§&Ntilde;§&ccedil;§à§&Otilde;§&Uacute;§&THORN; §&auml;§&Ntilde;§&Ograve;§&Yacute;§&Uacute;§è§&aring; §&iuml;§&Uuml;§&atilde;§á§à§&acirc;§&auml;§&Ntilde;
        PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)(hModule);
        if (::IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER))
                || IMAGE_DOS_SIGNATURE != pDosHeader->e_magic)
            return ::SetLastError(ERROR_INVALID_PARAMETER), FALSE;    PIMAGE_NT_HEADERS pNTHeaders =(PIMAGE_NT_HEADERS)
            MakePtr( hModule, pDosHeader->e_lfanew);
       
        if (::IsBadReadPtr(pNTHeaders, sizeof(IMAGE_NT_HEADERS))
                || IMAGE_NT_SIGNATURE != pNTHeaders->Signature)
            return ::SetLastError(ERROR_INVALID_PARAMETER), FALSE;
     
        IMAGE_DATA_DIRECTORY& expDir =
            pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
        PIMAGE_EXPORT_DIRECTORY pExpDir = (PIMAGE_EXPORT_DIRECTORY)
            MakePtr( hModule, expDir.VirtualAddress);    LPWORD pdwOrd = (LPWORD)MakePtr( hModule, pExpDir->AddressOfNameOrdinals);
        LPDWORD pdwNames = (LPDWORD)MakePtr(hModule, pExpDir->AddressOfNames);
        dwOrdinal -= pExpDir->Base;
    g_dwNames = pExpDir->NumberOfNames;
        for (DWORD iName = 0; iName < pExpDir->NumberOfNames; iName++)
        {
            // §±§&acirc;§à§&Oacute;§&Ouml;§&acirc;§&ntilde;§&Ouml;§&THORN; §&Oacute;§&atilde;§&Ouml; §&szlig;§à§&THORN;§&Ouml;§&acirc;§&Ntilde; §á§à §á§à§&acirc;§&ntilde;§&Otilde;§&Uuml;§&aring;
            if (dwOrdinal == pdwOrd[iName])
                return MakePtr(hModule, pdwNames[iName]);
        }/**/
        return NULL;
    }
    int main(int,char**)
    {
    if(!_UnicowsInit("C:\\Test.dll"))
    return -1;
    LPCSTR szName = GetNameFromOrdinal(g_hModuleUnicows,1);
    LPDWORD pTest = GetFunctionAddress(szName); __asm
    {
    call pTest
    } szName = GetNameFromOrdinal(g_hModuleUnicows,2);
    pTest = GetFunctionAddress(szName);
    int nOffset= g_dwNames*sizeof(LONG);
    __asm
    {
    push g_dwNames
    push        szName
    call        pTest
    add         esp,nOffset
    }
    _UnicowsRebindImports(g_hModuleUnicows);
    return 0;
    }
      

  4.   

    在程序编译的时候pe文件的导入表中记载其装载dll的名字和api的名字。你可以看看这部分
      

  5.   

    和PE文件结构有关,楼主可以找找PE文件导入表相关的文章。
      

  6.   

    正在使用的??好像 所有调用的API 可能还可以得到。。
      

  7.   

    原来学习PE文件的时候写的一个例子,是打印import表的,打印格式类似于dumpbin /imports
    #include "stdafx.h"
    #include "windows.h"// define区
    #define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (addValue) )
    #define MAX_NAME_LEN 256// 全局变量区
    FILE *hFile = NULL;
    IMAGE_DOS_HEADER dos_header;
    IMAGE_NT_HEADERS nt_header;
    IMAGE_SECTION_HEADER *psection_header;IMAGE_IMPORT_DESCRIPTOR *pimport_descriptor; // 输入表描述符
    int    numOfImportDescriptor; // 输入表项数void usage()
    {
    printf("usage: PEFile filename\n");
    }bool openFile(char * filename)
    {
    hFile = fopen(filename, "rb");
    if(!hFile)
    {
    printf("open file error\n");
    return false;
    }
    return true;
    }void closeFile()
    {
    fclose(hFile);
    }bool readDosHeader()
    {
    size_t num = fread(&dos_header, sizeof(dos_header), 1, hFile);
    if(num!=1)
    {
    printf("open dos header error\n");
    return false;
    }
    else
    return true;
    }bool readNtHeader()
    {
    int offset = dos_header.e_lfanew;
    if(fseek(hFile, offset, SEEK_SET)!=0)
    return false;
    size_t num = fread(&nt_header, sizeof(IMAGE_NT_HEADERS), 1, hFile);
    if(num != 1)
    {
    printf("read nt header error\n");
    return false;
    }
    return true;}bool readSectionHeaders()
    {
    // 没有重定位,所以必须在readNtHeader()之后调用
    int sectionNum = nt_header.FileHeader.NumberOfSections;
    psection_header = new IMAGE_SECTION_HEADER[sectionNum];
    size_t num = fread(psection_header, sizeof(IMAGE_SECTION_HEADER), sectionNum, hFile);
    if(num != sectionNum)
    {
    printf("read section header error\n");
    return false;
    }

    return true;
    }bool readImportDescriptor()
    {
    // 读取输入描述符
    int offset = nt_header.OptionalHeader.DataDirectory[1].VirtualAddress;
    int size = nt_header.OptionalHeader.DataDirectory[1].Size;
    pimport_descriptor = (IMAGE_IMPORT_DESCRIPTOR *)new char[size];
    if(fseek(hFile, offset, SEEK_SET)!=0)
    return false;
    size_t num = fread(pimport_descriptor, size, 1, hFile);
    if(num != 1)
    {
    printf("read import descriptor header error\n");
    return false;
    }
    numOfImportDescriptor = size/sizeof(IMAGE_IMPORT_DESCRIPTOR)-1; return true;
    }void displayImportFunction(IMAGE_IMPORT_DESCRIPTOR &import_descriptor)
    {
    int offset = import_descriptor.OriginalFirstThunk;
    if(fseek(hFile, offset, SEEK_SET)!=0)
    return;
    IMAGE_THUNK_DATA imageThunkData;
    for(;;)
    {
    size_t iRead = fread(&imageThunkData, sizeof(IMAGE_THUNK_DATA), 1, hFile);
    if(iRead != 1)
    {
    printf("read thunk data error\n");
    return;
    }
    if(*((DWORD *)(&imageThunkData)) == 0)
    break; // 最高位如果为1,表示函数以序号方式输入
    if(*((DWORD *)(&imageThunkData)) & 0x80000000)
    {
    DWORD ordinal = *((DWORD *)(&imageThunkData)) & 0x7fffffff;
    printf("                Ordinal  %d\n",ordinal);
    }
    else
    {
    // 最高位不为1,表示函数以字符串方式输入
    long  current = ftell(hFile); DWORD offset = *((DWORD *)(&imageThunkData));
    WORD  Hint;
    char  FunctionName[MAX_NAME_LEN];
    if(fseek(hFile, offset, SEEK_SET)!=0)
    return;
    fread(&Hint, sizeof(WORD), 1, hFile);
    int position=0;
    for(;;)
    {
    int ch = fgetc(hFile);
    FunctionName[position++] = ch;
    if(!ch)
    break;
    }
    printf("                %8X  %s\n", Hint, FunctionName);

    fseek(hFile, current, SEEK_SET);
    } }}void displayImportDescriptor()
    {
    printf(" Section contains the following imports:\n\n");
    for(int num = 0 ; num < numOfImportDescriptor ; num ++)
    {
    // 首先获取输入表名称
    char import_descriptor_name[MAX_NAME_LEN];
    int offset = pimport_descriptor[num].Name;
    if(fseek(hFile, offset, SEEK_SET)!=0)
    return;
    int position=0;
    for(;;)
    {
    int ch = fgetc(hFile);
    import_descriptor_name[position++] = ch;
    if(!ch)
    break;
    }
    printf("        %s\n",import_descriptor_name);
    printf("                %X Import Address Table\n", pimport_descriptor[num].FirstThunk+nt_header.OptionalHeader.ImageBase);
    printf("                %X Import Name Table\n", pimport_descriptor[num].OriginalFirstThunk+nt_header.OptionalHeader.ImageBase);
    printf("                %X time date stamp\n", pimport_descriptor[num].TimeDateStamp);
    printf("                %X Index of first forwarder reference\n", pimport_descriptor[num].ForwarderChain);
    printf("\n");
    displayImportFunction(pimport_descriptor[num]);
    printf("\n");
    }
    }void displaySectionTable()
    {
    printf(" Summary:\n\n");
    for(int num = 0 ; num < nt_header.FileHeader.NumberOfSections ; num++)
    {
    printf("        %6X  %s\n", psection_header[num].SizeOfRawData, psection_header[num].Name);
    }
    }int _tmain(int argc, _TCHAR* argv[])
    {
    if(argc<2)
    {
    usage();
    return 0;
    }
    if(!openFile(argv[1]))
    return -1;
    if(!readDosHeader())
    return -1;
    if(!readNtHeader())
    return -1;
    if(!readSectionHeaders())
    return -1;
    if(!readImportDescriptor())
    return -1; displayImportDescriptor();
    displaySectionTable();
    closeFile();
    return 0;
    }