View difference between Paste ID: RrkbXYZu and X0D4TVH5
SHOW: | | - or go back to the newest paste.
1
# This ruby program will patch the linker executable (link.exe)
2
# so that linker warning LNK4099 is ignorable.
3
#
4
# Reference: http://www.bottledlight.com/docs/lnk4099.html
5
6
require "fileutils"
7
8
def link_exes()
9
	res = []
10
	res << File.join(ENV["VS90COMNTOOLS"], "../../VC/bin/link.exe") if ENV["VS90COMNTOOLS"]
11
	res << File.join(ENV["VS100COMNTOOLS"], "../../VC/bin/link.exe") if ENV["VS100COMNTOOLS"]
12
	res << File.join(ENV["XEDK"], "bin/win32/link.exe") if ENV["XEDK"]
13
	return res
14
end
15
16
def patch_link_exe(exe)
17
	data = nil
18
	File.open(exe, "rb") {|f| data = f.read}
19-
	pattern = [4099].pack("I")
19+
	unpatched = [4088, 4099, 4105].pack("III")
20-
	offset = 0
20+
	patched = [4088, 65535, 4105].pack("III")
21-
	i = 0
21+
22-
	while true
22+
	if data.scan(patched).size > 0
23-
		i = data.index(pattern, offset)
23+
		puts "* Already patched #{exe}"
24-
		return false unless i
24+
		return
25-
		offset = i+1
25+
26-
		next unless i%4 == 0
26+
27-
		int_before = data[i-4,4].unpack("I")[0]
27+
	num_unpatched = data.scan(unpatched).size
28-
		int_after = data[i+4,4].unpack("I")[0]
28+
	raise "Multiple patch locations in #{exe}" if num_unpatched > 1
29-
		break if int_before == 4088 && int_after == 4105
29+
	raise "Patch location not found in #{exe}" if num_unpatched == 0
30
31-
	puts "* Found patch location #{exe}:#{i}"
31+
	offset = data.index(unpatched)
32
	puts "* Found patch location #{exe}:#{offset}"
33
	bak = exe + "-" + Time.now.strftime("%y%m%d-%H%M%S") + ".bak"
34
	puts "  Creating backup #{bak}"
35
	FileUtils.cp(exe, bak)
36-
	data[i,4] = [65535].pack("I")
36+
37
	data[offset,unpatched.size] = patched
38
	File.open(exe, "wb") {|f| f.write(data)}
39
	return true
40
end
41
42
link_exes.each do |exe|
43
	patch_link_exe(exe)
44
end