Accueil > > > FONCTIONS IMPORTÉES/EXPORTÉES D'UN EXECUTABLE (WIN32)
FONCTIONS IMPORTÉES/EXPORTÉES D'UN EXECUTABLE (WIN32)
Information sur la source
Description
Voici un petit programme qui permet de voir les fonctions importées et exportées d'un executable. Pour chaque fonction on ajoute un item dans un treeview, le texte de l'item contient le nom de la fonction plus d'autres infos, comme l'addresse virtuelle relative de la fonction par raport a l'addresse basse du module ou son Ordinal. Un item d'une fonction importée est présenté sous cette forme (exemple): 053 0x000261e8 NtReadFile - 053 est un nombre décimal qui sert juste a compter le nombre de fonction importées par la dll, - 0x000261e8 est l'addresse virtuelle relative de la fonction (hexadecimal), - NtReadFile est le nom public de la fonction. Un item d'une fonction exportée est présenté sous l'une des deux formes suivantes: - Si la fonction est exportée (exemple): 023 0x00003c22 socket - 023 est l'Ordinal de la fonction (décimal), - 0x00003c22 est l'addresse virtuelle relative de la fonction, - socket est le nom public de la fonction exportée. - Si la fonction est forwardée (exemple): 508 HeapAlloc ---> NTDLL.RtlAllocateHeap - 508 est l'Ordinal de la fonction exportée, - HeapAlloc est le nom de la fonction, - NTDLL.RtlAllocateHeap est le nom de la fonction et de sa dll vers laquelle HeapAlloc est forwardée. Un lien avec la doc de MS sur le format PE: http://betouchi.free.fr/doc_et_ebook/prog_win3 2/pe_coff_file_format.doc
Source
- #define _WIN32_WINNT 0x0500
- #include <windows.h>
- #include <commctrl.h>
- #include <commdlg.h>
- #include "resource.h"
- #pragma comment(lib, "comctl32.lib")
- #pragma comment(lib, "comdlg32.lib")
-
-
- HWND hMain, hTree, hPath;
- char szImagePath[260], szCurrentDirectory[260];
- char szMsgError[64] = "Erreur: ";
-
-
- //------------------------------------------------------------------------------------------
- // DisplayError: affiche un message d'erreur dans une messagebox
- //------------------------------------------------------------------------------------------
- int DisplayError(char * pszText, DWORD dwError)
- {
- ultoa(dwError, szMsgError + 8, 10);
- MessageBox(hMain, pszText, szMsgError, MB_ICONERROR);
- return 1;
- }
-
-
- //------------------------------------------------------------------------------------------
- // DisplayImportExport: affiche dans le treeview les fonctions importées/exportées de
- // l'executable szImagePath
- //------------------------------------------------------------------------------------------
- int DisplayImportExport(void)
- {
- char buffer[512], *b;
- TVITEMEX tvitem; // structure utilisée pour modifier des items
- TVINSERTSTRUCT tvi; // structure utilisée pour ajouter des items
- HTREEITEM hImportItem, hExportItem; // handle des 2 items a la racine du treeview
- HTREEITEM hFunctionItem, hForwardItem; // handle des 2 child items de l'item hExportItem
-
- // on charge le fichier
- BYTE *pBase = (BYTE*) LoadLibraryEx(szImagePath, 0, DONT_RESOLVE_DLL_REFERENCES);
- if(!pBase)
- {
- DisplayError("Erreur lors du chargement du module.", GetLastError());
- return 0;
- }
-
- // trouve et verifie la signature du fichier
- IMAGE_NT_HEADERS32 *pNTHeader = (IMAGE_NT_HEADERS32*)(pBase + ((IMAGE_DOS_HEADER*)pBase)->e_lfanew);
- if(pNTHeader->Signature != IMAGE_NT_SIGNATURE)
- {
- DisplayError("Signature PE invalide.", GetLastError());
- FreeLibrary((HMODULE)pBase);
- return 0;
- }
-
- // trouve les addresses des header COFF file et Optionnal/PE
- IMAGE_FILE_HEADER *pFileHeader = (IMAGE_FILE_HEADER*) &pNTHeader->FileHeader;
- IMAGE_OPTIONAL_HEADER32 *pPEHeader = (IMAGE_OPTIONAL_HEADER32*) &pNTHeader->OptionalHeader;
-
- // on trouve les RVA de l'Import Directory Table et de l'Export Directory Table
- // ainsi que leurs addresses virtuelles & leurs tailles
- IMAGE_IMPORT_DESCRIPTOR *pImportDirectoryTable = (IMAGE_IMPORT_DESCRIPTOR*)(pBase + pPEHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
- DWORD dwImportDirectorySize = (DWORD) pPEHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
- DWORD dwExportRVA = pPEHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
- IMAGE_EXPORT_DIRECTORY *pExportDirectoryTable = (IMAGE_EXPORT_DIRECTORY*)(pBase + dwExportRVA);
- DWORD dwExportDirectorySize = (DWORD) pPEHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
- DWORD dwExportEndRVA = dwExportRVA + dwExportDirectorySize;
-
- // vide le treeview et desactive le redraw
- SendMessage(hTree, TVM_DELETEITEM, 0, 0);
- SendMessage(hTree, WM_SETREDRAW, 0, 0);
-
- // ajout des deux items a la racine du treeview
- buffer[0] = 0;
- tvi.hParent = 0;
- tvi.hInsertAfter = TVI_ROOT;
- tvi.item.mask = TVIF_TEXT;
- tvi.item.pszText = buffer;
- hImportItem = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
- hExportItem = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
-
- // ajoute les items enfants de l'item hImport
- DWORD dwTotalCount = 0;
- if(dwImportDirectorySize)
- {
- // une itération par dll qui contient des fonctions importées
- for(; pImportDirectoryTable->Name; pImportDirectoryTable++)
- {
- // ajoute un item enfant a hImport, contenant le nom d'une dll
- tvi.hParent = hImportItem;
- tvi.hInsertAfter = TVI_SORT;
- tvi.item.pszText = (char*)(pBase + pImportDirectoryTable->Name);
- tvi.hParent = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
-
- // addresse base du module courant
- HMODULE hModDLL = GetModuleHandle(tvi.item.pszText);
- tvi.item.pszText = buffer;
-
- // CORRECTION BUG: certains linker mettent OriginalFirstThunk à zéro, et ne produisent pas
- // d'Import Lookup Table les noms/ordinaux des fonctions se trouvent donc dans le tableau
- // pointé par FirstThunk, et il n'est pas possible d'obtenir l'adresse des fonctions importées
- if(!pImportDirectoryTable->OriginalFirstThunk) // bug du linker
- {
- IMAGE_THUNK_DATA32 *pImportLookup = (IMAGE_THUNK_DATA32*)(pBase + pImportDirectoryTable->FirstThunk);
- for(DWORD i=0; pImportLookup->u1.Function; pImportLookup++, i++, dwTotalCount++)
- {
- if(pImportLookup->u1.Function & 0x80000000)
- {
- wsprintf(buffer, "%03u Import par Ordinal: 0x%08x", i, pImportLookup->u1.Ordinal & 0x7FFFFFFF);
- }
- else
- {
- wsprintf(buffer, "%03u <not bound> %s", i, pBase + pImportLookup->u1.AddressOfData+2);
- }
-
- // on ajoute l'item
- SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
- }
- }
- else
- {
- // trouve les addresses de l'Import Lookup Table (nom des fonctions) et de l'Import
- // Address Table (addresse des fonctions importées)
- IMAGE_THUNK_DATA32 *pImportLookup = (IMAGE_THUNK_DATA32*)(pBase + pImportDirectoryTable->OriginalFirstThunk);
- IMAGE_THUNK_DATA32 *pImportAddress = (IMAGE_THUNK_DATA32*)(pBase + pImportDirectoryTable->FirstThunk);
-
- for(DWORD i=0; pImportLookup->u1.Function; pImportLookup++, pImportAddress++, i++, dwTotalCount++)
- {
- // si le bit de poid fort de l'import lookup est a 1, la fonction est importée par
- // ordinal, sinon elle est importée par nom
- if(pImportLookup->u1.Function & 0x80000000)
- {
- wsprintf(buffer, "%03u Import par Ordinal: 0x%08x", i, pImportLookup->u1.Ordinal & 0x7FFFFFFF);
- }
- else
- {
- wsprintf(buffer, "%03u 0x%08x %s", i, pImportAddress->u1.Function - (DWORD)hModDLL, pBase + pImportLookup->u1.AddressOfData+2);
- }
-
- // on ajoute l'item
- SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
- }
- }
- }
- }
-
- // met a jour le texte de l'item "Import"
- strcpy(buffer, "Imports ["); b = buffer + 9;
- ultoa(dwTotalCount, b, 10); while(*b) b++;
- *b++ = ']'; *b = 0;
- tvitem.mask = TVIF_HANDLE | TVIF_TEXT;
- tvitem.pszText = buffer;
- tvitem.hItem = hImportItem;
- SendMessage(hTree, TVM_SETITEM, 0, (long) &tvitem);
-
- // ajoute les items enfants de l'item hExport
- dwTotalCount = 0;
- if(dwExportDirectorySize)
- {
- DWORD dwFuncsCount = 0, dwForwardsCount = 0, dwOrdinal = 0, dwFuncRVA = 0;
-
- // on trouve le nombre de symbole exportés, ainsi que les addresses de diverses choses:
- // Export Function Table: contient les RVA des fonctions,
- // Export Name Table: contient les RVA des noms des fonctions au format asciiz
- // Export Ordinal Table: index des RVA des fonctions
- DWORD dwExportNamesCount = (DWORD) pExportDirectoryTable->NumberOfNames;
- DWORD *pAddressTable = (DWORD*)(pBase + pExportDirectoryTable->AddressOfFunctions);
- DWORD *pNameTable = (DWORD*)(pBase + pExportDirectoryTable->AddressOfNames);
- WORD *pOrdinalTable = (WORD*)(pBase + pExportDirectoryTable->AddressOfNameOrdinals);
-
- // ajoute deux child item a hExport: hFunctionItem et hForwardItem
- buffer[0] = 0;
- tvi.hParent = hExportItem;
- hFunctionItem = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
- hForwardItem = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
-
- // on cherche le type du symbole (forwarder ou fonction/variable) et on ajoute un child item
- // a hFunctionItem ou hForwardItem
- for(; dwExportNamesCount; pOrdinalTable++, pNameTable++, dwExportNamesCount--)
- {
- dwOrdinal = (DWORD) *pOrdinalTable;
- dwFuncRVA = pAddressTable[dwOrdinal];
- dwOrdinal += pExportDirectoryTable->Base;
-
- // si dwFuncRVA est dans l'Export Table, c'est un forwarder, sinon c'est une fonction
- if(dwExportRVA < dwFuncRVA && dwFuncRVA < dwExportEndRVA)
- {
- dwForwardsCount++;
- wsprintf(buffer, "%03u %s ---> %s", dwOrdinal, pBase + *pNameTable, pBase + dwFuncRVA);
- tvi.hParent = hForwardItem;
- SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
- }
- else
- {
- dwFuncsCount++;
- wsprintf(buffer, "%03u 0x%08x %s", dwOrdinal, dwFuncRVA, pBase + *pNameTable);
- tvi.hParent = hFunctionItem;
- SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
- }
- }
- dwTotalCount = dwFuncsCount + dwForwardsCount;
-
- // met a jour le texte des items functions et forward
- // si l'un des items a 0 child item, on le suprime
- tvitem.hItem = hFunctionItem;
- if(dwFuncsCount)
- {
- strcpy(buffer, "Functions ["); b = buffer + 11;
- ultoa(dwFuncsCount, b, 10); while(*b) b++;
- *b++ = ']'; *b = 0;
- SendMessage(hTree, TVM_SETITEM, 0, (long) &tvitem);
- }
- else SendMessage(hTree, TVM_DELETEITEM, 0, (long) hFunctionItem);
- tvitem.hItem = hForwardItem;
- if(dwForwardsCount)
- {
- strcpy(buffer, "Forwarders ["); b = buffer + 12;
- ultoa(dwForwardsCount, b, 10); while(*b) b++;
- *b++ = ']'; *b = 0;
- SendMessage(hTree, TVM_SETITEM, 0, (long) &tvitem);
- }
- else SendMessage(hTree, TVM_DELETEITEM, 0, (long) hForwardItem);
- }
-
- // met a jour le texte de l'item "Export"
- strcpy(buffer, "Exports ["); b = buffer + 9;
- ultoa(dwTotalCount, b, 10); while(*b) b++;
- *b++ = ']'; *b = 0;
- tvitem.hItem = hExportItem;
- SendMessage(hTree, TVM_SETITEM, 0, (long) &tvitem);
-
- // ré-active le dessin du treeview et expand les deux branches principales
- SendMessage(hTree, WM_SETREDRAW, 1, 0);
- SendMessage(hTree, TVM_EXPAND, TVE_EXPAND, (long)hImportItem);
- SendMessage(hTree, TVM_EXPAND, TVE_EXPAND, (long)hExportItem);
- FreeLibrary((HMODULE)pBase);
- return 1;
- }
-
-
- //------------------------------------------------------------------------------------------
- // AskForPath: func qui ouvre la common dialog "openfilename"
- //------------------------------------------------------------------------------------------
- int AskForPath(void)
- {
- OPENFILENAME ofn;
- szImagePath[0] = 0;
- ZeroMemory(&ofn, sizeof(OPENFILENAME));
-
- ofn.lStructSize = sizeof(OPENFILENAME);
- ofn.hwndOwner = hMain;
- ofn.lpstrFile = szImagePath;
- ofn.nMaxFile = 256;
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES;
- ofn.lpstrFilter = "Executables (*.EXE, *.DLL)\0*.exe;*.dll\0";
- ofn.nFilterIndex = 1;
- ofn.lpstrInitialDir = szCurrentDirectory;
-
- // l'utilisateur n'a pas selectionné de fichier
- if(!GetOpenFileName(&ofn)) return 0;
-
- GetCurrentDirectory(260, szCurrentDirectory);
- SetWindowText(hPath, szImagePath);
- return 1;
- }
-
-
- //---------------------------------------------------------------------------------------------
- // DialogProc: callback de la fenetre principale
- //---------------------------------------------------------------------------------------------
- BOOL __stdcall DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch(uMsg)
- {
- case WM_INITDIALOG:
- hMain = hDlg;
- hPath = GetDlgItem(hDlg, IDC_PATH);
- hTree = GetDlgItem(hDlg, IDC_TREE);
- GetSystemDirectory(szCurrentDirectory, 260);
- PostMessage(hDlg, WM_COMMAND, IDOK, 0);
- return 1;
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case IDOK:
- if(AskForPath())
- DisplayImportExport();
- return 0;
- case IDCANCEL:
- EndDialog(hDlg, 0);
- }
- }
- return 0;
- }
-
-
- //---------------------------------------------------------------------------------------------
- // WinMain
- //---------------------------------------------------------------------------------------------
- int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
- {
- INITCOMMONCONTROLSEX ictrl;
- ictrl.dwSize = sizeof(INITCOMMONCONTROLSEX);
- ictrl.dwICC = ICC_TREEVIEW_CLASSES;
- InitCommonControlsEx(&ictrl);
- DialogBoxParam(hInstance, "MainDialog", 0, DialogProc, 0);
- return 0;
- }
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include "resource.h"
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "comdlg32.lib")
HWND hMain, hTree, hPath;
char szImagePath[260], szCurrentDirectory[260];
char szMsgError[64] = "Erreur: ";
//------------------------------------------------------------------------------------------
// DisplayError: affiche un message d'erreur dans une messagebox
//------------------------------------------------------------------------------------------
int DisplayError(char * pszText, DWORD dwError)
{
ultoa(dwError, szMsgError + 8, 10);
MessageBox(hMain, pszText, szMsgError, MB_ICONERROR);
return 1;
}
//------------------------------------------------------------------------------------------
// DisplayImportExport: affiche dans le treeview les fonctions importées/exportées de
// l'executable szImagePath
//------------------------------------------------------------------------------------------
int DisplayImportExport(void)
{
char buffer[512], *b;
TVITEMEX tvitem; // structure utilisée pour modifier des items
TVINSERTSTRUCT tvi; // structure utilisée pour ajouter des items
HTREEITEM hImportItem, hExportItem; // handle des 2 items a la racine du treeview
HTREEITEM hFunctionItem, hForwardItem; // handle des 2 child items de l'item hExportItem
// on charge le fichier
BYTE *pBase = (BYTE*) LoadLibraryEx(szImagePath, 0, DONT_RESOLVE_DLL_REFERENCES);
if(!pBase)
{
DisplayError("Erreur lors du chargement du module.", GetLastError());
return 0;
}
// trouve et verifie la signature du fichier
IMAGE_NT_HEADERS32 *pNTHeader = (IMAGE_NT_HEADERS32*)(pBase + ((IMAGE_DOS_HEADER*)pBase)->e_lfanew);
if(pNTHeader->Signature != IMAGE_NT_SIGNATURE)
{
DisplayError("Signature PE invalide.", GetLastError());
FreeLibrary((HMODULE)pBase);
return 0;
}
// trouve les addresses des header COFF file et Optionnal/PE
IMAGE_FILE_HEADER *pFileHeader = (IMAGE_FILE_HEADER*) &pNTHeader->FileHeader;
IMAGE_OPTIONAL_HEADER32 *pPEHeader = (IMAGE_OPTIONAL_HEADER32*) &pNTHeader->OptionalHeader;
// on trouve les RVA de l'Import Directory Table et de l'Export Directory Table
// ainsi que leurs addresses virtuelles & leurs tailles
IMAGE_IMPORT_DESCRIPTOR *pImportDirectoryTable = (IMAGE_IMPORT_DESCRIPTOR*)(pBase + pPEHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
DWORD dwImportDirectorySize = (DWORD) pPEHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
DWORD dwExportRVA = pPEHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
IMAGE_EXPORT_DIRECTORY *pExportDirectoryTable = (IMAGE_EXPORT_DIRECTORY*)(pBase + dwExportRVA);
DWORD dwExportDirectorySize = (DWORD) pPEHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
DWORD dwExportEndRVA = dwExportRVA + dwExportDirectorySize;
// vide le treeview et desactive le redraw
SendMessage(hTree, TVM_DELETEITEM, 0, 0);
SendMessage(hTree, WM_SETREDRAW, 0, 0);
// ajout des deux items a la racine du treeview
buffer[0] = 0;
tvi.hParent = 0;
tvi.hInsertAfter = TVI_ROOT;
tvi.item.mask = TVIF_TEXT;
tvi.item.pszText = buffer;
hImportItem = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
hExportItem = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
// ajoute les items enfants de l'item hImport
DWORD dwTotalCount = 0;
if(dwImportDirectorySize)
{
// une itération par dll qui contient des fonctions importées
for(; pImportDirectoryTable->Name; pImportDirectoryTable++)
{
// ajoute un item enfant a hImport, contenant le nom d'une dll
tvi.hParent = hImportItem;
tvi.hInsertAfter = TVI_SORT;
tvi.item.pszText = (char*)(pBase + pImportDirectoryTable->Name);
tvi.hParent = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
// addresse base du module courant
HMODULE hModDLL = GetModuleHandle(tvi.item.pszText);
tvi.item.pszText = buffer;
// CORRECTION BUG: certains linker mettent OriginalFirstThunk à zéro, et ne produisent pas
// d'Import Lookup Table les noms/ordinaux des fonctions se trouvent donc dans le tableau
// pointé par FirstThunk, et il n'est pas possible d'obtenir l'adresse des fonctions importées
if(!pImportDirectoryTable->OriginalFirstThunk) // bug du linker
{
IMAGE_THUNK_DATA32 *pImportLookup = (IMAGE_THUNK_DATA32*)(pBase + pImportDirectoryTable->FirstThunk);
for(DWORD i=0; pImportLookup->u1.Function; pImportLookup++, i++, dwTotalCount++)
{
if(pImportLookup->u1.Function & 0x80000000)
{
wsprintf(buffer, "%03u Import par Ordinal: 0x%08x", i, pImportLookup->u1.Ordinal & 0x7FFFFFFF);
}
else
{
wsprintf(buffer, "%03u <not bound> %s", i, pBase + pImportLookup->u1.AddressOfData+2);
}
// on ajoute l'item
SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
}
}
else
{
// trouve les addresses de l'Import Lookup Table (nom des fonctions) et de l'Import
// Address Table (addresse des fonctions importées)
IMAGE_THUNK_DATA32 *pImportLookup = (IMAGE_THUNK_DATA32*)(pBase + pImportDirectoryTable->OriginalFirstThunk);
IMAGE_THUNK_DATA32 *pImportAddress = (IMAGE_THUNK_DATA32*)(pBase + pImportDirectoryTable->FirstThunk);
for(DWORD i=0; pImportLookup->u1.Function; pImportLookup++, pImportAddress++, i++, dwTotalCount++)
{
// si le bit de poid fort de l'import lookup est a 1, la fonction est importée par
// ordinal, sinon elle est importée par nom
if(pImportLookup->u1.Function & 0x80000000)
{
wsprintf(buffer, "%03u Import par Ordinal: 0x%08x", i, pImportLookup->u1.Ordinal & 0x7FFFFFFF);
}
else
{
wsprintf(buffer, "%03u 0x%08x %s", i, pImportAddress->u1.Function - (DWORD)hModDLL, pBase + pImportLookup->u1.AddressOfData+2);
}
// on ajoute l'item
SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
}
}
}
}
// met a jour le texte de l'item "Import"
strcpy(buffer, "Imports ["); b = buffer + 9;
ultoa(dwTotalCount, b, 10); while(*b) b++;
*b++ = ']'; *b = 0;
tvitem.mask = TVIF_HANDLE | TVIF_TEXT;
tvitem.pszText = buffer;
tvitem.hItem = hImportItem;
SendMessage(hTree, TVM_SETITEM, 0, (long) &tvitem);
// ajoute les items enfants de l'item hExport
dwTotalCount = 0;
if(dwExportDirectorySize)
{
DWORD dwFuncsCount = 0, dwForwardsCount = 0, dwOrdinal = 0, dwFuncRVA = 0;
// on trouve le nombre de symbole exportés, ainsi que les addresses de diverses choses:
// Export Function Table: contient les RVA des fonctions,
// Export Name Table: contient les RVA des noms des fonctions au format asciiz
// Export Ordinal Table: index des RVA des fonctions
DWORD dwExportNamesCount = (DWORD) pExportDirectoryTable->NumberOfNames;
DWORD *pAddressTable = (DWORD*)(pBase + pExportDirectoryTable->AddressOfFunctions);
DWORD *pNameTable = (DWORD*)(pBase + pExportDirectoryTable->AddressOfNames);
WORD *pOrdinalTable = (WORD*)(pBase + pExportDirectoryTable->AddressOfNameOrdinals);
// ajoute deux child item a hExport: hFunctionItem et hForwardItem
buffer[0] = 0;
tvi.hParent = hExportItem;
hFunctionItem = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
hForwardItem = (HTREEITEM) SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
// on cherche le type du symbole (forwarder ou fonction/variable) et on ajoute un child item
// a hFunctionItem ou hForwardItem
for(; dwExportNamesCount; pOrdinalTable++, pNameTable++, dwExportNamesCount--)
{
dwOrdinal = (DWORD) *pOrdinalTable;
dwFuncRVA = pAddressTable[dwOrdinal];
dwOrdinal += pExportDirectoryTable->Base;
// si dwFuncRVA est dans l'Export Table, c'est un forwarder, sinon c'est une fonction
if(dwExportRVA < dwFuncRVA && dwFuncRVA < dwExportEndRVA)
{
dwForwardsCount++;
wsprintf(buffer, "%03u %s ---> %s", dwOrdinal, pBase + *pNameTable, pBase + dwFuncRVA);
tvi.hParent = hForwardItem;
SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
}
else
{
dwFuncsCount++;
wsprintf(buffer, "%03u 0x%08x %s", dwOrdinal, dwFuncRVA, pBase + *pNameTable);
tvi.hParent = hFunctionItem;
SendMessage(hTree, TVM_INSERTITEM, 0, (long) &tvi);
}
}
dwTotalCount = dwFuncsCount + dwForwardsCount;
// met a jour le texte des items functions et forward
// si l'un des items a 0 child item, on le suprime
tvitem.hItem = hFunctionItem;
if(dwFuncsCount)
{
strcpy(buffer, "Functions ["); b = buffer + 11;
ultoa(dwFuncsCount, b, 10); while(*b) b++;
*b++ = ']'; *b = 0;
SendMessage(hTree, TVM_SETITEM, 0, (long) &tvitem);
}
else SendMessage(hTree, TVM_DELETEITEM, 0, (long) hFunctionItem);
tvitem.hItem = hForwardItem;
if(dwForwardsCount)
{
strcpy(buffer, "Forwarders ["); b = buffer + 12;
ultoa(dwForwardsCount, b, 10); while(*b) b++;
*b++ = ']'; *b = 0;
SendMessage(hTree, TVM_SETITEM, 0, (long) &tvitem);
}
else SendMessage(hTree, TVM_DELETEITEM, 0, (long) hForwardItem);
}
// met a jour le texte de l'item "Export"
strcpy(buffer, "Exports ["); b = buffer + 9;
ultoa(dwTotalCount, b, 10); while(*b) b++;
*b++ = ']'; *b = 0;
tvitem.hItem = hExportItem;
SendMessage(hTree, TVM_SETITEM, 0, (long) &tvitem);
// ré-active le dessin du treeview et expand les deux branches principales
SendMessage(hTree, WM_SETREDRAW, 1, 0);
SendMessage(hTree, TVM_EXPAND, TVE_EXPAND, (long)hImportItem);
SendMessage(hTree, TVM_EXPAND, TVE_EXPAND, (long)hExportItem);
FreeLibrary((HMODULE)pBase);
return 1;
}
//------------------------------------------------------------------------------------------
// AskForPath: func qui ouvre la common dialog "openfilename"
//------------------------------------------------------------------------------------------
int AskForPath(void)
{
OPENFILENAME ofn;
szImagePath[0] = 0;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hMain;
ofn.lpstrFile = szImagePath;
ofn.nMaxFile = 256;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES;
ofn.lpstrFilter = "Executables (*.EXE, *.DLL)\0*.exe;*.dll\0";
ofn.nFilterIndex = 1;
ofn.lpstrInitialDir = szCurrentDirectory;
// l'utilisateur n'a pas selectionné de fichier
if(!GetOpenFileName(&ofn)) return 0;
GetCurrentDirectory(260, szCurrentDirectory);
SetWindowText(hPath, szImagePath);
return 1;
}
//---------------------------------------------------------------------------------------------
// DialogProc: callback de la fenetre principale
//---------------------------------------------------------------------------------------------
BOOL __stdcall DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
hMain = hDlg;
hPath = GetDlgItem(hDlg, IDC_PATH);
hTree = GetDlgItem(hDlg, IDC_TREE);
GetSystemDirectory(szCurrentDirectory, 260);
PostMessage(hDlg, WM_COMMAND, IDOK, 0);
return 1;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
if(AskForPath())
DisplayImportExport();
return 0;
case IDCANCEL:
EndDialog(hDlg, 0);
}
}
return 0;
}
//---------------------------------------------------------------------------------------------
// WinMain
//---------------------------------------------------------------------------------------------
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
INITCOMMONCONTROLSEX ictrl;
ictrl.dwSize = sizeof(INITCOMMONCONTROLSEX);
ictrl.dwICC = ICC_TREEVIEW_CLASSES;
InitCommonControlsEx(&ictrl);
DialogBoxParam(hInstance, "MainDialog", 0, DialogProc, 0);
return 0;
}
Historique
- 23 août 2004 00:38:45 :
- petit oubli
- 25 août 2004 01:31:11 :
- correction d'un bug dû a un autre bug de certains linkers qui ne produisent pas d'Import Lookup Table. On peut alors seulement connaitre le nom ou l'ordinal de la fonction importée mais pas son addresse.
L'explication du bug est ici:
http://win32assembly.online.fr/files/pe1.zip dans le fichier pe.txt, a la ligne 1260.
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Derniers Blogs
IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc SHAREPOINT BLOG SITE, PROBLèME D'ARCHIVESSHAREPOINT BLOG SITE, PROBLèME D'ARCHIVES par junarnoalg
Dernièrement, nous avons migré le site
myTIC
vers un nouveau serveur SharePoint 2010. Dans les contenus que nous vouloins récupérer, nous avions un certain nombre de blogs.
Nous avons utilisé les commandes Power...
Cliquez pour lire la suite de l'article par junarnoalg
Forum
MATRICE TEMPLATEMATRICE TEMPLATE par hjr2610
Cliquez pour lire la suite par hjr2610 RE : SAC A DOS RE : SAC A DOS par hadjkaddour
Cliquez pour lire la suite par hadjkaddour
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|