1625-5 王子昂 总结《2018年1月22日》 【连续第479天总结】
A. Frida-windows
B.
Frida是相比Xposed更加轻量级的Hook框架
具体介绍就不赘述了
使用方法大体为其他语言脚本(如Python)将js脚本发送给运行在另一端的frida服务端,服务端上的js引擎
老师之前给出了Hook脚本,但是在windows上怎么都跑不起来:
问题出在该python脚本中使用了pexpect.spawn
而windows中的pexpect是没有spawn的(或者是调不起?)
查了一下有winpexpect,但是需要pywin32某个版本的支持,然后又去找了安装包发现还要WIN10 SDK的支持……4G大小,杀了我吧(:з」∠)
搜索过程中发现spawn实际上就是管道开启进程的作用,那明明Windows也有管道干啥非要用pexpect的捏?
检索了一下,发现os.popen2可以做这件事
然后简单的把spawn改成popen,能跑起来了,但是frida报错
Frida:ERROR:../../../frida-core/src/linux/frida-helper-service-glue.c:2059:frida_resolve_library_function: assertion failed (local_library_path == remote_library_path): (“/system/lib/libc.so” == “/system/lib/arm/libc.so”)
**
Frida:ERROR:../../../frida-core/src/linux/frida-helper-service-glue.c:429:frida_inject_instance_new: assertion failed (ret == 0): (-1 == 0)
查了一下,在这里https://github.com/frida/frida/issues/295官方给出了解答:
Emulators that run JNI components with qemu-user are not supported. (Contributions welcome, but this is a low-priority issue for me personally so I doubt it will happen anytime soon.)
不支持模拟器╮(╯_╰)╭乖乖掏出真机
错误没啦,但是发现write以后总是read不到东西(:з」∠)
调试了很久都不出结果,最后整理了一下思路:管道就相当于直接开启的cmd进程,亲手去尝试一下就好了
总算发现问题_(:з」∠)_cmd他喵的不给我转发啊~
本身用cmd启动`adb shell /data/local/tmp/ctfmobile’时就无法输入和输出,自然用管道也不行了
这样捷径不行,那么我们平常是怎么用的?
adb shell
/data/local/tmp/ctfmobile
先进入shell,然后再启动程序
注意这里每条命令最后都要加’\n’来代替回车键,否则还是啥东西都没有~
模仿之,终于拿到结果
修改脚本后运行,发现main0函数跑完以后就没反应了(:з」∠)
来回打了几个log,发现输入输出流在后一个close()的时候就会阻塞
灵机一动:shell既然要手动开启,是不是也要手动结束啊?
write(‘exit\n’)
成功开始循环~
然而循环的第二次总是报frida.ProcessNotFoundError,每次都是第二次,估计是管道传递比python执行的慢,导致frida先接到hook进程的命令,管道还没开启进程。
刚开始用time.sleep(0.1),还是觉得慢。于是跑了个死循环让它不断地尝试attach。除了看起来挺辛苦的其他没啥异常
BUG全修掉以后又开始疯狂报找不到进程的错误,即使我手动开启然后看frida-PS -R明明能发现3个ctfmobile进程,脚本也要报这个异常
后来偶然进pythonShell里命令行执行,突然发现了详细信息:
frida.ProcessNotFoundError: ambiguous name; it matches: ctfmobile (pid: 8580), ctfmobile (pid: 13427), ctfmobile (pid: 13925)
(╯‵□′)╯︵┻━┻偷懒也不带这样的啊,多个进程也算在找不到进程的异常里就太过分了啊
找到pid然后手动kill掉即可
这几个遗留进程是因为跑脚本的中途强行中断,却没有对ctfmobile进程发送指令导致的
之后处理还有一点小问题:hook.js里
var format = Memory.allocUtf8String(‘%d\n’);
输出的是”1\n”,不会被readline截断,这是linux和windows的不同,手动将斜杠删去一个即可
附上完整脚本:
python2:
import string
import frida
import win32pipe
import os
def hook():
jscode = r"F:\ctf\xman\offline\Fifth\practice4\xman.js"
f = open(jscode)
while(1):
# 管道操作有时较慢,进程还未启动就进行了hook导致frida报错。所以用死循环等待它。
try:
process = frida.get_usb_device().attach("ctfmobile")
break
except frida.ProcessNotFoundError:
pass
script = process.create_script(f.read())
script.load()
f.close()
def main0(s):
pw, pr = os.popen2('adb shell', 'tb')
pw.write('/data/local/tmp/ctfmobile\n')
pw.flush()
(pr.readline())
hook()
pw.write(s + '\n')
pw.flush()
(pr.readline())
(pr.readline())
(pr.readline())
count = 0
while True:
line = pr.readline()
# print('line:', line)
if '1' in line:
count += 1
elif 'wrong' in line:
break
elif 'right' in line:
print('Get')
count = -1
break
else:
raise Exception()
pw.write('exit\n')
pw.flush()
(pr.readline())
(pr.readline())
pr.close()
pw.close()
return count
def main1():
print('success')
result = list()
count = len(result) + 1
stop = False
while not stop:
for i in string.digits + string.ascii_letters + string.punctuation:
print("".join(result) + i)
r = main0(''.join(result) + i)
if count <= r:
result.append(i)
break
elif r == -1:
result.append(i)
stop = True
break
count += 1
print(''.join(result))
main1()
js:
'use strict';
var printf = new NativeFunction(Module.findExportByName('/system/lib/libc.so', 'printf'), 'void', ['pointer', 'int']);
var format = Memory.allocUtf8String('%d\n');
var lib = Module.findBaseAddress('/data/local/tmp/ctfmobile');
var poc = lib.add(ptr(0x2F52 + 1));
Interceptor.attach(poc, function (args) {
printf(format, 1);
});
C. 明日计划
结营赛(°∀°)ノ