diff --git a/.gitignore b/.gitignore index e7c8f34b..247b688e 100644 --- a/.gitignore +++ b/.gitignore @@ -128,6 +128,8 @@ sparc_jump_to_zero ## files generated by popular Visual Studio add-ons. # User-specific files +*.opensdf +*.sdf *.suo *.user *.sln.docstates @@ -137,6 +139,7 @@ sparc_jump_to_zero [Dd]ebug/ [Rr]elease/ x64/ +Win32/ build/ [Bb]in/ [Oo]bj/ diff --git a/bindings/README b/bindings/README index d4145ea9..c3abec91 100644 --- a/bindings/README +++ b/bindings/README @@ -1,4 +1,4 @@ -This directory contains bindings & test code for Python, Java, Go and .NET. +This directory contains bindings & test code for Python, Java, Go, .NET and MSVC. See /README or /README.TXT for how to install each binding. The following bindings are contributed by community. @@ -6,6 +6,7 @@ The following bindings are contributed by community. - Java binding: by Chris Eagle. - Go binding: by Ryan Hileman. - .NET binding: by Antonio Parata. +- MSVC binding: by Zak Escano More bindings created & maintained externally by community are available as follows. diff --git a/bindings/msvc/README.TXT b/bindings/msvc/README.TXT index 7d2a9b31..29bc2508 100644 --- a/bindings/msvc/README.TXT +++ b/bindings/msvc/README.TXT @@ -1,3 +1,7 @@ + + +:: Overview + This documentation explains how to use Unicorn with Microsoft Visual C++ (MSVC). This will not build the Unicorn Engine itself, it just allows you to use the prebuilt Windows binaries when writing projects in Microsoft Visual C++. @@ -8,17 +12,19 @@ heading on the following page. Be sure to use the 32bit package when making build 64bit applications. http://www.unicorn-engine.org/download/ - - -It is not possible to use the prebuilt static Unicorn library, unicorn.lib, +It is not possible to use the prebuilt static Unicorn library "unicorn.lib" with Microsoft Visual C++ because it will complain about a bunch of missing functions, variables etc. -We therefore use the prebuilt dynamic Unicorn library, unicorn.dll. +We therefore use the prebuilt dynamic Unicorn library "unicorn.dll". There are two ways to use this with your Microsoft Visual C++ project: 1) By dynamically linking the dll into your project. 2) By statically linking the dll into your project. +There are pre-prepared sample projects that use each method, but in the event +you wish to set up your own projects there are details to do so below. + + :: 1) Dynamic Linking @@ -49,6 +55,7 @@ Now build your application as normal. + :: 2) Static Linking To perform static linking of unicorn.dll, you need to first generate some @@ -75,3 +82,106 @@ Or by adding "unicorn_staload.lib" to your project in: Configuration Properties -> C/C++ -> Linker -> Input -> Additional Dependencies + + +:: Notes about Visual Studio versions. + +These solution and project files were created using Visual Studio 2012. +They should be able to be opened in newer versions of Visual Studio. +For older versions of Visual Studio you could try a little hack of changing +the line in the solution file "samples.sln" from: + Microsoft Visual Studio Solution File, Format Version 12.00 +to + Microsoft Visual Studio Solution File, Format Version 11.00 + +Or whatever version number your Visual Studio version uses. +(Hint: Check an existing solution file you have created with your version + of Visual Studio to know what this value is expected to be.) + +Also note that all instructions below are for Visual Studio 2012. So if you +are using a different version then the settings may be located in different +areas or have different names. + + + + +:: Building the pre-prepared sample projects + +Some sample projects have been included in the bindings\msvc\samples directory. +The solution file in this directory is "samples.sln". +This was created with Visual Studio 2012 and once opened contains 2 projects +"dynload" and "staload". + +The "dynload" project is an example of a project that uses dynamic linking. +The "satload" project is an example of a project that uses static linking. + +Both projects have 32bit (win32) and 64bit (x64) target platforms. +The 32bit platform (win32) will create a 32bit app that can run on either +32bit or 64bit Windows. The 64bit platform (x64) can only run on 64bit Windows. + +All variants can be built at once by using the batch build function: +Go to "Build -> Batch Build" and tick all checkboxes, or at least the ones +that you wish to build. Then click on the Build or Rebuild button. +Note that when building the "staload" projects you must first have built +the static import libraries as mentioned above. + + + + +:: Running the pre-prepared sample projects + +When running the samples they will need to be able to load the unicorn dlls. + +The unicorn dlls required for 32bit apps are: + libgcc_s_dw2-1.dll + libglib-2.0-0.dll + libiconv-2.dll + libintl-8.dll + libwinpthread-1.dll + unicorn.dll + +The unicorn dlls required for 64bit apps are: + libgcc_s_seh-1.dll + libglib-2.0-0.dll + libiconv-2.dll + libintl-8.dll + libwinpthread-1.dll + unicorn.dll + +Note that while some of the 32bit and 64bit dlls have the same filename, +they are internally different in that they are either 32bit or 64bit files +themselves. So you will have to have separate directories to store them in. +I suggest using directory names such as "unicorn32" and "unicorn64" when +installing the prebuilt windows binaries. This will make it easy to +differentiate between them. + +If running the sample exe files from the command line or from Windows Explorer +then you need ensure that the exe file is in the same directory as either the +32bit or 64bit set of dlls. + +To run the samples from inside Visual Studio so that you can debug them or just +easily test various changes you should set the working directory to point to a +directory that contains all of the dlls. Assuming you are running a 32bit app +and have the 32bit unicorn dlls in the directory "C:\unicorn32" then do: + +1) Go to the Solution Explorer window in Visual Studio. +You can use "View -> Solution Explorer" to get to it. + +2) Highlight one or more projects that you want to run/debu from in +Visual Studio. Use hold control when selecting to select multiples, +or hold Shift to select ranges of projects. + +3) Right click on the selected projects and go to Properties. + +4) Now go to "Configuration Properties -> Debugging -> Working Directory". +Change the value for this to "C:\unicorn32". +You will need to change this for both Debug and Release configurations. +You can change between configurations on the top left of the Property Pages +dialog box that you are currently on. + +6) Click OK when done and then you are ready to run or debug the projects. +Do "Debug -> Start Debugging" or press F5 to debug the current project. +Do "Debug -> Start Without Debugging" or press Ctrl+F5 to run the current project. +You can change the current project by right clicking on a project in +Solution Explorer and selecting "Set as StartUp Project" + diff --git a/bindings/msvc/samples/dynload/dynload.vcxproj b/bindings/msvc/samples/dynload/dynload.vcxproj new file mode 100644 index 00000000..a73f04fc --- /dev/null +++ b/bindings/msvc/samples/dynload/dynload.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {EBBC5CEA-1237-4E20-9E38-E610D3C529EB} + Win32Proj + dynload + dynload + + + + Application + true + v110_xp + MultiByte + + + Application + true + v110_xp + MultiByte + + + Application + false + v110_xp + true + MultiByte + + + Application + false + v110_xp + true + MultiByte + + + + + + + + + + + + + + + + + + + true + $(ProjectDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + true + $(ProjectDir)$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + false + $(ProjectDir)$(Platform)\$(Configuration)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);DYNLOAD + MultiThreadedDebug + ..\..;..\..\..\..\include + + + Console + true + ..\.. + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);DYNLOAD + MultiThreadedDebug + ..\..;..\..\..\..\include + + + Console + true + ..\.. + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);DYNLOAD + MultiThreaded + ..\..;..\..\..\..\include + + + Console + true + true + true + ..\.. + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);DYNLOAD + MultiThreaded + ..\..;..\..\..\..\include + + + Console + true + true + true + ..\.. + + + + + + + + + + \ No newline at end of file diff --git a/bindings/msvc/samples/dynload/dynload.vcxproj.filters b/bindings/msvc/samples/dynload/dynload.vcxproj.filters new file mode 100644 index 00000000..9dcdb716 --- /dev/null +++ b/bindings/msvc/samples/dynload/dynload.vcxproj.filters @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/bindings/msvc/samples/main.c b/bindings/msvc/samples/main.c new file mode 100644 index 00000000..87cbbb55 --- /dev/null +++ b/bindings/msvc/samples/main.c @@ -0,0 +1,134 @@ +// +// Simple code as an example for building apps with MSVC++ using the Unicorn Engine. +// +// Zak Escano - December 2015 +// + +// windows specific +#ifdef _MSC_VER +#include +#include +#define PRIx64 "llX" +#ifdef DYNLOAD +#include +#else // DYNLOAD +#include +#ifdef _WIN64 +#pragma comment(lib, "unicorn_staload64.lib") +#else // _WIN64 +#pragma comment(lib, "unicorn_staload.lib") +#endif // _WIN64 +#endif // DYNLOAD + +// posix specific +#else // _MSC_VER +#include +#include +#include +#endif // _MSC_VER + + +// Test MIPS little endian code. +// It should loop 3 times before ending. +const uint64_t addr = 0x100000; +const unsigned char loop_test_code[] = { + 0x02,0x00,0x04,0x24, // 100000: li $a0, 2 + // loop1 + 0x00,0x00,0x00,0x00, // 100004: nop + 0xFE,0xFF,0x80,0x14, // 100008: bnez $a0, loop1 + 0xFF,0xFF,0x84,0x24, // 10000C: addiu $a0, -1 +}; +bool test_passed_ok = false; +int loop_count = 0; + + +static void mips_codehook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) +{ + if( address == 0x10000C ) + test_passed_ok = true; + if( address == 0x100004 ) + { + printf("\nloop %d:\n", loop_count); + loop_count++; + } + printf("Code: %llX\n", address); +} + + +int main(int argc, char **argv, char **envp) +{ + uc_engine *uc; + uc_err err; + uc_hook hhc; + uint32_t val; + + // dynamically load shared library +#ifdef DYNLOAD + if( !uc_dyn_load(NULL, 0) ) + { + printf("Error dynamically loading shared library.\n"); + printf("Please check that unicorn.dll/unicorn.so is available as well as\n"); + printf("any other dependent dll/so files.\n"); + printf("The easiest way is to place them in the same directory as this app.\n"); + return 1; + } +#endif + + // Initialize emulator in MIPS 32bit little endian mode + err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32, &uc); + if (err) + { + printf("Failed on uc_open() with error returned: %u\n", err); + return err; + } + + // map in a page of mem + err = uc_mem_map(uc, addr, 0x1000, UC_PROT_ALL); + if (err) + { + printf("Failed on uc_mem_map() with error returned: %u\n", err); + return err; + } + + // write machine code to be emulated to memory + err = uc_mem_write(uc, addr, loop_test_code, sizeof(loop_test_code)); + if( err ) + { + printf("Failed on uc_mem_write() with error returned: %u\n", err); + return err; + } + + // hook all instructions by having @begin > @end + uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, (uint64_t)1, (uint64_t)0); + if( err ) + { + printf("Failed on uc_hook_add(code) with error returned: %u\n", err); + return err; + } + + // execute code + printf("---- Executing Code ----\n"); + err = uc_emu_start(uc, addr, addr + sizeof(loop_test_code), 0, 0); + if (err) + { + printf("Failed on uc_emu_start() with error returned %u: %s\n", + err, uc_strerror(err)); + return err; + } + + // done executing, print some reg values as a test + printf("---- Execution Complete ----\n\n"); + uc_reg_read(uc, UC_MIPS_REG_PC, &val); printf("pc is %X\n", val); + uc_reg_read(uc, UC_MIPS_REG_A0, &val); printf("a0 is %X\n", val); + + // free resources + uc_close(uc); + + // dynamically free shared library +#ifdef DYNLOAD + uc_dyn_free(); +#endif + + return 0; +} + diff --git a/bindings/msvc/samples/samples.sln b/bindings/msvc/samples/samples.sln new file mode 100644 index 00000000..0594260e --- /dev/null +++ b/bindings/msvc/samples/samples.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynload", "dynload\dynload.vcxproj", "{EBBC5CEA-1237-4E20-9E38-E610D3C529EB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "staload", "staload\staload.vcxproj", "{85FFC5E9-CC3D-41F6-8970-092FAC8E5E39}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EBBC5CEA-1237-4E20-9E38-E610D3C529EB}.Debug|Win32.ActiveCfg = Debug|Win32 + {EBBC5CEA-1237-4E20-9E38-E610D3C529EB}.Debug|Win32.Build.0 = Debug|Win32 + {EBBC5CEA-1237-4E20-9E38-E610D3C529EB}.Debug|x64.ActiveCfg = Debug|x64 + {EBBC5CEA-1237-4E20-9E38-E610D3C529EB}.Debug|x64.Build.0 = Debug|x64 + {EBBC5CEA-1237-4E20-9E38-E610D3C529EB}.Release|Win32.ActiveCfg = Release|Win32 + {EBBC5CEA-1237-4E20-9E38-E610D3C529EB}.Release|Win32.Build.0 = Release|Win32 + {EBBC5CEA-1237-4E20-9E38-E610D3C529EB}.Release|x64.ActiveCfg = Release|x64 + {EBBC5CEA-1237-4E20-9E38-E610D3C529EB}.Release|x64.Build.0 = Release|x64 + {85FFC5E9-CC3D-41F6-8970-092FAC8E5E39}.Debug|Win32.ActiveCfg = Debug|Win32 + {85FFC5E9-CC3D-41F6-8970-092FAC8E5E39}.Debug|Win32.Build.0 = Debug|Win32 + {85FFC5E9-CC3D-41F6-8970-092FAC8E5E39}.Debug|x64.ActiveCfg = Debug|x64 + {85FFC5E9-CC3D-41F6-8970-092FAC8E5E39}.Debug|x64.Build.0 = Debug|x64 + {85FFC5E9-CC3D-41F6-8970-092FAC8E5E39}.Release|Win32.ActiveCfg = Release|Win32 + {85FFC5E9-CC3D-41F6-8970-092FAC8E5E39}.Release|Win32.Build.0 = Release|Win32 + {85FFC5E9-CC3D-41F6-8970-092FAC8E5E39}.Release|x64.ActiveCfg = Release|x64 + {85FFC5E9-CC3D-41F6-8970-092FAC8E5E39}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/bindings/msvc/samples/staload/staload.vcxproj b/bindings/msvc/samples/staload/staload.vcxproj new file mode 100644 index 00000000..dd9ba821 --- /dev/null +++ b/bindings/msvc/samples/staload/staload.vcxproj @@ -0,0 +1,165 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {85FFC5E9-CC3D-41F6-8970-092FAC8E5E39} + Win32Proj + staload + + + + Application + true + v110_xp + MultiByte + + + Application + true + v110_xp + MultiByte + + + Application + false + v110_xp + true + MultiByte + + + Application + false + v110_xp + true + MultiByte + + + + + + + + + + + + + + + + + + + true + $(ProjectDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + true + $(ProjectDir)$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + false + $(ProjectDir)$(Platform)\$(Configuration)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDebug + ..\..;..\..\..\..\include + + + Console + true + ..\.. + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDebug + ..\..;..\..\..\..\include + + + Console + true + ..\.. + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + ..\..;..\..\..\..\include + + + Console + true + true + true + ..\.. + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + ..\..;..\..\..\..\include + + + Console + true + true + true + ..\.. + + + + + + + + + \ No newline at end of file diff --git a/bindings/msvc/samples/staload/staload.vcxproj.filters b/bindings/msvc/samples/staload/staload.vcxproj.filters new file mode 100644 index 00000000..b2dc6e7d --- /dev/null +++ b/bindings/msvc/samples/staload/staload.vcxproj.filters @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bindings/msvc/unicorn_dynload.c b/bindings/msvc/unicorn_dynload.c index fcf58ec9..ae136c17 100644 --- a/bindings/msvc/unicorn_dynload.c +++ b/bindings/msvc/unicorn_dynload.c @@ -26,6 +26,9 @@ // Zak Escano - November 2015 // +// Only use this if DYNLOAD is set in preprocessor definitions +#ifdef DYNLOAD + // This is to detect whether we are loading a dll in windows or a so in linux. #ifdef _MSC_VER #define WINDOWS_DLL 1 @@ -276,3 +279,4 @@ uc_err uc_mem_protect(uc_engine *uc, uint64_t address, size_t size, uint32_t per return gp_uc_mem_protect(uc, address, size, perms); } +#endif // DYNLOAD diff --git a/samples/mem_apis.c b/samples/mem_apis.c index 8ec4c715..b9356aff 100644 --- a/samples/mem_apis.c +++ b/samples/mem_apis.c @@ -19,14 +19,36 @@ */ #define __STDC_FORMAT_MACROS -#include -#include + +// windows specific includes +#ifdef _MSC_VER +#include +#include +#define PRIx64 "llX" +#ifdef DYNLOAD +#include +#else // DYNLOAD +#include +#ifdef _WIN64 +#pragma comment(lib, "unicorn_staload64.lib") +#else // _WIN64 +#pragma comment(lib, "unicorn_staload.lib") +#endif // _WIN64 +#endif // DYNLOAD + +// posix specific includes +#else // _MSC_VER #include +#include +#include +#endif // _MSC_VER + +// common includes +#include #include #include #include -#include static int insts_executed; @@ -337,9 +359,26 @@ static void unmap_test() int main(int argc, char **argv, char **envp) { - nx_test(); + // dynamically load shared library +#ifdef DYNLOAD + if( !uc_dyn_load(NULL, 0) ) + { + printf("Error dynamically loading shared library.\n"); + printf("Please check that unicorn.dll/unicorn.so is available as well as\n"); + printf("any other dependent dll/so files.\n"); + printf("The easiest way is to place them in the same directory as this app.\n"); + return 1; + } +#endif + + nx_test(); perms_test(); unmap_test(); - return 0; + // dynamically free shared library +#ifdef DYNLOAD + uc_dyn_free(); +#endif + + return 0; } diff --git a/samples/msvc/README.TXT b/samples/msvc/README.TXT new file mode 100644 index 00000000..ea431d55 --- /dev/null +++ b/samples/msvc/README.TXT @@ -0,0 +1,141 @@ + + +:: Notes about Visual Studio versions. + +These solution and project files were created using Visual Studio 2012. +They should be able to be opened in newer versions of Visual Studio. +For older versions of Visual Studio you could try a little hack of changing +the line in the solution file "msvc.sln" from: + Microsoft Visual Studio Solution File, Format Version 12.00 +to + Microsoft Visual Studio Solution File, Format Version 11.00 + +Or whatever version number your Visual Studio version uses. +(Hint: Check an existing solution file you have created with your version + of Visual Studio to know what this value is expected to be.) + +Also note that all instructions below are for Visual Studio 2012. So if you +are using a different version then the settings may be located in different +areas or have different names. + + + + +:: Notes about the building the sample projects + +The projects have 32bit (win32) and 64bit (x64) target platforms. +The 32bit platform (win32) will create a 32bit app that can run on either +32bit or 64bit Windows. The 64bit platform (x64) can only run on 64bit Windows. + +All variants can be built at once by using the batch build function: +Go to "Build -> Batch Build" and tick all checkboxes, or at least the ones +that you wish to build. Then click on the Build or Rebuild button. +Note that when building the "staload" projects you must first have built +the static import libraries as mentioned above. + +The samples projects all come preset to be built using dynamic loading of +the unicorn dlls. If you wish to use static loading of the unicorn dlls +then you need see the next section. + + + + +:: Using static linking of dlls + +It is possible to perform static linking of the unicorn dlls which will +load and import the dlls when the exe file itself is loaded. Personally +I prefer dynamic loading in which you load the dlls in your program code +at runtime. This way if it fails you have the opportunity to display a +more meaning error message. Dynamic loading also gives you more +advanced options for where to load the dll files from. + +If you do wish to do static linking of dlls then the following changes +need to be made to each project. Note that multiple projects can be +highlighted and have their settings changed at the one time. + +1) First ensure the static linking library has been built. +Run bindings\msvc\make_staload.bat to build these. +You may need to first alter this batch file to point to the correct +location of your "vcvars32.bat" file. +If successful you will now have the files "bindings\msvc\unicorn_staload.lib" +and "bindings\msvc\unicorn_staload64.lib". + +2) Go to the Solution Explorer window in Visual Studio. +You can use "View -> Solution Explorer" to get to it. + +3) Highlight one or more projects that you want to change to use +static linking. Use hold control when selecting to select multiples, +or hold Shift to select ranges of projects. + +4) Right click on the selected projects and go to Properties. + +5) Now go to "Configuration Properties -> C/C++ -> Preprocessor -> +Preprocessor Definitions". Remove the DYNLOAD entry and its preceeding +semi-colon. You will need to remove DYNLOAD for both Debug and Release +configurations. You can change between configurations on the top left +of the Property Pages dialog box that you are currently on. + +6) Click OK when done and then rebuild the altered projects. +Be sure to Rebuild and not just Build to ensure that the change you +made are used. + + + + +:: Running the samples + +When running the samples they will need to be able to load the unicorn dlls. + +The unicorn dlls required for 32bit apps are: + libgcc_s_dw2-1.dll + libglib-2.0-0.dll + libiconv-2.dll + libintl-8.dll + libwinpthread-1.dll + unicorn.dll + +The unicorn dlls required for 64bit apps are: + libgcc_s_seh-1.dll + libglib-2.0-0.dll + libiconv-2.dll + libintl-8.dll + libwinpthread-1.dll + unicorn.dll + +Note that while some of the 32bit and 64bit dlls have the same filename, +they are internally different in that they are either 32bit or 64bit files +themselves. So you will have to have separate directories to store them in. +I suggest using directory names such as "unicorn32" and "unicorn64" when +installing the prebuilt windows binaries. This will make it easy to +differentiate between them. + +If running the sample exe files from the command line or from Windows Explorer +then you need ensure that the exe file is in the same directory as either the +32bit or 64bit set of dlls. + +To run the samples from inside Visual Studio so that you can debug them or just +easily test various changes you should set the working directory to point to a +directory that contains all of the dlls. Assuming you are running a 32bit app +and have the 32bit unicorn dlls in the directory "C:\unicorn32" then do: + +1) Go to the Solution Explorer window in Visual Studio. +You can use "View -> Solution Explorer" to get to it. + +2) Highlight one or more projects that you want to run/debu from in +Visual Studio. Use hold control when selecting to select multiples, +or hold Shift to select ranges of projects. + +3) Right click on the selected projects and go to Properties. + +4) Now go to "Configuration Properties -> Debugging -> Working Directory". +Change the value for this to "C:\unicorn32". +You will need to change this for both Debug and Release configurations. +You can change between configurations on the top left of the Property Pages +dialog box that you are currently on. + +6) Click OK when done and then you are ready to run or debug the projects. +Do "Debug -> Start Debugging" or press F5 to debug the current project. +Do "Debug -> Start Without Debugging" or press Ctrl+F5 to run the current project. +You can change the current project by right clicking on a project in +Solution Explorer and selecting "Set as StartUp Project" + diff --git a/samples/msvc/msvc.sln b/samples/msvc/msvc.sln new file mode 100644 index 00000000..02ce0ae6 --- /dev/null +++ b/samples/msvc/msvc.sln @@ -0,0 +1,96 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mem_apis", "mem_apis\mem_apis.vcxproj", "{ECA2292F-FD4F-4943-B0FC-093B6D35FEBA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_arm", "sample_arm\sample_arm.vcxproj", "{8FF2F8F8-14CE-4899-998F-2C0BBE43FB6E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_arm64", "sample_arm64\sample_arm64.vcxproj", "{43AEBCD7-BD18-4F0D-8AF8-536F62F92AAD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_m68k", "sample_m68k\sample_m68k.vcxproj", "{39ABA118-6289-43D6-AB6C-8B3AB3CB9390}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_mips", "sample_mips\sample_mips.vcxproj", "{5E004A76-1625-44F1-A1EA-64C4FD15F642}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_x86", "sample_x86\sample_x86.vcxproj", "{F8AD989E-D273-42DA-80A6-B6466EB134CA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_sparc", "sample_sparc\sample_sparc.vcxproj", "{2906001D-9B80-4400-8B3A-4445CDAED54F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shellcode", "shellcode\shellcode.vcxproj", "{4A8F2E9A-C2D8-4A93-8451-5F3BD73A4227}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ECA2292F-FD4F-4943-B0FC-093B6D35FEBA}.Debug|Win32.ActiveCfg = Debug|Win32 + {ECA2292F-FD4F-4943-B0FC-093B6D35FEBA}.Debug|Win32.Build.0 = Debug|Win32 + {ECA2292F-FD4F-4943-B0FC-093B6D35FEBA}.Debug|x64.ActiveCfg = Debug|x64 + {ECA2292F-FD4F-4943-B0FC-093B6D35FEBA}.Debug|x64.Build.0 = Debug|x64 + {ECA2292F-FD4F-4943-B0FC-093B6D35FEBA}.Release|Win32.ActiveCfg = Release|Win32 + {ECA2292F-FD4F-4943-B0FC-093B6D35FEBA}.Release|Win32.Build.0 = Release|Win32 + {ECA2292F-FD4F-4943-B0FC-093B6D35FEBA}.Release|x64.ActiveCfg = Release|x64 + {ECA2292F-FD4F-4943-B0FC-093B6D35FEBA}.Release|x64.Build.0 = Release|x64 + {8FF2F8F8-14CE-4899-998F-2C0BBE43FB6E}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FF2F8F8-14CE-4899-998F-2C0BBE43FB6E}.Debug|Win32.Build.0 = Debug|Win32 + {8FF2F8F8-14CE-4899-998F-2C0BBE43FB6E}.Debug|x64.ActiveCfg = Debug|x64 + {8FF2F8F8-14CE-4899-998F-2C0BBE43FB6E}.Debug|x64.Build.0 = Debug|x64 + {8FF2F8F8-14CE-4899-998F-2C0BBE43FB6E}.Release|Win32.ActiveCfg = Release|Win32 + {8FF2F8F8-14CE-4899-998F-2C0BBE43FB6E}.Release|Win32.Build.0 = Release|Win32 + {8FF2F8F8-14CE-4899-998F-2C0BBE43FB6E}.Release|x64.ActiveCfg = Release|x64 + {8FF2F8F8-14CE-4899-998F-2C0BBE43FB6E}.Release|x64.Build.0 = Release|x64 + {43AEBCD7-BD18-4F0D-8AF8-536F62F92AAD}.Debug|Win32.ActiveCfg = Debug|Win32 + {43AEBCD7-BD18-4F0D-8AF8-536F62F92AAD}.Debug|Win32.Build.0 = Debug|Win32 + {43AEBCD7-BD18-4F0D-8AF8-536F62F92AAD}.Debug|x64.ActiveCfg = Debug|x64 + {43AEBCD7-BD18-4F0D-8AF8-536F62F92AAD}.Debug|x64.Build.0 = Debug|x64 + {43AEBCD7-BD18-4F0D-8AF8-536F62F92AAD}.Release|Win32.ActiveCfg = Release|Win32 + {43AEBCD7-BD18-4F0D-8AF8-536F62F92AAD}.Release|Win32.Build.0 = Release|Win32 + {43AEBCD7-BD18-4F0D-8AF8-536F62F92AAD}.Release|x64.ActiveCfg = Release|x64 + {43AEBCD7-BD18-4F0D-8AF8-536F62F92AAD}.Release|x64.Build.0 = Release|x64 + {39ABA118-6289-43D6-AB6C-8B3AB3CB9390}.Debug|Win32.ActiveCfg = Debug|Win32 + {39ABA118-6289-43D6-AB6C-8B3AB3CB9390}.Debug|Win32.Build.0 = Debug|Win32 + {39ABA118-6289-43D6-AB6C-8B3AB3CB9390}.Debug|x64.ActiveCfg = Debug|x64 + {39ABA118-6289-43D6-AB6C-8B3AB3CB9390}.Debug|x64.Build.0 = Debug|x64 + {39ABA118-6289-43D6-AB6C-8B3AB3CB9390}.Release|Win32.ActiveCfg = Release|Win32 + {39ABA118-6289-43D6-AB6C-8B3AB3CB9390}.Release|Win32.Build.0 = Release|Win32 + {39ABA118-6289-43D6-AB6C-8B3AB3CB9390}.Release|x64.ActiveCfg = Release|x64 + {39ABA118-6289-43D6-AB6C-8B3AB3CB9390}.Release|x64.Build.0 = Release|x64 + {5E004A76-1625-44F1-A1EA-64C4FD15F642}.Debug|Win32.ActiveCfg = Debug|Win32 + {5E004A76-1625-44F1-A1EA-64C4FD15F642}.Debug|Win32.Build.0 = Debug|Win32 + {5E004A76-1625-44F1-A1EA-64C4FD15F642}.Debug|x64.ActiveCfg = Debug|x64 + {5E004A76-1625-44F1-A1EA-64C4FD15F642}.Debug|x64.Build.0 = Debug|x64 + {5E004A76-1625-44F1-A1EA-64C4FD15F642}.Release|Win32.ActiveCfg = Release|Win32 + {5E004A76-1625-44F1-A1EA-64C4FD15F642}.Release|Win32.Build.0 = Release|Win32 + {5E004A76-1625-44F1-A1EA-64C4FD15F642}.Release|x64.ActiveCfg = Release|x64 + {5E004A76-1625-44F1-A1EA-64C4FD15F642}.Release|x64.Build.0 = Release|x64 + {F8AD989E-D273-42DA-80A6-B6466EB134CA}.Debug|Win32.ActiveCfg = Debug|Win32 + {F8AD989E-D273-42DA-80A6-B6466EB134CA}.Debug|Win32.Build.0 = Debug|Win32 + {F8AD989E-D273-42DA-80A6-B6466EB134CA}.Debug|x64.ActiveCfg = Debug|x64 + {F8AD989E-D273-42DA-80A6-B6466EB134CA}.Debug|x64.Build.0 = Debug|x64 + {F8AD989E-D273-42DA-80A6-B6466EB134CA}.Release|Win32.ActiveCfg = Release|Win32 + {F8AD989E-D273-42DA-80A6-B6466EB134CA}.Release|Win32.Build.0 = Release|Win32 + {F8AD989E-D273-42DA-80A6-B6466EB134CA}.Release|x64.ActiveCfg = Release|x64 + {F8AD989E-D273-42DA-80A6-B6466EB134CA}.Release|x64.Build.0 = Release|x64 + {2906001D-9B80-4400-8B3A-4445CDAED54F}.Debug|Win32.ActiveCfg = Debug|Win32 + {2906001D-9B80-4400-8B3A-4445CDAED54F}.Debug|Win32.Build.0 = Debug|Win32 + {2906001D-9B80-4400-8B3A-4445CDAED54F}.Debug|x64.ActiveCfg = Debug|x64 + {2906001D-9B80-4400-8B3A-4445CDAED54F}.Debug|x64.Build.0 = Debug|x64 + {2906001D-9B80-4400-8B3A-4445CDAED54F}.Release|Win32.ActiveCfg = Release|Win32 + {2906001D-9B80-4400-8B3A-4445CDAED54F}.Release|Win32.Build.0 = Release|Win32 + {2906001D-9B80-4400-8B3A-4445CDAED54F}.Release|x64.ActiveCfg = Release|x64 + {2906001D-9B80-4400-8B3A-4445CDAED54F}.Release|x64.Build.0 = Release|x64 + {4A8F2E9A-C2D8-4A93-8451-5F3BD73A4227}.Debug|Win32.ActiveCfg = Debug|Win32 + {4A8F2E9A-C2D8-4A93-8451-5F3BD73A4227}.Debug|Win32.Build.0 = Debug|Win32 + {4A8F2E9A-C2D8-4A93-8451-5F3BD73A4227}.Debug|x64.ActiveCfg = Debug|x64 + {4A8F2E9A-C2D8-4A93-8451-5F3BD73A4227}.Debug|x64.Build.0 = Debug|x64 + {4A8F2E9A-C2D8-4A93-8451-5F3BD73A4227}.Release|Win32.ActiveCfg = Release|Win32 + {4A8F2E9A-C2D8-4A93-8451-5F3BD73A4227}.Release|Win32.Build.0 = Release|Win32 + {4A8F2E9A-C2D8-4A93-8451-5F3BD73A4227}.Release|x64.ActiveCfg = Release|x64 + {4A8F2E9A-C2D8-4A93-8451-5F3BD73A4227}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/samples/sample_arm.c b/samples/sample_arm.c index 48f3ebf2..96d031f9 100644 --- a/samples/sample_arm.c +++ b/samples/sample_arm.c @@ -3,9 +3,28 @@ /* Sample code to demonstrate how to emulate ARM code */ -#include - +// windows specific +#ifdef _MSC_VER +#include +#include +#define PRIx64 "llX" +#ifdef DYNLOAD +#include +#else // DYNLOAD #include +#ifdef _WIN64 +#pragma comment(lib, "unicorn_staload64.lib") +#else // _WIN64 +#pragma comment(lib, "unicorn_staload.lib") +#endif // _WIN64 +#endif // DYNLOAD + +// posix specific +#else // _MSC_VER +#include +#include +#include +#endif // _MSC_VER // code to be emulated @@ -132,9 +151,26 @@ static void test_thumb(void) int main(int argc, char **argv, char **envp) { - test_arm(); + // dynamically load shared library +#ifdef DYNLOAD + if( !uc_dyn_load(NULL, 0) ) + { + printf("Error dynamically loading shared library.\n"); + printf("Please check that unicorn.dll/unicorn.so is available as well as\n"); + printf("any other dependent dll/so files.\n"); + printf("The easiest way is to place them in the same directory as this app.\n"); + return 1; + } +#endif + + test_arm(); printf("==========================\n"); test_thumb(); + // dynamically free shared library +#ifdef DYNLOAD + uc_dyn_free(); +#endif + return 0; } diff --git a/samples/sample_arm64.c b/samples/sample_arm64.c index 6b0ee8db..b1e85cf2 100644 --- a/samples/sample_arm64.c +++ b/samples/sample_arm64.c @@ -3,9 +3,28 @@ /* Sample code to demonstrate how to emulate ARM64 code */ -#include - +// windows specific +#ifdef _MSC_VER +#include +#include +#define PRIx64 "llX" +#ifdef DYNLOAD +#include +#else // DYNLOAD #include +#ifdef _WIN64 +#pragma comment(lib, "unicorn_staload64.lib") +#else // _WIN64 +#pragma comment(lib, "unicorn_staload.lib") +#endif // _WIN64 +#endif // DYNLOAD + +// posix specific +#else // _MSC_VER +#include +#include +#include +#endif // _MSC_VER // code to be emulated @@ -79,7 +98,24 @@ static void test_arm64(void) int main(int argc, char **argv, char **envp) { - test_arm64(); + // dynamically load shared library +#ifdef DYNLOAD + if( !uc_dyn_load(NULL, 0) ) + { + printf("Error dynamically loading shared library.\n"); + printf("Please check that unicorn.dll/unicorn.so is available as well as\n"); + printf("any other dependent dll/so files.\n"); + printf("The easiest way is to place them in the same directory as this app.\n"); + return 1; + } +#endif + + test_arm64(); + // dynamically free shared library +#ifdef DYNLOAD + uc_dyn_free(); +#endif + return 0; } diff --git a/samples/sample_m68k.c b/samples/sample_m68k.c index cfebd8e0..204e503d 100644 --- a/samples/sample_m68k.c +++ b/samples/sample_m68k.c @@ -3,8 +3,28 @@ /* Sample code to demonstrate how to emulate m68k code */ +// windows specific +#ifdef _MSC_VER +#include +#include +#define PRIx64 "llX" +#ifdef DYNLOAD +#include +#else // DYNLOAD +#include +#ifdef _WIN64 +#pragma comment(lib, "unicorn_staload64.lib") +#else // _WIN64 +#pragma comment(lib, "unicorn_staload.lib") +#endif // _WIN64 +#endif // DYNLOAD + +// posix specific +#else // _MSC_VER +#include #include #include +#endif // _MSC_VER // code to be emulated #define M68K_CODE "\x76\xed" // movq #-19, %d3 @@ -140,6 +160,24 @@ static void test_m68k(void) int main(int argc, char **argv, char **envp) { - test_m68k(); + // dynamically load shared library +#ifdef DYNLOAD + if( !uc_dyn_load(NULL, 0) ) + { + printf("Error dynamically loading shared library.\n"); + printf("Please check that unicorn.dll/unicorn.so is available as well as\n"); + printf("any other dependent dll/so files.\n"); + printf("The easiest way is to place them in the same directory as this app.\n"); + return 1; + } +#endif + + test_m68k(); + + // dynamically free shared library +#ifdef DYNLOAD + uc_dyn_free(); +#endif + return 0; } diff --git a/samples/sample_mips.c b/samples/sample_mips.c index 60331737..578c688e 100644 --- a/samples/sample_mips.c +++ b/samples/sample_mips.c @@ -3,9 +3,28 @@ /* Sample code to demonstrate how to emulate Mips code (big endian) */ -#include - +// windows specific +#ifdef _MSC_VER +#include +#include +#define PRIx64 "llX" +#ifdef DYNLOAD +#include +#else // DYNLOAD #include +#ifdef _WIN64 +#pragma comment(lib, "unicorn_staload64.lib") +#else // _WIN64 +#pragma comment(lib, "unicorn_staload.lib") +#endif // _WIN64 +#endif // DYNLOAD + +// posix specific +#else // _MSC_VER +#include +#include +#include +#endif // _MSC_VER // code to be emulated @@ -126,8 +145,25 @@ static void test_mips_el(void) int main(int argc, char **argv, char **envp) { - test_mips_eb(); + // dynamically load shared library +#ifdef DYNLOAD + if( !uc_dyn_load(NULL, 0) ) + { + printf("Error dynamically loading shared library.\n"); + printf("Please check that unicorn.dll/unicorn.so is available as well as\n"); + printf("any other dependent dll/so files.\n"); + printf("The easiest way is to place them in the same directory as this app.\n"); + return 1; + } +#endif + + test_mips_eb(); test_mips_el(); + // dynamically free shared library +#ifdef DYNLOAD + uc_dyn_free(); +#endif + return 0; } diff --git a/samples/sample_sparc.c b/samples/sample_sparc.c index 45c185a5..1445e9d7 100644 --- a/samples/sample_sparc.c +++ b/samples/sample_sparc.c @@ -3,9 +3,28 @@ /* Sample code to demonstrate how to emulate Sparc code */ -#include - +// windows specific +#ifdef _MSC_VER +#include +#include +#define PRIx64 "llX" +#ifdef DYNLOAD +#include +#else // DYNLOAD #include +#ifdef _WIN64 +#pragma comment(lib, "unicorn_staload64.lib") +#else // _WIN64 +#pragma comment(lib, "unicorn_staload.lib") +#endif // _WIN64 +#endif // DYNLOAD + +// posix specific +#else // _MSC_VER +#include +#include +#include +#endif // _MSC_VER // code to be emulated @@ -81,7 +100,24 @@ static void test_sparc(void) int main(int argc, char **argv, char **envp) { - test_sparc(); + // dynamically load shared library +#ifdef DYNLOAD + if( !uc_dyn_load(NULL, 0) ) + { + printf("Error dynamically loading shared library.\n"); + printf("Please check that unicorn.dll/unicorn.so is available as well as\n"); + printf("any other dependent dll/so files.\n"); + printf("The easiest way is to place them in the same directory as this app.\n"); + return 1; + } +#endif + + test_sparc(); + // dynamically free shared library +#ifdef DYNLOAD + uc_dyn_free(); +#endif + return 0; } diff --git a/samples/sample_x86.c b/samples/sample_x86.c index 5f33833f..fe8b1b5f 100644 --- a/samples/sample_x86.c +++ b/samples/sample_x86.c @@ -3,11 +3,31 @@ /* Sample code to demonstrate how to emulate X86 code */ -#include -#include -#include - +// windows specific +#ifdef _MSC_VER +#include +#include +#define PRIx64 "llX" +#ifdef DYNLOAD +#include +#else // DYNLOAD #include +#ifdef _WIN64 +#pragma comment(lib, "unicorn_staload64.lib") +#else // _WIN64 +#pragma comment(lib, "unicorn_staload.lib") +#endif // _WIN64 +#endif // DYNLOAD + +// posix specific +#else // _MSC_VER +#include +#include +#include +#endif // _MSC_VER + +// common includes +#include // code to be emulated @@ -792,7 +812,19 @@ static void test_x86_16(void) int main(int argc, char **argv, char **envp) { - if (argc == 2) { + // dynamically load shared library +#ifdef DYNLOAD + if( !uc_dyn_load(NULL, 0) ) + { + printf("Error dynamically loading shared library.\n"); + printf("Please check that unicorn.dll/unicorn.so is available as well as\n"); + printf("any other dependent dll/so files.\n"); + printf("The easiest way is to place them in the same directory as this app.\n"); + return 1; + } +#endif + + if (argc == 2) { if (!strcmp(argv[1], "-32")) { test_i386(); test_i386_inout(); @@ -823,5 +855,10 @@ int main(int argc, char **argv, char **envp) printf("Syntax: %s <-16|-32|-64>\n", argv[0]); } + // dynamically free shared library +#ifdef DYNLOAD + uc_dyn_free(); +#endif + return 0; } diff --git a/samples/shellcode.c b/samples/shellcode.c index 5377ece9..234b361f 100644 --- a/samples/shellcode.c +++ b/samples/shellcode.c @@ -3,11 +3,31 @@ /* Sample code to trace code with Linux code with syscall */ -#include -#include -#include - +// windows specific +#ifdef _MSC_VER +#include +#include +#define PRIx64 "llX" +#ifdef DYNLOAD +#include +#else // DYNLOAD #include +#ifdef _WIN64 +#pragma comment(lib, "unicorn_staload64.lib") +#else // _WIN64 +#pragma comment(lib, "unicorn_staload.lib") +#endif // _WIN64 +#endif // DYNLOAD + +// posix specific +#else // _MSC_VER +#include +#include +#include +#endif // _MSC_VER + +// common includes +#include // code to be emulated @@ -32,7 +52,7 @@ static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user size = MIN(sizeof(tmp), size); if (!uc_mem_read(uc, address, tmp, size)) { - int i; + uint32_t i; for (i=0; i\n", argv[0]); } + // dynamically free shared library +#ifdef DYNLOAD + uc_dyn_free(); +#endif + return 0; }