日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python中emuterate用法_跨平台模拟执行 - AndroidNativeEmu实用手册

發(fā)布時(shí)間:2024/9/19 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python中emuterate用法_跨平台模拟执行 - AndroidNativeEmu实用手册 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原標(biāo)題:跨平臺(tái)模擬執(zhí)行 - AndroidNativeEmu實(shí)用手冊(cè)

本文為看雪論壇精華文章

看雪論壇作者ID:StriveMario

安裝

AndroidNativeEmu有什么用?

AndroidNativeEmu是基于Unicron實(shí)現(xiàn)的一個(gè)指令解析器, 讓您能夠跨平臺(tái)模擬Android Native庫(kù)函數(shù),例如JNI_,Java_XXX_XX等函數(shù)。

特性

模擬 JNI Invocation API so JNI_ can be called properly.

模擬 memory、malloc、memcpy

支持?jǐn)r截系統(tǒng)調(diào)用(SVC #0)

通過(guò)符號(hào)Hook

所有 JavaVM, JNIEnv 和 hooked functions 都可以用python來(lái)處理

支持 VFP

支持文件系統(tǒng)(也就是說(shuō)你可以模擬maps、status等文件)

項(xiàng)目地址:

https://github.com/AeonLucid/AndroidNativeEmu

安裝過(guò)程

環(huán)境要求: python 3.7 (注意必須是3.7版本, 我使用3.6裝keystone的時(shí)候踩了坑)

自測(cè)系統(tǒng)環(huán)境: win7

1. Clone 該項(xiàng)目

git clone http s://github. com/AeonLucid/AndroidNativeEmu.git

2. 安裝需要的支持模塊

pip install-r requirements.txt

安裝keystone-engine可能會(huì)失敗(反正我是沒裝上)。

解決方案:

克隆keystone倉(cāng)庫(kù):git clone https://github.com/keystone-engine/keystone.git

打開keystonebindings文件夾安裝: python setup.py install

下載對(duì)應(yīng)系統(tǒng)和版本dll(因?yàn)槲沂莣in), 下載鏈接: http://www.keystone-engine.org/download/

把dll復(fù)制到python的keystone目錄下: [python_path]Libsite-packageskeystone

3. 把a(bǔ)ndroidemu文件夾復(fù)制至sample文件夾下,并刪除example.py文件下的關(guān)于"samples/"的目錄訪問路徑。

"samples/example_binaries/libc.so"

改為

"example_binaries/libc.so"

4. 運(yùn)行例子。

pythonexample. py

5. 不出意外的話就可以看到結(jié)果了。

例子文件閱讀

example_binaries/ : 里面是需要加載的 so

vfs/ : 里面是虛擬的文件系統(tǒng), 有需要可以自己添加文件

androidemu/ : android虛擬機(jī)

importlogging

importsys

fromunicorn importUC_HOOK_CODE

fromunicorn.arm_const import*

fromandroidemu.emulator importEmulator

# 配置日志相關(guān)設(shè)置

logging.basicConfig(

stream=sys.stdout, #標(biāo)準(zhǔn)輸出流

level=logging.DEBUG, #輸出等級(jí)

format= "%(asctime)s %(levelname)7s %(name)34s | %(message)s"#輸出格式

)

logger = logging.getLogger(__name__) #實(shí)例化對(duì)象

# 實(shí)例化虛擬機(jī)

emulator = Emulator

#加載Libc庫(kù)

emulator.load_library( "example_binaries/libc.so", do_init= False)

#加載要模擬器的庫(kù)

lib_module = emulator.load_library( "example_binaries/libnative-lib.so")

#打印已經(jīng)加載的模塊

logger.info( "Loaded modules:")

formodule inemulator.modules:

logger.info( "[0x%x] %s"% (module.base, module.filename))

#trace 每步執(zhí)行的指令, 方便調(diào)試, 其實(shí)也可以取消

defhook_code(mu, address, size, user_data):

