An exported aliases symbol doesn't exist in PDB file (RegisterClipboardFormat has RegisterWindowMessage internal name)

StackOverflow https://stackoverflow.com/questions/10780402

Вопрос

I'm trying to set a breakpoint in user32!RegisterClipboardFormat Evidently, this function is exported (link /dump /exports - it is right there). Before downloading the PDB file from the Microsoft symbol server, I'm able to find this function:

0:001> lm m user32
start    end
76eb0000 76fcf000   USER32     (export symbols)       c:\Windows\system32\USER32.dll

0:001> x user32!RegisterClipboardFormat*
76ec4eae USER32!RegisterClipboardFormatA (<no parameter info>)
76ec6ffa USER32!RegisterClipboardFormatW (<no parameter info>)

No problems. I'm able to 'bu' any of these functions. But when I download the PDB symbols from the Microsoft PDB server:

0:001> 
start    end        module name
76d50000 76e6f000   USER32     (pdb symbols)          c:\symbols\user32.pdb\561A146545614951BDB6282F2E3522F72\user32.pdb

0:000> x user32!RegisterClipboardFormat

WinDBG cannot find the symbols. However, it can find RegisterWindowMesssage:

0:000> x user32!RegisterWindowMessage*
76d64eae          USER32!RegisterWindowMessageA = <no type information>
76d66ffa          USER32!RegisterWindowMessageW = <no type information>

Note that the functions have the same addresses (This is on Windows 8. Not sure about previous versions). This is probably achieved by the optimizer or in the DEF file (func1=func2 in the EXPORT section). 'link /dump /exports' shows RegisterWindowMessage and RegisterClipboardFormat have the same RVA.

Problem is that I spent way too much time on this. So my questions are:

  1. Is there is an easy way, from within WinDBG to find out missing aliased export symbols.
  2. Say I want to break only on RegisterClipboardFormatW. If I recall correctly, there should be a JMP instruction somewhere (in the calling module import table). How do I find that symbol? Is there a way to find this entry in all calling modules?
Это было полезно?

Решение

Since RegisterWindowMessage and RegisterClipboardFormat have the same RVA, they share the same implementation. Apparently Windows does not make any distinction between the two and both clipboard format and window messages share the same domain of identifiers.

For your first question -- how to find out which implementation function corresponds to exported function. (assuming you have symbols fixed up) First figure out RVA of the export:

C:\>link /dump /exports C:\Windows\Syswow64\user32.dll |findstr RegisterClipboardFormat
   2104  24F 00020AFA RegisterClipboardFormatA
   2105  250 00019EBD RegisterClipboardFormatW

Then in WinDbg find starting address where DLL is loaded from. Commands lm or lml list all modules, you just need to find the module you are after:

0:001> lml
start    end        module name
75460000 75560000   USER32   

Using RVA as offset to the starting address, get symbol that corresponds to it:

0:002> ln 75460000+00020AFA
(75480afa)   USER32!RegisterWindowMessageA   |  (75480b4a)   USER32!MsgWaitForMultipleObjects
Exact matches:
0:002> ln 75460000+00019EBD
(75479ebd)   USER32!RegisterWindowMessageW   |  (75479eea)   USER32!NtUserGetProcessWindowStation
Exact matches:

So here we actually found out that RegisterClipboardFormat actually calls into RegisterWindowMessage.

Your second question -- how to put breakpoint only on RegisterClipboardFormat, and not on RegisterWindowMessage. In general it is impossible, because they share the same implementation. For example, your app might call GetProcAddress("RegisterClipboardFormat") and you will have hard time figuring out if it called to one function or another. However if you know that the call was made through imported function, then you can do this. All imported functions are declared in import address table in your application. If you put an access breakpoint on the entry in import address table, you can break before the call is made. This might be compiler specific, but I know that Visual C++ assigns symbolic names to entries in import address table. In this case putting breakpoint is easy:

ba r4 MyModule!_imp_RegisterClipboardFormatA
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top