2016-06-22 10 views
0

DLLには、他のアプリケーションが呼び出せる、エクスポートされた関数のセットがあります。通常、これらの関数を呼び出すには、関数名または序数が必要です。dllから安定したアドレスを取得するには?

MSO.dllには、DLLへのエクスポートされたエントリポイントのほとんどが名前を持たないため、通常の方法で実際に必要な機能を呼び出すことはできません。

Googleの検索では、安定したアドレス(変更されていないアドレス)が電話したい機能になっていると主張するブロガーに出くわしました。

これらのアドレスの問題は、Officeのあるリリースから別のリリースに、またはある更新から次の更新にまで同じであると数えることができないということです。だから私は彼が彼の書いたblog postMSO.dllでこれらの安定したアドレスを発見した方法を見つける必要があります。彼のブログでソースコードを見つけることができます。

リーのコードの一部私は理解しようとしています:ここで

image

は、私はこれらのアドレスを見つけるために書いたいくつかのコードは次のとおりです。

#include <Windows.h> 
#include <stdint.h> 
#include <iostream> 
#include <map> 

int main() 
{ 
    HMODULE hGetProcIDDLL = LoadLibrary("C:\\Program Files\\Microsoft Office 15\\root\\vfs\\ProgramFilesCommonX86\\Microsoft Shared\\OFFICE15\\mso.dll"); 

    PIMAGE_NT_HEADERS header = (PIMAGE_NT_HEADERS)((char *)hGetProcIDDLL + ((PIMAGE_DOS_HEADER)hGetProcIDDLL)->e_lfanew); 
    PIMAGE_EXPORT_DIRECTORY exports = (PIMAGE_EXPORT_DIRECTORY)((char *)hGetProcIDDLL + header-> 
     OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 

    char** names = (char**)((int)hGetProcIDDLL + exports->AddressOfNames); 
    std::cout << "Total # of functions: " << exports->NumberOfFunctions << std::endl; 
    std::cout << "Total # of named functions: " << exports->NumberOfNames << std::endl; 

    std::map<uintptr_t, char*> addressToName; 

    for (uint16_t i = 0; i < exports->NumberOfNames; i++) 
    { 
     char* name = (char*)hGetProcIDDLL + (int)names[i]; 
     void* fn = GetProcAddress(hGetProcIDDLL, name); 
     addressToName[(uintptr_t)fn] = name; 
     //std::cout << "Export: Name: " << name << " Address: " << fn << "\n"; 

    } 

    for (uint16_t i = 1; i < exports->NumberOfFunctions; i++) 
    { 
     void* fn = GetProcAddress(hGetProcIDDLL, MAKEINTRESOURCE(i)); 
     std::map<uintptr_t, char*>::iterator it; 
     it = addressToName.find((uintptr_t)fn); 
     std::cout << "oridinal #: " << i << " address: " << fn << " Name: " << (it != addressToName.end() ? it->second : "N\\A") << "\n"; 
    } 

    // Free the DLL module. 
    if (!FreeLibrary(hGetProcIDDLL)) 
    { 
     return E_FAIL; 
    } 

    return 0; 
} 

それは本質的Dumpbin.exeと同じことを行い/Exportだけでなく、procAddress、名前、および序数を出力します。下の2つのランの差の写真を見ることができます。上位ワードの2バイトは安定しています。

diff example

bin dump 1bin dump 2を参照してください。

私の質問には、いくつかの部分で構成されています

安定した上位ワードと下位ワードは変更される場合が作るもの
  1. LeeがMSO.dllで見つけた安定したアドレスを取得するにはどうすればよいですか?

  2. clearclipboardgetClipboardCountのどちらの機能が安定したアドレスを見つけたら、どうすればわかりますか?

+0

誰かが* *「MSO.DLLで安定したアドレスを見つけました」 - 私は考えている、それが意味することになっているもの。 – IInspectable

+0

私はこのあいまいさを捕まえてくれて、もっと多くの背景情報を与えてくれます。 – user1881587

+0

@IInspectableはこれが優れていますか? – user1881587

答えて

0

1.)「高次の単語を安定させ、下位の単語を変えるのは何ですか?」 - 最初は、これはまったく真実ではありません。 CONCRETEバイナリを取得する場合mso.dll - すべての関数にはRVA(モジュールベースからの相対VA)があります。ほぼ100%の可用性を備えた別のmso.dllビルドを実行すると、別のRVAが機能するようになります。あなたはVA絶対アドレスを探しています。 VA = ImageBase + RVA、ImageBase - mso.dllがロードされているアドレス(HMODULE)。しかし、それはいつも異なるアドレス(ASLR)でロードするので、VAはまったく安定しません。 RVAは同じmso.dllバージョンを使用している間だけ安定します(別バージョンではRVAは別のバージョンになります)

2.)LeeがMSO.dllで見つけた安定したアドレスを取得するにはどうすればよいですか? - リーは何も見つかりませんでした。これは、私が記述しているように、間違いなく質問します。関数がエクスポートされた場合、名前または序数(序数は安定していない可能性もありますが、これはdllに非常に依存しています)でアドレスを取得できます。あなたがpdbファイルを持っていれば、パブリックシンボルアドレス(RVA)をpdbから(エクスポートされていないシンボルの場合でも)

3)どのように私が見つけるべきであるかを知るにはどうすればよいですか?安定した住所? - 再び - 「安定したアドレス」は存在しません。 PDBで唯一の輸出や記号

関連する問題