instruction = mu.mem_read(address, size)

instruction_str = ''.join( '{:02x} '.format(x) forx ininstruction)

print( '# Tracing instruction at 0x%x, instruction size = 0x%x, instruction = %s'% (address, size, instruction_str))

emulator.mu.hook_add(UC_HOOK_CODE, hook_code)

#通過(guò)導(dǎo)出符號(hào)來(lái)調(diào)用函數(shù)

emulator.call_symbol(lib_module, '_Z4testv')

#通過(guò)R0來(lái)獲取調(diào)用結(jié)構(gòu)

print( "String length is: %i"% emulator.mu.reg_read(UC_ARM_REG_R0))

自己寫個(gè)小Demo測(cè)試

Demo代碼

新建一個(gè)jni工程, demo的代碼很簡(jiǎn)單, 就是一個(gè)加法。

JNIEXPORT intnativeAdd(inta, intb)

{

returna + b;

}

extern"C"JNIEXPORT jint JNICALL

Java_com_mario_testunicorn_MainActivity_myAdd(

JNIEnv* env,

jobject /*this*/,

inta,

intb){

returnnativeAdd(a,b);

}

emu代碼

注釋寫的很詳細(xì), 具體看代碼吧。

importlogging

importposixpath

importsys

fromunicorn importUcError, UC_HOOK_CODE, UC_HOOK_MEM_UNMAPPED

fromunicorn.arm_const import*

fromandroidemu.emulator importEmulator

importdebug_utils

# 配置日志

logging.basicConfig(

stream=sys.stdout,

level=logging.DEBUG,

format= "%(asctime)s %(levelname)7s %(name)34s | %(message)s"

)

logger = logging.getLogger(__name__)

# 初始化模擬器

emulator = Emulator(

vfp_inst_set= True,

vfs_root=posixpath.join(posixpath.dirname(__file__), "vfs")

)

# 加載依賴的動(dòng)態(tài)庫(kù)

emulator.load_library( "example_binaries/libdl.so")

emulator.load_library( "example_binaries/libc.so", do_init= False)

emulator.load_library( "example_binaries/libstdc++.so")

emulator.load_library( "example_binaries/libm.so")

lib_module = emulator.load_library( "example_binaries/libmytest.so")

# 當(dāng)前已經(jīng)load的so

logger.info( "Loaded modules:")

formodule inemulator.modules:

logger.info( "=> 0x%08x - %s"% (module.base, module.filename))

try:

# 運(yùn)行jni 這里沒有, 但不影響執(zhí)行

emulator.call_symbol(lib_module, 'JNI_', emulator.java_vm.address_ptr, 0x00)

#直接調(diào)用符號(hào)1, 計(jì)算1+2

emulator.call_symbol(lib_module, '_Z9nativeAddii', 1, 2)

print( "_Z9nativeAddii result call: %i"% emulator.mu.reg_read(UC_ARM_REG_R0))

#直接調(diào)用符號(hào)2, 計(jì)算1000 + 1000

emulator.call_symbol(lib_module, 'Java_com_mario_testunicorn_MainActivity_myAdd', 0, 0, 1000, 1000)

print( "myAdd result call: %i"% emulator.mu.reg_read(UC_ARM_REG_R0))

#執(zhí)行完成, 退出虛擬機(jī)

logger.info( "Exited EMU.")

logger.info( "Native methods registered to MainActivity:")

exceptUcError ase:

print( "Exit at %x"% emulator.mu.reg_read(UC_ARM_REG_PC))

raise

RuntimeError: Unhandled syscall x (x) at 解決

這個(gè)錯(cuò)誤是因?yàn)闆]有實(shí)現(xiàn)對(duì)應(yīng)syscall導(dǎo)致的, 缺少什么函數(shù), 自己寫一個(gè)函數(shù)綁定一下, 返回給他需要的值就可以了, 比如getpid, 那么自己寫的函數(shù)隨便返回一個(gè)整形就可以了。

