Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
DLL Injector
$:.unshift("E:\\Tools\\metasm")
require 'metasm'
require 'optparse'
$ASMCODE =
# Win32 PEB based API Resolver
# Metasm seems to fail on jecxz so we compile using nasm and use the binary
"\xe8\x56\x00\x00\x00\x53\x55\x56\x57\x8b\x6c\x24\x18\x8b\x45\x3c" +
"\x8b\x54\x05\x78\x01\xea\x8b\x4a\x18\x8b\x5a\x20\x01\xeb\xe3\x32" +
"\x49\x8b\x34\x8b\x01\xee\x31\xff\xfc\x31\xc0\xac\x38\xe0\x74\x07" +
"\xc1\xcf\x0d\x01\xc7\xeb\xf2\x3b\x7c\x24\x14\x75\xe1\x8b\x5a\x24" +
"\x01\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c\x01\xeb\x8b\x04\x8b\x01\xe8" +
"\xeb\x02\x31\xc0\x5f\x5e\x5d\x5b\xc2\x08\x00\x31\xc9\x64\x8b\x71" +
"\x30\x8b\x76\x0c\x8b\x76\x1c\x8b\x5e\x08\x8b\x7e\x20\x8b\x36\x66" +
"\x39\x4f\x18\x75\xf2\x5e\x53\x68\x8e\x4e\x0e\xec\xff\xd6\x89\xc7" +
"\x57\x56\x53\x89\xe5" +
# %define LoadLibraryA [ebp + 8]
# %define LGetProcAddress [ebp + 4]
# %define KERNEL32 BASE [ebp + 0]
Metasm::Shellcode.assemble(Metasm::Ia32.new, %Q{
jmp _end
_start:
pop ecx ; DLL Path in ECX
; LoadLibraryA(DLL)
push ecx
call [ebp + 8]
test eax, eax
jz _exit
; GetProcessAddress() and find Init()
push eax ; DLL Base
push 0x95481bf4 ; Hash of Init
call [ebp + 4]
test eax, eax
jz _exit
call eax ; Init()
_exit:
; Resolve Exit Thread
push [ebp]
push 0x60e0ceef ; Hash of Exit Thread
call [ebp + 4]
; Call ExitThread
push 0x00
call eax
int 3
_end:
call _start
; Path (ASCII) for DLL goes here
}).encode_string()
def process_inject_dll(process, path)
puts "[+] Attempting to inject \"#{path}\" to pid: #{process.pid}"
Metasm::WinOS.inject_run_shellcode(process, $ASMCODE + path.to_s + "\x00")
end
if __FILE__ == $0
options = {}
opts = OptionParser.new do |opts|
opts.banner = "Usage: Injector.rb [options]"
opts.on("-p", "--pid [PID]", "Inject to process identified by PID") do |pid|
options[:pid] = pid.to_i
end
opts.on("-n", "--name [NAME]", "Inject to all processes matching name (eg. chrome.exe)") do |name|
options[:name] = name.to_s
end
opts.on("-D", "--dll-path [PATH]", "Path of DLL to inject") do |dll|
options[:dll] = dll.to_s
end
opts.on("-l", "--list", "List processes") do |v|
options[:list_processes] = true
end
end
opts.parse!
if options[:list_processes]
Metasm::WinOS.list_processes.each do |proc|
puts "%d: %s" % [proc.pid, proc.modules.size > 0 ? proc.modules[0].path : "N/A"]
end
exit
end
if (options[:dll].nil?) or (options[:pid].nil? and options[:name].nil?)
puts opts
exit(1)
end
Metasm::WinOS.list_processes.each do |process|
process_inject_dll(process, options[:dll]) if ((options[:pid]) and (process.pid == options[:pid].to_i)) or
((options[:name]) and (!process.modules.empty?) and
(File.basename(process.modules[0].path).downcase == options[:name].downcase))
end
end
C:\Injector>ruby Injector.rb
Usage: Injector.rb [options]
-p, --pid [PID] Inject to process identified by PID
-n, --name [NAME] Inject to all processes matching name (eg. chrome.exe)
-D, --dll-path [PATH] Path of DLL to inject
-l, --list List processes
@nicwhitts

This comment has been minimized.

Copy link

nicwhitts commented Aug 1, 2014

Any idea why this would crash after injection running windows 7?

@abhisek

This comment has been minimized.

Copy link
Owner Author

abhisek commented Sep 3, 2014

The injected DLL does not export an Init function?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.