metasm 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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'