在syscall_hooks.py文件里, 可以看到作者已經(jīng)實(shí)現(xiàn)的函數(shù)。

self._syscall_handler.set_handler( 0x4E, "gettimeofday", 2, self._handle_gettimeofday)

self._syscall_handler.set_handler( 0xAC, "prctl", 5, self._handle_prctl)

self._syscall_handler.set_handler( 0xF0, "futex", 6, self._handle_futex)

self._syscall_handler.set_handler( 0x107, "clock_gettime", 2, self._handle_clock_gettime)

self._syscall_handler.set_handler( 0x119, "socket", 3, self._socket)

self._syscall_handler.set_handler( 0x11b, "connect", 3, self._connect)

self._syscall_handler.set_handler( 0x159, "getcpu", 3, self._getcpu)

self._syscall_handler.set_handler( 0x14e, "faccessat", 4, self._faccessat)

self._syscall_handler.set_handler( 0x14, "getpid", 0, self._getpid)

self._syscall_handler.set_handler( 0xe0, "gettid", 0, self._gettid)

self._syscall_handler.set_handler( 0x180, "null1", 0, self._null)

set_handler函數(shù)參數(shù):

arg1: 中斷號(hào)(intno),中斷號(hào)可以在 ndk中的 unistd.h中找到

arg2: 函數(shù)名

arg3: 參數(shù)數(shù)量

arg4: 綁定的自定義函數(shù)

執(zhí)行結(jié)果

實(shí)戰(zhàn)一款風(fēng)控SO

實(shí)戰(zhàn)目標(biāo)

以下信息通過(guò)分析所得, 具體分析過(guò)程不是本文重點(diǎn),這里不贅述。

目標(biāo)文件: libtest.so

目標(biāo)函數(shù): a( char* buf, intbuf_len)

返回值: return_value > 0, 表示風(fēng)險(xiǎn)環(huán)境并且會(huì)在buf參數(shù)里寫入詳細(xì)風(fēng)險(xiǎn)環(huán)境信息;

return_value == 0, 表示正常環(huán)境

EMU代碼

詳情看注釋, 寫的很詳細(xì)。

importlogging

importposixpath

importsys

fromunicorn importUcError, UC_HOOK_CODE, UC_HOOK_MEM_UNMAPPED

fromunicorn.arm_const import*

fromandroidemu.emulator importEmulator

fromandroidemu.java.java_class_def importJavaClassDef

fromandroidemu.java.java_method_def importjava_method_def

# Create java class.

importdebug_utils

# 配置日志

logging.basicConfig(

stream=sys.stdout,

level=logging.DEBUG,

format= "%(asctime)s %(levelname)7s %(name)34s | %(message)s"

)

logger = logging.getLogger(__name__)

# 初始化模擬器

emulator = Emulator(

vfp_inst_set= True,

vfs_root=posixpath.join(posixpath.dirname(__file__), "vfs")

)

# 加載依賴的動(dòng)態(tài)庫(kù)

emulator.load_library( "example_binaries/libdl.so")

emulator.load_library( "example_binaries/libc.so", do_init= False)

emulator.load_library( "example_binaries/libstdc++.so")

emulator.load_library( "example_binaries/liblog.so")

emulator.load_library( "example_binaries/libm.so")

#目標(biāo)so

lib_module = emulator.load_library( "example_binaries/libtest.so")

# 當(dāng)前已經(jīng)load的so

logger.info( "Loaded modules:")

formodule inemulator.modules:

logger.info( "=> 0x%08x - %s"% (module.base, module.filename))

try:

# 運(yùn)行jni 這里沒有, 但不影響執(zhí)行

emulator.call_symbol(lib_module, 'JNI_', emulator.java_vm.address_ptr, 0x00)

# 增加properties, 該so或通過(guò)獲取一些properties來(lái)判斷環(huán)境

emulator.system_properties[ 'ro.build.fingerprint'] = 'google/passion/passion:2.3.3/GRI40/102588:user/release-keys'

