Created
July 18, 2024 18:35
-
-
Save rachejazz/c8afba49760983fec642015b29f4eb9b to your computer and use it in GitHub Desktop.
script to use unicorn to emulate x86 program while using external library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ctypes | |
import os | |
from unicorn import * | |
from unicorn.x86_const import * | |
from capstone import * | |
import struct | |
main_start = 0x00400000 | |
start = 0x00401255 | |
end = 0x00401324 | |
size = 1024 * 1024 * 2 | |
def read_file(): | |
libc = ctypes.CDLL('./challenge/glibc/libc.so.6') | |
open_f = libc.open | |
read = libc.read | |
close = libc.close | |
# Constants for file opening | |
O_RDONLY = os.O_RDONLY | |
# Open the input file for reading | |
input_filename = b'output.txt' | |
input_fd = open_f(input_filename, O_RDONLY) | |
if input_fd < 0: | |
raise OSError("Failed to open input file") | |
file_content = bytearray() | |
buffer = ctypes.create_string_buffer(1024) | |
while True: | |
num_read = read(input_fd, buffer, 1024) | |
if num_read <= 0: | |
break | |
file_content.extend(buffer.raw[:num_read]) | |
close(input_fd) | |
file_content_str = file_content.decode('utf-8') | |
print(file_content_str) | |
return True | |
def hook_input(mu, address, size, user_data): | |
if address == 0x4012C1: | |
if read_file(): | |
mu.reg_write(UC_X86_REG_RIP, address+size) | |
def hook_skip(mu, address, size, user_data): | |
instructions_skip_list = [0x401262, 0x401282, 0x4012AB] | |
if address in instructions_skip_list: | |
mu.reg_write(UC_X86_REG_RIP, address+size) | |
def hook_output(mu, address, size, user_data): | |
md = Cs(CS_ARCH_X86, CS_MODE_64) | |
md.detail = True | |
data = bytes(mu.mem_read(address, size)) | |
for each in md.disasm(data, address): | |
inst = ("\t%s\t%s" %(each.mnemonic, each.op_str)) | |
print(f"Tracing>>>0x{address:X}: {inst}") | |
def main(): | |
with open("./challenge/labyrinth", "rb") as f: | |
data = f.read() | |
# Initialize emulator | |
mu = Uc(UC_ARCH_X86, UC_MODE_64) | |
mu.mem_map(main_start, size) | |
#stack | |
mu.reg_write(UC_X86_REG_RSP, main_start + 0x200000) | |
# Write memory data | |
mu.mem_write(main_start, data) | |
#hooks | |
mu.hook_add(UC_HOOK_CODE, hook_output, begin=start, end=end) | |
mu.hook_add(UC_HOOK_CODE, hook_skip, begin=start, end=end) | |
mu.hook_add(UC_HOOK_CODE, hook_input, begin=start, end=end) | |
#emulate | |
mu.emu_start(start, end) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment