metasm 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. data/BUGS +11 -0
  2. data/CREDITS +17 -0
  3. data/README +270 -0
  4. data/TODO +114 -0
  5. data/doc/code_organisation.txt +146 -0
  6. data/doc/const_missing.txt +16 -0
  7. data/doc/core_classes.txt +75 -0
  8. data/doc/feature_list.txt +53 -0
  9. data/doc/index.txt +59 -0
  10. data/doc/install_notes.txt +170 -0
  11. data/doc/style.css +3 -0
  12. data/doc/use_cases.txt +18 -0
  13. data/lib/metasm.rb +80 -0
  14. data/lib/metasm/arm.rb +12 -0
  15. data/lib/metasm/arm/debug.rb +39 -0
  16. data/lib/metasm/arm/decode.rb +167 -0
  17. data/lib/metasm/arm/encode.rb +77 -0
  18. data/lib/metasm/arm/main.rb +75 -0
  19. data/lib/metasm/arm/opcodes.rb +177 -0
  20. data/lib/metasm/arm/parse.rb +130 -0
  21. data/lib/metasm/arm/render.rb +55 -0
  22. data/lib/metasm/compile_c.rb +1457 -0
  23. data/lib/metasm/dalvik.rb +8 -0
  24. data/lib/metasm/dalvik/decode.rb +196 -0
  25. data/lib/metasm/dalvik/main.rb +60 -0
  26. data/lib/metasm/dalvik/opcodes.rb +366 -0
  27. data/lib/metasm/decode.rb +213 -0
  28. data/lib/metasm/decompile.rb +2659 -0
  29. data/lib/metasm/disassemble.rb +2068 -0
  30. data/lib/metasm/disassemble_api.rb +1280 -0
  31. data/lib/metasm/dynldr.rb +1329 -0
  32. data/lib/metasm/encode.rb +333 -0
  33. data/lib/metasm/exe_format/a_out.rb +194 -0
  34. data/lib/metasm/exe_format/autoexe.rb +82 -0
  35. data/lib/metasm/exe_format/bflt.rb +189 -0
  36. data/lib/metasm/exe_format/coff.rb +455 -0
  37. data/lib/metasm/exe_format/coff_decode.rb +901 -0
  38. data/lib/metasm/exe_format/coff_encode.rb +1078 -0
  39. data/lib/metasm/exe_format/dex.rb +457 -0
  40. data/lib/metasm/exe_format/dol.rb +145 -0
  41. data/lib/metasm/exe_format/elf.rb +923 -0
  42. data/lib/metasm/exe_format/elf_decode.rb +979 -0
  43. data/lib/metasm/exe_format/elf_encode.rb +1375 -0
  44. data/lib/metasm/exe_format/macho.rb +827 -0
  45. data/lib/metasm/exe_format/main.rb +228 -0
  46. data/lib/metasm/exe_format/mz.rb +164 -0
  47. data/lib/metasm/exe_format/nds.rb +172 -0
  48. data/lib/metasm/exe_format/pe.rb +437 -0
  49. data/lib/metasm/exe_format/serialstruct.rb +246 -0
  50. data/lib/metasm/exe_format/shellcode.rb +114 -0
  51. data/lib/metasm/exe_format/xcoff.rb +167 -0
  52. data/lib/metasm/gui.rb +23 -0
  53. data/lib/metasm/gui/cstruct.rb +373 -0
  54. data/lib/metasm/gui/dasm_coverage.rb +199 -0
  55. data/lib/metasm/gui/dasm_decomp.rb +369 -0
  56. data/lib/metasm/gui/dasm_funcgraph.rb +103 -0
  57. data/lib/metasm/gui/dasm_graph.rb +1354 -0
  58. data/lib/metasm/gui/dasm_hex.rb +543 -0
  59. data/lib/metasm/gui/dasm_listing.rb +599 -0
  60. data/lib/metasm/gui/dasm_main.rb +906 -0
  61. data/lib/metasm/gui/dasm_opcodes.rb +291 -0
  62. data/lib/metasm/gui/debug.rb +1228 -0
  63. data/lib/metasm/gui/gtk.rb +884 -0
  64. data/lib/metasm/gui/qt.rb +495 -0
  65. data/lib/metasm/gui/win32.rb +3004 -0
  66. data/lib/metasm/gui/x11.rb +621 -0
  67. data/lib/metasm/ia32.rb +14 -0
  68. data/lib/metasm/ia32/compile_c.rb +1523 -0
  69. data/lib/metasm/ia32/debug.rb +193 -0
  70. data/lib/metasm/ia32/decode.rb +1167 -0
  71. data/lib/metasm/ia32/decompile.rb +564 -0
  72. data/lib/metasm/ia32/encode.rb +314 -0
  73. data/lib/metasm/ia32/main.rb +233 -0
  74. data/lib/metasm/ia32/opcodes.rb +872 -0
  75. data/lib/metasm/ia32/parse.rb +327 -0
  76. data/lib/metasm/ia32/render.rb +91 -0
  77. data/lib/metasm/main.rb +1193 -0
  78. data/lib/metasm/mips.rb +11 -0
  79. data/lib/metasm/mips/compile_c.rb +7 -0
  80. data/lib/metasm/mips/decode.rb +253 -0
  81. data/lib/metasm/mips/encode.rb +51 -0
  82. data/lib/metasm/mips/main.rb +72 -0
  83. data/lib/metasm/mips/opcodes.rb +443 -0
  84. data/lib/metasm/mips/parse.rb +51 -0
  85. data/lib/metasm/mips/render.rb +43 -0
  86. data/lib/metasm/os/gnu_exports.rb +270 -0
  87. data/lib/metasm/os/linux.rb +1112 -0
  88. data/lib/metasm/os/main.rb +1686 -0
  89. data/lib/metasm/os/remote.rb +527 -0
  90. data/lib/metasm/os/windows.rb +2027 -0
  91. data/lib/metasm/os/windows_exports.rb +745 -0
  92. data/lib/metasm/parse.rb +876 -0
  93. data/lib/metasm/parse_c.rb +3938 -0
  94. data/lib/metasm/pic16c/decode.rb +42 -0
  95. data/lib/metasm/pic16c/main.rb +17 -0
  96. data/lib/metasm/pic16c/opcodes.rb +68 -0
  97. data/lib/metasm/ppc.rb +11 -0
  98. data/lib/metasm/ppc/decode.rb +264 -0
  99. data/lib/metasm/ppc/decompile.rb +251 -0
  100. data/lib/metasm/ppc/encode.rb +51 -0
  101. data/lib/metasm/ppc/main.rb +129 -0
  102. data/lib/metasm/ppc/opcodes.rb +410 -0
  103. data/lib/metasm/ppc/parse.rb +52 -0
  104. data/lib/metasm/preprocessor.rb +1277 -0
  105. data/lib/metasm/render.rb +130 -0
  106. data/lib/metasm/sh4.rb +8 -0
  107. data/lib/metasm/sh4/decode.rb +336 -0
  108. data/lib/metasm/sh4/main.rb +292 -0
  109. data/lib/metasm/sh4/opcodes.rb +381 -0
  110. data/lib/metasm/x86_64.rb +12 -0
  111. data/lib/metasm/x86_64/compile_c.rb +1025 -0
  112. data/lib/metasm/x86_64/debug.rb +59 -0
  113. data/lib/metasm/x86_64/decode.rb +268 -0
  114. data/lib/metasm/x86_64/encode.rb +264 -0
  115. data/lib/metasm/x86_64/main.rb +135 -0
  116. data/lib/metasm/x86_64/opcodes.rb +118 -0
  117. data/lib/metasm/x86_64/parse.rb +68 -0
  118. data/misc/bottleneck.rb +61 -0
  119. data/misc/cheader-findpppath.rb +58 -0
  120. data/misc/hexdiff.rb +74 -0
  121. data/misc/hexdump.rb +55 -0
  122. data/misc/metasm-all.rb +13 -0
  123. data/misc/objdiff.rb +47 -0
  124. data/misc/objscan.rb +40 -0
  125. data/misc/pdfparse.rb +661 -0
  126. data/misc/ppc_pdf2oplist.rb +192 -0
  127. data/misc/tcp_proxy_hex.rb +84 -0
  128. data/misc/txt2html.rb +440 -0
  129. data/samples/a.out.rb +31 -0
  130. data/samples/asmsyntax.rb +77 -0
  131. data/samples/bindiff.rb +555 -0
  132. data/samples/compilation-steps.rb +49 -0
  133. data/samples/cparser_makestackoffset.rb +55 -0
  134. data/samples/dasm-backtrack.rb +38 -0
  135. data/samples/dasmnavig.rb +318 -0
  136. data/samples/dbg-apihook.rb +228 -0
  137. data/samples/dbghelp.rb +143 -0
  138. data/samples/disassemble-gui.rb +102 -0
  139. data/samples/disassemble.rb +133 -0
  140. data/samples/dump_upx.rb +95 -0
  141. data/samples/dynamic_ruby.rb +1929 -0
  142. data/samples/elf_list_needed.rb +46 -0
  143. data/samples/elf_listexports.rb +33 -0
  144. data/samples/elfencode.rb +25 -0
  145. data/samples/exeencode.rb +128 -0
  146. data/samples/factorize-headers-elfimports.rb +77 -0
  147. data/samples/factorize-headers-peimports.rb +109 -0
  148. data/samples/factorize-headers.rb +43 -0
  149. data/samples/gdbclient.rb +583 -0
  150. data/samples/generate_libsigs.rb +102 -0
  151. data/samples/hotfix_gtk_dbg.rb +59 -0
  152. data/samples/install_win_env.rb +78 -0
  153. data/samples/lindebug.rb +924 -0
  154. data/samples/linux_injectsyscall.rb +95 -0
  155. data/samples/machoencode.rb +31 -0
  156. data/samples/metasm-shell.rb +91 -0
  157. data/samples/pe-hook.rb +69 -0
  158. data/samples/pe-ia32-cpuid.rb +203 -0
  159. data/samples/pe-mips.rb +35 -0
  160. data/samples/pe-shutdown.rb +78 -0
  161. data/samples/pe-testrelocs.rb +51 -0
  162. data/samples/pe-testrsrc.rb +24 -0
  163. data/samples/pe_listexports.rb +31 -0
  164. data/samples/peencode.rb +19 -0
  165. data/samples/peldr.rb +494 -0
  166. data/samples/preprocess-flatten.rb +19 -0
  167. data/samples/r0trace.rb +308 -0
  168. data/samples/rubstop.rb +399 -0
  169. data/samples/scan_pt_gnu_stack.rb +54 -0
  170. data/samples/scanpeexports.rb +62 -0
  171. data/samples/shellcode-c.rb +40 -0
  172. data/samples/shellcode-dynlink.rb +146 -0
  173. data/samples/source.asm +34 -0
  174. data/samples/struct_offset.rb +47 -0
  175. data/samples/testpe.rb +32 -0
  176. data/samples/testraw.rb +45 -0
  177. data/samples/win32genloader.rb +132 -0
  178. data/samples/win32hooker-advanced.rb +169 -0
  179. data/samples/win32hooker.rb +96 -0
  180. data/samples/win32livedasm.rb +33 -0
  181. data/samples/win32remotescan.rb +133 -0
  182. data/samples/wintrace.rb +92 -0
  183. data/tests/all.rb +8 -0
  184. data/tests/dasm.rb +39 -0
  185. data/tests/dynldr.rb +35 -0
  186. data/tests/encodeddata.rb +132 -0
  187. data/tests/ia32.rb +82 -0
  188. data/tests/mips.rb +116 -0
  189. data/tests/parse_c.rb +239 -0
  190. data/tests/preprocessor.rb +269 -0
  191. data/tests/x86_64.rb +62 -0
  192. metadata +255 -0
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This file is part of Metasm, the Ruby assembly manipulation suite
4
+ # Copyright (C) 2006-2009 Yoann GUILLOT
5
+ #
6
+ # Licence is LGPL, see LICENCE in the top-level directory
7
+
8
+ #
9
+ # this script scans directories recursively for ELF files which have a PT_GNU_STACK rwe or absent
10
+ # usage : scan_pt_gnu_stack.rb <dir> [<dir>]
11
+ #
12
+
13
+ require 'metasm'
14
+
15
+ def _puts(a)
16
+ puts a.to_s.ljust(60)
17
+ end
18
+ def _printadv(a)
19
+ $stderr.print a.to_s.ljust(60)[-60, 60] + "\r"
20
+ end
21
+
22
+ # the recursive scanning procedure
23
+ iter = lambda { |f|
24
+ if File.symlink? f
25
+ elsif File.directory? f
26
+ # show where we are & recurse
27
+ _printadv f
28
+ Dir[ File.join(f, '*') ].each { |ff|
29
+ iter[ff]
30
+ }
31
+ else
32
+ # interpret any file as a ELF
33
+ begin
34
+ elf = Metasm::ELF.decode_file_header(f)
35
+ next if not elf.segments or elf.header.type == 'REL'
36
+ seg = elf.segments.find { |seg_| seg_.type == 'GNU_STACK' }
37
+ if not seg
38
+ _puts "PT_GNU_STACK absent : #{f}"
39
+ elsif seg.flags.include? 'X'
40
+ _puts "PT_GNU_STACK RWE : #{f}"
41
+ else
42
+ _puts "#{f} : #{seg.inspect}" if $VERBOSE
43
+ end
44
+ rescue
45
+ # the file is not a valid ELF
46
+ _puts "E: #{f} #{$!}" if $VERBOSE
47
+ end
48
+ end
49
+ }
50
+
51
+ # go
52
+ ARGV.each { |dir| iter[dir] }
53
+
54
+ _printadv ''
@@ -0,0 +1,62 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2009 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+ #
7
+ # this script scans a directory for PE files which export a given symbol name (regexp case-insensitive)
8
+ # usage : ruby scanpeexports.rb <dir> <pattern>
9
+ #
10
+
11
+ require 'metasm'
12
+
13
+ if not base = ARGV.shift
14
+ puts 'base dir ?'
15
+ base = gets.chomp
16
+ end
17
+ if not pat = ARGV.shift
18
+ puts 'pattern ?'
19
+ pat = gets.chomp
20
+ puts 'searching...'
21
+ end
22
+
23
+ def _puts(a)
24
+ puts a.to_s.ljust(60)
25
+ end
26
+ def _printadv(a)
27
+ $stderr.print a.to_s.ljust(60)[-60, 60] + "\r"
28
+ end
29
+
30
+ # the recursive scanning procedure
31
+ iter = lambda { |f, match|
32
+ if File.directory? f
33
+ # show where we are & recurse
34
+ _printadv f
35
+ Dir[ File.join(f, '*') ].each { |ff|
36
+ iter[ff, match]
37
+ }
38
+ else
39
+ # interpret any file as a PE
40
+ begin
41
+ pe = Metasm::PE.decode_file_header(f)
42
+ pe.decode_exports
43
+ next if not pe.export
44
+ # scan the export directory for the symbol pattern, excluding forwarders
45
+ pe.export.exports.each { |exp|
46
+ if exp.name =~ /#{match}/i and not exp.forwarder_lib
47
+ _puts f + " : " + exp.name
48
+ end
49
+ }
50
+ rescue
51
+ # the file is not a valid PE
52
+ end
53
+ end
54
+ }
55
+
56
+ # go
57
+ iter[base, pat]
58
+
59
+ if RUBY_PLATFORM =~ /win32/i
60
+ _puts "press [enter] to exit"
61
+ gets
62
+ end
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+ # This file is part of Metasm, the Ruby assembly manipulation suite
3
+ # Copyright (C) 2006-2009 Yoann GUILLOT
4
+ #
5
+ # Licence is LGPL, see LICENCE in the top-level directory
6
+
7
+
8
+ #
9
+ # in this exemple we can write a shellcode using a C function
10
+ #
11
+
12
+ require 'metasm'
13
+
14
+ # load and decode the file
15
+ sc = Metasm::Shellcode.new(Metasm::Ia32.new)
16
+ sc.parse <<EOS
17
+ jmp c_func
18
+
19
+ some_func:
20
+ mov eax, 42
21
+ ret
22
+ EOS
23
+
24
+ cp = sc.cpu.new_cparser
25
+ cp.parse <<EOS
26
+ void some_func(void);
27
+ /* __declspec(naked) */ void c_func() {
28
+ int i;
29
+ for (i=0 ; i<10 ; ++i)
30
+ some_func();
31
+ }
32
+ EOS
33
+ asm = sc.cpu.new_ccompiler(cp, sc).compile
34
+
35
+ sc.parse asm
36
+ sc.assemble
37
+
38
+ sc.encode_file 'shellcode.raw'
39
+
40
+ puts Metasm::Shellcode.load_file('shellcode.raw', Metasm::Ia32.new).disassemble
@@ -0,0 +1,146 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2009 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+ # this script compiles a source file (asm or C) into a shellcode that will
7
+ # dynamically resolve the address of functions it uses
8
+ # windows only, supposes the shellcode is run in the address space of a process
9
+ # whose PEB allows to find all required libraries.
10
+
11
+ require 'metasm'
12
+
13
+ sc = Metasm::Shellcode.new(Metasm::Ia32.new)
14
+
15
+ case ARGV[0]
16
+ when /\.c(pp)?$/i
17
+ src_c = File.read(ARGV[0])
18
+ sc.assemble 'jmp main'
19
+ sc.compile_c src_c
20
+ when /\.asm$/i
21
+ src = File.read(ARGV[0])
22
+ sc.assemble src
23
+ when nil; abort "need sourcefile"
24
+ else abort "unknown srcfile extension"
25
+ end
26
+
27
+ # find external symbols needed by the shellcode
28
+ ext_syms = sc.encoded.reloc_externals
29
+
30
+ # resolver code
31
+ sc.parse <<EOS
32
+ get_libbase:
33
+ mov eax, fs:[0x30] // peb
34
+ mov eax, [eax+12] // peb_ldr
35
+ add eax, 12 // &inloadorder
36
+ libbase_loop:
37
+ mov eax, [eax] // next
38
+ mov edx, [eax+12*4] // basename ptr
39
+ mov cl, [edx+6]
40
+ shl ecx, 8
41
+ mov cl, [edx+4]
42
+ shl ecx, 8
43
+ mov cl, [edx+2]
44
+ shl ecx, 8
45
+ mov cl, [edx]
46
+ or ecx, 0x20202020 // downcase
47
+ cmp ecx, [esp+4]
48
+ jnz libbase_loop
49
+ mov eax, [eax+6*4] // baseaddr
50
+ ret 4
51
+
52
+ hash_name:
53
+ push ecx
54
+ push edx
55
+ xor eax, eax
56
+ xor ecx, ecx
57
+ mov edx, [esp+12]
58
+ dec edx
59
+ hash_loop:
60
+ ror eax, 0dh
61
+ add eax, ecx
62
+ inc edx
63
+ mov cl, [edx]
64
+ test cl, cl
65
+ jnz hash_loop
66
+ pop edx
67
+ pop ecx
68
+ ret 4
69
+
70
+ resolve_proc:
71
+ push ecx
72
+ push edx
73
+ push ebp
74
+ push dword ptr [esp+0x14] // arg_2
75
+ call get_libbase
76
+ mov ebp, eax // imagebase
77
+ add eax, [eax+0x3c] // coffhdr
78
+ mov edx, [eax+0x78] // exportdirectory
79
+ add edx, ebp
80
+ or ecx, -1
81
+ resolve_loop:
82
+ inc ecx
83
+ mov eax, [edx+0x20] // name
84
+ add eax, ebp
85
+ mov eax, [eax+4*ecx]
86
+ add eax, ebp
87
+ push eax
88
+ call hash_name
89
+ cmp eax, [esp+0x10] // cmp hash(name[i]), arg_1
90
+ jnz resolve_loop
91
+ mov eax, [edx+0x24] // ord
92
+ add eax, ebp
93
+ movzx ecx, word ptr [eax+2*ecx]
94
+ mov eax, [edx+0x1c] // func
95
+ add eax, ebp
96
+ mov eax, [eax+4*ecx] // func[ord[i]]
97
+ add eax, ebp
98
+ pop ebp
99
+ pop edx
100
+ pop ecx
101
+ ret 8
102
+ EOS
103
+
104
+ def hash_name(sym)
105
+ hash = 0
106
+ sym.each_byte { |char|
107
+ hash = (((hash >> 0xd) | (hash << (32-0xd))) + char) & 0xffff_ffff
108
+ }
109
+ hash
110
+ end
111
+
112
+ def lib_name(sym)
113
+ raise "unknown libname for #{sym}" if not lib = Metasm::WindowsExports::EXPORT[sym]
114
+ n = lib.downcase[0, 4].unpack('C*')
115
+ n[0] + (n[1]<<8) + (n[2] << 16) + (n[3] << 24)
116
+ end
117
+
118
+ # encode stub for each symbol
119
+ ext_syms.uniq.each { |sym|
120
+ next if sym == 'next_payload'
121
+ sc.parse <<EOS
122
+ #{sym}:
123
+ push #{lib_name(sym)}
124
+ push #{hash_name(sym)}
125
+ call resolve_proc
126
+ jmp eax
127
+ EOS
128
+ }
129
+
130
+ # marker to the next payload if the payload is a stager
131
+ sc.assemble "next_payload:"
132
+
133
+ # output to a file
134
+ sc.encode_file 'shellcode-dynlink.raw'
135
+
136
+ __END__
137
+ // sample payload
138
+
139
+ extern __stdcall int MessageBoxA(int, char*, char*, int);
140
+ extern void next_payload(void);
141
+
142
+ int main(void)
143
+ {
144
+ MessageBoxA(0, "Hello, world !", "Hi", 0);
145
+ next_payload();
146
+ }
@@ -0,0 +1,34 @@
1
+ .pt_gnu_stack rw // elf-specific instruction
2
+ //.interp none // request minimal elf, no section/dynamic/interpreter
3
+
4
+ #define __i386__
5
+ #include <asm/unistd.h> // can use the C preprocessor
6
+
7
+ stdout equ 1 // 'equ' constant definition
8
+
9
+ syscall macro nr // asm-style macros
10
+ mov eax, nr ; the syscall number goes in eax
11
+ int 80h
12
+ endm
13
+
14
+ #define syscall1(nr, arg) mov ebx, arg syscall(__NR_##nr) // c++-style macros
15
+ #define syscall3(nr, arg1, arg2, arg3) mov edx, arg3 mov ecx, arg2 syscall1(nr, arg1)
16
+
17
+ .entrypoint // the elf entrypoint
18
+ nop nop
19
+ call 1f // 1f is the first label named '1' found forward
20
+ toto_str db "toto\n"
21
+ toto_str_len equ $ - toto_str // $ is the address of the start of the current instruction/data
22
+
23
+ 1:
24
+ pop ebp
25
+
26
+ syscall3(write, stdout, ebp, toto_str_len)
27
+
28
+ /*
29
+ ; hang forever
30
+ jmp $
31
+ */
32
+
33
+ syscall1(exit, 0)
34
+ hlt
@@ -0,0 +1,47 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2009 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+ #
7
+ # This exemple illustrates the usage of the C parser to compute the offset of members of a given structure
8
+ # usage: struct_offset.rb <c file> <struct name>
9
+ #
10
+
11
+ require 'metasm'
12
+ include Metasm
13
+
14
+ require 'optparse'
15
+ opts = { :hdrs => [], :defs => {}, :path => [], :cpu => 'X86', :offbase => 16 }
16
+ OptionParser.new { |opt|
17
+ opt.on('-o outfile') { |f| opts[:outfile] = f }
18
+ opt.on('-H additional_header') { |f| opts[:hdrs] << f }
19
+ opt.on('-I path', '--includepath path') { |f| opts[:path] << f }
20
+ opt.on('-D var') { |f| k, v = f.split('=', 2) ; opts[:defs].update k => (v || '') }
21
+ opt.on('-d') { opts[:offbase] = 10 }
22
+ opt.on('--cpu CpuClass') { |c| opts[:cpu] = c }
23
+ opt.on('--gcc') { opts[:gcc] = true }
24
+ opt.on('--vs', '--visualstudio') { opts[:vs] = true }
25
+ }.parse!(ARGV)
26
+
27
+ cp = Metasm.const_get(opts[:cpu]).new.new_cparser
28
+
29
+ cp.prepare_gcc if opts[:gcc]
30
+ cp.prepare_visualstudio if opts[:vs]
31
+
32
+ pp = cp.lexer
33
+ pp.warn_redefinition = false
34
+ pp.include_search_path[0, 0] = opts[:path]
35
+ opts[:defs].each { |k, v| pp.define k, v }
36
+
37
+ cp.parse opts[:hdrs].map { |h| "#include <#{h}>" }.join("\n")
38
+
39
+ abort 'need source + struct name' unless ARGV.length >= 2
40
+
41
+ cp.parse_file(ARGV.shift)
42
+
43
+ $stdout.reopen File.open(opts[:outfile], 'w') if opts[:outfile]
44
+
45
+ ARGV.each { |structname|
46
+ puts cp.alloc_c_struct(structname)
47
+ }
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+ # This file is part of Metasm, the Ruby assembly manipulation suite
3
+ # Copyright (C) 2006-2009 Yoann GUILLOT
4
+ #
5
+ # Licence is LGPL, see LICENCE in the top-level directory
6
+
7
+
8
+ #
9
+ # a sample application
10
+ #
11
+
12
+
13
+ require 'metasm'
14
+
15
+ pe = Metasm::PE.assemble Metasm::Ia32.new, <<EOS
16
+ .entrypoint
17
+ push 0
18
+ push title
19
+ push message
20
+ push 0
21
+ call messagebox
22
+
23
+ xor eax, eax
24
+ ret
25
+
26
+ .import 'user32' MessageBoxA messagebox
27
+
28
+ .data
29
+ message db 'kikoo lol', 0
30
+ title db 'blaaa', 0
31
+ EOS
32
+ pe.encode_file 'testpe.exe'
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+ # This file is part of Metasm, the Ruby assembly manipulation suite
3
+ # Copyright (C) 2006-2009 Yoann GUILLOT
4
+ #
5
+ # Licence is LGPL, see LICENCE in the top-level directory
6
+
7
+
8
+
9
+ # usage: test.rb < source.asm
10
+
11
+ require 'metasm'
12
+
13
+
14
+ dump = ARGV.delete '--dump'
15
+
16
+ source = ARGF.read
17
+
18
+ cpu = Metasm::Ia32.new
19
+ shellcode = Metasm::Shellcode.assemble(cpu, source).encode_string
20
+ shellstring = shellcode.unpack('C*').map { |b| '\\x%02x' % b }.join
21
+
22
+ if dump
23
+ puts shellstring
24
+ exit
25
+ end
26
+
27
+ File.open('test-testraw.c', 'w') { |fd|
28
+ fd.puts <<EOS
29
+ unsigned char sc[] = "#{shellstring}";
30
+ int main(void)
31
+ {
32
+ ((void (*)())sc)();
33
+ return 42;
34
+ }
35
+ EOS
36
+ }
37
+
38
+ system 'gcc -W -Wall -o test-testraw test-testraw.c'
39
+ system 'chpax -psm test-testraw'
40
+
41
+ puts "running"
42
+ system './test-testraw'
43
+ puts "done"
44
+ #File.unlink 'test-testraw'
45
+ File.unlink 'test-testraw.c'