emulator.system_properties[ 'ro.product.cpu.abi'] = 'arm'

emulator.system_properties[ 'microvirt.vbox_dpi'] = ''

#申請(qǐng)一塊buff, 用作參數(shù)

emulator.call_symbol(lib_module, 'malloc', 0x1000)

address = emulator.mu.reg_read(UC_ARM_REG_R0)

#在之前申請(qǐng)的buff讀取內(nèi)存

detect_str = memory_helpers.read_utf8(emulator.mu, address)

print( "detect_str: "+ detect_str)

#執(zhí)行完成, 退出虛擬機(jī)

logger.info( "Exited EMU.")

logger.info( "Native methods registered to MainActivity:")

exceptUcError ase:

print( "Exit at %x"% emulator.mu.reg_read(UC_ARM_REG_PC))

raise

執(zhí)行結(jié)果:

可以看見, 函數(shù)已經(jīng)調(diào)用成功, 并且已經(jīng)成功獲取返回值和參數(shù), 不過(guò)檢測(cè)出風(fēng)險(xiǎn)環(huán)境了(因?yàn)槲业膙fs文件都是從虛擬機(jī)里拷貝出來(lái)的), 接下來(lái)就可以分析檢測(cè)點(diǎn)了!~~

過(guò)檢測(cè)

1. 通過(guò)執(zhí)行日志分析, 發(fā)現(xiàn)頻繁訪問了build.prop, maps等系統(tǒng)環(huán)境, 猜測(cè)可能是通過(guò)這些文件來(lái)判斷的, 這里列出個(gè)別幾個(gè)。

2019- 09- 2116: 08: 27, 677INFO androidemu.vfs.file_system | Reading 1024bytes from '/proc/cpuinfo'

2019- 09- 2116: 08: 27, 680DEBUG androidemu.cpu.syscall_handlers | Executing syscall read( 00000005, 02089000, 00000400) at 0xcbc1ba7c

2019- 09- 2116: 08: 27, 783INFO androidemu.vfs.file_system | Reading 1024bytes from '/proc/self/maps'

2019- 09- 2116: 08: 27, 784DEBUG androidemu.cpu.syscall_handlers | Executing syscall close( 00000008) at 0xcbc1a854

2019- 09- 2116: 08: 27, 886INFO androidemu.vfs.file_system | File opened '/proc/self/status'

2019- 09- 2116: 08: 27, 887DEBUG androidemu.cpu.syscall_handlers | Executing syscall fstat64( 0000000a, 000ff3e8) at 0xcbc1b314

2. 通過(guò)反復(fù)測(cè)試, 修改對(duì)應(yīng)文件中的關(guān)鍵信息, 最終成功躲過(guò)該風(fēng)控模塊的環(huán)境檢測(cè)。

如下:

總結(jié)

該項(xiàng)目是通過(guò)Unicron來(lái)實(shí)現(xiàn)的, Unicorn 是一款非常優(yōu)秀的跨平臺(tái)模擬執(zhí)行框架, 通過(guò)上帝視角來(lái)調(diào)試和調(diào)用二進(jìn)制代碼, 幾乎可以很清晰發(fā)現(xiàn)反調(diào)試和檢測(cè)手段, 而Unicorn的應(yīng)用絕不僅僅只是個(gè)虛擬機(jī), 可以實(shí)現(xiàn)很多騷操作, 再次感謝QEMU, Unicron, AndroidNativeEmu等等這些開源大神, 是這些人的分享精神推進(jìn)了整個(gè)圈子的技術(shù)迭代。

看雪ID:StriveMario

https://bbs.pediy.com/user-773600.htm

*本文由看雪論壇 StriveMario 原創(chuàng),轉(zhuǎn)載請(qǐng)注明來(lái)自看雪社區(qū)

責(zé)任編輯:

總結(jié)

以上是生活随笔為你收集整理的python中emuterate用法_跨平台模拟执行 - AndroidNativeEmu实用手册的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。