class TestPreproc
BEWARE OF TEH RUBY PARSER use single-quoted source strings
Public Instance Methods
asm_dasm(src)
click to toggle source
# File tests/dasm.rb, line 13 def asm_dasm(src) @cpu ||= Ia32.new raw = Shellcode.assemble(src, @cpu).encode_string dasm = Shellcode.decode(raw, @cpu).disassembler dasm.disassemble_fast(0) dasm end
do_test_bd2(src, bd)
click to toggle source
# File tests/dasm.rb, line 21 def do_test_bd2(src, bd) d = asm_dasm(src) calc_bd = d.compose_bt_binding(*d.decoded[0].block.list) calc_bd.delete_if { |k, v| k.to_s =~ /flag/ } assert_equal bd, calc_bd end
helper_preparse(text, result) { |p| ... }
click to toggle source
# File tests/preprocessor.rb, line 49 def helper_preparse(text, result) p = load(text, caller.first) yield p if block_given? txt = '' until p.eos? or not t = p.readtok txt << t.raw end assert_equal(result, txt.strip) end
load(txt, bt = caller.first)
click to toggle source
# File tests/preprocessor.rb, line 15 def load txt, bt = caller.first p = Metasm::Preprocessor.new bt =~ /^(.*?):(\d+)/ p.feed txt, $1, $2.to_i+1 p end
test_comment()
click to toggle source
# File tests/preprocessor.rb, line 34 def test_comment p = load <<'EOS' foo /*/ bar ' " * /*/ baz kikoo // lol \ asv EOS toks = [] nil while tok = p.readtok and (tok.type == :space or tok.type == :eol) until p.eos? toks << tok.raw nil while tok = p.readtok and (tok.type == :space or tok.type == :eol) end assert_equal %w[foo baz kikoo], toks end
test_compose_bt_binding()
click to toggle source
# File tests/dasm.rb, line 28 def test_compose_bt_binding do_test_bd2 'mov eax, 1 mov ebx, 2', :eax => Expression[1], :ebx => Expression[2] do_test_bd2 'mov eax, 1 push eax', :eax => Expression[1], Indirection[:esp, 4] => Expression[1], :esp => Expression[:esp, :+, -4] do_test_bd2 'mov [eax], ebx mov [eax], ecx', Indirection[:eax, 4] => Expression[:ecx] do_test_bd2 'add eax, 4 mov [eax], ecx', Indirection[:eax, 4] => Expression[:ecx], :eax => Expression[:eax, :+, 4] do_test_bd2 'mov [eax], ecx mov ebx, eax', :ebx => Expression[:eax], Indirection[:eax, 4] => Expression[:ecx], Indirection[:ebx, 4] => Expression[:ecx] do_test_bd2 'mov [eax], ecx add eax, 4', :eax => Expression[:eax, :+, 4], Indirection[[:eax, :+, -4], 4] => Expression[:ecx] do_test_bd2 'mov [eax+4], ecx add eax, 4', :eax => Expression[:eax, :+, 4], Indirection[:eax, 4] => Expression[:ecx] do_test_bd2 'push 1 push 2', :esp => Expression[:esp, :+, -8], Indirection[:esp, 4] => Expression[2], Indirection[[:esp, :+, 4], 4] => Expression[1] end
test_errors()
click to toggle source
# File tests/preprocessor.rb, line 246 def test_errors test_err = lambda { |txt| assert_raise(Metasm::ParseError) { p = load(txt, caller.first) ; p.readtok until p.eos? } } t_float = lambda { |txt| assert_raise(Metasm::ParseError) { p = load("#if #{txt}\n#endif", caller.first) ; p.readtok } } test_err["\"abc\n\""] test_err['"abc\x"'] test_err['/*'] test_err['#if 0'] test_err["#define toto(tutu,"] test_err["#define toto( (tutu, tata)"] test_err['#error bla'] test_err[<<EOS] #if 0 #elif 1 #else #if 2 #endif EOS test_err[<<EOS] #define abc(def) abc (1, 3) EOS test_err["#if 0LUL\n#endif"] # warnings only #test_err["#define aa\n#define aa"] #test_err['#define a(b) #c'] #test_err['#define a(b, b)'] #test_err['#define a ##z'] t_float['1e++4'] t_float['1.0e 4'] t_float['_1.0'] t_float['.e2'] t_float['1.1e+_1'] t_float['.2e'] t_float['.'] t_float['1.2e*4'] t_float['0x1.e4'] t_float['0x1.p4a'] t_float['0x.p1'] t_float['0x.1lp1'] end
test_floats()
click to toggle source
# File tests/preprocessor.rb, line 222 def test_floats t_float = lambda { |txt| text = <<EOS #if #{txt} 1 #endif EOS p = load text, caller.first txt = '' t = nil txt << t.raw until p.eos? or not t = p.readtok assert_equal('1', txt.strip) } t_float['1 > 0'] t_float['1.0 > 0'] t_float['1e2 > 10 && 1.0e2 < 1000'] t_float['1.0e+2 > 10'] t_float['10_00e-2 > 1 && 10_00e-2 < 100'] t_float['.1e2 > 1'] #t_float['0x1.p2L > 1 && 0x1p2f < 5'] t_float['0x1.p2L > 1'] t_float['0x1p2f < 5'] end
test_gettok()
click to toggle source
# File tests/preprocessor.rb, line 22 def test_gettok p = load <<'EOS' test boo " bla bla\ \"\\" \ xx EOS assert_equal \ ['test', :space, :string, :eol, :quoted, :space, 'xx', :eol, true], [p.readtok.raw, p.readtok.type, p.readtok.type, p.readtok.type, p.readtok.type, p.readtok.type, p.readtok.raw, p.readtok.type, p.eos?] end
test_preproc()
click to toggle source
# File tests/preprocessor.rb, line 59 def test_preproc # ignores eol/space at begin/end helper_preparse(<<EOS, '') #if 0 // test # as first char toto #endif EOS helper_preparse(<<EOS, 'coucou') #define tutu #if defined ( tutu ) tutu coucou #endif EOS helper_preparse(<<EOS, 'a1') #define tutu #if ! defined ( tutu ) a0 #else a1 #endif EOS helper_preparse(<<EOS, 'a1') #define tutu #if defined(tutu) ? 0 : 1 a0 #endif #if defined(toto) ? 0 : 1 a1 #endif EOS helper_preparse('a #define b', 'a #define b') helper_preparse(<<EOS, "// true !\nblu") #ifdef toto // this is false bla #elif .2_3e-4 > 2 /* this one too */ blo #elif (1+1)*2 > 2 // true ! blu #elif 4 > 2 // not you ble #else bli #endif EOS helper_preparse(<<'EOS', 'ab#define x') a\ b\ #define x EOS p = load('__LINE__,__DATE__,__TIME__') assert_equal(__LINE__, p.readtok.value) ; p.readtok assert_not_equal('__DATE__', p.readtok.raw) ; p.readtok assert_not_equal('__TIME__', p.readtok.raw) helper_preparse(<<EOS, 'toto 1 toto 12 toto 3+(3-2) otot hoho') #define azer(k) 12 # define xxx azer(7) #define macro(a, b, c) toto a toto b toto c otot macro(1, xxx, 3+(3-2)) hoho EOS helper_preparse(<<EOS, 'c') #define a b #define d c #define c d #define b c a EOS helper_preparse(<<EOS, 'b') #define b c #define a b #undef b a EOS helper_preparse(<<EOS, 'toto tutu huhu()') #define toto() abcd #define tata huhu toto tutu tata() EOS helper_preparse(<<EOS, '"haha"') #define d(a) #a d(haha) EOS helper_preparse(<<EOS, '{') #define toto(a) a toto({) EOS helper_preparse(<<EOS, 'x(, 1)') #define d(a,b) x(a, b) d(,1) EOS helper_preparse(<<EOS, '"foo" "4"') #define str(x) #x #define xstr(x) str(x) #define foo 4 str(foo) xstr(foo) EOS begin File.open('tests/prepro_testinclude.asm', 'w') { |fd| fd.puts '#define out in' } helper_preparse(<<EOS, 'in') #pragma include_path "." #include <tests/prepro_testinclude.asm> out EOS rescue Errno::ENOENT ensure File.unlink('tests/prepro_testinclude.asm') rescue nil end helper_preparse(<<EOS, 'in') { |p_| p_.hooked_include['bla.h'] = '#define out in' } #include <bla.h> out EOS helper_preparse(<<EOS, 'in') { |p_| p_.define('out', 'in') } out EOS helper_preparse(<<EOS, 'in') { |p_| p_.define_strong('out', 'in') } out EOS helper_preparse(<<EOS, 'in') { |p_| p_.define_strong('out', 'in') } #define out poil out EOS helper_preparse(<<EOS, 'in') { |p_| p_.define('out', 'in') ; p_.define_weak('out', 'poil') } out EOS p = load <<EOS #define cct(a, b) a ## _ ## b cct(toto, tutu) EOS nil while tok = p.readtok and (tok.type == :space or tok.type == :eol) assert_equal('toto_tutu', tok.raw) # check we get only 1 token back # assert_outputs_a_warning ? helper_preparse(<<EOS, <<EOS.strip) #define va1(a, b...) toto(a, ##b) #define va3(a, ...) toto(a, __VA_ARGS__) va1(1, 2); va1(1,2); va1(1); va3(1, 2); va3(1); EOS toto(1, 2); toto(1,2); toto(1); toto(1, 2); toto(1, ); EOS helper_preparse(<<EOS, "#define a c\n#define b d\na b") #define x(z) z #define y #define x(#)define a c y b d a b EOS helper_preparse("#define a(a) a(a)\na(1)", '1(1)') helper_preparse("#if 0\n#endif", '') helper_preparse("#if 0U\n#endif", '') helper_preparse("#if 0L\n#endif", '') helper_preparse("#if 0LLU\n#endif", '') end