librex 0.0.13 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (435) hide show
  1. data/README.markdown +1 -1
  2. data/Rakefile +1 -0
  3. metadata +3 -435
  4. data/lib/rex/LICENSE +0 -29
  5. data/lib/rex/arch.rb +0 -103
  6. data/lib/rex/arch/sparc.rb +0 -75
  7. data/lib/rex/arch/sparc.rb.ut.rb +0 -18
  8. data/lib/rex/arch/x86.rb +0 -513
  9. data/lib/rex/arch/x86.rb.ut.rb +0 -93
  10. data/lib/rex/assembly/nasm.rb +0 -104
  11. data/lib/rex/assembly/nasm.rb.ut.rb +0 -22
  12. data/lib/rex/codepage.map +0 -104
  13. data/lib/rex/compat.rb +0 -311
  14. data/lib/rex/constants.rb +0 -113
  15. data/lib/rex/elfparsey.rb +0 -11
  16. data/lib/rex/elfparsey/elf.rb +0 -123
  17. data/lib/rex/elfparsey/elfbase.rb +0 -258
  18. data/lib/rex/elfparsey/exceptions.rb +0 -27
  19. data/lib/rex/elfscan.rb +0 -12
  20. data/lib/rex/elfscan/scanner.rb +0 -207
  21. data/lib/rex/elfscan/search.rb +0 -46
  22. data/lib/rex/encoder/alpha2.rb +0 -31
  23. data/lib/rex/encoder/alpha2/alpha_mixed.rb +0 -68
  24. data/lib/rex/encoder/alpha2/alpha_upper.rb +0 -79
  25. data/lib/rex/encoder/alpha2/generic.rb +0 -114
  26. data/lib/rex/encoder/alpha2/unicode_mixed.rb +0 -117
  27. data/lib/rex/encoder/alpha2/unicode_upper.rb +0 -129
  28. data/lib/rex/encoder/ndr.rb +0 -89
  29. data/lib/rex/encoder/ndr.rb.ut.rb +0 -44
  30. data/lib/rex/encoder/nonalpha.rb +0 -61
  31. data/lib/rex/encoder/nonupper.rb +0 -64
  32. data/lib/rex/encoder/xdr.rb +0 -106
  33. data/lib/rex/encoder/xdr.rb.ut.rb +0 -29
  34. data/lib/rex/encoder/xor.rb +0 -69
  35. data/lib/rex/encoder/xor/dword.rb +0 -13
  36. data/lib/rex/encoder/xor/dword_additive.rb +0 -13
  37. data/lib/rex/encoders/xor_dword.rb +0 -35
  38. data/lib/rex/encoders/xor_dword_additive.rb +0 -53
  39. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +0 -12
  40. data/lib/rex/encoding/xor.rb +0 -20
  41. data/lib/rex/encoding/xor.rb.ts.rb +0 -14
  42. data/lib/rex/encoding/xor/byte.rb +0 -15
  43. data/lib/rex/encoding/xor/byte.rb.ut.rb +0 -21
  44. data/lib/rex/encoding/xor/dword.rb +0 -21
  45. data/lib/rex/encoding/xor/dword.rb.ut.rb +0 -15
  46. data/lib/rex/encoding/xor/dword_additive.rb +0 -92
  47. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +0 -15
  48. data/lib/rex/encoding/xor/exceptions.rb +0 -17
  49. data/lib/rex/encoding/xor/generic.rb +0 -146
  50. data/lib/rex/encoding/xor/generic.rb.ut.rb +0 -120
  51. data/lib/rex/encoding/xor/qword.rb +0 -15
  52. data/lib/rex/encoding/xor/word.rb +0 -21
  53. data/lib/rex/encoding/xor/word.rb.ut.rb +0 -13
  54. data/lib/rex/exceptions.rb +0 -275
  55. data/lib/rex/exceptions.rb.ut.rb +0 -44
  56. data/lib/rex/exploitation/cmdstager.rb +0 -9
  57. data/lib/rex/exploitation/cmdstager/base.rb +0 -175
  58. data/lib/rex/exploitation/cmdstager/debug_asm.rb +0 -142
  59. data/lib/rex/exploitation/cmdstager/debug_write.rb +0 -136
  60. data/lib/rex/exploitation/cmdstager/tftp.rb +0 -63
  61. data/lib/rex/exploitation/cmdstager/vbs.rb +0 -128
  62. data/lib/rex/exploitation/egghunter.rb +0 -277
  63. data/lib/rex/exploitation/egghunter.rb.ut.rb +0 -25
  64. data/lib/rex/exploitation/encryptjs.rb +0 -77
  65. data/lib/rex/exploitation/heaplib.js.b64 +0 -331
  66. data/lib/rex/exploitation/heaplib.rb +0 -94
  67. data/lib/rex/exploitation/javascriptosdetect.rb +0 -897
  68. data/lib/rex/exploitation/obfuscatejs.rb +0 -335
  69. data/lib/rex/exploitation/omelet.rb +0 -320
  70. data/lib/rex/exploitation/omelet.rb.ut.rb +0 -13
  71. data/lib/rex/exploitation/opcodedb.rb +0 -818
  72. data/lib/rex/exploitation/opcodedb.rb.ut.rb +0 -279
  73. data/lib/rex/exploitation/seh.rb +0 -92
  74. data/lib/rex/exploitation/seh.rb.ut.rb +0 -19
  75. data/lib/rex/file.rb +0 -112
  76. data/lib/rex/file.rb.ut.rb +0 -16
  77. data/lib/rex/image_source.rb +0 -12
  78. data/lib/rex/image_source/disk.rb +0 -60
  79. data/lib/rex/image_source/image_source.rb +0 -46
  80. data/lib/rex/image_source/memory.rb +0 -37
  81. data/lib/rex/io/bidirectional_pipe.rb +0 -157
  82. data/lib/rex/io/datagram_abstraction.rb +0 -35
  83. data/lib/rex/io/stream.rb +0 -319
  84. data/lib/rex/io/stream_abstraction.rb +0 -197
  85. data/lib/rex/io/stream_server.rb +0 -211
  86. data/lib/rex/job_container.rb +0 -187
  87. data/lib/rex/logging.rb +0 -4
  88. data/lib/rex/logging/log_dispatcher.rb +0 -179
  89. data/lib/rex/logging/log_sink.rb +0 -42
  90. data/lib/rex/logging/sinks/flatfile.rb +0 -55
  91. data/lib/rex/logging/sinks/stderr.rb +0 -43
  92. data/lib/rex/machparsey.rb +0 -9
  93. data/lib/rex/machparsey/exceptions.rb +0 -34
  94. data/lib/rex/machparsey/mach.rb +0 -209
  95. data/lib/rex/machparsey/machbase.rb +0 -408
  96. data/lib/rex/machscan.rb +0 -9
  97. data/lib/rex/machscan/scanner.rb +0 -217
  98. data/lib/rex/mime.rb +0 -9
  99. data/lib/rex/mime/header.rb +0 -77
  100. data/lib/rex/mime/message.rb +0 -144
  101. data/lib/rex/mime/part.rb +0 -20
  102. data/lib/rex/nop/opty2.rb +0 -108
  103. data/lib/rex/nop/opty2.rb.ut.rb +0 -23
  104. data/lib/rex/nop/opty2_tables.rb +0 -300
  105. data/lib/rex/ole.rb +0 -205
  106. data/lib/rex/ole/clsid.rb +0 -47
  107. data/lib/rex/ole/difat.rb +0 -141
  108. data/lib/rex/ole/directory.rb +0 -231
  109. data/lib/rex/ole/direntry.rb +0 -240
  110. data/lib/rex/ole/docs/dependencies.txt +0 -8
  111. data/lib/rex/ole/docs/references.txt +0 -1
  112. data/lib/rex/ole/fat.rb +0 -99
  113. data/lib/rex/ole/header.rb +0 -204
  114. data/lib/rex/ole/minifat.rb +0 -77
  115. data/lib/rex/ole/propset.rb +0 -144
  116. data/lib/rex/ole/samples/create_ole.rb +0 -27
  117. data/lib/rex/ole/samples/dir.rb +0 -35
  118. data/lib/rex/ole/samples/dump_stream.rb +0 -34
  119. data/lib/rex/ole/samples/ole_info.rb +0 -23
  120. data/lib/rex/ole/storage.rb +0 -395
  121. data/lib/rex/ole/stream.rb +0 -53
  122. data/lib/rex/ole/substorage.rb +0 -49
  123. data/lib/rex/ole/util.rb +0 -157
  124. data/lib/rex/parser/arguments.rb +0 -97
  125. data/lib/rex/parser/arguments.rb.ut.rb +0 -67
  126. data/lib/rex/parser/ini.rb +0 -185
  127. data/lib/rex/parser/ini.rb.ut.rb +0 -29
  128. data/lib/rex/parser/ip360_aspl_xml.rb +0 -102
  129. data/lib/rex/parser/ip360_xml.rb +0 -93
  130. data/lib/rex/parser/nessus_xml.rb +0 -118
  131. data/lib/rex/parser/netsparker_xml.rb +0 -94
  132. data/lib/rex/parser/nexpose_xml.rb +0 -131
  133. data/lib/rex/parser/nmap_xml.rb +0 -121
  134. data/lib/rex/parser/retina_xml.rb +0 -109
  135. data/lib/rex/payloads.rb +0 -1
  136. data/lib/rex/payloads/win32.rb +0 -2
  137. data/lib/rex/payloads/win32/common.rb +0 -26
  138. data/lib/rex/payloads/win32/kernel.rb +0 -53
  139. data/lib/rex/payloads/win32/kernel/common.rb +0 -54
  140. data/lib/rex/payloads/win32/kernel/migration.rb +0 -12
  141. data/lib/rex/payloads/win32/kernel/recovery.rb +0 -50
  142. data/lib/rex/payloads/win32/kernel/stager.rb +0 -194
  143. data/lib/rex/peparsey.rb +0 -12
  144. data/lib/rex/peparsey/exceptions.rb +0 -32
  145. data/lib/rex/peparsey/pe.rb +0 -212
  146. data/lib/rex/peparsey/pe_memdump.rb +0 -63
  147. data/lib/rex/peparsey/pebase.rb +0 -1680
  148. data/lib/rex/peparsey/section.rb +0 -136
  149. data/lib/rex/pescan.rb +0 -13
  150. data/lib/rex/pescan/analyze.rb +0 -309
  151. data/lib/rex/pescan/scanner.rb +0 -206
  152. data/lib/rex/pescan/search.rb +0 -56
  153. data/lib/rex/platforms.rb +0 -1
  154. data/lib/rex/platforms/windows.rb +0 -51
  155. data/lib/rex/poly.rb +0 -132
  156. data/lib/rex/poly/block.rb +0 -477
  157. data/lib/rex/poly/register.rb +0 -100
  158. data/lib/rex/poly/register/x86.rb +0 -40
  159. data/lib/rex/post.rb +0 -8
  160. data/lib/rex/post/dir.rb +0 -51
  161. data/lib/rex/post/file.rb +0 -172
  162. data/lib/rex/post/file_stat.rb +0 -220
  163. data/lib/rex/post/gen.pl +0 -13
  164. data/lib/rex/post/io.rb +0 -182
  165. data/lib/rex/post/meterpreter.rb +0 -4
  166. data/lib/rex/post/meterpreter/channel.rb +0 -445
  167. data/lib/rex/post/meterpreter/channel_container.rb +0 -54
  168. data/lib/rex/post/meterpreter/channels/pool.rb +0 -160
  169. data/lib/rex/post/meterpreter/channels/pools/file.rb +0 -62
  170. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +0 -103
  171. data/lib/rex/post/meterpreter/channels/stream.rb +0 -87
  172. data/lib/rex/post/meterpreter/client.rb +0 -364
  173. data/lib/rex/post/meterpreter/client_core.rb +0 -274
  174. data/lib/rex/post/meterpreter/dependencies.rb +0 -3
  175. data/lib/rex/post/meterpreter/extension.rb +0 -32
  176. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +0 -58
  177. data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +0 -16
  178. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +0 -94
  179. data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +0 -21
  180. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +0 -57
  181. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +0 -15
  182. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +0 -118
  183. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +0 -61
  184. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +0 -111
  185. data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +0 -28
  186. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +0 -101
  187. data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +0 -26
  188. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +0 -333
  189. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +0 -282
  190. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +0 -266
  191. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +0 -103
  192. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +0 -48
  193. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +0 -144
  194. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +0 -73
  195. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +0 -56
  196. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +0 -137
  197. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +0 -180
  198. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +0 -167
  199. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +0 -208
  200. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +0 -6
  201. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +0 -38106
  202. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +0 -31
  203. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +0 -47
  204. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +0 -36
  205. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +0 -1818
  206. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +0 -96
  207. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +0 -3848
  208. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +0 -26
  209. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +0 -153
  210. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +0 -21
  211. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +0 -3169
  212. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +0 -599
  213. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +0 -318
  214. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +0 -100
  215. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +0 -42
  216. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +0 -148
  217. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +0 -127
  218. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +0 -309
  219. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +0 -204
  220. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +0 -51
  221. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +0 -630
  222. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +0 -75
  223. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +0 -103
  224. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +0 -149
  225. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +0 -97
  226. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +0 -192
  227. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +0 -41
  228. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +0 -61
  229. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +0 -370
  230. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +0 -129
  231. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +0 -55
  232. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +0 -336
  233. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +0 -141
  234. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +0 -279
  235. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +0 -193
  236. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +0 -102
  237. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +0 -180
  238. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +0 -211
  239. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +0 -227
  240. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +0 -63
  241. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +0 -30
  242. data/lib/rex/post/meterpreter/object_aliases.rb +0 -83
  243. data/lib/rex/post/meterpreter/packet.rb +0 -688
  244. data/lib/rex/post/meterpreter/packet_dispatcher.rb +0 -431
  245. data/lib/rex/post/meterpreter/packet_parser.rb +0 -94
  246. data/lib/rex/post/meterpreter/packet_response_waiter.rb +0 -83
  247. data/lib/rex/post/meterpreter/ui/console.rb +0 -137
  248. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +0 -62
  249. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +0 -730
  250. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +0 -108
  251. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +0 -241
  252. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +0 -231
  253. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +0 -61
  254. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +0 -98
  255. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +0 -51
  256. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +0 -132
  257. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +0 -187
  258. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +0 -65
  259. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +0 -442
  260. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +0 -298
  261. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +0 -486
  262. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +0 -315
  263. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +0 -157
  264. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +0 -95
  265. data/lib/rex/post/permission.rb +0 -26
  266. data/lib/rex/post/process.rb +0 -57
  267. data/lib/rex/post/thread.rb +0 -57
  268. data/lib/rex/post/ui.rb +0 -52
  269. data/lib/rex/proto.rb +0 -13
  270. data/lib/rex/proto.rb.ts.rb +0 -8
  271. data/lib/rex/proto/dcerpc.rb +0 -6
  272. data/lib/rex/proto/dcerpc.rb.ts.rb +0 -9
  273. data/lib/rex/proto/dcerpc/client.rb +0 -361
  274. data/lib/rex/proto/dcerpc/client.rb.ut.rb +0 -491
  275. data/lib/rex/proto/dcerpc/exceptions.rb +0 -150
  276. data/lib/rex/proto/dcerpc/handle.rb +0 -47
  277. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +0 -85
  278. data/lib/rex/proto/dcerpc/ndr.rb +0 -72
  279. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +0 -41
  280. data/lib/rex/proto/dcerpc/packet.rb +0 -253
  281. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +0 -56
  282. data/lib/rex/proto/dcerpc/response.rb +0 -187
  283. data/lib/rex/proto/dcerpc/response.rb.ut.rb +0 -15
  284. data/lib/rex/proto/dcerpc/uuid.rb +0 -84
  285. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +0 -46
  286. data/lib/rex/proto/dhcp.rb +0 -7
  287. data/lib/rex/proto/dhcp/constants.rb +0 -33
  288. data/lib/rex/proto/dhcp/server.rb +0 -292
  289. data/lib/rex/proto/drda.rb +0 -5
  290. data/lib/rex/proto/drda.rb.ts.rb +0 -17
  291. data/lib/rex/proto/drda/constants.rb +0 -49
  292. data/lib/rex/proto/drda/constants.rb.ut.rb +0 -23
  293. data/lib/rex/proto/drda/packet.rb +0 -252
  294. data/lib/rex/proto/drda/packet.rb.ut.rb +0 -109
  295. data/lib/rex/proto/drda/utils.rb +0 -123
  296. data/lib/rex/proto/drda/utils.rb.ut.rb +0 -84
  297. data/lib/rex/proto/http.rb +0 -5
  298. data/lib/rex/proto/http.rb.ts.rb +0 -12
  299. data/lib/rex/proto/http/client.rb +0 -821
  300. data/lib/rex/proto/http/client.rb.ut.rb +0 -95
  301. data/lib/rex/proto/http/handler.rb +0 -46
  302. data/lib/rex/proto/http/handler/erb.rb +0 -128
  303. data/lib/rex/proto/http/handler/erb.rb.ut.rb +0 -21
  304. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +0 -1
  305. data/lib/rex/proto/http/handler/proc.rb +0 -60
  306. data/lib/rex/proto/http/handler/proc.rb.ut.rb +0 -24
  307. data/lib/rex/proto/http/header.rb +0 -161
  308. data/lib/rex/proto/http/header.rb.ut.rb +0 -46
  309. data/lib/rex/proto/http/packet.rb +0 -407
  310. data/lib/rex/proto/http/packet.rb.ut.rb +0 -165
  311. data/lib/rex/proto/http/request.rb +0 -356
  312. data/lib/rex/proto/http/request.rb.ut.rb +0 -214
  313. data/lib/rex/proto/http/response.rb +0 -90
  314. data/lib/rex/proto/http/response.rb.ut.rb +0 -149
  315. data/lib/rex/proto/http/server.rb +0 -369
  316. data/lib/rex/proto/http/server.rb.ut.rb +0 -79
  317. data/lib/rex/proto/ntlm.rb +0 -7
  318. data/lib/rex/proto/ntlm.rb.ut.rb +0 -177
  319. data/lib/rex/proto/ntlm/base.rb +0 -326
  320. data/lib/rex/proto/ntlm/constants.rb +0 -74
  321. data/lib/rex/proto/ntlm/crypt.rb +0 -415
  322. data/lib/rex/proto/ntlm/exceptions.rb +0 -9
  323. data/lib/rex/proto/ntlm/message.rb +0 -533
  324. data/lib/rex/proto/ntlm/utils.rb +0 -763
  325. data/lib/rex/proto/proxy/socks4a.rb +0 -440
  326. data/lib/rex/proto/rfb.rb +0 -19
  327. data/lib/rex/proto/rfb.rb.ut.rb +0 -37
  328. data/lib/rex/proto/rfb/cipher.rb +0 -84
  329. data/lib/rex/proto/rfb/client.rb +0 -207
  330. data/lib/rex/proto/rfb/constants.rb +0 -52
  331. data/lib/rex/proto/smb.rb +0 -7
  332. data/lib/rex/proto/smb.rb.ts.rb +0 -8
  333. data/lib/rex/proto/smb/client.rb +0 -1952
  334. data/lib/rex/proto/smb/client.rb.ut.rb +0 -223
  335. data/lib/rex/proto/smb/constants.rb +0 -1047
  336. data/lib/rex/proto/smb/constants.rb.ut.rb +0 -18
  337. data/lib/rex/proto/smb/crypt.rb +0 -36
  338. data/lib/rex/proto/smb/evasions.rb +0 -66
  339. data/lib/rex/proto/smb/exceptions.rb +0 -858
  340. data/lib/rex/proto/smb/simpleclient.rb +0 -306
  341. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +0 -128
  342. data/lib/rex/proto/smb/utils.rb +0 -103
  343. data/lib/rex/proto/smb/utils.rb.ut.rb +0 -20
  344. data/lib/rex/proto/sunrpc.rb +0 -1
  345. data/lib/rex/proto/sunrpc/client.rb +0 -195
  346. data/lib/rex/proto/tftp.rb +0 -12
  347. data/lib/rex/proto/tftp/constants.rb +0 -39
  348. data/lib/rex/proto/tftp/server.rb +0 -497
  349. data/lib/rex/proto/tftp/server.rb.ut.rb +0 -28
  350. data/lib/rex/script.rb +0 -42
  351. data/lib/rex/script/base.rb +0 -59
  352. data/lib/rex/script/meterpreter.rb +0 -15
  353. data/lib/rex/script/shell.rb +0 -9
  354. data/lib/rex/service.rb +0 -48
  355. data/lib/rex/service_manager.rb +0 -141
  356. data/lib/rex/service_manager.rb.ut.rb +0 -32
  357. data/lib/rex/services/local_relay.rb +0 -423
  358. data/lib/rex/socket.rb +0 -684
  359. data/lib/rex/socket.rb.ut.rb +0 -107
  360. data/lib/rex/socket/comm.rb +0 -119
  361. data/lib/rex/socket/comm/local.rb +0 -412
  362. data/lib/rex/socket/comm/local.rb.ut.rb +0 -75
  363. data/lib/rex/socket/ip.rb +0 -130
  364. data/lib/rex/socket/parameters.rb +0 -345
  365. data/lib/rex/socket/parameters.rb.ut.rb +0 -51
  366. data/lib/rex/socket/range_walker.rb +0 -346
  367. data/lib/rex/socket/range_walker.rb.ut.rb +0 -55
  368. data/lib/rex/socket/ssl_tcp.rb +0 -184
  369. data/lib/rex/socket/ssl_tcp.rb.ut.rb +0 -39
  370. data/lib/rex/socket/ssl_tcp_server.rb +0 -122
  371. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +0 -61
  372. data/lib/rex/socket/subnet_walker.rb +0 -75
  373. data/lib/rex/socket/subnet_walker.rb.ut.rb +0 -28
  374. data/lib/rex/socket/switch_board.rb +0 -278
  375. data/lib/rex/socket/switch_board.rb.ut.rb +0 -52
  376. data/lib/rex/socket/tcp.rb +0 -76
  377. data/lib/rex/socket/tcp.rb.ut.rb +0 -64
  378. data/lib/rex/socket/tcp_server.rb +0 -67
  379. data/lib/rex/socket/tcp_server.rb.ut.rb +0 -44
  380. data/lib/rex/socket/udp.rb +0 -164
  381. data/lib/rex/socket/udp.rb.ut.rb +0 -44
  382. data/lib/rex/struct2.rb +0 -5
  383. data/lib/rex/struct2/c_struct.rb +0 -181
  384. data/lib/rex/struct2/c_struct_template.rb +0 -39
  385. data/lib/rex/struct2/constant.rb +0 -26
  386. data/lib/rex/struct2/element.rb +0 -44
  387. data/lib/rex/struct2/generic.rb +0 -73
  388. data/lib/rex/struct2/restraint.rb +0 -54
  389. data/lib/rex/struct2/s_string.rb +0 -72
  390. data/lib/rex/struct2/s_struct.rb +0 -111
  391. data/lib/rex/sync.rb +0 -6
  392. data/lib/rex/sync/event.rb +0 -94
  393. data/lib/rex/sync/read_write_lock.rb +0 -176
  394. data/lib/rex/sync/ref.rb +0 -57
  395. data/lib/rex/sync/thread_safe.rb +0 -82
  396. data/lib/rex/test.rb +0 -35
  397. data/lib/rex/text.rb +0 -1149
  398. data/lib/rex/text.rb.ut.rb +0 -190
  399. data/lib/rex/thread_factory.rb +0 -42
  400. data/lib/rex/time.rb +0 -65
  401. data/lib/rex/transformer.rb +0 -115
  402. data/lib/rex/transformer.rb.ut.rb +0 -38
  403. data/lib/rex/ui.rb +0 -21
  404. data/lib/rex/ui/interactive.rb +0 -254
  405. data/lib/rex/ui/output.rb +0 -78
  406. data/lib/rex/ui/output/none.rb +0 -18
  407. data/lib/rex/ui/progress_tracker.rb +0 -96
  408. data/lib/rex/ui/subscriber.rb +0 -149
  409. data/lib/rex/ui/text/color.rb +0 -97
  410. data/lib/rex/ui/text/color.rb.ut.rb +0 -18
  411. data/lib/rex/ui/text/dispatcher_shell.rb +0 -467
  412. data/lib/rex/ui/text/input.rb +0 -117
  413. data/lib/rex/ui/text/input/buffer.rb +0 -75
  414. data/lib/rex/ui/text/input/readline.rb +0 -129
  415. data/lib/rex/ui/text/input/socket.rb +0 -95
  416. data/lib/rex/ui/text/input/stdio.rb +0 -45
  417. data/lib/rex/ui/text/irb_shell.rb +0 -57
  418. data/lib/rex/ui/text/output.rb +0 -80
  419. data/lib/rex/ui/text/output/buffer.rb +0 -61
  420. data/lib/rex/ui/text/output/file.rb +0 -43
  421. data/lib/rex/ui/text/output/socket.rb +0 -43
  422. data/lib/rex/ui/text/output/stdio.rb +0 -40
  423. data/lib/rex/ui/text/progress_tracker.rb +0 -56
  424. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +0 -34
  425. data/lib/rex/ui/text/shell.rb +0 -328
  426. data/lib/rex/ui/text/table.rb +0 -279
  427. data/lib/rex/ui/text/table.rb.ut.rb +0 -55
  428. data/lib/rex/zip.rb +0 -93
  429. data/lib/rex/zip/archive.rb +0 -184
  430. data/lib/rex/zip/blocks.rb +0 -182
  431. data/lib/rex/zip/entry.rb +0 -104
  432. data/lib/rex/zip/samples/comment.rb +0 -32
  433. data/lib/rex/zip/samples/mkwar.rb +0 -138
  434. data/lib/rex/zip/samples/mkzip.rb +0 -19
  435. data/lib/rex/zip/samples/recursive.rb +0 -58
