Created
July 28, 2016 17:45
-
-
Save adamdriscoll/40124e4283a68559882ca5cc5b1a8d40 to your computer and use it in GitHub Desktop.
Example of how to use EasyHook with powershell to override GetSystemTimeAsFileTime
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function New-Detour | |
{ | |
param( | |
$Library, | |
$FunctionName, | |
[ScriptBlock]$Detour, | |
[String[]]$ReferencedAssemblies | |
) | |
#Download from easyhook.codeplex.com | |
$EasyHook = Join-Path $PSScriptRoot 'EasyHook.dll' | |
[Reflection.Assembly]::LoadFile($EasyHook) | |
$ReferencedAssemblies += $EasyHook | |
$psParameters = @() | |
foreach($parameter in $Detour.Ast.ParamBlock.Parameters) | |
{ | |
$psParameter = [PSCustomObject]@{Name=$parameter.Name.ToString().Replace("$", "");TypeName="";IsOut=$false} | |
foreach($attribute in $parameter.Attributes) | |
{ | |
if ($attribute.TypeName.Name -eq "ref") | |
{ | |
$psParameter.IsOut = $true | |
} | |
else | |
{ | |
$psParameter.TypeName = $attribute.TypeName.FullName | |
} | |
} | |
$psParameters += $psParameter | |
} | |
$parameters = "" | |
$outParameters = @() | |
$psParameters | % { | |
$parameters = "" | |
if ($_.IsOut) | |
{ | |
$parameters += "out " | |
$outParameters += $_ | |
} | |
$parameters += "$($_.TypeName) $($_.Name)," | |
$parameterNames += "$($_.Name)," | |
} | |
$parameters = $parameters.Substring(0, $parameters.Length - 1) | |
$parameterNames = $parameterNames.Substring(0, $parameterNames.Length - 1) | |
$initializeSnippet = "" | |
$outVarSnippet = "" | |
$i = 0 | |
foreach($outParam in $outParameters) | |
{ | |
$initializeSnippet += "$($outParam.Name) = default($($outParam.TypeName));`n" | |
$outVarSnippet += "$($outParam.Name) = ($($outParam.TypeName))outVars[$i].ImmediateBaseObject;`n" | |
$i++ | |
} | |
$random = Get-Random | |
$Class = " | |
namespace Detoured | |
{ | |
using System.Runtime.InteropServices; | |
using System.Management.Automation; | |
using System.Management.Automation.Runspaces; | |
using EasyHook; | |
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet=CharSet.Unicode, SetLastError=true)] | |
public delegate void $($FunctionName)_Delegate$random($parameters); | |
public class Detour$random : IEntryPoint { | |
private static ScriptBlock _sb; | |
private static Runspace _rp; | |
public Detour$random(ScriptBlock sb, Runspace rp) | |
{ | |
_sb = sb; | |
_rp = rp; | |
} | |
public static void $($FunctionName)_Hooked($parameters) | |
{ | |
$initializeSnippet | |
try | |
{ | |
Runspace.DefaultRunspace = _rp; | |
var outVars = _sb.Invoke($parameterNames); | |
$outVarSnippet | |
} | |
catch (System.Exception ex) | |
{ | |
System.Console.WriteLine(ex.Message); | |
} | |
} | |
} | |
} | |
" | |
$TempFile = [IO.Path]::GetTempPath() | |
$TempFile = Join-Path $TempFile "Detoured$random.dll" | |
Add-Type -TypeDefinition $Class -ReferencedAssemblies $ReferencedAssemblies -OutputAssembly $TempFile | |
Add-Type -Path $TempFile | |
$DetourObject = New-Object -TypeName "Detoured.Detour$random" -ArgumentList $Detour,([System.Management.Automation.Runspaces.Runspace]::DefaultRunspace) | |
$Delegate = $DetourObject.GetType().GetMember("$($FunctionName)_Hooked").CreateDelegate([Type]"Detoured.$($FunctionName)_Delegate$random") | |
$CreateFileHook = [EasyHook.LocalHook]::Create([EasyHook.LocalHook]::GetProcAddress($library, $FunctionName), $delegate, $DetourObject); | |
$CreateFileHook.ThreadACL.SetExclusiveACL(@()) | |
$CreateFileHook | |
} | |
$Detour = New-Detour -Library "Kernel32.dll" -FunctionName GetSystemTimeAsFileTime -Detour { param([ref][System.Int64]$time) | |
125911583990000000 | |
} | |
Get-Date |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment