Monday, September 19, 2005

Compiling Snort on Windows

Many of you have undoubtedly read the snort-users thread where some people complain about not having Snort in compiled form as soon as Sourcefire releases Snort in source code form. Sourcefire released Snort 2.4.1, a vulnerability bug fix, on Friday. They only released an updated snort-2.4.1.tar.gz archive. There were no Linux RPMs or Win32 installation packages.

I decided to learn what was involved with compiling Snort on Windows. Right now I will say I did not finish the job. I am not a Windows programmer. I do not use Windows as a software development platform. Today was the first day I used the tools I describe below. The purpose of this post is to demonstrate that compiling Snort on Windows is not rocket science.

First, notice the snort-2.4.1.tar.gz archive has a src\win32 directory with these contents:

Makefile.in
WIN32-Code
WIN32-Includes
WIN32-Prj
WIN32-Libraries
Makefile.am

This looks promising. Let's see the contents of the WIN32-Prj directory.

snort_installer.nsi
build_releases.bat
snort_installer_options.ini
snort.dsw
snort.dsp
pcre.dll
LibnetNT.dll
snort.mak
snort.dep

snort.dsp is a Visual C++ project file. I don't have Visual C++ on my Windows 2000 laptop. A visit to MSDN shows Visual C++ Express Edition Beta 2 is free for download. I retrieve and install the program. After agreeing to convert Sourcefire's Visual C++ 6 files into a newer format, I am ready to try to "Build" Snort.

Along the way I read an error about a missing executable called mc. David Bianco in #snort-gui hypothesizes that mc means message compiler, a program available in the Windows® Server 2003 SP1 Platform SDK. Since the SDK works fine on Windows 2000, I install it. I also edit my system's environment variables so Windows knows where to find mc.exe in the future.

Once Visual Studio knows how to find mc.exe, it begins complaining about finding header files found in the C:\Program Files\Microsoft Platform SDK\Include directory like winsock2.h. Remember, I have never used Visual Studio before, and I have read no documentation. I figure the easiest way forward is to just copy the contents of the C:\Program Files\Microsoft Platform SDK\Include directory into the src\win32\WIN32-Includes directory. That problem is solved.

My next hurdle involves providing Snort with the WinPcap headers it needs. I retrieve WinPcap 3.0 in source code format since my test system uses WinPcap 3.0. Should I get Snort to compile I figure it should have the same version of WinPcap as installed on the laptop. I use the same *.h file copy trick to copy the contents of \winpcap\wpcap\libpcap\Win32\Include to src\win32\WIN32-Includes. I do the same for \winpcap\wpcap\libpcap\ .h files.

At this point I run into a problem caused by the Visual Studio project's insistence on building a version of Snort with database support. I figure the easiest once to build is a "release" version for MySQL (as opposed to a "debug" version).

During the build I see an error about mysql_time.h not being found. I download the Windows source for MySQL 4.0.26 only to find mysql_time.h is not in the mysql-4.0.26\include directory. I then download 5.0.12-BETA and see mysql-5.0.12-beta\include has mysql_time.h, just as I needed.

After taking care of relating library file locations, I had everything I needed to progress to the linking stage. Unfortunately, this was where my build process ended with the following errors:

