2009-08-21 20 views
8

che sto debug di un'applicazione C++ Win32 e mi piacerebbe chiamare un API Win32 arbitraria dal contesto di quel processo, come se il programma era eseguito questa riga di codice:Posso chiamare un'API Win32 dalla finestra di Visual Studio Immediate?

DestroyWindow(0x00021c0e); 

Ma entrare che in la finestra immediata dà:

CXX0017: Error: symbol "DestroyWindow" not found 

Edit: utilizzando il nome completo della funzione, {,,user32.dll}[email protected], posso ottenere la finestra immediata per capire quale funzione intendo e visualizzare l'indirizzo della funzione:

{,,user32.dll}[email protected] 
0x76600454 [email protected] 

ma quando provo a chiamarlo, questo accade:

{,,user32.dll}[email protected](0x00021c0e); 
CXX0004: Error: syntax error 

E 'anche possibile chiamare una funzione C dalla finestra immediata come questo, o sono abbaiare contro l'albero sbagliato?

risposta

4

Una volta ottenuto l'indirizzo della funzione (come avete fatto per la questione aggiornato), si può provare il cast di un puntatore a funzione e chiamarlo:

(*(BOOL (*)(HWND))0x76600454)((HWND)0x00021c0e) 

La prima parte che getta l'indirizzo a BOOL (*)(HWND), che è un puntatore a una funzione che utilizza un parametro HWND e restituisce BOOL. Quindi, il puntatore della funzione è dereferenziato e chiamato. Assicurati di avere i parametri corretti, altrimenti accadranno cose brutte. Sui sistemi a 64 bit, e HWND potrebbe essere 64 bit, quindi potresti non essere in grado di farla franca passando il parametro come int.

Modifica: Vedere i commenti per la storia completa.

+1

Grazie per l'idea, ma ... Questo mi dà 'CXX0004: Errore: errore di sintassi'. Sostituire i tipi di Windows ('BOOL' e' HWND') con i tipi primitivi ('int' in entrambi i casi) migliora le cose, ma poi ottengo' CXX0014: Error: missing operando'. (Sono in un processo a 32 bit, BTW.) – RichieHindle

+1

Il debugger di VS è davvero pessimo per analizzare i tipi di puntatore di funzione, apparentemente. Prova a creare un typedef per questo. Metti 'typedef BOOL (* DESTROYWINDOW) (HWND);' nel tuo codice, quindi scrivi '(* (DESTROYWINDOW) 0x76600454) ((void *) 0x00021c0e)' nel debugger. –

+0

@Adam: Yay! (ma qualificata). Aggiungendo il tuo 'typedef' al mio codice, * e * effettivamente usando il' typedef' nel codice in modo che il compilatore non butta via la definizione, * e * interrompendo l'esecuzione del processo all'interno dell'unità di compilazione in cui ho usato il 'typedef', ora posso chiamare DestroyWindow dalla finestra immediata. Grazie! È un peccato dover saltare attraverso questi cerchi per farlo, ma almeno è possibile. – RichieHindle

2

Credo che il problema sia che il C++ EE ha problemi a risolvere il contesto di DestroyWindow. Provate il seguente

{,,user32}DestroyWindow(0x00021c0e); 

Non sono sicuro se la sintassi chiamata di metodo supporta questo stile di qualificazione (solo lo usavano per la fusione in passato). Ma vale la pena sparare.

MODIFICA Potrebbe essere necessario aggiungere o meno un! dopo la chiusura}. È passato un po 'di tempo da quando ho usato questa sintassi e spesso lo confondo con quello equivalente di windbg.

+0

Grazie per il suggerimento, ma l'ho già provato e non funziona. E ho provato a decorarlo come '_DestroyWindow @ 4' ecc., Fino al completo {{user32.dll} _DestroyWindow @ 4', senza alcuna gioia. – RichieHindle

+0

@RichieHindle, disapointing :( – JaredPar

+0

@JaredPar: +1 per aiutare a migliorare la situazione - vedi la mia domanda modificata.Posso ora capisco per capire quale funzione intendo, ma non riesco ancora a farlo chiamare – RichieHindle

1

Ho trovato una soluzione alternativa, ma preferirei comunque far funzionare la finestra immediata.

La soluzione è:

  • ottenere l'indirizzo della funzione, come indicato nella domanda
  • utilizzare la finestra di smontaggio di andare a questo indirizzo, e mettere un punto di interruzione non
  • fare qualcosa per l'applicazione per renderla chiamare DestroyWindow
  • passo indietro lo stack di chiamate al chiamante di DestroyWindow, che assomiglia a questo:

    6D096A9D spinta ECx
    6D096A9E chiamata DWORD PTR ds: [6D0BB4B8h]

  • mettere un punto di interruzione sulla istruzioni push ecx, e cancellare quello sul DestroyWindow

  • colpo Continuare, e di nuovo fare qualcosa per l'applicazione rendono chiamare quel codice
  • nota stabilisce il valore di ecx
  • variazione del valore della ecx nel debugger al valore desiderato e scavalcare il push/call
  • ripristinare il valore della ecx e utilizzare Imposta istruzione successiva per tornare alla push, quindi Continua

E 'prolisso, ma funziona. Suppone che tu possa fare in modo che l'applicazione chiami l'API appropriata a volontà.

Problemi correlati