def dump_and_rebuild(pid, oep, newimpdir="newimpdir", newiat="newiat"):
    '''Dump process and rebuild with new original entry point.
    @param pid: process ID
    @param oep: original entry point
    @param newimpdir: name for new section that will contain imports
    @param newiat: name for new section that will contain new IAT
    '''
    System.request_debug_privileges()
    process = Process( pid )
    try:
        process.suspend()
    except WindowsError as e:
        pass
    file_path = process.get_filename()
    file_name = p_os.path.basename(file_path)

    #######################################################################
    # 
    # REBUILD THE DUMPED PE
    #
    # I'm sure there is a better way to do this because all we are really 
    # doing is dumping the PE mapped sections. Suggestions welcome!
    #
    # The crazy way we do this is to get a memory map of the whole process
    # then find the pages that are owned by the file that spawned the process.
    #
    #######################################################################
    mem_map = get_mem_map(process)

    temp_data_arr = {}
    for page in mem_map:
        if file_name.upper() in page["Owner"].upper():
            dump_data = process.peek(page["BaseAddress"],page["RegionSize"])
            temp_data_arr[page["BaseAddress"]] = dump_data
    
    # we need to work with the dump as one contiguous data block in "mapped" format.
    ordered_mem = temp_data_arr.keys()
    ordered_mem.sort()
    block_data = temp_data_arr[ordered_mem[0]]
    for addr_ptr in range(1,len(ordered_mem)):
        padding_len  = ordered_mem[addr_ptr] - (ordered_mem[0] + len(block_data))
        #print "Padding: %d" % padding_len
        # These should be contiguous pages so there should be no need for padding!
        block_data += temp_data_arr[ordered_mem[addr_ptr]] + '\x00'*padding_len

    # The lowest mapped section is the base address
    base_address = ordered_mem[0]

    # Elfesteem has a small issue with the way it loads mapped PE files
    # instead of using the virtual size for segments it uses the raw size
    # this messes up unpacker dumps so we will fix it manually. 

    pf = pe_init.PE(loadfrommem=True, pestr=block_data)
    new_sections = []
    for tmp_section in pf.SHList:
         new_sections.append({"name": tmp_section.name ,"offset": tmp_section.addr ,"size": tmp_section.size ,"addr": tmp_section.addr ,"flags": tmp_section.flags ,"rawsize": tmp_section.size})

    # Remove existing sections
    pf.SHList.shlist=[]
    
    for tmp_section in new_sections:
        pf.SHList.add_section(name=tmp_section["name"], 
            data=block_data[tmp_section["offset"]:tmp_section["offset"] + tmp_section["rawsize"]], 
            size=tmp_section["size"], 
            addr=tmp_section["addr"], 
            offset=tmp_section["offset"], 
            rawsize=tmp_section["rawsize"])

    pf.NThdr.ImageBase = base_address
    pf.Opthdr.AddressOfEntryPoint = oep
    # Disable rebase, since addresses are absolute any rebase will make this explode
    pf.NThdr.dllcharacteristics = 0x0

    #######################################################################
    # 
    # At this point pf contains a fully reconstructed PE but with a 
    # broken IAT. Fix the IAT!
    #
    #######################################################################
    return rebuild_iat(pid, str(pf), base_address, oep, newimpdir=newimpdir, newiat=newiat, loadfrommem=False)