Last active
April 30, 2016 03:03
-
-
Save gr33n7007h/3f22cc1f6cc4fe902472 to your computer and use it in GitHub Desktop.
fiddle examples
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
#!/usr/bin/env ruby | |
require 'fiddle' | |
require 'fiddle/import' | |
include Fiddle | |
@libc = "/usr/lib64/libc.so.6" # location of shared object file on Arch Linux | |
TC = TrueClass.dup | |
FC = FalseClass.dup | |
PR_SET_NAME = 15 # set process name (from /usr/include/linux/prctl.h) | |
PR_GET_NAME = 16 # get process name ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
CDROMEJECT = 0x00005309 # (from /usr/include/linux/cdrom.h) | |
LIBC = @libc | |
# Some examples using Fiddle (A libffi wrapper for Ruby) | |
def getpid # returns the process id of the calling process | |
p Function.new(Handle.new(@libc)['getpid'], [], TYPE_INT).call | |
end | |
def getppid # returns the process id of the parent of the calling process | |
p Function.new(Handle.new(@libc)['getppid'], [], TYPE_INT).call | |
end | |
def getuid # returns the real user id of the calling process | |
p Function.new(Handle.new(@libc)['getuid'], [], TYPE_INT).call | |
end | |
def geteuid # returns the effective user id of the calling process | |
p Function.new(Handle.new(@libc)['geteuid'], [], TYPE_INT).call | |
end | |
def getenv(env_var) # get an environment variable | |
p Function.new(Handle.new(@libc)['getenv'], [TYPE_VOIDP], TYPE_VOIDP).call(env_var).to_s | |
end | |
def time # returns the time as the number of seconds since the epoch | |
p Function.new(Handle.new(@libc)['time'], [TYPE_VOIDP], TYPE_INT).call(NULL) | |
end | |
def true2false(kptr1, kptr2, bytes) | |
Pointer.new(kptr1.__id__ << 1)[0,bytes] = Pointer.new(kptr2.__id__ << 1)[0,bytes] | |
p "1 == 1 #=> #{1 == 1}" | |
end | |
def false2true(kptr1, kptr2, bytes) | |
Pointer.new(kptr1.__id__ << 1)[0,bytes] = Pointer.new(kptr2.__id__ << 1)[0,bytes] | |
p "1 == 2 #=> #{1 == 2}" | |
end | |
def set_process_title(name) # set process/thread name | |
Function.new( | |
Handle.new(@libc)['prctl'], | |
[ TYPE_INT, TYPE_VOIDP, TYPE_LONG, TYPE_LONG, TYPE_LONG ], | |
TYPE_INT | |
).call(PR_SET_NAME, name, NULL,NULL,NULL) | |
end | |
def get_process_title # get process/thread name | |
buffer = Pointer.malloc(24) | |
Function.new( | |
Handle.new(@libc)['prctl'], | |
[TYPE_INT, TYPE_VOIDP, *[TYPE_LONG]*3], | |
TYPE_INT | |
).call(PR_GET_NAME, ptr, *[NULL]*3) | |
p buffer.to_s | |
end | |
# call methods | |
getpid #=> 13785 | |
getppid #=> 13646 | |
getuid #=> 1000 | |
geteuid #=> 1000 | |
getenv("SHELL") #=> "/bin/bash" | |
time #=> 1458512941 | |
true2false(TrueClass, FC, 36) #=> false | |
false2true(FalseClass, TC, 36) #=> true | |
set_process_title("voodoo") #=> 0 (zero means success) | |
get_process_title | |
# example using structs | |
module Foo | |
extend Fiddle::Importer | |
dlload LIBC | |
extern 'int gettimeofday(void *, void *)' | |
T = struct [ | |
'long tv_sec', | |
'long tv_usec', | |
] | |
end | |
tv = Foo::T.malloc | |
x = Foo.gettimeofday(tv, NULL) | |
p tv.tv_sec #=> 1458592642 | |
p tv.tv_usec #=> 829213 | |
# silly trick | |
def eject dp | |
fd = open(dp, 2048) | |
fileno = fd.fileno | |
Function.new(Handle.new(@libc)['ioctl'], [TYPE_INT, TYPE_VOIDP, TYPE_INT], TYPE_INT).call(fileno, CDROMEJECT, 0) | |
fd.close | |
end | |
eject "/dev/sr0" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment