Click here to Skip to main content
15,885,028 members
Articles / Desktop Programming / Win32

Analyzing a .NET Executable or DLL without .NET Installed

Rate me:
Please Sign up or sign in to vote.
4.86/5 (59 votes)
15 Feb 2013CPOL 67.6K   1.4K   68  
A pure Win32 API application that can analyze a .NET binary without .NET installed
This article describes how to add to a Win32 API, C++ application, the ability to browse for executables (.exe) files, and to determine whether they are .NET ones, and if so, to analyze their classes and display a list of them, without having .NET installed on the machine running it.
#include <windows.h>
#include "resource\resource.h"
#include <commctrl.h>
#include "PEParser.h"

// Net Analyze - by Michael Haephrati
// �2010 Michael Haephrati, haephrati@gmail.com 
//======================Handles================================================//
HINSTANCE hInst; // main function handler
#define WIN32_LEAN_AND_MEAN // this will assume smaller exe
TV_ITEM tvi, tvi2;
HTREEITEM Selected;
TV_INSERTSTRUCT tvinsert;   // struct to config out tree control
HTREEITEM Parent;           // Tree item handle
HTREEITEM Before;           // .......
HTREEITEM Root;             // .......
HIMAGELIST hImageList;      // Image list array hadle
HBITMAP hBitMap;            // bitmap handler
bool flagSelected=false;

// for drag and drop
HWND hTree;
TVHITTESTINFO tvht; 
HTREEITEM hitTarget;
POINTS Pos;
bool Dragging;

