Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

FONCTIONS IMPORTÉES/EXPORTÉES D'UN EXECUTABLE (WIN32)


Information sur la source

Catégorie :Système Niveau : Initié Date de création : 23/08/2004 Date de mise à jour : 25/08/2004 01:31:10 Vu / téléchargé: 16 018 / 704

Note :
9,75 / 10 - par 8 personnes
9,75 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (13)
Ajouter un commentaire et/ou une note


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_win32/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;
}

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

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.

Commentaires et avis

signaler à un administrateur
Commentaire de LordBob le 23/08/2004 00:53:13

rien a dire, très bon programme, et très bonne source (bien commenté !!!)... rien a dire...

signaler à un administrateur
Commentaire de BruNews le 23/08/2004 01:15:11 administrateur CS

Sobre et efficace, c'est du aardman en pleine forme.

signaler à un administrateur
Commentaire de Pamaury le 24/08/2004 19:49:33

ton prog est très bien mais en le testant je suis tombé sur un problème: sur un exe(et un seul) qui est celui de milkshape 3D, il m'affiche l'adresse mais pas les noms et quand il les affiche c'est du charabia . Peux-tu me dire pourquoi ?

signaler à un administrateur
Commentaire de aardman le 24/08/2004 21:56:11

Salut,
Oula en effet, je viens de telecharger le logiciel et d'essayer et le résultat est pas joli joli.
Je vais essayer de corriger cela.
Et encore merci pour les commentaires..

signaler à un administrateur
Commentaire de Pamaury le 24/08/2004 22:14:46

je sais pas si çà peut t'aider mais je crois bien(en fouillant dans l'exe) que certain champs ont été volontairement modifiés car par exemple, dans l'exe la partie ressource doit être préfixé de ".rsrc" or là elle ne l'ai pas . Je pense que cet exe doit être crypté ou il a été crée ainsi volontairement pour décourager les gens qui voudrais lire les info dessus .

signaler à un administrateur
Commentaire de aardman le 24/08/2004 22:50:51

Salut,
depends.exe (que tu peux facilement trouver sur google) lis très bien les infos de cet exe.

signaler à un administrateur
Commentaire de aardman le 25/08/2004 01:33:21

Salut,
C'est corrigé, les noms des fonctions importées s'affichent, mais pas les addresses.
D'ailleur depends.exe aussi n'affiche pas les addresses.

signaler à un administrateur
Commentaire de Pamaury le 25/08/2004 08:11:47

quel était le problème ?

signaler à un administrateur
Commentaire de cosmobob le 26/08/2004 16:06:35

super de chez super cette source ! en+ c'est bien commenté, et c'est donc compréhensible par tout ceux qui connaissent un peu le format PE.

a+ ;)

signaler à un administrateur
Commentaire de korrox le 16/10/2004 21:21:43

Tres bonne source tant qu'au niveau programmation qu'au niveau informations.

signaler à un administrateur
Commentaire de hakim0 le 16/08/2007 14:57:33

bonne source, est documentation aussi,
Merci

signaler à un administrateur
Commentaire de mayadoz le 08/02/2009 09:45:20

slt tres bon programme c'est ce que je cherche (mais mon but et de l'obtenir en java)l'essentiel
dis moi svp a ce que on peut faire un lien entre ce programme c a d les noms des fonctions importées et un autre code en java qui fait des testes sur ces noms  des fonctions importées pare exemple appler ce programme ecrit en c par des instruction java

signaler à un administrateur
Commentaire de mayadoz le 09/02/2009 17:50:34

slt tous
tres beau programme felicitation
c'est ce que je cherche mais en java l'essentiel ils me ditent prend ce meme programme et faire l'appeler en java par d'autre instruction
mais moi j'ai besoin de recuperer dans un fichier seulement les noms des fonctions importées  bien sur en" c" comme votre programme le faire d'ailleur puis appler l'executable par des instruction java
svp est que vous pouvez m'aider un petit peu pour recuperer seulement les noms des fonction importées et seulement pour les executables en c
puisq je suis null en c
merci d'avence et excuse moi..

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,390 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.