unicorn
unicorn copied to clipboard
mu.mem_write(BASE, shellcode) issue
Dear Dr. Quynh,
I have tried to play around with the shellcode analysis: https://eternal.red/2018/unicorn-engine-tutorial/
However, I have got the following error, do you have any hints? Thank you.
Regards, Anthony
Exploits-MBP:unicorn exploitmachine$ python3 solve2.py
Traceback (most recent call last):
File "solve2.py", line 17, in <module>
mu.mem_write(BASE, shellcode)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 585, in mem_write
status = _uc.uc_mem_write(self._uch, address, data, len(data))
ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type
Exploits-MBP:unicorn exploitmachine$ nano solve2.py
Exploits-MBP:unicorn exploitmachine$
It's weird, how to reproduce?
I run it on :
Model Name: MacBook Pro
Model Identifier: MacBookPro15,1
Processor Name: 6-Core Intel Core i9
Processor Speed: 2.9 GHz
Number of Processors: 1
Total Number of Cores: 6
L2 Cache (per Core): 256 KB
L3 Cache: 12 MB
Hyper-Threading Technology: Enabled
Memory: 32 GB
System Firmware Version: 1731.140.2.0.0 (iBridge: 19.16.16064.0.0,0)
OS Loader Version: 540.120.3~19
Serial Number (system): C02XC0SNJG5K
Hardware UUID: DB77C90B-45AF-5D5C-858B-A96D18D2295E
Provisioning UDID: DB77C90B-45AF-5D5C-858B-A96D18D2295E
Activation Lock Status: Disabled
Here are my findings below:
- The code I run is in Task 2 in solutions:
from unicorn import *
from unicorn.x86_const import *
shellcode = "\xe8\xff\xff\xff\xff\xc0\x5d\x6a\x05\x5b\x29\xdd\x83\xc5\x4e\x89\xe9\x6a\x02\x03\x0c\x24\x5b\x31\xd2\x66\xba\x12\x00\x8b\x39\xc1\xe7\x10\xc1\xef\x10\x81\xe9\xfe\xff\xff\xff\x8b\x45\x00\xc1\xe0\x10\xc1\xe8\x10\x89\xc3\x09\xfb\x21\xf8\xf7\xd0\x21\xd8\x66\x89\x45\x00\x83\xc5\x02\x4a\x85\xd2\x0f\x85\xcf\xff\xff\xff\xec\x37\x75\x5d\x7a\x05\x28\xed\x24\xed\x24\xed\x0b\x88\x7f\xeb\x50\x98\x38\xf9\x5c\x96\x2b\x96\x70\xfe\xc6\xff\xc6\xff\x9f\x32\x1f\x58\x1e\x00\xd3\x80"
BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024*1024
mu = Uc (UC_ARCH_X86, UC_MODE_32)
mu.mem_map(BASE, 1024*1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
mu.mem_write(BASE, shellcode)
mu.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE/2)
def syscall_num_to_name(num):
syscalls = {1: "sys_exit", 15: "sys_chmod"}
return syscalls[num]
def hook_code(mu, address, size, user_data):
#print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))
machine_code = mu.mem_read(address, size)
if machine_code == "\xcd\x80":
r_eax = mu.reg_read(UC_X86_REG_EAX)
r_ebx = mu.reg_read(UC_X86_REG_EBX)
r_ecx = mu.reg_read(UC_X86_REG_ECX)
r_edx = mu.reg_read(UC_X86_REG_EDX)
syscall_name = syscall_num_to_name(r_eax)
print "--------------"
print "We intercepted system call: "+syscall_name
if syscall_name == "sys_chmod":
s = mu.mem_read(r_ebx, 20).split("\x00")[0]
print "arg0 = 0x%x -> %s" % (r_ebx, s)
print "arg1 = " + oct(r_ecx)
elif syscall_name == "sys_exit":
print "arg0 = " + hex(r_ebx)
exit()
mu.reg_write(UC_X86_REG_EIP, address + size)
mu.hook_add(UC_HOOK_CODE, hook_code)
mu.emu_start(BASE, BASE-1)
- I try to run another code from Sakura (https://xz.aliyun.com/t/7545):
from unicorn import *
from unicorn.x86_const import *
mu = Uc(UC_ARCH_X86, UC_MODE_32)
BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024*1024
mu.mem_map(BASE, 1024*1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d\x6a\x05\x5b\x29\xdd\x83\xc5\x4e\x89\xe9\x6a\x02\x03\x0c\x24\x5b\x31\xd2\x66\xba\x12\x00\x8b\x39\xc1\xe7\x10\xc1\xef\x10\x81\xe9\xfe\xff\xff\xff\x8b\x45\x00\xc1\xe0\x10\xc1\xe8\x10\x89\xc3\x09\xfb\x21\xf8\xf7\xd0\x21\xd8\x66\x89\x45\x00\x83\xc5\x02\x4a\x85\xd2\x0f\x85\xcf\xff\xff\xff\xec\x37\x75\x5d\x7a\x05\x28\xed\x24\xed\x24\xed\x0b\x88\x7f\xeb\x50\x98\x38\xf9\x5c\x96\x2b\x96\x70\xfe\xc6\xff\xc6\xff\x9f\x32\x1f\x58\x1e\x00\xd3\x80"
mu.mem_write(BASE, shellcode)
mu.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE-1)
def hook_code(mu, address, size, user_data):
# print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))
code = mu.mem_read(address,size)
# print(code)
if code == b"\xcd\x80":
print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))
eax = mu.reg_read(UC_X86_REG_EAX)
ebx = mu.reg_read(UC_X86_REG_EBX)
ecx = mu.reg_read(UC_X86_REG_ECX)
edx = mu.reg_read(UC_X86_REG_EDX)
print("{}: {} {} {}".format(eax,ebx,ecx,edx))
if(eax == 15):
file_name = bytes(mu.mem_read(ebx,32)).split(b'\x00')[0]
print("file_name is {}".format(file_name))
mu.reg_write(UC_X86_REG_EIP, address+size)
mu.hook_add(UC_HOOK_CODE, hook_code)
mu.emu_start(BASE,BASE+len(shellcode))
It is okay but tracing to second time is problematic:
Exploits-MBP:unicorn exploitmachine$ python3 solve2a.py
>>> Tracing instruction at 0x40006b, instruction size = 0x2
15: 4194392 438 0
file_name is b'/etc/shadow'
>>> Tracing instruction at 0x400070, instruction size = 0x2
1: 4194392 438 0
Traceback (most recent call last):
File "solve2a.py", line 35, in <module>
mu.emu_start(BASE,BASE+len(shellcode))
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 548, in emu_start
raise UcError(status)
unicorn.unicorn.UcError: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)
Exploits-MBP:unicorn exploitmachine$
- When I try to run task 3 (https://eternal.red/2018/unicorn-engine-tutorial/#task-3) code on my Mac OS:
from unicorn import *
from unicorn.x86_const import *
import struct
def read(name):
with open(name) as f:
return f.read()
def u32(data):
return struct.unpack("I", data)[0]
def p32(num):
return struct.pack("I", num)
mu = Uc (UC_ARCH_X86, UC_MODE_32)
BASE = 0x08048000
STACK_ADDR = 0x0
STACK_SIZE = 1024*1024
mu.mem_map(BASE, 1024*1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
mu.mem_write(BASE, read("./function"))
r_esp = STACK_ADDR + (STACK_SIZE/2) #ESP points to this address at function call
STRING_ADDR = 0x0
mu.mem_write(STRING_ADDR, "batman\x00") #write "batman" somewhere. We have choosen an address 0x0 which belongs to the stack.
mu.reg_write(UC_X86_REG_ESP, r_esp) #set ESP
mu.mem_write(r_esp+4, p32(5)) #set the first argument. It is integer 5
mu.mem_write(r_esp+8, p32(STRING_ADDR)) #set the second argument. This is a pointer to the string "batman"
mu.emu_start(0x8048464, 0x804849A) #start emulation from the beginning of super_function, end at RET instruction
return_value = mu.reg_read(UC_X86_REG_EAX)
print "The returned value is: %d" % return_value
I have changed the base address and superfunction offset:
0000057b <super_function>:
57b: 55 pushl %ebp
57c: 89 e5 movl %esp, %ebp
57e: e8 53 00 00 00 calll 0x5d6 <__x86.get_pc_thunk.ax>
583: 05 7d 1a 00 00 addl $6781, %eax # imm = 0x1A7D
588: 83 7d 08 05 cmpl $5, 8(%ebp)
58c: 75 1d jne 0x5ab <super_function+0x30>
58e: 8d 80 60 e6 ff ff leal -6560(%eax), %eax
594: 50 pushl %eax
595: ff 75 0c pushl 12(%ebp)
598: e8 70 ff ff ff calll 0x50d <strcmp>
59d: 83 c4 08 addl $8, %esp
5a0: 85 c0 testl %eax, %eax
5a2: 75 07 jne 0x5ab <super_function+0x30>
5a4: b8 01 00 00 00 movl $1, %eax
5a9: eb 05 jmp 0x5b0 <super_function+0x35>
5ab: b8 00 00 00 00 movl $0, %eax
5b0: c9 leave
5b1: c2 08 00 retl $8
Exploits-MBP:unicorn exploitmachine$ objdump -d function
function: file format elf32-i386
Disassembly of section .init:
00000378 <_init>:
378: 53 pushl %ebx
379: 83 ec 08 subl $8, %esp
37c: e8 8f 00 00 00 calll 0x410 <__x86.get_pc_thunk.bx>
381: 81 c3 7f 1c 00 00 addl $7295, %ebx # imm = 0x1C7F
387: 8b 83 f4 ff ff ff movl -12(%ebx), %eax
38d: 85 c0 testl %eax, %eax
38f: 74 05 je 0x396 <_init+0x1e>
391: e8 32 00 00 00 calll 0x3c8 <function.c+0x3c8>
396: 83 c4 08 addl $8, %esp
399: 5b popl %ebx
39a: c3 retl
It gives: Without changing any offsets:
Exploits-MBP:unicorn exploitmachine$ python3 solve4.py
Traceback (most recent call last):
File "solve4.py", line 23, in <module>
mu.mem_map(BASE, 1024*1024)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 622, in mem_map
raise UcError(status)
unicorn.unicorn.UcError: Invalid argument (UC_ERR_ARG)
Exploits-MBP:unicorn exploitmachine$
After change the offsets:
Exploits-MBP:unicorn exploitmachine$ python3 solve4.py
Traceback (most recent call last):
File "solve4.py", line 24, in <module>
mu.mem_map(STACK_ADDR, STACK_SIZE)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 622, in mem_map
raise UcError(status)
unicorn.unicorn.UcError: Invalid memory mapping (UC_ERR_MAP)
Questions:
-
Will it be related to my Mac runs on Intel Core i9? If yes, what is the change of the mem base? https://en.wikichip.org/wiki/intel/core_i9/i9-9900k
-
I can run this code successfully without error: https://github.com/unicorn-engine/unicorn/blob/master/bindings/python/shellcode.py
-
Are there any suggestions of changes of the above tutorial programs?
-
Do you have any latest docker image of Unicorn engine available for download?
Thank you so much.
It's weird, how to reproduce?
Yes, I have attached details in the immediate reply. Thank you so much, Lazymio, I heard your big name from XWings 👍
(1) i think your Mac on x86 should be fine, so that is the the reason of the issue.
(4): no, we do not have docker support, since unicorn is easy enough to build & run.
are you on Unicorn 2.0, or older version?
are you on Unicorn 2.0, or older version?
Should be latest version as I freshly install and set it up.
you can confirm the version with print(unicorn.__version__)
It is 2.0.0.
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.
Hey there @0xdarkfloyd ,
I was going through the same exercises and came across this issue too. I believe the wrong type
is referring to the shellcode string, whereas it expects bytes. It was a very simple fix for me:
shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d..."
Hope this helps!
Let me try thank you so much bro
On Wed, 2 Nov 2022 at 4:18 AM, danielmoder @.***> wrote:
Hey there @0xdarkfloyd https://github.com/0xdarkfloyd ,
I was going through the same exercises and came across this issue too. I believe the wrong type is referring to the shellcode string, whereas it expects bytes. It was a very simple fix for me:
shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d..."
Hope this helps!
— Reply to this email directly, view it on GitHub https://github.com/unicorn-engine/unicorn/issues/1677#issuecomment-1299088159, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFKKU56MJVA5BEONORVBIP3WGF3I5ANCNFSM56OKIMCA . You are receiving this because you were mentioned.Message ID: @.***>
Traceback (most recent call last):
File "/home/hacker/solve2.py", line 18, in
Any thoughts about this error? Thank you all.
On Wed, Nov 2, 2022 at 4:18 AM danielmoder @.***> wrote:
Hey there @0xdarkfloyd https://github.com/0xdarkfloyd ,
I was going through the same exercises and came across this issue too. I believe the wrong type is referring to the shellcode string, whereas it expects bytes. It was a very simple fix for me:
shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d..."
Hope this helps!
— Reply to this email directly, view it on GitHub https://github.com/unicorn-engine/unicorn/issues/1677#issuecomment-1299088159, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFKKU56MJVA5BEONORVBIP3WGF3I5ANCNFSM56OKIMCA . You are receiving this because you were mentioned.Message ID: @.***>
-- Regards, Anthony LAI Founder & Security Researcher Valkyrie-X Security Research Group "Offensive . Creative . Fun"
__ _
.-.' `; `-._ __ _
(_, .-:' `; `-._
,'o"( (, )
(,-' ,'o"( )>
( (,-' )
-'._.--._( ) ||| |||
-'..--._.-'
||| |||
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.