// for lable editing
HWND hEdit;
//====================MAIN DIALOG==========================================//
BOOL CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) // what are we doing ?
	{ 	 
		// This Window Message is the heart of the dialog //
		//================================================//
		case WM_INITDIALOG: 
		{
		}
		break;

		case WM_LBUTTONDOWN: 
		{
			ReleaseCapture(); 
			SendMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0); 
		}
		break;

		case WM_NOTIFY:
		{
		    case IDC_TREE1:
            
			if(((LPNMHDR)lParam)->code == NM_CLICK) // if code == NM_CLICK - Single click on an item
			{
				Selected=(HTREEITEM)SendDlgItemMessage(hWnd,IDC_TREE1,TVM_GETNEXTITEM,TVGN_CARET,(LPARAM)Selected);
				TreeView_Expand(GetDlgItem(hWnd, IDC_TREE1), Selected, TVM_EXPAND);
			}

			if(((LPNMHDR)lParam)->code == NM_RCLICK) // Right Click
			{
				Selected=(HTREEITEM)SendDlgItemMessage (hWnd,IDC_TREE1,TVM_GETNEXTITEM,TVGN_DROPHILITE,0);
				if(Selected==NULL)
				{
					MessageBox(hWnd,"No Items in TreeView","Error",MB_OK|MB_ICONINFORMATION);
					break;
				}
				
				SendDlgItemMessage(hWnd,IDC_TREE1,TVM_SELECTITEM,TVGN_CARET,(LPARAM)Selected);
				SendDlgItemMessage(hWnd,IDC_TREE1,TVM_SELECTITEM,TVGN_DROPHILITE,(LPARAM)Selected);
				TreeView_EnsureVisible(hTree,Selected);
			}

			if(((LPNMHDR)lParam)->code == TVN_BEGINDRAG)
			{
				HIMAGELIST hImg;
				LPNMTREEVIEW lpnmtv = (LPNMTREEVIEW) lParam;
				hImg=TreeView_CreateDragImage(hTree, lpnmtv->itemNew.hItem);
				ImageList_BeginDrag(hImg, 0, 0, 0);
				ImageList_DragEnter(hTree,lpnmtv->ptDrag.x,lpnmtv->ptDrag.y);
				ShowCursor(FALSE); 
				SetCapture(hWnd); 
				Dragging = TRUE;	
			}

			if(((LPNMHDR)lParam)->code == TVN_BEGINLABELEDIT)
			{
				hEdit=TreeView_GetEditControl(hTree);
			}

			if(((LPNMHDR)lParam)->code == TVN_ENDLABELEDIT)
			{
				char Text[256]="";
				tvi.hItem=Selected;
				SendDlgItemMessage(hWnd,IDC_TREE1,TVM_GETITEM,0,(WPARAM)&tvi);
				GetWindowText(hEdit, Text, sizeof(Text)); 
				tvi.pszText=Text;
				SendDlgItemMessage(hWnd,IDC_TREE1,TVM_SETITEM,0,(WPARAM)&tvi);
			}
		}
		break;

		case WM_MOUSEMOVE:
		{
			if (Dragging) 
			{ 
				Pos = MAKEPOINTS(lParam);
				ImageList_DragMove(Pos.x-32, Pos.y-25); // where to draw the drag from
				ImageList_DragShowNolock(FALSE);
				tvht.pt.x = Pos.x-20; // the highlight items should be as the same points as the drag
				tvht.pt.y = Pos.y-20; //
				if(hitTarget=(HTREEITEM)SendMessage(hTree,TVM_HITTEST,NULL,(LPARAM)&tvht)) // if there is a hit
					SendMessage(hTree,TVM_SELECTITEM,TVGN_DROPHILITE,(LPARAM)hitTarget);   // highlight it
			
			    ImageList_DragShowNolock(TRUE); 
			} 
		}
		break;

        case WM_LBUTTONUP:
        {
            if (Dragging) 
            {
                ImageList_DragLeave(hTree);
                ImageList_EndDrag();
                Selected=(HTREEITEM)SendDlgItemMessage(hWnd,IDC_TREE1,TVM_GETNEXTITEM,TVGN_DROPHILITE,0);
                SendDlgItemMessage(hWnd,IDC_TREE1,TVM_SELECTITEM,TVGN_CARET,(LPARAM)Selected);
                SendDlgItemMessage(hWnd,IDC_TREE1,TVM_SELECTITEM,TVGN_DROPHILITE,0);
                ReleaseCapture();
                ShowCursor(TRUE); 
                Dragging = FALSE;
            }
        }
        break;


		case WM_PAINT: // constantly painting the window
		{
			return 0;
		}
		break;
		
		case WM_COMMAND: // Controling the Buttons
		{
			switch (LOWORD(wParam)) // what we pressed on?
			{ 	 

				case IDC_DELETE: // Generage Button is pressed
				{
					
					OPENFILENAME ofn;
					char szFileName[MAX_PATH] = "";

					ZeroMemory(&ofn, sizeof(ofn));

					ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
					ofn.hwndOwner = hWnd;
					ofn.lpstrFilter = "Exe Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0";
					ofn.lpstrFile = szFileName;
					ofn.nMaxFile = MAX_PATH;
					ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT;
					ofn.lpstrDefExt = "exe";

					if(GetOpenFileName(&ofn))
					{
						CPEParser objPEParser;
						list<string> lString= objPEParser.GetDotNetClassName(ofn.lpstrFile);
						
						if(lString.size() == 0)
						{
							SendDlgItemMessage(hWnd,IDC_TREE1,TVM_DELETEITEM,TVGN_CARET,(LPARAM)tvi.hItem);
							MessageBox(hWnd,"It's not a .NET EXE file","Error",MB_OK|MB_ICONINFORMATION);
							break;
						}
						// Do something usefull with the filename stored in szFileName 
						InitCommonControls();	    // make our tree control to work
						hTree=GetDlgItem(hWnd,IDC_TREE1);
						
						list<string>::iterator iteStr = lString.begin();
						

						tvinsert.hParent=NULL;			// top most level no need handle
						tvinsert.hInsertAfter=TVI_ROOT; // work as root level
						tvinsert.item.mask=TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
						tvinsert.item.pszText=const_cast<char *>((*iteStr++).c_str());
						Parent=(HTREEITEM)SendDlgItemMessage(hWnd,IDC_TREE1,TVM_INSERTITEM,0,(LPARAM)&tvinsert);
						Root=Parent;
						Before=Parent;

						for(; iteStr != lString.end(); iteStr++)
						{
							tvinsert.hParent=Root;			// top most level no need handle
							tvinsert.hInsertAfter=TVI_LAST; // work as root level
							tvinsert.item.pszText=const_cast<char *>((*iteStr).append(".cs", 3).c_str());
							Parent=(HTREEITEM)SendDlgItemMessage(hWnd,IDC_TREE1,TVM_INSERTITEM,0,(LPARAM)&tvinsert);
						}
					}
				} 
				break;

			}
			break;

			case WM_CLOSE: // We colsing the Dialog
			{
				EndDialog(hWnd,0); 
			}
			break;
		}
		break;
	}
	return 0;
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	hInst=hInstance;
	DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DialogProc,0);
	return 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO Secured Globe, Inc.
United States United States
Michael Haephrati is a music composer, an inventor and an expert specializes in software development and information security, who has built a unique perspective which combines technology and the end user experience. He is the author of a the book Learning C++ , which teaches C++ 20, and was published in August 2022.

He is the CEO of Secured Globe, Inc., and also active at Stack Overflow.

Read our Corporate blog or read my Personal blog.





Comments and Discussions