data/lib/rex/peparsey.rb DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # $Id: peparsey.rb 5413 2008-02-13 02:43:56Z ramon $
4
-
5
- module Rex
6
- module PeParsey
7
-
8
- end
9
- end
10
-
11
- require 'rex/peparsey/pe'
12
- require 'rex/peparsey/pe_memdump'
@@ -1,32 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # $Id: exceptions.rb 5871 2008-11-10 21:18:12Z hdm $
4
-
5
- module Rex
6
- module PeParsey
7
-
8
- class PeError < ::RuntimeError
9
- end
10
-
11
- class ParseError < PeError
12
- end
13
-
14
- class DosHeaderError < ParseError
15
- end
16
-
17
- class FileHeaderError < ParseError
18
- end
19
-
20
- class OptionalHeaderError < ParseError
21
- end
22
-
23
- class BoundsError < PeError
24
- end
25
-
26
- class WtfError < PeError
27
- end
28
-
29
- class SkipError < PeError
30
- end
31
-
32
- end end
@@ -1,212 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # $Id: pe.rb 10036 2010-08-18 04:39:38Z jduck $
4
-
5
- require 'rex/image_source'
6
- require 'rex/peparsey/exceptions'
7
- require 'rex/peparsey/pebase'
8
- require 'rex/peparsey/section'
9
- require 'rex/struct2'
10
-
11
- module Rex
12
- module PeParsey
13
- class Pe < PeBase
14
-
15
- def initialize(isource)
16
-
17
- #
18
- # DOS Header
19
- #
20
- # Parse the initial dos header, starting at the file beginning
21
- #
22
- offset = 0
23
- dos_header = self.class._parse_dos_header(isource.read(offset, IMAGE_DOS_HEADER_SIZE))
24
-
25
- #
26
- # File Header
27
- #
28
- # If there is going to be a PE, the dos header tells us where to find it
29
- # So now we try to parse the file (pe) header
30
- #
31
- offset += dos_header.e_lfanew
32
-
33
- # most likely an invalid e_lfanew...
34
- if offset > isource.size
35
- raise FileHeaderError, "e_lfanew looks invalid", caller
36
- end
37
-
38
- file_header = self.class._parse_file_header(isource.read(offset, IMAGE_FILE_HEADER_SIZE))
39
-
40
- #
41
- # Optional Header
42
- #
43
- # After the file header, we find the optional header. Right now
44
- # we require a optional header. Despite it's name, all binaries
45
- # that we are interested in should have one. We need this
46
- # header for a lot of stuff, so we die without it...
47
- #
48
- offset += IMAGE_FILE_HEADER_SIZE
49
- optional_header = self.class._parse_optional_header(
50
- isource.read(offset, file_header.SizeOfOptionalHeader)
51
- )
52
-
53
- if !optional_header
54
- raise OptionalHeaderError, "No optional header!", caller
55
- end
56
-
57
- base = optional_header.ImageBase
58
-
59
- #
60
- # Section Headers
61
- #
62
- # After the optional header should be the section headers.
63
- # We know how many there should be from the file header...
64
- #
65
- offset += file_header.SizeOfOptionalHeader
66
-
67
- num_sections = file_header.NumberOfSections
68
- section_headers = self.class._parse_section_headers(
69
- isource.read(offset, IMAGE_SIZEOF_SECTION_HEADER * num_sections)
70
- )
71
-
72
- #
73
- # End of Headers
74
- #
75
- # After the section headers (which are padded to FileAlignment)
76
- # we should find the section data, described by the section
77
- # headers...
78
- #
79
- # So this is the end of our header data, lets store this
80
- # in an image source for possible access later...
81
- #
82
- offset += IMAGE_SIZEOF_SECTION_HEADER * num_sections
83
- offset = self.class._align_offset(offset, optional_header.FileAlignment)
84
-
85
- header_section = Section.new(isource.subsource(0, offset), 0, nil)
86
-
87
- #
88
- # Sections
89
- #
90
- # So from here on out should be section data, and then any
91
- # trailing data (like authenticode and stuff I think)
92
- #
93
-
94
- sections = [ ]
95
-
96
- section_headers.each do |section_header|
97
-
98
- rva = section_header.VirtualAddress
99
- size = section_header.SizeOfRawData
100
- file_offset = section_header.PointerToRawData
101
-
102
- sections << Section.new(
103
- isource.subsource(file_offset, size),
104
- rva,
105
- section_header
106
- )
107
- end
108
-
109
-
110
-
111
- #
112
- # Save the stuffs!
113
- #
114
- # We have parsed enough to load the file up here, now we just
115
- # save off all of the structures and data... We will
116
- # save our fake header section, the real sections, etc.
117
- #
118
-
119
- #
120
- # These should not be accessed directly
121
- #
122
-
123
- self._isource = isource
124
-
125
- self._dos_header = dos_header
126
- self._file_header = file_header
127
- self._optional_header = optional_header
128
- self._section_headers = section_headers
129
-
130
- self.image_base = base
131
- self.sections = sections
132
- self.header_section = header_section
133
-
134
- self._config_header = _parse_config_header()
135
- self._tls_header = _parse_tls_header()
136
-
137
- # These can be accessed directly
138
- self.hdr = HeaderAccessor.new
139
- self.hdr.dos = self._dos_header
140
- self.hdr.file = self._file_header
141
- self.hdr.opt = self._optional_header
142
- self.hdr.sections = self._section_headers
143
- self.hdr.config = self._config_header
144
- self.hdr.tls = self._tls_header
145
- self.hdr.exceptions = self._exception_header
146
-
147
- # We load the exception directory last as it relies on hdr.file to be created above.
148
- self._exception_header = _load_exception_directory()
149
- end
150
-
151
- #
152
- # Return everything that's going to be mapped in the process
153
- # and accessable. This should include all of the sections
154
- # and our "fake" section for the header data...
155
- #
156
- def all_sections
157
- [ header_section ] + sections
158
- end
159
-
160
- #
161
- # Returns true if this binary is for a 64-bit architecture.
162
- #
163
- def ptr_64?
164
- [
165
- IMAGE_FILE_MACHINE_IA64,
166
- IMAGE_FILE_MACHINE_ALPHA64,
167
- IMAGE_FILE_MACHINE_AMD64
168
- ].include?(self._file_header.Machine)
169
- end
170
-
171
- #
172
- # Returns true if this binary is for a 32-bit architecture.
173
- # This check does not take into account 16-bit binaries at the moment.
174
- #
175
- def ptr_32?
176
- ptr_64? == false
177
- end
178
-
179
- #
180
- # Converts a virtual address to a string representation based on the
181
- # underlying architecture.
182
- #
183
- def ptr_s(va)
184
- (ptr_32?) ? ("0x%.8x" % va) : ("0x%.16x" % va)
185
- end
186
-
187
- #
188
- # Converts a file offset into a virtual address
189
- #
190
- def file_offset_to_va(offset)
191
- image_base + file_offset_to_rva(offset)
192
- end
193
-
194
- #
195
- # Read raw bytes from the specified offset in the underlying file
196
- #
197
- # NOTE: You should pass raw file offsets into this, not offsets from
198
- # the beginning of the section. If you need to read from within a
199
- # section, add section.file_offset prior to passing the offset in.
200
- #
201
- def read(offset, len)
202
- _isource.read(offset, len)
203
- end
204
-
205
- def size
206
- _isource.size
207
- end
208
- def length
209
- _isource.size
210
- end
211
-
212
- end end end
@@ -1,63 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # $Id: pe_memdump.rb 5871 2008-11-10 21:18:12Z hdm $
4
-
5
- require 'rex/image_source'
6
- require 'rex/peparsey/exceptions'
7
- require 'rex/peparsey/pebase'
8
- require 'rex/peparsey/section'
9
- require 'rex/struct2'
10
-
11
- #
12
- # This class is for use with memdump.exe generated dump images. It basically
13
- # just lies, gets the ImageBase from the file name, and generates 1 big
14
- # header_section with all of the data in it...
15
- #
16
-
17
- module Rex
18
- module PeParsey
19
- class PeMemDump < Pe
20
-
21
- def self.new_from_string(data)
22
- raise NotImplementError
23
- end
24
-
25
- def self.new_from_file(filename, disk_backed = false)
26
-
27
- if filename[-4, 4] != '.rng'
28
- raise "Not a .rng file: #{filename}"
29
- end
30
-
31
- if filename[-9, 9] == "index.rng"
32
- raise SkipError
33
- end
34
-
35
- file = File.open(filename, 'rb')
36
-
37
- if disk_backed
38
- obj = ImageSource::Disk.new(file)
39
- else
40
- obj = ImageSource::Memory.new(file.read)
41
- obj.close
42
- end
43
-
44
- return self.new(obj, filename.gsub(/.*[\/\\]/, '')[0,8].hex)
45
- end
46
-
47
- def initialize(isource, base)
48
- self._isource = isource
49
- self.header_section = Section.new(isource, base, nil)
50
- self.sections = [ self.header_section ]
51
- self.image_base = 0
52
- end
53
-
54
- def all_sections
55
- self.sections
56
- end
57
-
58
- # No 64-bit support
59
- def ptr_64?
60
- false
61
- end
62
-
63
- end end end
@@ -1,1680 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # $Id: pebase.rb 10036 2010-08-18 04:39:38Z jduck $
4
-
5
- require 'rex/peparsey/exceptions'
6
- require 'rex/struct2'
7
-
8
- module Rex
9
- module PeParsey
10
- class PeBase
11
-
12
-
13
- # #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
14
-
15
- IMAGE_DOS_SIGNATURE = 0x5a4d
16
-
17
- #
18
- # typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
19
- # WORD e_magic; // Magic number
20
- # WORD e_cblp; // Bytes on last page of file
21
- # WORD e_cp; // Pages in file
22
- # WORD e_crlc; // Relocations
23
- # WORD e_cparhdr; // Size of header in paragraphs
24
- # WORD e_minalloc; // Minimum extra paragraphs needed
25
- # WORD e_maxalloc; // Maximum extra paragraphs needed
26
- # WORD e_ss; // Initial (relative) SS value
27
- # WORD e_sp; // Initial SP value
28
- # WORD e_csum; // Checksum
29
- # WORD e_ip; // Initial IP value
30
- # WORD e_cs; // Initial (relative) CS value
31
- # WORD e_lfarlc; // File address of relocation table
32
- # WORD e_ovno; // Overlay number
33
- # WORD e_res[4]; // Reserved words
34
- # WORD e_oemid; // OEM identifier (for e_oeminfo)
35
- # WORD e_oeminfo; // OEM information; e_oemid specific
36
- # WORD e_res2[10]; // Reserved words
37
- # LONG e_lfanew; // File address of new exe header
38
- # } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
39
- #
40
-
41
- IMAGE_DOS_HEADER_SIZE = 64
42
- IMAGE_DOS_HEADER = Rex::Struct2::CStructTemplate.new(
43
- [ 'uint16v', 'e_magic', IMAGE_DOS_SIGNATURE ],
44
- [ 'uint16v', 'e_cblp', 0 ],
45
- [ 'uint16v', 'e_cp', 0 ],
46
- [ 'uint16v', 'e_crlc', 0 ],
47
- [ 'uint16v', 'e_cparhdr', 0 ],
48
- [ 'uint16v', 'e_minalloc', 0 ],
49
- [ 'uint16v', 'e_maxalloc', 0 ],
50
- [ 'uint16v', 'e_ss', 0 ],
51
- [ 'uint16v', 'e_sp', 0 ],
52
- [ 'uint16v', 'e_csum', 0 ],
53
- [ 'uint16v', 'e_ip', 0 ],
54
- [ 'uint16v', 'e_cs', 0 ],
55
- [ 'uint16v', 'e_lfarlc', 0 ],
56
- [ 'uint16v', 'e_ovno', 0 ],
57
- [ 'template', 'e_res', Rex::Struct2::CStructTemplate.new(
58
- [ 'uint16v', 'e_res_0', 0 ],
59
- [ 'uint16v', 'e_res_1', 0 ],
60
- [ 'uint16v', 'e_res_2', 0 ],
61
- [ 'uint16v', 'e_res_3', 0 ]
62
- )],
63
- [ 'uint16v', 'e_oemid', 0 ],
64
- [ 'uint16v', 'e_oeminfo', 0 ],
65
- [ 'template', 'e_res2', Rex::Struct2::CStructTemplate.new(
66
- [ 'uint16v', 'e_res2_0', 0 ],
67
- [ 'uint16v', 'e_res2_1', 0 ],
68
- [ 'uint16v', 'e_res2_2', 0 ],
69
- [ 'uint16v', 'e_res2_3', 0 ],
70
- [ 'uint16v', 'e_res2_4', 0 ],
71
- [ 'uint16v', 'e_res2_5', 0 ],
72
- [ 'uint16v', 'e_res2_6', 0 ],
73
- [ 'uint16v', 'e_res2_7', 0 ],
74
- [ 'uint16v', 'e_res2_8', 0 ],
75
- [ 'uint16v', 'e_res2_9', 0 ]
76
- )],
77
- [ 'uint32v', 'e_lfanew', 0 ]
78
- )
79
-
80
-
81
- class HeaderAccessor
82
- attr_accessor :dos, :file, :opt, :sections, :config, :exceptions, :tls
83
- def initialize
84
- end
85
- end
86
-
87
- class GenericStruct
88
- attr_accessor :struct
89
- def initialize(_struct)
90
- self.struct = _struct
91
- end
92
-
93
- # The following methods are just pass-throughs for struct
94
-
95
- # Access a value
96
- def v
97
- struct.v
98
- end
99
-
100
- # Access a value by array
101
- def [](*args)
102
- struct[*args]
103
- end
104
-
105
- # Obtain an array of all fields
106
- def keys
107
- struct.keys
108
- end
109
-
110
- def method_missing(meth, *args)
111
- v[meth.to_s] || (raise NoMethodError.new, meth)
112
- end
113
- end
114
-
115
- class GenericHeader < GenericStruct
116
- end
117
-
118
- class DosHeader < GenericHeader
119
-
120
- def initialize(rawdata)
121
- dos_header = IMAGE_DOS_HEADER.make_struct
122
-
123
- if !dos_header.from_s(rawdata)
124
- raise DosHeaderError, "Couldn't parse IMAGE_DOS_HEADER", caller
125
- end
126
-
127
- if dos_header.v['e_magic'] != IMAGE_DOS_SIGNATURE
128
- raise DosHeaderError, "Couldn't find DOS e_magic", caller
129
- end
130
-
131
- self.struct = dos_header
132
- end
133
-
134
- def e_lfanew
135
- v['e_lfanew']
136
- end
137
- end
138
-
139
-
140
- def self._parse_dos_header(rawdata)
141
- return DosHeader.new(rawdata)
142
- end
143
-
144
- #
145
- # typedef struct _IMAGE_FILE_HEADER {
146
- # WORD Machine;
147
- # WORD NumberOfSections;
148
- # DWORD TimeDateStamp;
149
- # DWORD PointerToSymbolTable;
150
- # DWORD NumberOfSymbols;
151
- # WORD SizeOfOptionalHeader;
152
- # WORD Characteristics;
153
- # } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
154
- #
155
- # #define IMAGE_NT_SIGNATURE 0x00004550 // PE00
156
- # #define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
157
- # #define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64
158
- # #define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64
159
- # #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8)
160
- # #define IMAGE_SIZEOF_FILE_HEADER 20
161
- #
162
-
163
- IMAGE_NT_SIGNATURE = 0x00004550
164
- IMAGE_FILE_MACHINE_I386 = 0x014c
165
- IMAGE_FILE_MACHINE_IA64 = 0x0200
166
- IMAGE_FILE_MACHINE_ALPHA64 = 0x0284
167
- IMAGE_FILE_MACHINE_AMD64 = 0x8664
168
- IMAGE_FILE_HEADER_SIZE = 20+4 # because we include the signature
169
- IMAGE_FILE_HEADER = Rex::Struct2::CStructTemplate.new(
170
- # not really in the header, but easier for us this way
171
- [ 'uint32v', 'NtSignature', 0 ],
172
- [ 'uint16v', 'Machine', 0 ],
173
- [ 'uint16v', 'NumberOfSections', 0 ],
174
- [ 'uint32v', 'TimeDateStamp', 0 ],
175
- [ 'uint32v', 'PointerToSymbolTable', 0 ],
176
- [ 'uint32v', 'NumberOfSymbols', 0 ],
177
- [ 'uint16v', 'SizeOfOptionalHeader', 0 ],
178
- [ 'uint16v', 'Characteristics', 0 ]
179
- )
180
-
181
- SUPPORTED_MACHINES = [
182
- IMAGE_FILE_MACHINE_I386,
183
- IMAGE_FILE_MACHINE_IA64,
184
- IMAGE_FILE_MACHINE_ALPHA64,
185
- IMAGE_FILE_MACHINE_AMD64
186
- ]
187
-
188
- class FileHeader < GenericHeader
189
- def initialize(rawdata)
190
- file_header = IMAGE_FILE_HEADER.make_struct
191
-
192
- if !file_header.from_s(rawdata)
193
- raise FileHeaderError, "Couldn't parse IMAGE_FILE_HEADER", caller
194
- end
195
-
196
- if file_header.v['NtSignature'] != IMAGE_NT_SIGNATURE
197
- raise FileHeaderError, "Couldn't find the PE magic!"
198
- end
199
-
200
- if SUPPORTED_MACHINES.include?(file_header.v['Machine']) == false
201
- raise FileHeaderError, "Unsupported machine type: #{file_header.v['Machine']}", caller
202
- end
203
-
204
- self.struct = file_header
205
- end
206
-
207
- def Machine
208
- v['Machine']
209
- end
210
-
211
- def SizeOfOptionalHeader
212
- v['SizeOfOptionalHeader']
213
- end
214
-
215
- def NumberOfSections
216
- v['NumberOfSections']
217
- end
218
- end
219
-
220
- def self._parse_file_header(rawdata)
221
- return FileHeader.new(rawdata)
222
- end
223
-
224
- #
225
- # typedef struct _IMAGE_IMPORT_DESCRIPTOR {
226
- # union {
227
- # DWORD Characteristics; // 0 for terminating null import descriptor
228
- # DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
229
- # };
230
- # DWORD TimeDateStamp; // 0 if not bound,
231
- # // -1 if bound, and real date\time stamp
232
- # // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
233
- # // O.W. date/time stamp of DLL bound to (Old BIND)
234
- #
235
- # DWORD ForwarderChain; // -1 if no forwarders
236
- # DWORD Name;
237
- # DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
238
- # } IMAGE_IMPORT_DESCRIPTOR;
239
- #
240
- IMAGE_ORDINAL_FLAG32 = 0x80000000
241
- IMAGE_IMPORT_DESCRIPTOR_SIZE = 20
242
- IMAGE_IMPORT_DESCRIPTOR = Rex::Struct2::CStructTemplate.new(
243
- [ 'uint32v', 'OriginalFirstThunk', 0 ],
244
- [ 'uint32v', 'TimeDateStamp', 0 ],
245
- [ 'uint32v', 'ForwarderChain', 0 ],
246
- [ 'uint32v', 'Name', 0 ],
247
- [ 'uint32v', 'FirstThunk', 0 ]
248
- )
249
-
250
- #
251
- # typedef struct _IMAGE_IMPORT_BY_NAME {
252
- # WORD Hint;
253
- # BYTE Name[1];
254
- # } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
255
- #
256
-
257
- class ImportDescriptor
258
- attr_accessor :name, :entries
259
- def initialize(_name, _entries)
260
- self.name = _name
261
- self.entries = _entries
262
- end
263
- end
264
-
265
- class ImportEntry
266
- attr_accessor :name, :ordinal
267
- def initialize(_name, _ordinal)
268
- self.name = _name
269
- self.ordinal = _ordinal
270
- end
271
- end
272
-
273
- #
274
- # typedef struct _IMAGE_EXPORT_DIRECTORY {
275
- # DWORD Characteristics;
276
- # DWORD TimeDateStamp;
277
- # WORD MajorVersion;
278
- # WORD MinorVersion;
279
- # DWORD Name;
280
- # DWORD Base;
281
- # DWORD NumberOfFunctions;
282
- # DWORD NumberOfNames;
283
- # DWORD AddressOfFunctions; // RVA from base of image
284
- # DWORD AddressOfNames; // RVA from base of image
285
- # DWORD AddressOfNameOrdinals; // RVA from base of image
286
- # } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
287
- #
288
- IMAGE_EXPORT_DESCRIPTOR_SIZE = 40
289
- IMAGE_EXPORT_DESCRIPTOR = Rex::Struct2::CStructTemplate.new(
290
- [ 'uint32v', 'Characteristics', 0 ],
291
- [ 'uint32v', 'TimeDateStamp', 0 ],
292
- [ 'uint16v', 'MajorVersion', 0 ],
293
- [ 'uint16v', 'MinorVersion', 0 ],
294
- [ 'uint32v', 'Name', 0 ],
295
- [ 'uint32v', 'Base', 0 ],
296
- [ 'uint32v', 'NumberOfFunctions', 0 ],
297
- [ 'uint32v', 'NumberOfNames', 0 ],
298
- [ 'uint32v', 'AddressOfFunctions', 0 ],
299
- [ 'uint32v', 'AddressOfNames', 0 ],
300
- [ 'uint32v', 'AddressOfNameOrdinals', 0 ]
301
- )
302
-
303
- class ExportDirectory
304
- attr_accessor :name, :entries, :base
305
-
306
- def initialize(_name, _entries, _base)
307
- self.name = _name
308
- self.entries = _entries
309
- self.base = _base
310
- end
311
- end
312
-
313
- class ExportEntry
314
- attr_accessor :name, :ordinal, :rva
315
- def initialize(_name, _ordinal, _rva)
316
- self.name = _name
317
- self.ordinal = _ordinal
318
- self.rva = _rva
319
- end
320
- end
321
-
322
- #
323
- # typedef struct _IMAGE_DATA_DIRECTORY {
324
- # DWORD VirtualAddress;
325
- # DWORD Size;
326
- # } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
327
- #
328
- IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16
329
- IMAGE_DATA_DIRECTORY_SIZE = 8
330
- IMAGE_DIRECTORY_ENTRY_EXPORT = 0
331
- IMAGE_DIRECTORY_ENTRY_IMPORT = 1
332
- IMAGE_DIRECTORY_ENTRY_RESOURCE = 2
333
- IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3
334
- IMAGE_DIRECTORY_ENTRY_SECURITY = 4
335
- IMAGE_DIRECTORY_ENTRY_BASERELOC = 5
336
- IMAGE_DIRECTORY_ENTRY_DEBUG = 6
337
- IMAGE_DIRECTORY_ENTRY_COPYRIGHT = 7
338
- IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7
339
- IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8
340
- IMAGE_DIRECTORY_ENTRY_TLS = 9
341
- IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10
342
- IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11
343
- IMAGE_DIRECTORY_ENTRY_IAT = 12
344
- IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13
345
- IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14
346
- IMAGE_DATA_DIRECTORY = Rex::Struct2::CStructTemplate.new(
347
- [ 'uint32v', 'VirtualAddress', 0 ],
348
- [ 'uint32v', 'Size', 0 ]
349
- )
350
-
351
- #
352
- # typedef struct _IMAGE_OPTIONAL_HEADER {
353
- # //
354
- # // Standard fields.
355
- # //
356
- #
357
- # WORD Magic;
358
- # BYTE MajorLinkerVersion;
359
- # BYTE MinorLinkerVersion;
360
- # DWORD SizeOfCode;
361
- # DWORD SizeOfInitializedData;
362
- # DWORD SizeOfUninitializedData;
363
- # DWORD AddressOfEntryPoint;
364
- # DWORD BaseOfCode;
365
- # DWORD BaseOfData;
366
- #
367
- # //
368
- # // NT additional fields.
369
- # //
370
- #
371
- # DWORD ImageBase;
372
- # DWORD SectionAlignment;
373
- # DWORD FileAlignment;
374
- # WORD MajorOperatingSystemVersion;
375
- # WORD MinorOperatingSystemVersion;
376
- # WORD MajorImageVersion;
377
- # WORD MinorImageVersion;
378
- # WORD MajorSubsystemVersion;
379
- # WORD MinorSubsystemVersion;
380
- # DWORD Win32VersionValue;
381
- # DWORD SizeOfImage;
382
- # DWORD SizeOfHeaders;
383
- # DWORD CheckSum;
384
- # WORD Subsystem;
385
- # WORD DllCharacteristics;
386
- # DWORD SizeOfStackReserve;
387
- # DWORD SizeOfStackCommit;
388
- # DWORD SizeOfHeapReserve;
389
- # DWORD SizeOfHeapCommit;
390
- # DWORD LoaderFlags;
391
- # DWORD NumberOfRvaAndSizes;
392
- # IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
393
- # } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
394
- #
395
- # #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
396
- # #define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224
397
- #
398
-
399
- IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b
400
- IMAGE_SIZEOF_NT_OPTIONAL32_HEADER = 224
401
- IMAGE_OPTIONAL_HEADER32 = Rex::Struct2::CStructTemplate.new(
402
- [ 'uint16v', 'Magic', 0 ],
403
- [ 'uint8', 'MajorLinkerVersion', 0 ],
404
- [ 'uint8', 'MinorLinkerVersion', 0 ],
405
- [ 'uint32v', 'SizeOfCode', 0 ],
406
- [ 'uint32v', 'SizeOfInitializeData', 0 ],
407
- [ 'uint32v', 'SizeOfUninitializeData', 0 ],
408
- [ 'uint32v', 'AddressOfEntryPoint', 0 ],
409
- [ 'uint32v', 'BaseOfCode', 0 ],
410
- [ 'uint32v', 'BaseOfData', 0 ],
411
- [ 'uint32v', 'ImageBase', 0 ],
412
- [ 'uint32v', 'SectionAlignment', 0 ],
413
- [ 'uint32v', 'FileAlignment', 0 ],
414
- [ 'uint16v', 'MajorOperatingSystemVersion', 0 ],
415
- [ 'uint16v', 'MinorOperatingSystemVersion', 0 ],
416
- [ 'uint16v', 'MajorImageVersion', 0 ],
417
- [ 'uint16v', 'MinorImageVersion', 0 ],
418
- [ 'uint16v', 'MajorSubsystemVersion', 0 ],
419
- [ 'uint16v', 'MinorSubsystemVersion', 0 ],
420
- [ 'uint32v', 'Win32VersionValue', 0 ],
421
- [ 'uint32v', 'SizeOfImage', 0 ],
422
- [ 'uint32v', 'SizeOfHeaders', 0 ],
423
- [ 'uint32v', 'CheckSum', 0 ],
424
- [ 'uint16v', 'Subsystem', 0 ],
425
- [ 'uint16v', 'DllCharacteristics', 0 ],
426
- [ 'uint32v', 'SizeOfStackReserve', 0 ],
427
- [ 'uint32v', 'SizeOfStackCommit', 0 ],
428
- [ 'uint32v', 'SizeOfHeapReserve', 0 ],
429
- [ 'uint32v', 'SizeOfHeapCommit', 0 ],
430
- [ 'uint32v', 'LoaderFlags', 0 ],
431
- [ 'uint32v', 'NumberOfRvaAndSizes', 0 ],
432
- [ 'template', 'DataDirectory', Rex::Struct2::CStructTemplate.new(
433
- [ 'template', 'DataDirectoryEntry_0', IMAGE_DATA_DIRECTORY ],
434
- [ 'template', 'DataDirectoryEntry_1', IMAGE_DATA_DIRECTORY ],
435
- [ 'template', 'DataDirectoryEntry_2', IMAGE_DATA_DIRECTORY ],
436
- [ 'template', 'DataDirectoryEntry_3', IMAGE_DATA_DIRECTORY ],
437
- [ 'template', 'DataDirectoryEntry_4', IMAGE_DATA_DIRECTORY ],
438
- [ 'template', 'DataDirectoryEntry_5', IMAGE_DATA_DIRECTORY ],
439
- [ 'template', 'DataDirectoryEntry_6', IMAGE_DATA_DIRECTORY ],
440
- [ 'template', 'DataDirectoryEntry_7', IMAGE_DATA_DIRECTORY ],
441
- [ 'template', 'DataDirectoryEntry_8', IMAGE_DATA_DIRECTORY ],
442
- [ 'template', 'DataDirectoryEntry_9', IMAGE_DATA_DIRECTORY ],
443
- [ 'template', 'DataDirectoryEntry_10', IMAGE_DATA_DIRECTORY ],
444
- [ 'template', 'DataDirectoryEntry_11', IMAGE_DATA_DIRECTORY ],
445
- [ 'template', 'DataDirectoryEntry_12', IMAGE_DATA_DIRECTORY ],
446
- [ 'template', 'DataDirectoryEntry_13', IMAGE_DATA_DIRECTORY ],
447
- [ 'template', 'DataDirectoryEntry_14', IMAGE_DATA_DIRECTORY ],
448
- [ 'template', 'DataDirectoryEntry_15', IMAGE_DATA_DIRECTORY ]
449
- )]
450
- )
451
-
452
- #
453
- # typedef struct _IMAGE_OPTIONAL_HEADER64 {
454
- # USHORT Magic;
455
- # UCHAR MajorLinkerVersion;
456
- # UCHAR MinorLinkerVersion;
457
- # ULONG SizeOfCode;
458
- # ULONG SizeOfInitializedData;
459
- # ULONG SizeOfUninitializedData;
460
- # ULONG AddressOfEntryPoint;
461
- # ULONG BaseOfCode;
462
- # ULONGLONG ImageBase;
463
- # ULONG SectionAlignment;
464
- # ULONG FileAlignment;
465
- # USHORT MajorOperatingSystemVersion;
466
- # USHORT MinorOperatingSystemVersion;
467
- # USHORT MajorImageVersion;
468
- # USHORT MinorImageVersion;
469
- # USHORT MajorSubsystemVersion;
470
- # USHORT MinorSubsystemVersion;
471
- # ULONG Win32VersionValue;
472
- # ULONG SizeOfImage;
473
- # ULONG SizeOfHeaders;
474
- # ULONG CheckSum;
475
- # USHORT Subsystem;
476
- # USHORT DllCharacteristics;
477
- # ULONGLONG SizeOfStackReserve;
478
- # ULONGLONG SizeOfStackCommit;
479
- # ULONGLONG SizeOfHeapReserve;
480
- # ULONGLONG SizeOfHeapCommit;
481
- # ULONG LoaderFlags;
482
- # ULONG NumberOfRvaAndSizes;
483
- # IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
484
- # } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
485
- #
486
- # #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
487
- # #define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240
488
- #
489
-
490
- IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b
491
- IMAGE_SIZEOF_NT_OPTIONAL64_HEADER = 240
492
- IMAGE_OPTIONAL_HEADER64 = Rex::Struct2::CStructTemplate.new(
493
- [ 'uint16v', 'Magic', 0 ],
494
- [ 'uint8', 'MajorLinkerVersion', 0 ],
495
- [ 'uint8', 'MinorLinkerVersion', 0 ],
496
- [ 'uint32v', 'SizeOfCode', 0 ],
497
- [ 'uint32v', 'SizeOfInitializeData', 0 ],
498
- [ 'uint32v', 'SizeOfUninitializeData', 0 ],
499
- [ 'uint32v', 'AddressOfEntryPoint', 0 ],
500
- [ 'uint32v', 'BaseOfCode', 0 ],
501
- [ 'uint64v', 'ImageBase', 0 ],
502
- [ 'uint32v', 'SectionAlignment', 0 ],
503
- [ 'uint32v', 'FileAlignment', 0 ],
504
- [ 'uint16v', 'MajorOperatingsystemVersion', 0 ],
505
- [ 'uint16v', 'MinorOperatingsystemVersion', 0 ],
506
- [ 'uint16v', 'MajorImageVersion', 0 ],
507
- [ 'uint16v', 'MinorImageVersion', 0 ],
508
- [ 'uint16v', 'MajorSubsystemVersion', 0 ],
509
- [ 'uint16v', 'MinorSubsystemVersion', 0 ],
510
- [ 'uint32v', 'Win32VersionValue', 0 ],
511
- [ 'uint32v', 'SizeOfImage', 0 ],
512
- [ 'uint32v', 'SizeOfHeaders', 0 ],
513
- [ 'uint32v', 'CheckSum', 0 ],
514
- [ 'uint16v', 'Subsystem', 0 ],
515
- [ 'uint16v', 'DllCharacteristics', 0 ],
516
- [ 'uint64v', 'SizeOfStackReserve', 0 ],
517
- [ 'uint64v', 'SizeOfStackCommit', 0 ],
518
- [ 'uint64v', 'SizeOfHeapReserve', 0 ],
519
- [ 'uint64v', 'SizeOfHeapCommit', 0 ],
520
- [ 'uint32v', 'LoaderFlags', 0 ],
521
- [ 'uint32v', 'NumberOfRvaAndSizes', 0 ],
522
- [ 'template', 'DataDirectory', Rex::Struct2::CStructTemplate.new(
523
- [ 'template', 'DataDirectoryEntry_0', IMAGE_DATA_DIRECTORY ],
524
- [ 'template', 'DataDirectoryEntry_1', IMAGE_DATA_DIRECTORY ],
525
- [ 'template', 'DataDirectoryEntry_2', IMAGE_DATA_DIRECTORY ],
526
- [ 'template', 'DataDirectoryEntry_3', IMAGE_DATA_DIRECTORY ],
527
- [ 'template', 'DataDirectoryEntry_4', IMAGE_DATA_DIRECTORY ],
528
- [ 'template', 'DataDirectoryEntry_5', IMAGE_DATA_DIRECTORY ],
529
- [ 'template', 'DataDirectoryEntry_6', IMAGE_DATA_DIRECTORY ],
530
- [ 'template', 'DataDirectoryEntry_7', IMAGE_DATA_DIRECTORY ],
531
- [ 'template', 'DataDirectoryEntry_8', IMAGE_DATA_DIRECTORY ],
532
- [ 'template', 'DataDirectoryEntry_9', IMAGE_DATA_DIRECTORY ],
533
- [ 'template', 'DataDirectoryEntry_10', IMAGE_DATA_DIRECTORY ],
534
- [ 'template', 'DataDirectoryEntry_11', IMAGE_DATA_DIRECTORY ],
535
- [ 'template', 'DataDirectoryEntry_12', IMAGE_DATA_DIRECTORY ],
536
- [ 'template', 'DataDirectoryEntry_13', IMAGE_DATA_DIRECTORY ],
537
- [ 'template', 'DataDirectoryEntry_14', IMAGE_DATA_DIRECTORY ],
538
- [ 'template', 'DataDirectoryEntry_15', IMAGE_DATA_DIRECTORY ]
539
- )]
540
- )
541
-
542
- class OptionalHeader < GenericHeader
543
- def ImageBase
544
- v['ImageBase']
545
- end
546
- def FileAlignment
547
- v['FileAlignment']
548
- end
549
- end
550
-
551
- class OptionalHeader32 < OptionalHeader
552
- def initialize(rawdata)
553
- optional_header = IMAGE_OPTIONAL_HEADER32.make_struct
554
-
555
- if !optional_header.from_s(rawdata)
556
- raise OptionalHeaderError, "Couldn't parse IMAGE_OPTIONAL_HEADER32", caller
557
- end
558
-
559
- if optional_header.v['Magic'] != IMAGE_NT_OPTIONAL_HDR32_MAGIC
560
- raise OptionalHeaderError, "Magic did not match!", caller()
561
- end
562
-
563
- self.struct = optional_header
564
- end
565
- end
566
-
567
- class OptionalHeader64 < OptionalHeader
568
- def initialize(rawdata)
569
- optional_header = IMAGE_OPTIONAL_HEADER64.make_struct
570
-
571
- if !optional_header.from_s(rawdata)
572
- raise OptionalHeaderError, "Couldn't parse IMAGE_OPTIONAL_HEADER64", caller
573
- end
574
-
575
- if optional_header.v['Magic'] != IMAGE_NT_OPTIONAL_HDR64_MAGIC
576
- raise OptionalHeaderError, "Magic did not match!", caller()
577
- end
578
-
579
- self.struct = optional_header
580
- end
581
- end
582
-
583
- def self._parse_optional_header(rawdata)
584
- case rawdata.length
585
- # no optional header
586
- when 0
587
- return nil
588
-
589
- # good, good
590
- when IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
591
- return OptionalHeader32.new(rawdata)
592
-
593
- when IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
594
- return OptionalHeader64.new(rawdata)
595
-
596
- # bad, bad
597
- else
598
- raise OptionalHeaderError, "I don't know this header size, #{rawdata.length}", caller
599
- end
600
-
601
- end
602
-
603
- #
604
- # typedef struct _IMAGE_SECTION_HEADER {
605
- # BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
606
- # union {
607
- # DWORD PhysicalAddress;
608
- # DWORD VirtualSize;
609
- # } Misc;
610
- # DWORD VirtualAddress;
611
- # DWORD SizeOfRawData;
612
- # DWORD PointerToRawData;
613
- # DWORD PointerToRelocations;
614
- # DWORD PointerToLinenumbers;
615
- # WORD NumberOfRelocations;
616
- # WORD NumberOfLinenumbers;
617
- # DWORD Characteristics;
618
- # } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
619
- #
620
- # #define IMAGE_SIZEOF_SECTION_HEADER 40
621
- #
622
-
623
- IMAGE_SIZEOF_SECTION_HEADER = 40
624
- IMAGE_SECTION_HEADER = Rex::Struct2::CStructTemplate.new(
625
- [ 'string', 'Name', 8, '' ],
626
- [ 'uint32v', 'Misc', 0 ],
627
- [ 'uint32v', 'VirtualAddress', 0 ],
628
- [ 'uint32v', 'SizeOfRawData', 0 ],
629
- [ 'uint32v', 'PointerToRawData', 0 ],
630
- [ 'uint32v', 'PointerToRelocations', 0 ],
631
- [ 'uint32v', 'NumberOfRelocations', 0 ],
632
- [ 'uint32v', 'NumberOfLineNumbers', 0 ],
633
- [ 'uint32v', 'Characteristics', 0 ]
634
- )
635
-
636
- class SectionHeader < GenericHeader
637
- def initialize(rawdata)
638
- section_header = IMAGE_SECTION_HEADER.make_struct
639
-
640
- if !section_header.from_s(rawdata)
641
- raise SectionHeaderError, "Could not parse header", caller
642
- end
643
-
644
- self.struct = section_header
645
- end
646
-
647
- def VirtualAddress
648
- v['VirtualAddress']
649
- end
650
- def SizeOfRawData
651
- v['SizeOfRawData']
652
- end
653
- def PointerToRawData
654
- v['PointerToRawData']
655
- end
656
- end
657
-
658
- def self._parse_section_headers(rawdata)
659
- section_headers = [ ]
660
- size = IMAGE_SIZEOF_SECTION_HEADER
661
- numsections = rawdata.length / size
662
-
663
- numsections.times do |i|
664
- data = rawdata[i * size, size]
665
- section_headers << SectionHeader.new(data)
666
- end
667
-
668
- return section_headers
669
- end
670
-
671
- #
672
- # typedef struct _IMAGE_BASE_RELOCATION {
673
- # DWORD VirtualAddress;
674
- # DWORD SizeOfBlock;
675
- # // WORD TypeOffset[1];
676
- # } IMAGE_BASE_RELOCATION;
677
- # typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
678
- #
679
- # #define IMAGE_SIZEOF_BASE_RELOCATION 8
680
- #
681
- IMAGE_SIZEOF_BASE_RELOCATION = 8
682
- IMAGE_BASE_RELOCATION = Rex::Struct2::CStructTemplate.new(
683
- [ 'uint32v', 'VirtualAddress', 0 ],
684
- [ 'uint32v', 'SizeOfBlock', 0 ]
685
- )
686
- IMAGE_BASE_RELOCATION_TYPE_OFFSET = Rex::Struct2::CStructTemplate.new(
687
- [ 'uint16v', 'TypeOffset', 0 ]
688
- )
689
-
690
- class RelocationDirectory
691
- attr_accessor :entries, :rva
692
-
693
- def initialize(rva, entries)
694
- self.rva = rva
695
- self.entries = entries
696
- self.name = name
697
- self.characteristics = chars
698
- self.timedate = timedate
699
- self.version = version
700
- self.entries = []
701
- end
702
- end
703
-
704
- class RelocationEntry
705
- attr_accessor :rva, :reltype
706
-
707
- def initialize(_rva, _type)
708
- self.rva = _rva
709
- self.reltype = _type
710
- end
711
- end
712
-
713
-
714
- class ResourceDirectory
715
- attr_accessor :entries, :name
716
-
717
- def initialize(name, entries)
718
- self.name = name
719
- self.entries = entries
720
- end
721
- end
722
-
723
- class ResourceEntry
724
- attr_accessor :path, :lang, :code, :rva, :size, :pe, :file
725
-
726
- def initialize(pe, path, lang, code, rva, size, file)
727
- self.pe = pe
728
- self.path = path
729
- self.lang = lang
730
- self.code = code
731
- self.rva = rva
732
- self.size = size
733
- self.file = file.to_s
734
- end
735
-
736
- def data
737
- pe._isource.read(pe.rva_to_file_offset(rva), size)
738
- end
739
- end
740
-
741
- #
742
- # typedef struct {
743
- # DWORD Size;
744
- # DWORD TimeDateStamp;
745
- # WORD MajorVersion;
746
- # WORD MinorVersion;
747
- # DWORD GlobalFlagsClear;
748
- # DWORD GlobalFlagsSet;
749
- # DWORD CriticalSectionDefaultTimeout;
750
- # DWORD DeCommitFreeBlockThreshold;
751
- # DWORD DeCommitTotalFreeThreshold;
752
- # DWORD LockPrefixTable; // VA
753
- # DWORD MaximumAllocationSize;
754
- # DWORD VirtualMemoryThreshold;
755
- # DWORD ProcessHeapFlags;
756
- # DWORD ProcessAffinityMask;
757
- # WORD CSDVersion;
758
- # WORD Reserved1;
759
- # DWORD EditList; // VA
760
- # DWORD SecurityCookie; // VA
761
- # DWORD SEHandlerTable; // VA
762
- # DWORD SEHandlerCount;
763
- # } IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32;
764
- #
765
- IMAGE_LOAD_CONFIG_DIRECTORY32 = Rex::Struct2::CStructTemplate.new(
766
- [ 'uint32v', 'Size', 0 ],
767
- [ 'uint32v', 'TimeDateStamp', 0 ],
768
- [ 'uint16v', 'MajorVersion', 0 ],
769
- [ 'uint16v', 'MinorVersion', 0 ],
770
- [ 'uint32v', 'GlobalFlagsClear', 0 ],
771
- [ 'uint32v', 'GlobalFlagsSet', 0 ],
772
- [ 'uint32v', 'CriticalSectionDefaultTimeout', 0 ],
773
- [ 'uint32v', 'DeCommitFreeBlockThreshold', 0 ],
774
- [ 'uint32v', 'DeCommitTotalFreeThreshold', 0 ],
775
- [ 'uint32v', 'LockPrefixTable', 0 ],
776
- [ 'uint32v', 'MaximumAllocationSize', 0 ],
777
- [ 'uint32v', 'VirtualMemoryThreshold', 0 ],
778
- [ 'uint32v', 'ProcessHeapFlags', 0 ],
779
- [ 'uint32v', 'ProcessAffinityMask', 0 ],
780
- [ 'uint16v', 'CSDVersion', 0 ],
781
- [ 'uint16v', 'Reserved1', 0 ],
782
- [ 'uint32v', 'EditList', 0 ],
783
- [ 'uint32v', 'SecurityCookie', 0 ],
784
- [ 'uint32v', 'SEHandlerTable', 0 ],
785
- [ 'uint32v', 'SEHandlerCount', 0 ]
786
- )
787
-
788
- #
789
- # typedef struct {
790
- # ULONG Size;
791
- # ULONG TimeDateStamp;
792
- # USHORT MajorVersion;
793
- # USHORT MinorVersion;
794
- # ULONG GlobalFlagsClear;
795
- # ULONG GlobalFlagsSet;
796
- # ULONG CriticalSectionDefaultTimeout;
797
- # ULONGLONG DeCommitFreeBlockThreshold;
798
- # ULONGLONG DeCommitTotalFreeThreshold;
799
- # ULONGLONG LockPrefixTable; // VA
800
- # ULONGLONG MaximumAllocationSize;
801
- # ULONGLONG VirtualMemoryThreshold;
802
- # ULONGLONG ProcessAffinityMask;
803
- # ULONG ProcessHeapFlags;
804
- # USHORT CSDVersion;
805
- # USHORT Reserved1;
806
- # ULONGLONG EditList; // VA
807
- # ULONGLONG SecurityCookie; // VA
808
- # ULONGLONG SEHandlerTable; // VA
809
- # ULONGLONG SEHandlerCount;
810
- # } IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;
811
- #
812
- IMAGE_LOAD_CONFIG_DIRECTORY64 = Rex::Struct2::CStructTemplate.new(
813
- [ 'uint32v', 'Size', 0 ],
814
- [ 'uint32v', 'TimeDateStamp', 0 ],
815
- [ 'uint16v', 'MajorVersion', 0 ],
816
- [ 'uint16v', 'MinorVersion', 0 ],
817
- [ 'uint32v', 'GlobalFlagsClear', 0 ],
818
- [ 'uint32v', 'GlobalFlagsSet', 0 ],
819
- [ 'uint32v', 'CriticalSectionDefaultTimeout', 0 ],
820
- [ 'uint64v', 'DeCommitFreeBlockThreshold', 0 ],
821
- [ 'uint64v', 'DeCommitTotalFreeThreshold', 0 ],
822
- [ 'uint64v', 'LockPrefixTable', 0 ],
823
- [ 'uint64v', 'MaximumAllocationSize', 0 ],
824
- [ 'uint64v', 'VirtualMemoryThreshold', 0 ],
825
- [ 'uint64v', 'ProcessAffinityMask', 0 ],
826
- [ 'uint32v', 'ProcessHeapFlags', 0 ],
827
- [ 'uint16v', 'CSDVersion', 0 ],
828
- [ 'uint16v', 'Reserved1', 0 ],
829
- [ 'uint64v', 'EditList', 0 ],
830
- [ 'uint64v', 'SecurityCookie', 0 ],
831
- [ 'uint64v', 'SEHandlerTable', 0 ],
832
- [ 'uint64v', 'SEHandlerCount', 0 ]
833
- )
834
-
835
-
836
- class ConfigHeader < GenericHeader
837
-
838
- end
839
-
840
- # doesn't seem to be used -- not compatible with 64-bit
841
- #def self._parse_config_header(rawdata)
842
- # header = IMAGE_LOAD_CONFIG_DIRECTORY32.make_struct
843
- # header.from_s(rawdata)
844
- # ConfigHeader.new(header)
845
- #end
846
-
847
- def _parse_config_header
848
-
849
- #
850
- # Get the data directory entry, size, etc
851
- #
852
- exports_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG]
853
- rva = exports_entry.v['VirtualAddress']
854
- size = exports_entry.v['Size']
855
-
856
- return nil if size == 0
857
-
858
- #
859
- # Ok, so we have the data directory, now lets parse it
860
- #
861
-
862
- dirdata = _isource.read(rva_to_file_offset(rva), size)
863
- klass = (ptr_64?) ? IMAGE_LOAD_CONFIG_DIRECTORY64 : IMAGE_LOAD_CONFIG_DIRECTORY32
864
- header = klass.make_struct
865
-
866
- header.from_s(dirdata)
867
-
868
- @config = ConfigHeader.new(header)
869
- end
870
-
871
-
872
- def config
873
- _parse_config_header if @config.nil?
874
- @config
875
- end
876
-
877
- #
878
- # TLS Directory
879
- #
880
-
881
- #
882
- # typedef struct {
883
- # DWORD Size;
884
- # DWORD TimeDateStamp;
885
- # WORD MajorVersion;
886
- # WORD MinorVersion;
887
- # DWORD GlobalFlagsClear;
888
- # DWORD GlobalFlagsSet;
889
- # DWORD CriticalSectionDefaultTimeout;
890
- # DWORD DeCommitFreeBlockThreshold;
891
- # DWORD DeCommitTotalFreeThreshold;
892
- # DWORD LockPrefixTable; // VA
893
- # DWORD MaximumAllocationSize;
894
- # DWORD VirtualMemoryThreshold;
895
- # DWORD ProcessHeapFlags;
896
- # DWORD ProcessAffinityMask;
897
- # WORD CSDVersion;
898
- # WORD Reserved1;
899
- # DWORD EditList; // VA
900
- # DWORD SecurityCookie; // VA
901
- # DWORD SEHandlerTable; // VA
902
- # DWORD SEHandlerCount;
903
- # } IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32;
904
- #
905
- IMAGE_LOAD_TLS_DIRECTORY32 = Rex::Struct2::CStructTemplate.new(
906
- [ 'uint32v', 'Size', 0 ],
907
- [ 'uint32v', 'TimeDateStamp', 0 ],
908
- [ 'uint16v', 'MajorVersion', 0 ],
909
- [ 'uint16v', 'MinorVersion', 0 ],
910
- [ 'uint32v', 'GlobalFlagsClear', 0 ],
911
- [ 'uint32v', 'GlobalFlagsSet', 0 ],
912
- [ 'uint32v', 'CriticalSectionDefaultTimeout', 0 ],
913
- [ 'uint32v', 'DeCommitFreeBlockThreshold', 0 ],
914
- [ 'uint32v', 'DeCommitTotalFreeThreshold', 0 ],
915
- [ 'uint32v', 'LockPrefixTable', 0 ],
916
- [ 'uint32v', 'MaximumAllocationSize', 0 ],
917
- [ 'uint32v', 'VirtualMemoryThreshold', 0 ],
918
- [ 'uint32v', 'ProcessHeapFlags', 0 ],
919
- [ 'uint32v', 'ProcessAffinityMask', 0 ],
920
- [ 'uint16v', 'CSDVersion', 0 ],
921
- [ 'uint16v', 'Reserved1', 0 ],
922
- [ 'uint32v', 'EditList', 0 ],
923
- [ 'uint32v', 'SecurityCookie', 0 ],
924
- [ 'uint32v', 'SEHandlerTable', 0 ],
925
- [ 'uint32v', 'SEHandlerCount', 0 ]
926
- )
927
-
928
- #
929
- # typedef struct {
930
- # ULONG Size;
931
- # ULONG TimeDateStamp;
932
- # USHORT MajorVersion;
933
- # USHORT MinorVersion;
934
- # ULONG GlobalFlagsClear;
935
- # ULONG GlobalFlagsSet;
936
- # ULONG CriticalSectionDefaultTimeout;
937
- # ULONGLONG DeCommitFreeBlockThreshold;
938
- # ULONGLONG DeCommitTotalFreeThreshold;
939
- # ULONGLONG LockPrefixTable; // VA
940
- # ULONGLONG MaximumAllocationSize;
941
- # ULONGLONG VirtualMemoryThreshold;
942
- # ULONGLONG ProcessAffinityMask;
943
- # ULONG ProcessHeapFlags;
944
- # USHORT CSDVersion;
945
- # USHORT Reserved1;
946
- # ULONGLONG EditList; // VA
947
- # ULONGLONG SecurityCookie; // VA
948
- # ULONGLONG SEHandlerTable; // VA
949
- # ULONGLONG SEHandlerCount;
950
- # } IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;
951
- #
952
- IMAGE_LOAD_TLS_DIRECTORY64 = Rex::Struct2::CStructTemplate.new(
953
- [ 'uint32v', 'Size', 0 ],
954
- [ 'uint32v', 'TimeDateStamp', 0 ],
955
- [ 'uint16v', 'MajorVersion', 0 ],
956
- [ 'uint16v', 'MinorVersion', 0 ],
957
- [ 'uint32v', 'GlobalFlagsClear', 0 ],
958
- [ 'uint32v', 'GlobalFlagsSet', 0 ],
959
- [ 'uint32v', 'CriticalSectionDefaultTimeout', 0 ],
960
- [ 'uint64v', 'DeCommitFreeBlockThreshold', 0 ],
961
- [ 'uint64v', 'DeCommitTotalFreeThreshold', 0 ],
962
- [ 'uint64v', 'LockPrefixTable', 0 ],
963
- [ 'uint64v', 'MaximumAllocationSize', 0 ],
964
- [ 'uint64v', 'VirtualMemoryThreshold', 0 ],
965
- [ 'uint64v', 'ProcessAffinityMask', 0 ],
966
- [ 'uint32v', 'ProcessHeapFlags', 0 ],
967
- [ 'uint16v', 'CSDVersion', 0 ],
968
- [ 'uint16v', 'Reserved1', 0 ],
969
- [ 'uint64v', 'EditList', 0 ],
970
- [ 'uint64v', 'SecurityCookie', 0 ],
971
- [ 'uint64v', 'SEHandlerTable', 0 ],
972
- [ 'uint64v', 'SEHandlerCount', 0 ]
973
- )
974
-
975
-
976
- class TLSHeader < GenericHeader
977
-
978
- end
979
-
980
- def _parse_tls_header
981
-
982
- #
983
- # Get the data directory entry, size, etc
984
- #
985
- exports_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_TLS]
986
- rva = exports_entry.v['VirtualAddress']
987
- size = exports_entry.v['Size']
988
-
989
- return nil if size == 0
990
-
991
- #
992
- # Ok, so we have the data directory, now lets parse it
993
- #
994
-
995
- dirdata = _isource.read(rva_to_file_offset(rva), size)
996
- klass = (ptr_64?) ? IMAGE_LOAD_TLS_DIRECTORY64 : IMAGE_LOAD_TLS_DIRECTORY32
997
- header = klass.make_struct
998
-
999
- header.from_s(dirdata)
1000
-
1001
- @tls = TLSHeader.new(header)
1002
- end
1003
-
1004
-
1005
- def tls
1006
- _parse_config_header if @tls.nil?
1007
- @tls
1008
- end
1009
-
1010
- ##
1011
- #
1012
- # Exception directory
1013
- #
1014
- ##
1015
-
1016
- #
1017
- # typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY {
1018
- # DWORD BeginAddress;
1019
- # DWORD EndAddress;
1020
- # DWORD UnwindInfoAddress;
1021
- # } _IMAGE_RUNTIME_FUNCTION_ENTRY, *_PIMAGE_RUNTIME_FUNCTION_ENTRY;
1022
- #
1023
- IMAGE_RUNTIME_FUNCTION_ENTRY_SZ = 12
1024
- IMAGE_RUNTIME_FUNCTION_ENTRY = Rex::Struct2::CStructTemplate.new(
1025
- [ 'uint32v', 'BeginAddress', 0 ],
1026
- [ 'uint32v', 'EndAddress', 0 ],
1027
- [ 'uint32v', 'UnwindInfoAddress', 0 ]
1028
- )
1029
-
1030
- UNWIND_INFO_HEADER_SZ = 4
1031
- UNWIND_INFO_HEADER = Rex::Struct2::CStructTemplate.new(
1032
- [ 'uint8', 'VersionFlags', 0 ],
1033
- [ 'uint8', 'SizeOfProlog', 0 ],
1034
- [ 'uint8', 'CountOfCodes', 0 ],
1035
- [ 'uint8', 'FrameRegisterAndOffset', 0 ]
1036
- )
1037
-
1038
- UWOP_PUSH_NONVOL = 0 # 1 node
1039
- UWOP_ALLOC_LARGE = 1 # 2 or 3 nodes
1040
- UWOP_ALLOC_SMALL = 2 # 1 node
1041
- UWOP_SET_FPREG = 3 # 1 node
1042
- UWOP_SAVE_NONVOL = 4 # 2 nodes
1043
- UWOP_SAVE_NONVOL_FAR = 5 # 3 nodes
1044
- UWOP_SAVE_XMM128 = 8 # 2 nodes
1045
- UWOP_SAVE_XMM128_FAR = 9 # 3 nodes
1046
- UWOP_PUSH_MACHFRAME = 10 # 1 node
1047
-
1048
- UNW_FLAG_EHANDLER = 1
1049
- UNW_FLAG_UHANDLER = 2
1050
- UNW_FLAG_CHAININFO = 4
1051
-
1052
- class UnwindCode
1053
- def initialize(data)
1054
-
1055
- self.code_offset = data[0].to_i
1056
- self.unwind_op = data[1].to_i & 0xf
1057
- self.op_info = data[1].to_i >> 4
1058
- self.frame_offset = data[2..3].unpack("v")[0]
1059
-
1060
- data.slice!(0, 4)
1061
- end
1062
-
1063
- attr_reader :code_offset, :unwind_op, :op_info, :frame_offset
1064
- attr_writer :code_offset, :unwind_op, :op_info, :frame_offset
1065
-
1066
- end
1067
-
1068
- class UnwindInfo
1069
- def initialize(pe, unwind_rva)
1070
- data = pe.read_rva(unwind_rva, UNWIND_INFO_HEADER_SZ)
1071
-
1072
- unwind = UNWIND_INFO_HEADER.make_struct
1073
- unwind.from_s(data)
1074
-
1075
- @version = unwind.v['VersionFlags'] & 0x7
1076
- @flags = unwind.v['VersionFlags'] >> 3
1077
- @size_of_prolog = unwind.v['SizeOfProlog']
1078
- @count_of_codes = unwind.v['CountOfCodes']
1079
- @frame_register = unwind.v['FrameRegisterAndOffset'] & 0xf
1080
- @frame_register_offset = unwind.v['FrameRegisterAndOffset'] >> 4
1081
-
1082
- # Parse unwind codes
1083
- clist = pe.read_rva(unwind_rva + UNWIND_INFO_HEADER_SZ, count_of_codes * 4)
1084
-
1085
- @unwind_codes = []
1086
-
1087
- while clist.length > 0
1088
- @unwind_codes << UnwindCode.new(clist)
1089
- end
1090
- end
1091
-
1092
- attr_reader :version, :flags, :size_of_prolog, :count_of_codes
1093
- attr_reader :frame_register, :frame_register_offset
1094
-
1095
- def unwind_codes
1096
- @unwind_codes
1097
- end
1098
-
1099
- end
1100
-
1101
- class RuntimeFunctionEntry
1102
-
1103
- def initialize(pe, data)
1104
- @pe = pe
1105
- @begin_address, @end_address, @unwind_info_address = data.unpack("VVV");
1106
- self.unwind_info = UnwindInfo.new(pe, unwind_info_address)
1107
- end
1108
-
1109
- attr_reader :begin_address, :end_address, :unwind_info_address
1110
- attr_reader :unwind_info
1111
- attr_writer :unwind_info
1112
-
1113
- end
1114
-
1115
- def _load_exception_directory
1116
- @exception = []
1117
-
1118
- exception_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_EXCEPTION]
1119
- rva = exception_entry.v['VirtualAddress']
1120
- size = exception_entry.v['Size']
1121
-
1122
- return if (rva == 0)
1123
-
1124
- data = _isource.read(rva_to_file_offset(rva), size)
1125
-
1126
- case hdr.file.Machine
1127
- when IMAGE_FILE_MACHINE_AMD64
1128
- count = data.length / IMAGE_RUNTIME_FUNCTION_ENTRY_SZ
1129
-
1130
- count.times { |current|
1131
- @exception << RuntimeFunctionEntry.new(self,
1132
- data.slice!(0, IMAGE_RUNTIME_FUNCTION_ENTRY_SZ))
1133
- }
1134
- else
1135
- end
1136
-
1137
- return @exception
1138
- end
1139
-
1140
-
1141
- def exception
1142
- _load_exception_directory if @exception.nil?
1143
- @exception
1144
- end
1145
-
1146
- #
1147
- # Just a stupid routine to round an offset up to it's alignment.
1148
- #
1149
- # For example, you're going to want this for FileAlignment and
1150
- # SectionAlignment, etc...
1151
- #
1152
- def self._align_offset(offset, alignment)
1153
- offset += alignment - 1
1154
- offset -= offset % alignment
1155
- return offset
1156
- end
1157
-
1158
- #
1159
- # instance stuff
1160
- #
1161
-
1162
- attr_accessor :_isource
1163
- attr_accessor :_dos_header, :_file_header, :_optional_header,
1164
- :_section_headers, :_config_header, :_tls_header, :_exception_header
1165
-
1166
- attr_accessor :sections, :header_section, :image_base
1167
-
1168
- attr_accessor :_imports_cache, :_imports_cached
1169
- attr_accessor :_exports_cache, :_exports_cached
1170
- attr_accessor :_relocations_cache, :_relocations_cached
1171
- attr_accessor :_resources_cache, :_resources_cached
1172
-
1173
- attr_accessor :hdr
1174
-
1175
- def self.new_from_file(filename, disk_backed = false)
1176
-
1177
- file = ::File.new(filename)
1178
- file.binmode # windows... :\
1179
-
1180
- if disk_backed
1181
- return self.new(ImageSource::Disk.new(file))
1182
- else
1183
- obj = new_from_string(file.read)
1184
- file.close
1185
- return obj
1186
- end
1187
- end
1188
-
1189
- def self.new_from_string(data)
1190
- return self.new(ImageSource::Memory.new(data))
1191
- end
1192
-
1193
- def close
1194
- _isource.close
1195
- end
1196
-
1197
- #
1198
- #
1199
- # Random rva, vma, file offset, section offset, etc
1200
- # conversion routines...
1201
- #
1202
- #
1203
- def rva_to_vma(rva)
1204
- return rva + image_base
1205
- end
1206
-
1207
- def vma_to_rva(vma)
1208
- return vma - image_base
1209
- end
1210
-
1211
- def rva_to_file_offset(rva)
1212
- all_sections.each do |section|
1213
- if section.contains_rva?(rva)
1214
- return section.rva_to_file_offset(rva)
1215
- end
1216
- end
1217
- raise WtfError, "wtf!", caller
1218
- end
1219
-
1220
- def vma_to_file_offset(vma)
1221
- return rva_to_file_offset(vma_to_rva(vma))
1222
- end
1223
-
1224
- def file_offset_to_rva(foffset)
1225
- if foffset < 0
1226
- raise WtfError, "lame", caller
1227
- end
1228
-
1229
- all_sections.each do |section|
1230
- if section.contains_file_offset?(foffset)
1231
- return section.file_offset_to_rva(foffset)
1232
- end
1233
- end
1234
-
1235
- raise WtfError, "wtf! #{foffset}", caller
1236
- end
1237
-
1238
- def file_offset_to_vma(foffset)
1239
- return rva_to_vma(file_offset_to_rva(foffset))
1240
- end
1241
-
1242
- #
1243
- #
1244
- # Some routines to find which section something belongs
1245
- # to. These will search all_sections (so including
1246
- # our fake header section, etc...
1247
- #
1248
- #
1249
-
1250
- #
1251
- # Find a section by an RVA
1252
- #
1253
- def _find_section_by_rva(rva)
1254
- all_sections.each do |section|
1255
- if section.contains_rva?(rva)
1256
- return section
1257
- end
1258
- end
1259
-
1260
- return nil
1261
- end
1262
- def find_section_by_rva(rva)
1263
- section = _find_section_by_rva(rva)
1264
-
1265
- if !section
1266
- raise WtfError, "Cannot find rva! #{rva}", caller
1267
- end
1268
-
1269
- return section
1270
- end
1271
-
1272
- #
1273
- # Find a section by a VMA
1274
- #
1275
- def find_section_by_vma(vma)
1276
- return find_section_by_rva(vma_to_rva(vma))
1277
- end
1278
-
1279
- def valid_rva?(rva)
1280
- _find_section_by_rva(rva) != nil
1281
- end
1282
- def valid_vma?(vma)
1283
- _find_section_by_rva(vma_to_rva(vma)) != nil
1284
- end
1285
-
1286
- #
1287
- #
1288
- # Some convenient methods to read a vma/rva without having
1289
- # the section... (inefficent though I suppose...)
1290
- #
1291
- #
1292
-
1293
- def read_rva(rva, length)
1294
- return find_section_by_rva(rva).read_rva(rva, length)
1295
- end
1296
-
1297
- def read_vma(vma, length)
1298
- return read_rva(vma_to_rva(vma), length)
1299
- end
1300
-
1301
- def read_asciiz_rva(rva)
1302
- return find_section_by_rva(rva).read_asciiz_rva(rva)
1303
- end
1304
-
1305
- def read_asciiz_vma(vma)
1306
- return read_asciiz_rva(vma_to_rva(vma))
1307
- end
1308
-
1309
- #
1310
- #
1311
- # Imports, exports, and other stuff!
1312
- #
1313
- #
1314
-
1315
- #
1316
- # We lazily parse the imports, and then cache it
1317
- #
1318
- def imports
1319
- if !_imports_cached
1320
- self._imports_cache = _load_imports
1321
- self._imports_cached = true
1322
- end
1323
- return _imports_cache
1324
- end
1325
-
1326
- def _load_imports
1327
- #
1328
- # Get the data directory entry, size, etc
1329
- #
1330
- imports_entry = _optional_header['DataDirectory'][1]
1331
- rva = imports_entry.v['VirtualAddress']
1332
- size = imports_entry.v['Size']
1333
-
1334
- return nil if size == 0
1335
-
1336
- #
1337
- # Ok, so we have the data directory, now lets parse it
1338
- #
1339
-
1340
- imports = [ ]
1341
-
1342
- descriptors_data = _isource.read(rva_to_file_offset(rva), size)
1343
-
1344
- while descriptors_data.length >= IMAGE_IMPORT_DESCRIPTOR_SIZE
1345
- descriptor = IMAGE_IMPORT_DESCRIPTOR.make_struct
1346
- descriptor.from_s(descriptors_data)
1347
- descriptors_data = descriptor.leftover
1348
-
1349
- othunk = descriptor.v['OriginalFirstThunk']
1350
- fthunk = descriptor.v['FirstThunk']
1351
-
1352
- break if fthunk == 0
1353
-
1354
- dllname = _isource.read_asciiz(rva_to_file_offset(descriptor.v['Name']))
1355
-
1356
- import = ImportDescriptor.new(dllname, [ ])
1357
-
1358
- # we prefer the Characteristics/OriginalFirstThunk...
1359
- thunk_off = rva_to_file_offset(othunk == 0 ? fthunk : othunk)
1360
-
1361
- while (orgrva = _isource.read(thunk_off, 4).unpack('V')[0]) != 0
1362
- hint = nil
1363
- name = nil
1364
-
1365
- if (orgrva & IMAGE_ORDINAL_FLAG32) != 0
1366
- hint = orgrva & 0xffff
1367
- else
1368
- foff = rva_to_file_offset(orgrva)
1369
- hint = _isource.read(foff, 2).unpack('v')[0]
1370
- name = _isource.read_asciiz(foff + 2)
1371
- end
1372
-
1373
- import.entries << ImportEntry.new(name, hint)
1374
-
1375
- thunk_off += 4
1376
- end
1377
-
1378
- imports << import
1379
- end
1380
-
1381
- return imports
1382
- end
1383
-
1384
-
1385
-
1386
- #
1387
- # We lazily parse the exports, and then cache it
1388
- #
1389
- def exports
1390
- if !_exports_cached
1391
- self._exports_cache = _load_exports
1392
- self._exports_cached = true
1393
- end
1394
- return _exports_cache
1395
- end
1396
-
1397
- def _load_exports
1398
-
1399
- #
1400
- # Get the data directory entry, size, etc
1401
- #
1402
- exports_entry = _optional_header['DataDirectory'][0]
1403
- rva = exports_entry.v['VirtualAddress']
1404
- size = exports_entry.v['Size']
1405
-
1406
- return nil if size == 0
1407
-
1408
- #
1409
- # Ok, so we have the data directory, now lets parse it
1410
- #
1411
-
1412
- directory = IMAGE_EXPORT_DESCRIPTOR.make_struct
1413
- directory.from_s(_isource.read(rva_to_file_offset(rva), IMAGE_EXPORT_DESCRIPTOR_SIZE))
1414
-
1415
- #
1416
- # We can have nameless exports, so we need to do the whole
1417
- # NumberOfFunctions NumberOfNames foo
1418
- #
1419
- num_functions = directory.v['NumberOfFunctions']
1420
- num_names = directory.v['NumberOfNames']
1421
-
1422
- dllname_rva = directory.v['Name']
1423
- dllname = _isource.read_asciiz(rva_to_file_offset(dllname_rva))
1424
-
1425
- # FIXME Base, etc
1426
- fun_off = rva_to_file_offset(directory.v['AddressOfFunctions'])
1427
- name_off = rva_to_file_offset(directory.v['AddressOfNames'])
1428
- ord_off = rva_to_file_offset(directory.v['AddressOfNameOrdinals'])
1429
- base = directory.v['Base']
1430
-
1431
- # Allocate the list of names
1432
- names = Array.new(num_functions)
1433
-
1434
- #
1435
- # Iterate the names and name/ordinal list, getting the names
1436
- # and storing them in the name list...
1437
- #
1438
- num_names.times do |i|
1439
- name_rva = _isource.read(name_off + (i * 4), 4).unpack('V')[0]
1440
- ordinal = _isource.read(ord_off + (i * 2), 2).unpack('v')[0]
1441
- name = _isource.read_asciiz(rva_to_file_offset(name_rva))
1442
-
1443
- # store the exported name in the name list
1444
- names[ordinal] = name
1445
- end
1446
-
1447
- exports = ExportDirectory.new(dllname, [ ], base)
1448
-
1449
- #
1450
- # Now just iterate the functions (rvas) list..
1451
- #
1452
- num_functions.times do |i|
1453
- rva = _isource.read(fun_off + (i * 4), 4).unpack('V')[0]
1454
-
1455
- # ExportEntry.new(name, ordinal, rva)
1456
- exports.entries << ExportEntry.new(names[i], i + base, rva)
1457
- end
1458
-
1459
- return exports
1460
- end
1461
-
1462
- #
1463
- # Base relocations in the hizzy
1464
- #
1465
- def relocations
1466
- if !_relocations_cached
1467
- self._relocations_cache = _load_relocations
1468
- self._relocations_cached = true
1469
- end
1470
- return _relocations_cache
1471
- end
1472
-
1473
- def _load_relocations
1474
-
1475
- #
1476
- # Get the data directory entry, size, etc
1477
- #
1478
- exports_entry = _optional_header['DataDirectory'][5]
1479
- rva = exports_entry.v['VirtualAddress']
1480
- size = exports_entry.v['Size']
1481
-
1482
- return nil if size == 0
1483
-
1484
- #
1485
- # Ok, so we have the data directory, now lets parse it
1486
- #
1487
-
1488
- dirdata = _isource.read(rva_to_file_offset(rva), size)
1489
-
1490
- relocdirs = [ ]
1491
-
1492
- while dirdata.length >= IMAGE_SIZEOF_BASE_RELOCATION
1493
- header = IMAGE_BASE_RELOCATION.make_struct
1494
- header.from_s(dirdata)
1495
- dirdata = header.leftover
1496
-
1497
- numrelocs = (header.v['SizeOfBlock'] - IMAGE_SIZEOF_BASE_RELOCATION) / 2
1498
-
1499
- relocbase = header.v['VirtualAddress']
1500
-
1501
- relocdir = RelocationDirectory.new(relocbase, [ ])
1502
-
1503
- numrelocs.times do
1504
- reloc = IMAGE_BASE_RELOCATION_TYPE_OFFSET.make_struct
1505
- reloc.from_s(dirdata)
1506
- dirdata = reloc.leftover
1507
-
1508
- typeoffset = reloc.v['TypeOffset']
1509
-
1510
- relocrva = relocbase + (typeoffset & 0xfff)
1511
- reloctype = (typeoffset >> 12) & 0xf
1512
-
1513
- relocdir.entries << RelocationEntry.new(relocrva, reloctype)
1514
- end
1515
-
1516
- relocdirs << relocdir
1517
- end
1518
-
1519
- return relocdirs
1520
- end
1521
-
1522
-
1523
- #
1524
- # We lazily parse the resources, and then cache them
1525
- #
1526
- def resources
1527
- if !_resources_cached
1528
- _load_resources
1529
- self._resources_cached = true
1530
- end
1531
-
1532
- return self._resources_cache
1533
- end
1534
-
1535
- def _load_resources
1536
- #
1537
- # Get the data directory entry, size, etc
1538
- #
1539
- rsrc_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_RESOURCE]
1540
- rva = rsrc_entry.v['VirtualAddress']
1541
- size = rsrc_entry.v['Size']
1542
-
1543
- return nil if size == 0
1544
-
1545
- #
1546
- # Ok, so we have the data directory, now lets parse it
1547
- #
1548
- data = _isource.read(rva_to_file_offset(rva), size)
1549
-
1550
- self._resources_cache = {}
1551
- _parse_resource_directory(data)
1552
- end
1553
-
1554
- def _parse_resource_directory(data, rname=0, rvalue=0x80000000, path='0', pname=nil)
1555
-
1556
- pname = _parse_resource_name(data, rname)
1557
- if (path.scan('/').length == 1)
1558
- if (pname !~ /^\d+/)
1559
- path = "/" + pname
1560
- else
1561
- path = "/" + _resource_lookup( (rname & ~0x80000000).to_s)
1562
- end
1563
- end
1564
-
1565
-
1566
- rvalue &= ~0x80000000
1567
- vals = data[rvalue, 16].unpack('VVvvvv')
1568
-
1569
- chars = vals[0]
1570
- tdate = vals[1]
1571
- vers = "#{vals[2]}#{vals[3]}"
1572
- count = vals[4] + vals[5]
1573
-
1574
- 0.upto(count-1) do |i|
1575
-
1576
- ename, evalue = data[rvalue + 16 + ( i * 8), 8].unpack('VV')
1577
- epath = path + '/' + i.to_s
1578
-
1579
- if (ename & 0x80000000 != 0)
1580
- pname = _parse_resource_name(data, ename)
1581
- end
1582
-
1583
- if (evalue & 0x80000000 != 0)
1584
- # This is a subdirectory
1585
- _parse_resource_directory(data, ename, evalue, epath, pname)
1586
- else
1587
- # This is an entry
1588
- _parse_resource_entry(data, ename, evalue, epath, pname)
1589
- end
1590
- end
1591
-
1592
- end
1593
-
1594
- def _resource_lookup(i)
1595
- tbl = {
1596
- '1' => 'RT_CURSOR',
1597
- '2' => 'RT_BITMAP',
1598
- '3' => 'RT_ICON',
1599
- '4' => 'RT_MENU',
1600
- '5' => 'RT_DIALOG',
1601
- '6' => 'RT_STRING',
1602
- '7' => 'RT_FONTDIR',
1603
- '8' => 'RT_FONT',
1604
- '9' => 'RT_ACCELERATORS',
1605
- '10' => 'RT_RCDATA',
1606
- '11' => 'RT_MESSAGETABLE',
1607
- '12' => 'RT_GROUP_CURSOR',
1608
- '14' => 'RT_GROUP_ICON',
1609
- '16' => 'RT_VERSION',
1610
- '17' => 'RT_DLGINCLUDE',
1611
- '19' => 'RT_PLUGPLAY',
1612
- '20' => 'RT_VXD',
1613
- '21' => 'RT_ANICURSOR',
1614
- '22' => 'RT_ANIICON',
1615
- '23' => 'RT_HTML',
1616
- '24' => 'RT_MANIFEST',
1617
- '32767' => 'RT_ERROR',
1618
- '8192' => 'RT_NEWRESOURCE',
1619
- '8194' => 'RT_NEWBITMAP',
1620
- '8196' => 'RT_NEWMENU',
1621
- '8197' => 'RT_NEWDIALOG'
1622
- }
1623
- tbl[i] || i
1624
- end
1625
-
1626
- def _parse_resource_entry(data, rname, rvalue, path, pname)
1627
-
1628
- rva, size, code = data[rvalue, 12].unpack('VVV')
1629
- lang = _parse_resource_name(data, rname)
1630
-
1631
- ent = ResourceEntry.new(
1632
- self,
1633
- path,
1634
- lang,
1635
- code,
1636
- rva,
1637
- size,
1638
- pname
1639
- )
1640
- self._resources_cache[path] = ent
1641
- end
1642
-
1643
- def _parse_resource_name(data, rname)
1644
- if (rname & 0x80000000 != 0)
1645
- rname &= ~0x80000000
1646
- unistr = data[rname+2, 2 * data[rname,2].unpack('v')[0] ]
1647
- unistr, trash = unistr.split(/\x00\x00/, 2)
1648
- return unistr ? unistr.gsub(/\x00/, '') : nil
1649
- end
1650
-
1651
- rname.to_s
1652
- end
1653
-
1654
- def update_checksum
1655
- off = _dos_header.e_lfanew + IMAGE_FILE_HEADER_SIZE + 0x40
1656
- _isource.rawdata[off, 4] = [0].pack('V')
1657
-
1658
- rem = _isource.size % 4
1659
- sum_me = ''
1660
- sum_me << _isource.rawdata
1661
- sum_me << "\x00" * (4 - rem) if rem > 0
1662
-
1663
- cksum = 0
1664
- sum_me.unpack('V*').each { |el|
1665
- cksum = (cksum & 0xffffffff) + (cksum >> 32) + el
1666
- if cksum > 2**32
1667
- cksum = (cksum & 0xffffffff) + (cksum >> 32)
1668
- end
1669
- }
1670
-
1671
- cksum = (cksum & 0xffff) + (cksum >> 16)
1672
- cksum += (cksum >> 16)
1673
- cksum &= 0xffff
1674
-
1675
- cksum += _isource.size
1676
-
1677
- _isource.rawdata[off, 4] = [cksum].pack('V')
1678
- end
1679
-
1680
- end end end