Esempio n. 1
0
def assemble(insn_list):
    ks = Ks(KS_ARCH_X86, KS_MODE_64)
    iarray, cnt = ks.asm("\n".join(insn_list))
    code = ""
    for i in iarray:
        code += chr(i)
    return code
Esempio n. 2
0
 def runTest(self):
     ks = Ks(KS_ARCH_PPC, KS_MODE_PPC32 + KS_MODE_BIG_ENDIAN)
     encoding, count = ks.asm(self.asm, 0xc0000000)
     expected_encoding = [
         56, 128, 0, 1, 56, 132, 0, 1, 72, 0, 191, 249, 56, 128, 0, 1, 56,
         165, 0, 1, 72, 0, 191, 249
     ]
     self.assertEqual(encoding, expected_encoding)
Esempio n. 3
0
 def runTest(self):
     ks = Ks(KS_ARCH_ARM, KS_MODE_ARM)
     encoding, count = ks.asm(self.asm, 0xc0000000)
     expected_encoding = [
         48, 0, 160, 227, 91, 172, 33, 235, 16, 0, 0, 230, 65, 0, 160, 227,
         84, 172, 33, 235
     ]
     self.assertEqual(encoding, expected_encoding)
Esempio n. 4
0
def run(uc, inp):
    try:
        ks = Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
        bytecode, _ = ks.asm(inp)
        uc.mem_write(BASE_ADR, bytes(bytecode))
        uc.emu_start(BASE_ADR, BASE_ADR + 4, 0, 1)
    except KsError as ke:
        print(ke)
    except UcError as ue:
        print(ue)
    except:
        print("Assemler error")
Esempio n. 5
0
    def assemble(self, code, thumb=True):
        """
        Assemble code using Keystone and write it at the current position.

        Args:
            code (:obj:`str`): the code to assemble
            thumb (:obj:`bool`): True if Thumb, False otherwise

        Returns:
            :obj:`int`: the number of bytes written
        """
        from keystone import Ks, KS_ARCH_ARM, KS_MODE_ARM, KS_MODE_THUMB

        ks = Ks(KS_ARCH_ARM, KS_MODE_THUMB if thumb else KS_MODE_ARM)

        addr = self._ptr.value
        bs, size = ks.asm(code, addr)
        self.write(bytes(bytearray(bs)))
        return len(bs)
Esempio n. 6
0
def sample_elf(request):
    with tempfile.NamedTemporaryFile(suffix='.elf', delete=False) as f:
        e = ElfBuilder()
        e.set_endianity('>')
        e.set_machine(elf_consts.EM_ARM)

        # add a segment
        text_address = 0x1234

        ks = Ks(KS_ARCH_ARM, KS_MODE_ARM | KS_MODE_BIG_ENDIAN)

        text_buffer = ks.asm(
            '''
        ret_1:
            mov r0, #1
            bx lr
        eloop:
             b eloop
        data:
            .word 0x11223344
            .word 0x55667788
        .code 32
        main:
            push {r4-r7, lr}
            bl 0x1234-8
            ldr r0, =data
            bl 0x1234-8
            pop {r4-r7, pc}
        ''', text_address)[0]
        text_buffer = bytearray(text_buffer)

        e.add_segment(text_address, text_buffer,
                      elf_consts.PF_R | elf_consts.PF_W | elf_consts.PF_X)
        e.add_code_section('.text', text_address, len(text_buffer))
        f.write(e.build())
        yield f
Esempio n. 7
0
def asm(code, addr=0x0):
    ks = Ks(KS_ARCH_ARM, KS_MODE_ARM)
    encoding, count = ks.asm(code, addr=addr)
    return encoding
Esempio n. 8
0
class Hooker:
    """
    :type emu androidemu.emulator.Emulator
    """
    def __init__(self, emu, base_addr, size):
        self._emu = emu
        self._keystone = Ks(KS_ARCH_ARM, KS_MODE_THUMB)
        self._size = size
        self._current_id = 0xFF00
        self._hooks = dict()
        self._hook_magic = base_addr
        self._hook_start = base_addr + 4
        self._hook_current = self._hook_start
        self._emu.mu.hook_add(UC_HOOK_CODE, self._hook, None, self._hook_start,
                              self._hook_start + size)

    def _get_next_id(self):
        idx = self._current_id
        self._current_id += 1
        return idx

    def write_function(self, func):
        # Get the hook id.
        hook_id = self._get_next_id()
        hook_addr = self._hook_current

        # Create the ARM assembly code.
        # Make sure to update STACK_OFFSET if you change the PUSH/POP.
        asm = "PUSH {R4,LR}\n" \
              "MOV R4, #" + hex(hook_id) + "\n" \
              "MOV R4, R4\n" \
              "POP {R4,PC}"

        asm_bytes_list, asm_count = self._keystone.asm(
            bytes(asm, encoding='ascii'))

        if asm_count != 4:
            raise ValueError("Expected asm_count to be 4 instead of %u." %
                             asm_count)

        # Write assembly code to the emulator.
        self._emu.mu.mem_write(hook_addr, bytes(asm_bytes_list))

        # Save results.
        self._hook_current += len(asm_bytes_list)
        self._hooks[hook_id] = func

        return hook_addr

    def write_function_table(self, table):
        if not isinstance(table, dict):
            raise ValueError("Expected a dictionary for the function table.")

        index_max = int(max(table, key=int)) + 1

        # First, we write every function and store its result address.
        hook_map = dict()

        for index, func in table.items():
            hook_map[index] = self.write_function(func)

        # Then we write the function table.
        table_bytes = b""
        table_address = self._hook_current

        for index in range(0, index_max):
            address = hook_map[index] if index in hook_map else 0
            table_bytes += int(address + 1).to_bytes(
                4, byteorder='little')  # + 1 because THUMB.

        self._emu.mu.mem_write(table_address, table_bytes)
        self._hook_current += len(table_bytes)

        # Then we write the a pointer to the table.
        ptr_address = self._hook_current
        self._emu.mu.mem_write(ptr_address,
                               table_address.to_bytes(4, byteorder='little'))
        self._hook_current += 4

        return ptr_address, table_address

    def _hook(self, mu, address, size, user_data):
        # Check if instruction is "MOV R4, R4"
        if size != 2 or self._emu.mu.mem_read(address, size) != b"\x24\x46":
            return

        # Find hook.
        hook_id = self._emu.mu.reg_read(UC_ARM_REG_R4)
        hook_func = self._hooks[hook_id]

        # Call hook.
        try:
            hook_func(self._emu)
        except:
            # Make sure we catch exceptions inside hooks and stop emulation.
            mu.emu_stop()
            raise
