-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathDotNetDllPathPatcher.ps1
73 lines (62 loc) · 2.14 KB
/
DotNetDllPathPatcher.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using namespace System.IO
using namespace System.Text
param([string]$exe_path, [string]$target_path = 'bin')
$ErrorActionPreference = 'Stop'
#$DebugPreference = 'Continue'
$exe_path = (Resolve-Path -Path $exe_path).Path
Write-Host "Origin path: `"$exe_path`""
Write-Host "Target dll path: $target_path"
$separator = '\'
$max_path_length = 1024
$exe_name = [Path]::GetFileName($exe_path)
$dll_name = [Path]::ChangeExtension($exe_name, '.dll')
Write-Debug "exe: $exe_name"
Write-Debug "dll: $dll_name"
function Update-Exe {
$old_bytes = [Encoding]::UTF8.GetBytes("$dll_name`0")
if ($old_bytes.Count -gt $max_path_length) {
throw [PathTooLongException] 'old dll path is too long'
}
$new_dll_path = "$target_path$separator$dll_name"
$new_bytes = [Encoding]::UTF8.GetBytes("$new_dll_path`0")
Write-Host "Dll path Change to `"$new_dll_path`""
if ($new_bytes.Count -gt $max_path_length) {
throw [PathTooLongException] 'new dll path is too long'
}
$bytes = [File]::ReadAllBytes($exe_path)
$index = (Get-Content $exe_path -Raw -Encoding 28591).IndexOf("$dll_name`0")
if ($index -lt 0) {
throw [InvalidDataException] 'Could not find old dll path'
}
Write-Debug "Position: $index"
$end_postion = $index + $($new_bytes.Count)
$end_length = $bytes.Count - $end_postion
if ($end_postion -gt $bytes.Count) {
throw [PathTooLongException] 'new dll path is too long'
}
Write-Debug "End Position: $end_postion"
Write-Debug "End Length: $end_length"
$fs = [File]::OpenWrite($exe_path)
try {
$fs.Write($bytes, 0, $index)
$fs.Write($new_bytes)
$fs.Write($bytes, $end_postion, $end_length)
}
finally {
$fs.Dispose();
}
}
function Move-Dll {
$tmpbin = 'tmpbin'
$dir = [Path]::GetDirectoryName($exe_path);
$root = [Path]::GetDirectoryName($dir);
Write-Debug "root path: $root"
Write-Debug "dir path: $dir"
Rename-Item $dir $tmpbin
New-Item -ItemType Directory $dir > $null
Move-Item $root\$tmpbin $dir
Rename-Item $dir\$tmpbin $target_path
Move-Item $dir\$target_path\$exe_name $dir
}
Update-Exe
Move-Dll