
from pydbg import *
from pydbg.defines import *
import utils
import sys
import re
import struct


def ssl_sniff_encryptmessage( dbg, args ):
    buffer = ""
    addr_bufflen=dbg.context.Esp + 0x2C
    bufflen=struct.unpack('L',dbg.read_process_memory(addr_bufflen, 4))[0]
    addr=dbg.context.Esp + 0x34
    addr_buffer = struct.unpack('L',dbg.read_process_memory(addr, 4))[0]
    try:
      buffer=dbg.read_process_memory(addr_buffer,bufflen)
      buffer=re.sub('.*gzip.*\r\n','',buffer)
      dbg.write_process_memory(addr_buffer, buffer)
    except:
      pass
    print "Comando: \n\n%s" % buffer
    print "\n-----------------------------------------\n"
    return DBG_CONTINUE

def ssl_sniff_wininet( dbg, args ):
    buffer = ""
    addr_bufflen=dbg.context.Esp + 0x8
    bufflen=struct.unpack('L',dbg.read_process_memory(addr_bufflen, 4))[0]
    addr=dbg.context.Esp + 0x4
    addr_buffer = struct.unpack('L',dbg.read_process_memory(addr, 4))[0]
    try:
      buffer=dbg.read_process_memory(addr_buffer,bufflen)
      buffer=re.sub('.*gzip.*\r\n','',buffer)
      dbg.write_process_memory(addr_buffer,buffer)
      dbg.write_process_memory(addr_bufflen, struct.pack("L",len(buffer))[0])
    except:
      pass
    print "Comando: \n\n%s" % buffer
    print "\n-----------------------------------------\n"
    return DBG_CONTINUE

def ssl_sniff_decrypt(dbg, args, ret):
    buffer = ""
    offset = 0
    addr=dbg.context.Esp + 32
    addr_buffer = struct.unpack('L',dbg.read_process_memory(addr, 4))[0]
    try:
        while 1:
           byte = dbg.read_process_memory(addr_buffer + offset, 1 )  
           if byte != "\x00":
               buffer += byte
               offset += 1
               continue
           else:
               break
        
        print "Repuesta: \n\n%s" % buffer
        print "\n-----------------------------------------\n"
    except:
        pass
    return DBG_CONTINUE

def Main():
  dbg = pydbg()
  test_ie= False
  for (pid, name) in dbg.enumerate_processes():
    print "PID: %s Procesos: %s" % (pid, name)
  proc_id = raw_input("\nIntroduzca el PID dl proceso a agregar: ")
  for (pid, name) in dbg.enumerate_processes():
    if pid==int(proc_id) and name.lower() == "iexplore.exe":
      answer=raw_input("\nProbamos a hacer hook con wininet.dll => EncryptMessage (Y or N)?: ")
      if answer.lower()=='y':
        test_ie=True
  try:
    hooks = utils.hook_container()
    dbg.attach(int(proc_id))
    print "\n[*] Agregamos el proceso con el PID: %d" % int(proc_id)
    if test_ie:
      hook_address = 0x77AA1000  # dirección de wininet.dll

    else:
      hook_address = dbg.func_resolve_debuggee("Secur32.dll","EncryptMessage")
    hook_address2 = dbg.func_resolve_debuggee("Secur32.dll","DecryptMessage")
    if hook_address and hook_address2:
      if test_ie:
        hooks.add( dbg, hook_address, 4, ssl_sniff_wininet, None )
        print "[*] Wininet.dll hooked at: 0x%08x" % hook_address
      else:
        hooks.add( dbg, hook_address, 4, ssl_sniff_encryptmessage, None )
        print "[*] Secur32.EncryptMessage hooked at: 0x%08x" % hook_address
      hooks.add( dbg, hook_address2, 4, None, ssl_sniff_decrypt )
      print "[*] Secur32.DecryptMessage hooked at: 0x%08x" % hook_address2
  except:
    print "[*] Error: No puedo resolver la dirección del hook."
    sys.exit(-1)
  print "[*] Hook válido, continuamos."
  dbg.run()
  
if __name__== '__main__': Main()   