Esempio n. 9
0
 def runTest(self):
     ks = Ks(KS_ARCH_PPC, KS_MODE_PPC32 + KS_MODE_BIG_ENDIAN)
     encoding, count = ks.asm(self.asm, 0xc0000000)
     expected_encoding = [56, 128, 0, 1, 56, 132, 0, 1, 72, 0, 191, 249, 56,
                          128, 0, 1, 56, 165, 0, 1, 72, 0, 191, 249]
     self.assertEqual(encoding, expected_encoding)
Esempio n. 10
0
 def runTest(self):
     ks = Ks(KS_ARCH_ARM, KS_MODE_ARM)
     encoding, count = ks.asm(self.asm, 0xc0000000)
     expected_encoding = [48, 0, 160, 227, 91, 172, 33, 235, 16,
                          0, 0, 230, 65, 0, 160, 227, 84, 172, 33, 235]
     self.assertEqual(encoding, expected_encoding)
Esempio n. 11
0
 def assemble(code, entry_point):
     ks = Ks(KS_ARCH_X86, KS_MODE_32)
     asm = "%s JMP offset_%s; %s" % (_init(), entry_point, code)
     # print asm.replace("; ", "\n").replace(";", "\n")
     return "".join(map(chr, ks.asm(asm)[0]))
Esempio n. 12
0
import binascii

from keystone import Ks, KS_ARCH_ARM, KS_MODE_ARM

ks = Ks(KS_ARCH_ARM, KS_MODE_ARM)

assembly_text = \
    """
    sub sp, sp, #8
    push {sp, lr}
    bl #0xc6ab8
    ldr lr, [sp, #4]
    add sp, sp, #8
    pop {r2, r3}
    bx lr
    """

for i in range(100):
    output = ks.asm(assembly_text, 0x902c4, as_bytes=True)
    # print("{}: {}: {}".format(i, assembly_text, output))
    output_2 = ks.asm("b #0", 0x4, as_bytes=True)
    # print("{}: {}: {}".format(i, "b #0",  output_2))
Esempio n. 13
0
from keystone import Ks, KS_ARCH_ARM, KS_MODE_ARM

asm = Ks(KS_ARCH_ARM, KS_MODE_ARM)
code = '''mov r0, #0x37;
sub r1, r2, r3'''
asm_code = asm.asm(code)
print(asm_code)
print(bytes(asm_code[0]))
// n is r0, we will pass it from python, ans is r1
mov r1, 1       	// ans = 1
loop:
cmp r0, 0       	// while n >= 0:
mulgt r1, r1, r0	//   ans *= n
subgt r0, r0, 1 	//   n = n - 1
bgt loop        	// 
                	// answer is in r1
"""

print("Assembling the ARM code")
try:
    # initialize the keystone object with the ARM architecture
    ks = Ks(KS_ARCH_ARM, KS_MODE_ARM)
    # Assemble the ARM code
    ARM_BYTECODE, _ = ks.asm(ARM_CODE)
    # convert the array of integers into bytes
    ARM_BYTECODE = bytes(ARM_BYTECODE)
    print(f"Code successfully assembled (length = {len(ARM_BYTECODE)})")
    print("ARM bytecode:", ARM_BYTECODE)
except KsError as e:
    print("Keystone Error: %s" % e)
    exit(1)

# memory address where emulation starts
ADDRESS = 0x1000000

print("Emulating the ARM code")
try:
    # Initialize emulator in ARM mode
    mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
Esempio n. 15
0
e = ELF(argv[1])

new_section = Elf64_Shdr_ST()

# creating our shellcode (exit(14);)
asm = """
    mov rax, 0x3c
    mov rdi, 14
    syscall
    """

ks = Ks(KS_ARCH_X86, KS_MODE_64)
ks.syntax = KS_OPT_SYNTAX_NASM

shellcode = ks.asm(asm)[0]
shellcode = (c_char * len(shellcode)).from_buffer(bytearray(shellcode)).raw

# we can modify the .text section to jmp to the sc but we will directly modified the entrypoint
# stub = ks.asm("jmp 0x3308")[0]
# stub = (c_char * len(stub)).from_buffer(bytearray(stub)).raw
# e.get_section_by_name(".text").data = stub

new_section.data = shellcode

new_section.sh_name = 1 # choose a random name
# right after the last sh there is the sht table so it offset will be the addr of the new section
new_section.sh_offset = e.Elf64_Ehdr.e_shoff # nice if it would be filled automatically by save
new_section.sh_size = len(new_section.data)
new_section.sh_addralign = 16
new_section.sh_type = 0x1 # PROGBITS