2017-03-08 3 views
2

Je fais de la bureautique avec MS Word à partir d'une application C#, et je trouve que Word est parfois bloqué. Je ne peux pas reproduire le blocage dans un environnement de développement, j'espère donc pouvoir diagnostiquer exactement pourquoi Word est suspendu en effectuant un vidage de base puis en l'analysant à l'aide de WinDbg.WinDbg: Comment afficher le message affiché dans une boîte de dialogue Word à partir d'une image mémoire?

Si je cours kb, je reçois cette trace de la pile (je l'ai laissé hors tout après l'avertissement qu'il est probablement hors de propos):

ChildEBP RetAddr Args to Child    
003bc94c 762ed846 00037b72 00000008 00000000 user32!NtUserWaitMessage+0x15 
003bc988 762eda5c 00047b12 00037b72 00000008 user32!DialogBox2+0x222 
003bc9b4 762ed98a 59870000 0089aa30 00037b72 user32!InternalDialogBox+0xe5 
003bc9d4 762ed70e 59870000 0089aa30 00037b72 user32!DialogBoxIndirectParamAorW+0x37 
003bc9f4 59acdf5e 59870000 0089aa30 00037b72 user32!DialogBoxIndirectParamW+0x1b 
WARNING: Stack unwind information not available. Following frames may be wrong. 

Donc, cela semble indiquer que la Parole est suspendue parce qu'il est montrant une boite de dialogue. Comment puis-je obtenir le contenu de cette boîte de dialogue?

Si je regarde la mémoire à l'adresse 0089aa30, je vois ceci:

........................3.... 
.M.i.c.r.o.s.o.f.t. .W.o.r.d. 
........T.a.h.o.m.a.......... 
....P#.!.*...........O.K..... 
...........PW.!.*...........& 
.H.e.l.p..................P.. 
............................. 
....P+...r.......M.S.O.U.N.I. 
S.T.A.T...W.o.r.d. .c.a.n.n.o 
.t. .o.p.e.n. .t.h.e. .e.x.i. 
s.t.i.n.g. .f.i.l.e..... .(.N 
.o.r.m.a.l.)[email protected] 
..+.........M.S.O.U.N.I.S.T.A 
.T...2.0.0.5.2.1............. 

Donc, pour moi, ce dit que le message dans la boîte de dialogue est « Word ne peut pas ouvrir le fichier existant (Normal) ».

Suis-je sur la bonne voie? Est-ce que je regarde le bon morceau de mémoire?

Est-il possible d'obtenir l'adresse mémoire exacte du message? (Je pense que je devine un peu, parce que le message ci-dessus se trouve juste à proximité d'un paramètre à DialogBoxIndirectParam.) J'ai regardé les documents MSDN pour DialogBoxIndirectParam, espérant trouver exactement où en mémoire je devrais s'attendre à voir le message du dialogue, mais n'est pas allé très loin.


Modifier: Après avoir vu de (absolument incroyable) de blabb réponse, je l'ai essayé d'effectuer les mêmes étapes WinDbg pour mon core dump MS Word. Voici le résultat:

0:000> ub 762ed98a 
user32!DialogBoxIndirectParamAorW+0x1f: 
762ed972 83c801   or  eax,1 
762ed975 50    push eax 
762ed976 ff7518   push dword ptr [ebp+18h] 
762ed979 ff7514   push dword ptr [ebp+14h] 
762ed97c ff7510   push dword ptr [ebp+10h] 
762ed97f ff750c   push dword ptr [ebp+0Ch] 
762ed982 ff7508   push dword ptr [ebp+8] 
762ed985 e809000000  call user32!InternalDialogBox (762ed993) 
0:000> .frame /r 2 
02 003bc9b4 762ed98a user32!InternalDialogBox+0xe5 
eax=00000000 ebx=00037b72 ecx=00000000 edx=00000000 esi=003bc97c edi=003bc918 
eip=762eda5c esp=003bc990 ebp=003bc9b4 iopl=0   nv up ei pl zr na pe nc 
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b    efl=00000246 
user32!InternalDialogBox+0xe5: 
762eda5c 5f    pop  edi 
0:000> dc /c 1 003bc990 l8 
003bc990 00047b12 .{.. 
003bc994 00037b72 r{.. 
003bc998 00000008 .... 
003bc99c 00000000 .... 
003bc9a0 00000000 .... 
003bc9a4 00037b72 r{.. 
003bc9a8 003bcb98 ..;. 
003bc9ac 00000000 .... 

Je sais que je suis à la recherche au mauvais peu de mémoire (à savoir l'adresse que je suis de passage à courant continu est incorrect), mais je ne sais pas pourquoi. J'ai utilisé ".frame/r 2" pour aller chercher l'adresse de esp, qu'est-ce que j'ai fait de mal?

+1

Vous pouvez vous faciliter la vie en téléchargeant et en utilisant [pde] (https://onedrive.live.com/redir?resid=DAE128BD454CF957!7152&authkey=!AJeSzeiu8SQ7T4w&ithint=folder%2czip) d'Andrew Richards. Dans Windbg, chargez-le en tant que '.load \ pde.dll' et exécutez'! Dpx'. Il vous montrera entre autres toutes les chaînes qui peuvent être récupérées de la pile. –

+0

Comme vous êtes probablement déjà dans la bonne direction en ce qui concerne l'erreur, il est peut-être plus facile de télécharger 'procmon' depuis sysinternals. Démarrez-le, lancez votre code, arrêtez-le et allez dans 'tools - count occurences - column: result - count 'et filtrez les erreurs ou accédez aux valeurs refusées. –

+0

Merci Lieven. Étant donné que le bug est intermittent, je pense que procmon pourrait être difficile. Je n'étais pas au courant de pde alors je vais essayer maintenant. – Justin

Répondre

5

Le InternalDialogBox Api prend six arguments

C:\>cdb -c ".fnent user32!InternalDialogbox;q" cdb | grep Params 
Params: 0n6 (0x18 bytes) 

vous pouvez essayer déchiffrage cet appel en faisant un démontage en arrière sur l'adresse de retour sur la pile

0:000> kb 1 
# ChildEBP RetAddr Args to Child    
00 0017fad8 778be0d5 77860000 001ec4f0 00000000 USER32!InternalDialogBox 

0:000> ub @$ra 
USER32!SoftModalMessageBox+0x66d: 
778be0b8 e87c48fdff  call USER32!MessageBeep (77892939) 
778be0bd 56    push esi 
778be0be 53    push ebx 
778be0bf 6848d68b77  push offset USER32!MB_DlgProc (778bd648) 
778be0c4 ff75ac   push dword ptr [ebp-54h] 
778be0c7 ff75e4   push dword ptr [ebp-1Ch] 
778be0ca ff35d0908c77 push dword ptr [USER32!hmodUser (778c90d0)] 
778be0d0 e8a059fdff  call USER32!InternalDialogBox (77893a75) 

dans un accident vous videz pouvez remplacer l'adresse à la place de registre ou vous pouvez faire.Cadre/r {numéro d'image} pour chercher l'adresse de esp

0:000> dc /c 1 @esp l8 
0017fadc 778be0d5 ...w 
0017fae0 77860000 ...w 
0017fae4 001ec4f0 .... 
0017fae8 00000000 .... 
0017faec 778bd648 H..w 
0017faf0 0017fcd8 .... 
0017faf4 00000000 .... 
0017faf8 00000001 .... 

1) Le premier argument est hModUser une variable globale 2) Le quatrième argument est un rappel de DialogProc qui est documenté 3) 3e et 6e arguments sont NULL

le second consits argument d'un tableau de DLGTEMPLATE suivi par la structure DLGITEMTEMPLATE lire le document pour le format de ce tableau taille variable

le cinquième argument est une structure MSGBOXPARAMS

une décharge d'échantillon et déchiffrant la décharge pour le tableau de taille variable comme suit

0:000> db 1ec4f0 l f8 
001ec4f0 c5 01 c8 80 00 00 00 00-02 00 1a 01 9b 00 a7 00 ................ 
001ec500 3e 00 00 00 00 00 54 00-68 00 69 00 73 00 20 00 >.....T.h.i.s. . 
001ec510 69 00 73 00 20 00 4d 00-79 00 20 00 43 00 61 00 i.s. .M.y. .C.a. 
001ec520 70 00 74 00 69 00 6f 00-6e 00 20 00 46 00 6f 00 p.t.i.o.n. .F.o. 
001ec530 72 00 20 00 32 00 30 00-31 00 35 00 20 00 43 00 r. .2.0.1.5. .C. 
001ec540 6f 00 6d 00 6d 00 75 00-6e 00 69 00 74 00 79 00 o.m.m.u.n.i.t.y. 
001ec550 20 00 76 00 73 00 00 00-ff 7f 00 00 01 00 03 50 .v.s..........P 
001ec560 00 00 00 00 71 00 2a 00-32 00 0e 00 01 00 ff ff ....q.*.2....... 
001ec570 80 00 4f 00 4b 00 00 00-00 00 00 00 80 20 02 50 ..O.K........ .P 
001ec580 00 00 00 00 07 00 0e 00-8c 00 09 00 ff ff ff ff ................ 
001ec590 82 00 54 00 68 00 69 00-73 00 20 00 69 00 73 00 ..T.h.i.s. .i.s. 
001ec5a0 20 00 6d 00 79 00 20 00-66 00 69 00 72 00 73 00 .m.y. .f.i.r.s. 
001ec5b0 74 00 20 00 54 00 65 00-73 00 74 00 20 00 77 00 t. .T.e.s.t. .w. 
001ec5c0 69 00 74 00 68 00 20 00-32 00 30 00 31 00 35 00 i.t.h. .2.0.1.5. 
001ec5d0 20 00 63 00 6f 00 6d 00-6d 00 75 00 6e 00 69 00 .c.o.m.m.u.n.i. 
001ec5e0 74 00 79 00 00 00 00 00       t.y..... 
0:000> dt ConsoleApplication1!DLGTEMPLATE 1ec4f0 
    +0x000 style   : 0x80c801c5 
    +0x004 dwExtendedStyle : 0 
    +0x008 cdit    : 2 
    +0x00a x    : 0x11a 
    +0x00c y    : 0x9b 
    +0x00e cx    : 0xa7 
    +0x010 cy    : 0x3e 
0:000> du 1ec504 
001ec504 "" 
0:000> du 1ec506 
001ec506 "This is My Caption For 2015 Comm" 
001ec546 "unity vs" 
0:000> dt ConsoleApplication1!DLGITEMTEMPLATE 1ec55c 
    +0x000 style   : 0x50030001 
    +0x004 dwExtendedStyle : 0 
    +0x008 x    : 0x71 
    +0x00a y    : 0x2a 
    +0x00c cx    : 0x32 
    +0x00e cy    : 0xe 
    +0x010 id    : 1 
0:000> $$ 80 is a predfined button and the text is OK 
0:000> dt ConsoleApplication1!DLGITEMTEMPLATE 1ec57c 
    +0x000 style   : 0x50022080 
    +0x004 dwExtendedStyle : 0 
    +0x008 x    : 7 
    +0x00a y    : 0xe 
    +0x00c cx    : 0x8c 
    +0x00e cy    : 9 
    +0x010 id    : 0xffff 
0:000> $$ 82 is a predfined static text and the text is 
0:000> du 1ec592 
001ec592 "This is my first Test with 2015 " 
001ec5d2 "community" 

ici est un MSGBOXPARAMSW vidage

0:000> dt ConsoleApplication1!MSGBOXPARAMSW 0017fcd8 
    +0x000 cbSize   : 0x28 
    +0x004 hwndOwner  : (null) 
    +0x008 hInstance  : (null) 
    +0x00c lpszText   : 0x01172150 "This is my first Test with 2015 community" 
    +0x010 lpszCaption  : 0x011720f8 "This is My Caption For 2015 Community vs" 
    +0x014 dwStyle   : 0 
    +0x018 lpszIcon   : (null) 
    +0x01c dwContextHelpId : 0 
    +0x020 lpfnMsgBoxCallback : (null) 
    +0x024 dwLanguageId  : 0 

EDIT

a créé une décharge de taskmanager et chargé

0:000> .shell -ci "version" grep DMP 
Full memory user mini dump: C:\Users\HP\Desktop\cons.DMP 
command line: 'windbg -z cons.DMP' Debugger Process 0x17CC 
.shell: Process exited 

juste pour être sûr de réinitialiser le record du contexte

0:000> .cxr 
Resetting default scope 

le dumping stacktrace cadre 9Le d'intérêt ne sont pas en haut ici)

0:000> kb 5 
# ChildEBP RetAddr Args to Child    
00 0028f6fc 778766c9 7789382a 00000000 00000000 ntdll!KiFastSystemCallRet 
01 0028f700 7789382a 00000000 00000000 00000000 user32!NtUserWaitMessage+0xc 
02 0028f734 77893b27 00aa0350 00000000 00000000 user32!DialogBox2+0x207 
03 0028f758 778be0d5 77860000 002f63f0 00000000 user32!InternalDialogBox+0xcb 
04 0028f7fc 778be659 00000000 69d52104 69d52108 user32!SoftModalMessageBox+0x68a 

contexte local prioritaire pour le numéro de châssis d'intérêt

0:000> .frame /c /r 04 
04 0028f7fc 778be659 user32!SoftModalMessageBox+0x68a 
eax=00000001 ebx=0028f958 ecx=0028f458 edx=77ad70f4 esi=005fab18 edi=00000001 
eip=778be0d5 esp=0028f760 ebp=0028f7fc iopl=0   nv up ei pl zr na pe nc 
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000    efl=00000246 
user32!SoftModalMessageBox+0x68a: 
778be0d5 8945e8   mov  dword ptr [ebp-18h],eax ss:0023:0028f7e4=00000000 

checking esp you can use esp as it is instead of groping for address 

0:000> dc /c 1 @esp l 8 
0028f760 77860000 ...w 
0028f764 002f63f0 .c/. 
0028f768 00000000 .... 
0028f76c 778bd648 H..w 
0028f770 0028f958 X.(. 
0028f774 00000000 .... 
0028f778 00000001 .... 
0028f77c 0028f958 X.(. 

le dumping DLGTEMPLATE deuxième arg

0:000> db 2f63f0 lf8 
002f63f0 c5 01 c8 80 00 00 00 00-02 00 1a 01 9b 00 a7 00 ................ 
002f6400 3e 00 00 00 00 00 54 00-68 00 69 00 73 00 20 00 >.....T.h.i.s. . 
002f6410 69 00 73 00 20 00 4d 00-79 00 20 00 43 00 61 00 i.s. .M.y. .C.a. 
002f6420 70 00 74 00 69 00 6f 00-6e 00 20 00 46 00 6f 00 p.t.i.o.n. .F.o. 
002f6430 72 00 20 00 32 00 30 00-31 00 35 00 20 00 43 00 r. .2.0.1.5. .C. 
002f6440 6f 00 6d 00 6d 00 75 00-6e 00 69 00 74 00 79 00 o.m.m.u.n.i.t.y. 
002f6450 20 00 76 00 73 00 00 00-ff 7f 00 00 01 00 03 50 .v.s..........P 
002f6460 00 00 00 00 71 00 2a 00-32 00 0e 00 01 00 ff ff ....q.*.2....... 
002f6470 80 00 4f 00 4b 00 00 00-00 00 00 00 80 20 02 50 ..O.K........ .P 
002f6480 00 00 00 00 07 00 0e 00-8c 00 09 00 ff ff ff ff ................ 
002f6490 82 00 54 00 68 00 69 00-73 00 20 00 69 00 73 00 ..T.h.i.s. .i.s. 
002f64a0 20 00 6d 00 79 00 20 00-66 00 69 00 72 00 73 00 .m.y. .f.i.r.s. 
002f64b0 74 00 20 00 54 00 65 00-73 00 74 00 20 00 77 00 t. .T.e.s.t. .w. 
002f64c0 69 00 74 00 68 00 20 00-32 00 30 00 31 00 35 00 i.t.h. .2.0.1.5. 
002f64d0 20 00 63 00 6f 00 6d 00-6d 00 75 00 6e 00 69 00 .c.o.m.m.u.n.i. 
002f64e0 74 00 79 00 00 00 00 00       t.y..... 

typeinfo (dont vous avez besoin pdb privé approprié ou pirater charger un binaire qui vous compilez dans l'espace d'adressage ou d'ajouter la struct DLGTEMPLATE dans le pdb officiel user32 de ms (i Je pensais que j'avais un post expliquant cela en soi, mais je ne peux pas sembler trouver) lien malade plus tard si je le trouve ou google sitesearch pour savoir comment ajouter typeinfo à pdb dans le site: woodmann.com

0:000> dt cons!DLGTEMPLATE poi(@esp+4) 
    +0x000 style   : 0x80c801c5 
    +0x004 dwExtendedStyle : 0 
    +0x008 cdit    : 2 
    +0x00a x    : 0n282 
    +0x00c y    : 0n155 
    +0x00e cx    : 0n167 
    +0x010 cy    : 0n62 

0:000> du poi(@esp+4)+16 
002f6406 "This is My Caption For 2015 Comm" 
002f6446 "unity vs" 

modifier 2 ceci est pour une session live en mode de vidage vous devez modifier un pdb que vous ne pouvez pas l'exécution d'utiliser les commandes

nous sommes dans une séance dbg en direct, nous pouvons utiliser les commandes étape qui arent disponible en mode dmp

0:000> .tlist -c -v 
0n3324 Msgbox.exe 
     Session: 1 User: HP-PC\HP Command Line: Msgbox.exe 

permet la recherche de quelques typeinfo nous avons besoin

0:000> dt *!*DLGTEMPLATE* 
0:000> $$ no the thype info is not available 
0:000> $$ we know ole32.dll has it 
0:000> $$ so lets hack load it 

allouer de la mémoire

0:000> .dvalloc 1000 
Allocated 1000 bytes starting at 00020000 
save the current eip 

0:000> ? @eip 
Evaluate expression: 2008221094 = 77b305a6 

intégrer la chaîne de modulename à une certaine adresse dans la mémoire allouée

0:000> ea 20100 "ole32.dll" 
0:000> db 20100 l20 
00020100 6f 6c 65 33 32 2e 64 6c-6c 00 00 00 00 00 00 00 ole32.dll....... 
00020110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 

assembler une ligne d'appel LoadLibraryA

0:000> a 20000 
00020000 push 20100 
push 20100 
00020005 call kernel32!LoadLibraryA 
call kernel32!LoadLibraryA 
0002000a 

changement eip à l'adresse de déviation

0:000> r eip = 20000 

single step to load a dll into the address space 


0:000> p 
eax=00000000 ebx=00000000 ecx=0026f80c edx=77ad70f4 esi=fffffffe edi=00000000 
eip=00020005 esp=0026f824 ebp=0026f854 iopl=0   nv up ei pl zr na pe nc 
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000    efl=00000246 
00020005 e852395877  call kernel32!LoadLibraryA (775a395c) 
0:000> p 
ModLoad: 77930000 77a8c000 C:\Windows\system32\ole32.dll 
ModLoad: 75ee0000 75f81000 C:\Windows\system32\RPCRT4.dll 
ModLoad: 77530000 7754f000 C:\Windows\system32\IMM32.DLL 
ModLoad: 76030000 760fc000 C:\Windows\system32\MSCTF.dll 
eax=77930000 ebx=00000000 ecx=77ae6570 edx=002b0174 esi=fffffffe edi=00000000 
eip=0002000a esp=0026f828 ebp=0026f854 iopl=0   nv up ei pl zr na pe nc 
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000    efl=00000246 
0002000a 0000   add  byte ptr [eax],al   ds:0023:77930000=4d 

reset eip

0:000> r eip = 77b305a6 

nous recherchons le typeinfo et le bingo nous l'avons

0:000> dt *!*DLGTEMPLATE* 
      ole32!LPDLGTEMPLATEA 
      ole32!LPDLGTEMPLATE 
      ole32!LPDLGTEMPLATEW 
      ole32!LPCDLGTEMPLATE 
      ole32!LPCDLGTEMPLATEA 
      ole32!LPCDLGTEMPLATEW 
      ole32!DLGTEMPLATE 
      ole32!DLGTEMPLATE 
+0

Tout d'abord, merci beaucoup pour tous vos efforts dans ce domaine, j'ai été absolument soufflé loin quand je lis ceci pour la première fois. J'ai tenté de terminer les mêmes étapes que vous et j'ai modifié la question pour inclure ma sortie WinDbg.Pour moi, InternalDialogBox n'est pas au sommet de la pile des appels, alors j'ai essayé d'obtenir l'adresse ESP correcte en utilisant .frame/r, comme vous l'avez suggéré. Mais malheureusement, la sortie de DC ne me donne pas les arguments à InternalDialogBox. Y a-t-il une chance que tu saches ce que je fais de mal de mon montage? – Justin

+0

cela dépend j'ai ajouté quelques informations en créant un vidage d'un processus en cours dans le gestionnaire de tâches et l'annotant voir si cela aide (je ne peux pas sembler corelater votre ancienne adresse de vidage avec la dernière édition (aslr ne s'applique pas au dump iirc mais l'adresse varie dans vos messages est que la même décharge ou un vidage differnent) – blabb

+0

Désolé, j'ai basculé vidages. :) Je vais voir si je peux trouver l'original et mettre à jour la question. – Justin