2010-03-13 4 views
1

J'ai une application Winodws Mobile 6.1 exécutée sur un processeur ARMV4I. Étant donné une adresse de pile (à partir d'une exception), j'aime déterminer quel module possède cette adresse.Recherche de modules par adresse de pile

Utilisation du ToolHelpAPI, je suis en mesure de déterminer la plupart des modules en utilisant la méthode suivante:

HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_GETALLMODS, 0); 
if(INVALID_HANDLE_VALUE != snapshot) 
{ 
    MODULEENTRY32 mod = { 0 }; 
    mod.dwSize = sizeof(mod); 
    if(::Module32First(snapshot, &mod)) 
    { 
     do { 
      if(stack_address > (DWORD)mod.modBaseAddr && 
       stack_address < (DWORD)(mod.modBaseAddr + mod.modBaseSize)) 
      { 
       // Found the module! 
       // offset = stack_address - mod.modBaseAddr 
       break; 
      } 
     } while(::Module32Next(snapshot, &mod)); 
    } 
    ::CloseToolhelp32Snapshot(snapshot); 
} 

// if it's still not found 

snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPNOHEAPS, 0); 
if(INVALID_HANDLE_VALUE != snapshot) 
{ 
    PROCESSENTRY32 proc = { 0 }; 
    proc.dwSize = sizeof(proc); 
    if(::Process32First(snapshot, &proc)) 
    { 
     do 
     { 
      if(stack_address > proc.th32MemoryBase && 
       stack_address < (proc.th32MemoryBase + 0x2000000)) 
      { 
       // Found the executable 
       // offset = stack_address - proc.th32MemoryBase 
       break; 
      } 

     } while(::Process32Next(snapshot, &proc)); 
    } 
    ::CloseToolhelp32Snapshot(snapshot); 
} 

Mais, je ne semble pas toujours être en mesure de trouver un module qui correspond à une adresse. Par exemple:

stack address  module  offset 
0x03f65bd8  coredll.dll + 0x0001bbd8 
0x785cab1c  mylib.dll + 0x0002ab1c 
0x785ca9e8  mylib.dll + 0x0002a9e8 
0x785ca0a0  mylib.dll + 0x0002a0a0 
0x785c8144  mylib.dll + 0x00028144 
0x3001d95c   my.exe + 0x0001d95c 
0x3001dd44   my.exe + 0x0001dd44 
0x3001db90   my.exe + 0x0001db90 
0x03f88030  coredll.dll + 0x0003e030 
0x03f8e46c  coredll.dll + 0x0004446c 
0x801087c4    ???  
0x801367b4    ???  
0x8010ce78    ???  
0x801086dc    ???  
0x03f8e588  coredll.dll + 0x00044588 
0x785a56a4  mylib.dll + 0x000056a4 
0x785bdd60  mylib.dll + 0x0001dd60 
0x785bbd0c  mylib.dll + 0x0001bd0c 
0x785bdb38  mylib.dll + 0x0001db38 
0x3001db20   my.exe + 0x0001db20 
0x3001dc40   my.exe + 0x0001dc40 
0x3001a8a4   my.exe + 0x0001a8a4 
0x3001a79c   my.exe + 0x0001a79c 
0x03f67348  coredll.dll + 0x0001d348 

Où puis-je trouver les adresses de pile manquantes? Aucune suggestion?

Merci, PaulH

Edit: En prenant @ suggestion de SoapBox, j'ai rempli dans certaines des lacunes avec "my.exe"

+1

Cette fonction renvoie-t-elle tous les modules attendus? Peut-être son manque quelque chose d'important (comme votre programme principal, ou kernel32, ou quelque chose) ... Aussi ne devrait pas vos comparaisons d'adresses être <=/> = au lieu de? – SoapBox

+0

@SoapBox - Intéressant. Non, ça ne l'est pas. 1 article est manquant. Mon application est une DLL qui est chargée par un fichier .exe. Ce fichier .exe est manquant dans la liste. – PaulH

+0

Il semble que d'après les adresses, il manque plusieurs bibliothèques, ce n'est probablement pas votre réponse, mais peut-être que cela représente une partie de ce qui manque. – SoapBox

Répondre

0

La pile de l'UC contient plus que les adresses de code. Les arguments de fonction sont également transmis sur la pile. Seul un débogueur sait exactement ce qu'il y a dans le cadre de la pile, il l'obtient à partir du fichier .pdb. Cela ne vous aidera pas vraiment, un programme ne peut pas déboguer lui-même. Sur Windows standard, vous utiliseriez un minidump pour faire une analyse post-mortem, aucune idée si c'est disponible sur Mobile. CA devrait etre.

+0

Voulez-vous dire que ces adresses 0x80000000 ne se réfèrent pas au code? À quelle sorte de choses pouvaient-ils se référer? – PaulH

+0

@PaulH: Données, comme je l'ai expliqué. Pourrait être des arguments flottants. –

Questions connexes