diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index 9fa6662..1c2a032 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="windows-1251"?> <VisualStudioProject ProjectType="Visual C++" - Version="9.00" + Version="9,00" Name="pykd" ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}" RootNamespace="pykd" @@ -99,6 +99,7 @@ /> <Tool Name="VCPostBuildEventTool" + CommandLine=""$(SolutionDir)test\scripts\_run_pykdtest.cmd" "$(TargetDir)targetapp.exe" $(PlatformName)" /> </Configuration> <Configuration @@ -179,6 +180,7 @@ /> <Tool Name="VCPostBuildEventTool" + CommandLine=""$(SolutionDir)test\scripts\_run_pykdtest.cmd" "$(TargetDir)targetapp.exe" $(PlatformName)" /> </Configuration> <Configuration @@ -256,6 +258,7 @@ /> <Tool Name="VCPostBuildEventTool" + CommandLine=""$(SolutionDir)test\scripts\_run_pykdtest.cmd" "$(TargetDir)targetapp.exe" $(PlatformName)" /> </Configuration> <Configuration @@ -334,6 +337,7 @@ /> <Tool Name="VCPostBuildEventTool" + CommandLine=""$(SolutionDir)test\scripts\_run_pykdtest.cmd" "$(TargetDir)targetapp.exe" $(PlatformName)" /> </Configuration> </Configurations> diff --git a/pykd_2008.sln b/pykd_2008.sln index e8ecace..f135593 100644 --- a/pykd_2008.sln +++ b/pykd_2008.sln @@ -2,17 +2,13 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pykd", "pykd\pykd_2008.vcproj", "{FE961905-666F-4908-A212-961465F46F13}" + ProjectSection(ProjectDependencies) = postProject + {C6254E16-AB8E-41EE-887D-31458E93FC68} = {C6254E16-AB8E-41EE-887D-31458E93FC68} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "targetapp", "test\targetapp\targetapp.vcproj", "{C6254E16-AB8E-41EE-887D-31458E93FC68}" EndProject Global - GlobalSection(TeamFoundationVersionControl) = preSolution - SccNumberOfProjects = 2 - SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} - SccTeamFoundationServer = https://tfs.codeplex.com/tfs/TFS08 - SccLocalPath0 = . - SccProjectUniqueName1 = pykd\\pykd_2008.vcproj - SccProjectName1 = pykd - SccLocalPath1 = pykd - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 @@ -28,8 +24,25 @@ Global {FE961905-666F-4908-A212-961465F46F13}.Release|Win32.Build.0 = Release|Win32 {FE961905-666F-4908-A212-961465F46F13}.Release|x64.ActiveCfg = Release|x64 {FE961905-666F-4908-A212-961465F46F13}.Release|x64.Build.0 = Release|x64 + {C6254E16-AB8E-41EE-887D-31458E93FC68}.Debug|Win32.ActiveCfg = Debug|Win32 + {C6254E16-AB8E-41EE-887D-31458E93FC68}.Debug|Win32.Build.0 = Debug|Win32 + {C6254E16-AB8E-41EE-887D-31458E93FC68}.Debug|x64.ActiveCfg = Debug|x64 + {C6254E16-AB8E-41EE-887D-31458E93FC68}.Debug|x64.Build.0 = Debug|x64 + {C6254E16-AB8E-41EE-887D-31458E93FC68}.Release|Win32.ActiveCfg = Release|Win32 + {C6254E16-AB8E-41EE-887D-31458E93FC68}.Release|Win32.Build.0 = Release|Win32 + {C6254E16-AB8E-41EE-887D-31458E93FC68}.Release|x64.ActiveCfg = Release|x64 + {C6254E16-AB8E-41EE-887D-31458E93FC68}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(TeamFoundationVersionControl) = preSolution + SccNumberOfProjects = 2 + SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} + SccTeamFoundationServer = https://tfs.codeplex.com/tfs/TFS08 + SccLocalPath0 = . + SccProjectUniqueName1 = pykd\\pykd_2008.vcproj + SccProjectName1 = pykd + SccLocalPath1 = pykd + EndGlobalSection EndGlobal diff --git a/test/scripts/_run_pykdtest.cmd b/test/scripts/_run_pykdtest.cmd new file mode 100644 index 0000000..220ed32 --- /dev/null +++ b/test/scripts/_run_pykdtest.cmd @@ -0,0 +1,23 @@ +:: Pass $(TargetDir)\<TestApp.exe> from Visual Studio +set TestAppPath=%1 + +:: Pass $(PlatformName) from Visual Studio +set TestAppPlatform=%2 + +set Arch=x64 +if "%PROCESSOR_ARCHITECTURE%" == "x86" ( + if not defined PROCESSOR_ARCHITEW6432 set Arch=x86 +) + +:: Select appropriate python.exe path +set PythonRegKey=HKLM\Software\Python\PythonCore\2.6\InstallPath +if "%Arch%" == "x64" ( + if "%TestAppPlatform%" == "Win32" set PythonRegKey=HKLM\Software\Wow6432Node\Python\PythonCore\2.6\InstallPath +) + +for /F "tokens=3*" %%A in ('reg.exe query %PythonRegKey% /ve 2^>NUL ^| FIND "REG_SZ"') do set PythonInstallPath=%%B +::echo %PythonInstallPath% + +%PythonInstallPath%python.exe "%~dp0pykdtest.py" %TestAppPath% + +::pause diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py new file mode 100644 index 0000000..0688453 --- /dev/null +++ b/test/scripts/pykdtest.py @@ -0,0 +1,37 @@ +import sys +import os +import unittest + +# Append current pykd.pyd path to PYTHONPATH +sys.path.append(os.path.dirname(sys.argv[1])) +import pykd + +class TestPykd(unittest.TestCase): + + def setUp(self): + self.targetAppPath = sys.argv[1] + self.targetModuleName = os.path.splitext(os.path.basename(self.targetAppPath))[0] + self.targetModule = None + self.gVerInfoOffset = 0L + self.verInfo = None + + def testPykd(self): + print self.targetAppPath + + self.assertTrue(pykd.startProcess(self.targetAppPath)) + + self.targetModule = pykd.loadModule(self.targetModuleName) + self.assertNotEqual(self.targetModule, None) + pykd.go() + + self.gVerInfoOffset = pykd.getOffset(self.targetModuleName, "gVerInfo") + self.assertNotEqual(self.gVerInfoOffset, 0L) + + self.verInfo = pykd.typedVar(self.targetModuleName, "_OSVERSIONINFOA", self.gVerInfoOffset) + self.assertNotEqual(self.verInfo, None) + pykd.go() + +if __name__ == '__main__': + #unittest.main(argv=[]) + suite = unittest.TestLoader().loadTestsFromTestCase(TestPykd) + unittest.TextTestRunner().run(suite) diff --git a/test/targetapp/stdafx.cpp b/test/targetapp/stdafx.cpp new file mode 100644 index 0000000..7709cdc --- /dev/null +++ b/test/targetapp/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// targetapp.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/test/targetapp/stdafx.h b/test/targetapp/stdafx.h new file mode 100644 index 0000000..6795c57 --- /dev/null +++ b/test/targetapp/stdafx.h @@ -0,0 +1,14 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include <stdio.h> +#include <tchar.h> + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> \ No newline at end of file diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp new file mode 100644 index 0000000..d9866aa --- /dev/null +++ b/test/targetapp/targetapp.cpp @@ -0,0 +1,37 @@ +#include "stdafx.h" + +#include <intrin.h> + +#include <iostream> + +#include "utils.h" + +OSVERSIONINFOA gVerInfo = {0}; + +void test_getOffset_typedVar() +{ + gVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + if (!::GetVersionExA(&gVerInfo)) + throw std::runtime_error("Can't get OS version: " + utils::GetLastErrorStr()); + __debugbreak(); +} + +int _tmain(int argc, _TCHAR* argv[]) +{ + try + { + test_getOffset_typedVar(); + } + catch(std::exception & ex) + { + std::cout << ex.what() << std::endl; + return 1; + } + catch (...) + { + std::cout << "Unknown error" << std::endl; + return 1; + } + return 0; +} + diff --git a/test/targetapp/targetapp.vcproj b/test/targetapp/targetapp.vcproj new file mode 100644 index 0000000..c5731f9 --- /dev/null +++ b/test/targetapp/targetapp.vcproj @@ -0,0 +1,395 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="targetapp" + ProjectGUID="{C6254E16-AB8E-41EE-887D-31458E93FC68}" + RootNamespace="targetapp" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="2" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="2" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="2" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="2" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\stdafx.cpp" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|x64" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|x64" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\targetapp.cpp" + > + </File> + <File + RelativePath=".\utils.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\stdafx.h" + > + </File> + <File + RelativePath=".\targetver.h" + > + </File> + <File + RelativePath=".\utils.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/test/targetapp/targetver.h b/test/targetapp/targetver.h new file mode 100644 index 0000000..956cad8 --- /dev/null +++ b/test/targetapp/targetver.h @@ -0,0 +1,13 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target other versions of Windows. +#endif + diff --git a/test/targetapp/utils.cpp b/test/targetapp/utils.cpp new file mode 100644 index 0000000..220606e --- /dev/null +++ b/test/targetapp/utils.cpp @@ -0,0 +1,44 @@ +#include "stdafx.h" + +#include <string> +#include <memory> + +namespace utils +{ + +std::string GetWinErrorText(DWORD dwError) +{ + HLOCAL hLocal = NULL; // Buffer that gets the error message string + + // Get the error code's textual description + DWORD strSize = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, dwError, 0 /* Default language */, (LPSTR) &hLocal, 0, NULL); + + if (!strSize) + { + // Is it a network-related error? + HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES); + if (hDll == INVALID_HANDLE_VALUE) + return std::string("Can't load netmsg.dll"); + std::tr1::shared_ptr<void> guard1(hDll, ::FreeLibrary); + strSize = FormatMessageA(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM, + hDll, dwError, 0 /* Default language */, (LPSTR) &hLocal, 0, NULL); + } + + if (strSize != NULL) + { + std::tr1::shared_ptr<void> guard2(hLocal, ::LocalFree); + std::string str; + str += reinterpret_cast<const char*>(::LocalLock(hLocal)); + return str; + } + + return std::string("Unknown error."); +} + +std::string GetLastErrorStr() +{ + return GetWinErrorText(::GetLastError()); +} + +} // namespace utils \ No newline at end of file diff --git a/test/targetapp/utils.h b/test/targetapp/utils.h new file mode 100644 index 0000000..07d2222 --- /dev/null +++ b/test/targetapp/utils.h @@ -0,0 +1,12 @@ +#pragma once + +#include <string> + +namespace utils +{ + +std::string GetWinErrorText(DWORD dwError); + +std::string GetLastErrorStr(); + +} // namespace utils \ No newline at end of file