Linking...
util.obj : error LNK2019: unresolved external symbol __imp__DeregisterEventSource@4 referenced in function _CreateApplicationEventLogEntry
syslog.obj : error LNK2001: unresolved external symbol __imp__DeregisterEventSource@4
util.obj : error LNK2019: unresolved external symbol __imp__ReportEventA@36 referenced in function _CreateApplicationEventLogEntry
syslog.obj : error LNK2001: unresolved external symbol __imp__ReportEventA@36
util.obj : error LNK2019: unresolved external symbol __imp__RegisterEventSourceA@8 referenced in function _CreateApplicationEventLogEntry
syslog.obj : error LNK2001: unresolved external symbol __imp__RegisterEventSourceA@8
misc.obj : error LNK2019: unresolved external symbol __imp__IsTextUnicode@12 referenced in function _print_interface
syslog.obj : error LNK2019: unresolved external symbol __imp__RegCloseKey@4 referenced in function _AddEventSource
win32_service.obj : error LNK2001: unresolved external symbol __imp__RegCloseKey@4
mysqlclient.lib(my_init.obj) : error LNK2001: unresolved external symbol __imp__RegCloseKey@4
syslog.obj : error LNK2019: unresolved external symbol __imp__RegSetValueExA@24 referenced in function _AddEventSource
win32_service.obj : error LNK2001: unresolved external symbol __imp__RegSetValueExA@24
syslog.obj : error LNK2019: unresolved external symbol __imp__RegCreateKeyA@12 referenced in function _AddEventSource
win32_service.obj : error LNK2019: unresolved external symbol __imp__RegQueryValueExA@24 referenced in function _ReadServiceCommandLineParams
win32_service.obj : error LNK2019: unresolved external symbol __imp__RegOpenKeyExA@20 referenced in function _ReadServiceCommandLineParams
mysqlclient.lib(my_init.obj) : error LNK2001: unresolved external symbol __imp__RegOpenKeyExA@20
win32_service.obj : error LNK2019: unresolved external symbol __imp__SetServiceStatus@8 referenced in function _SnortServiceCtrlHandler@4
win32_service.obj : error LNK2019: unresolved external symbol __imp__CloseServiceHandle@4 referenced in function _InstallSnortService
win32_service.obj : error LNK2019: unresolved external symbol __imp__CreateServiceA@52 referenced in function _InstallSnortService
win32_service.obj : error LNK2019: unresolved external symbol __imp__OpenSCManagerA@12 referenced in function _InstallSnortService
win32_service.obj : error LNK2019: unresolved external symbol __imp__RegCreateKeyExA@36 referenced in function _InstallSnortService
win32_service.obj : error LNK2019: unresolved external symbol __imp__DeleteService@4 referenced in function _UninstallSnortService
win32_service.obj : error LNK2019: unresolved external symbol __imp__OpenServiceA@12 referenced in function _UninstallSnortService
win32_service.obj : error LNK2019: unresolved external symbol __imp__RegDeleteKeyA@8 referenced in function _UninstallSnortService
win32_service.obj : error LNK2019: unresolved external symbol __imp__RegisterServiceCtrlHandlerA@8 referenced in function _SnortServiceStart@8
win32_service.obj : error LNK2019: unresolved external symbol __imp__StartServiceCtrlDispatcherA@4 referenced in function _SnortServiceMain
mysqlclient.lib(my_init.obj) : error LNK2019: unresolved external symbol __imp__RegEnumValueA@32 referenced in function _my_win_init
.\snort___Win32_MySQL_Release/snort.exe : fatal error LNK1120: 20 unresolved externals

I do not know how to fix these unresolved external symbols. Does anyone have any ideas?

At this point, I do not think I've done too badly for someone with zero Windows development experience!

8 comments:

Anonymous said...

Don't know if this will help but it might help checking to see how you are compiling the app. From the provided link it seems that there is a difference between compiling a windows application and a console application which can create those LNK2019 errors.

http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=90517

HTH,
Bill

Anonymous said...

Doh, I meant LNK2001! But I did a quick google on LNK2019 and spotted a couple of threads where it's the same issue. Are you compiling as console or windows app?

Bill

yawl said...

It is very likely that Visual C++ Express Edition Beta 2 enables /clr option by default. Since neither snort nor mysql use .NET, you should turn it off(modify Project property), so they are compiled as "plain old" C/C++.

John Ward said...

If you are only copying the Include directories, you are only copying the headers and may be missing some implementation files, although usually the headers for SDKs will just point to an object file or DLL. I would look in one of the header files you copied for some of the functions like RegQueryValueExA to see how they were declared.

You may also be running into some incompatibility for the complier version differences. You are compiling the source with a version of C++ that is based on a completely different platform than the one Snort was developed on. The C++ Express beta that Microsoft has release is a .Net 2.0 based compiler, where as VC 6 is based on the older COM model. While the newer version is supposed to be backwards compatible, there may be issues since Microsoft kind of uses a kludge for handling older COM and API calls using .Net. There may also be compiler options you may need to set in order to turn on “legacy” compiling. Yawl recommended turning off CLR. To find that, go under “Solution Explorer”, then under the Project name (you will see a icon called “solution “name””, it will be the icon under the first branch of that entitled “name”, where name is the title of your project), right click and go to properties. Under “C/C++”, select the General group and changed the option for “Compiled as Managed” to “Not using Managed Extensions”. This will turn off the CLR option.

Your best bet, if you do happen to have a copy of Visual C++ 6 laying around somewhere, is to compile from it and eliminate the Beta .Net compiler from the equation altogether. Also check some of the README files, the build environment may need to be very specific, with certain ENVIRONMENT variables, Registry values and object files in particular locations needed for compiling.

Richard Bejtlich said...

John,

How about you exercise some of your Windows programming-fu and compile Snort, then post how you did it on your blog? :)

John Ward said...

Is that a challenge from my former teacher? "The circle is now complete. When I left you I was but the learner. Now I am the master" :) Sorry couldn't resist.

I'm finishing up and proof reading the text now and adding the screen shots. I will have it posted tommorrow.

Richard Bejtlich said...

Only a master of Windows, John! :)

Anonymous said...

Hello Richard

> util.obj : error LNK2019: unresolved external symbol __imp__DeregisterEventSource@4

Simply add proper windows library files to project.
Project - properties - linker - additional dependicies.
advapi32.lib - for this function ( DeregisterEventSource )

And, of course add sdk libray directory to linker general properties.

Greetings from .pl