from binaryninja import load, BinaryReader

bv = load('extracted_3.exe')
print(bv.start)

importTableEntry_offset = 0x100

br = BinaryReader(bv)
br.seek(bv.start + importTableEntry_offset)
import_table_va = bv.start + br.read32()
br.seek(import_table_va)

def read_until_byte(br, offset, byte_val):
    old_offset = br.offset
    br.seek(offset)
    result = b''
    while True:
        c = br.read(1)
        result += c
        if ord(c) == byte_val:
            break

    br.seek(old_offset)
    return result


def xor(input, byte_val):
    result = ''
    for i in range(len(input)):
        c = chr(input[i] ^ byte_val)
        result += c

    return result


def process_one_entry(br, start, address):
    old_offset = br.offset
    br.seek(address)
    br.read16()

    # print('br.offset', hex(br.offset))
    name = read_until_byte(br, br.offset, 0xc3)
    restored_name = xor(name, 0xc3)
    print(restored_name)
    bv.write(address + 2, restored_name)

    br.seek(old_offset)


def process_table(br, start, offset):
    old_offset = br.offset
    br.seek(offset)

    while True:
        int_rva = br.read32()
        if (int_rva == 0):
            break
        if (int_rva & 0x80000000 != 0):
            continue
        else:
            int_va = start + int_rva
            # print('int_va', hex(int_va))
            process_one_entry(br, start, int_va)

    br.seek(old_offset)

while True:
    table_rva = br.read32()
    if table_rva == 0:
        break

    br.seek(br.offset + 8)
    name_rva = br.read32()
    # print('name_rva: 0x%x' % name_rva)
    name_va = bv.start + name_rva
    name = read_until_byte(br, name_va, 0xc3)
    restored_name = xor(name, 0xc3)
    print(restored_name)
    bv.write(name_va, restored_name)

    table_va = bv.start + table_rva
    # print("table_va", hex(table_va))
    process_table(br, bv.start, table_va)

    br.seek(br.offset + 4)

bv.save('extracted.dll')