title: How to get stable Address from a dll?
body: <p>A DLL has a set of exported functions that other applications can call. Typically to call these functions you either have a function name or an ordinal number.</p>
  
  <p>In <code>MSO.dll</code>, most of the exported entry points to the DLL don't have names, so I can't call the function I want pragmatically by normal means.</p>
  
  <p>Upon a bit of Google searching I ran into a blogger that claims to have found stable addresses (addresses that don't change) to the very function I want to call.</p>
  
  <p>The issue with these addresses is that they can't be counted on to be the same from one release of Office to another, or even from one update to the next. So I need to find out how Lee Benfield found these stable addresses in <code>MSO.dll</code> when he wrote his <a href="http://www.benf.org/excel/officeclip/" rel="nofollow noreferrer">blog post</a>. You can find the source code on his blog.</p>
  
  <p>The portion of Lee's code I am trying to understand:</p>
  
  <p><a href="https://i.stack.imgur.com/VkNzm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VkNzm.png" alt="image"></a></p>
  
  <p>Here is some code I wrote to find these addresses:</p>
  
  <pre><code>#include &lt;Windows.h&gt;
  #include &lt;stdint.h&gt;
  #include &lt;iostream&gt;
  #include &lt;map&gt;
  
  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)-&gt;e_lfanew);
      PIMAGE_EXPORT_DIRECTORY exports = (PIMAGE_EXPORT_DIRECTORY)((char *)hGetProcIDDLL + header-&gt;
          OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  
      char** names = (char**)((int)hGetProcIDDLL + exports-&gt;AddressOfNames);
      std::cout &lt;&lt; "Total # of functions: " &lt;&lt; exports-&gt;NumberOfFunctions &lt;&lt; std::endl;
      std::cout &lt;&lt; "Total # of named functions: " &lt;&lt; exports-&gt;NumberOfNames &lt;&lt; std::endl;
  
      std::map&lt;uintptr_t, char*&gt; addressToName;
  
      for (uint16_t i = 0; i &lt; exports-&gt;NumberOfNames; i++)
      {
          char* name = (char*)hGetProcIDDLL + (int)names[i];
          void* fn = GetProcAddress(hGetProcIDDLL, name);
          addressToName[(uintptr_t)fn] = name;
          //std::cout &lt;&lt; "Export: Name: " &lt;&lt; name &lt;&lt; " Address: " &lt;&lt; fn &lt;&lt; "\n";
  
      }
  
      for (uint16_t i = 1; i &lt; exports-&gt;NumberOfFunctions; i++)
      {
          void* fn = GetProcAddress(hGetProcIDDLL, MAKEINTRESOURCE(i));
          std::map&lt;uintptr_t, char*&gt;::iterator it;
          it = addressToName.find((uintptr_t)fn);
          std::cout &lt;&lt; "oridinal #: " &lt;&lt; i &lt;&lt; " address: " &lt;&lt; fn &lt;&lt; " Name: " &lt;&lt; (it != addressToName.end() ? it-&gt;second : "N\\A") &lt;&lt; "\n";
      }
  
      // Free the DLL module.
      if (!FreeLibrary(hGetProcIDDLL))
      {
          return E_FAIL;
      }
  
      return 0;
  }
  </code></pre>
  
  <p>It essentially does the same thing as <a href="https://msdn.microsoft.com/en-us/library/c1h23y6c.aspx" rel="nofollow noreferrer">Dumpbin.exe</a> <a href="https://msdn.microsoft.com/en-us/library/30e78zd0.aspx" rel="nofollow noreferrer">/Export</a>, but also prints out the <code>procAddress</code>, name, and ordinal value. Below you can see a picture of a diff of two runs. The two byte of the higher order word are stable.</p>
  
  <p><a href="https://i.stack.imgur.com/2CBkd.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/2CBkd.png" alt="diff example"></a></p>
  
  <p>see <a href="http://pastebin.com/A5BsLdJK" rel="nofollow noreferrer">bin dump 1</a> and <a href="http://pastebin.com/5irDX5Ec" rel="nofollow noreferrer">bin dump 2</a>.</p>
  
  <p>My question has a few parts:</p>
  
  <ol>
  <li><p>what makes the higher order word stable and the lower order word vary?</p></li>
  <li><p>how do I get the stable addresses that Lee found in the MSO.dll?</p></li>
  <li><p>how do I find out which one is the <code>clearclipboard</code> and <code>getClipboardCount</code> function should I find a stable address?</p></li>
  </ol>