TensorFlow数据集-Dataset-API

TensorFlow在学习的时候, 它是有一个mnist数据集让我们学习的. 通过batch_size来每轮数据训练的大小, 现在打算将一个我们实际的数据转换为跟mnist数据集一样的效果

内存中自定义数据

Dataset-API是1.3版引入的, 支持从内存中/硬盘中生成数据集.

  • 一维数组
    直接就是给到一维数组, 生成数据集
dataset = tf.data.Dataset.from_tensor_slices(
    (np.array([1.0, 2.0, 3.0, 4.0, 5.0]), np.random.uniform(size=(5, 2)))
)
out_put="""
元组的形式:
(1.0, array([ 0.41459922,  0.75492457]))
(2.0, array([ 0.47954237,  0.93916116]))
(3.0, array([ 0.70576017,  0.58064858]))
(4.0, array([ 0.8239234 ,  0.92814029]))
(5.0, array([ 0.03073594,  0.16718188]))
"""
  • 字典
    字典的格式给到,结果也是字典, 按照key索引(这种用的比较多一些)
dataset = tf.data.Dataset.from_tensor_slices(
    {
        "a": np.array([1.0, 2.0, 3.0, 4.0, 5.0]),
        "b": np.random.uniform(size=(5, 2))
    }
)

out_put="""
字典的形式:
{'a': 1.0, 'b': array([ 0.15337225,  0.97730736])}
{'a': 2.0, 'b': array([ 0.89860896,  0.95473649])}
{'a': 3.0, 'b': array([ 0.79198725,  0.84507321])}
{'a': 4.0, 'b': array([ 0.27289686,  0.56223038])}
{'a': 5.0, 'b': array([ 0.19825011,  0.44183586])}
"""

两种输出验证方式

当内存中数据生成后, 我们通过这两种方式来验证下
dataset来自上方代码

Jan 20, 2018
MachineLearning

wda玩微信跳一跳

… 等我写完这个脚本,刷到了372分, 才发现Android的大佬们早就有一套操作了, 似乎想法都差不多,我的环境是在ios-mac上执行

安装环境

WebDriverAgent

https://github.com/facebook/WebDriverAgent
facebook开源的自动化驱动框架, 调的私有Api,所以执行的速度应该说是最准的,这也是这套玩法的关键点
需要一些环境依赖,代码clone下来之后, 得在项目路径下执行下:

./Scripts/bootstrap.sh

xcode打开,选择Target是WebDriverAgentRunner,Test到手机(签名用个人Appid就可以,然后Test到手机后,信任一下证书)

facebook-wda

https://github.com/openatx/facebook-wda
wda,一个python脚本,配合WebDriverAgent使用,便捷的安装方法:

sudo pip install --pre facebook-wda

测试下环境

用个终端端口转发下(iproxy 可以通过 brew install usbmuxd安装):

iproxy 8100 8100

用以下命令启动下WebDriverAgent,你需要改下下方的name=你自己的手机名:

xcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination 'platform=iOS,name=YourDeviceName' test

看到输出这个就启动正常了:

另开个终端,启动下python,如下测试下:

脚本实现:

git代码地址-python3.6.3

IMAGE_PLACE = '/tmp/screen.webp'
each_pixel_d = 0.00190
c = wda.Client()
s = c.session('com.tencent.xin')
input("请自行切换到游戏里面的界面,回车即可开始")

def change_to_duration(position_list):
    """
    勾股定理 求d=C=开根号(A^2+B^2)
    """
    if not position_list:
        return
    x1,y1 = position_list[0]
    x2,y2 = position_list[1]
    the_d = math.sqrt(math.pow(y2 - y1, 2) + math.pow(x2 - x1, 2))
    return float('%.3f' % (the_d * each_pixel_d))

if __name__ == '__main__':
    while 1:
        x = c.screenshot(IMAGE_PLACE)
        if not os.path.exists(IMAGE_PLACE):
            continue
        # time.sleep(1)  #图片就算在了,渲染还没结束,这1秒阻塞就给了吧,或者不给,为渲染正常的以下方阴影为准
        pl.imshow(pl.array(Image.open(IMAGE_PLACE)))
        position_list = pl.ginput(2,timeout=2147483647)
        pl.ion()
        duration = change_to_duration(position_list)
        pl.ioff()
        if duration and os.path.exists(IMAGE_PLACE):
            s.tap_hold(200, 200, duration=duration)
            os.remove(IMAGE_PLACE)

首先进入到游戏页面,截图到本地
使用plt.imshow展示这张图片, 通过plt.ginput我们点击的两个点会被记录下来,
我们通过分析这两个点, 得到小人到对面物体的地点:
嗯, 勾股定理:

Dec 30, 2017
Python

探探逆向之旅

一阵子下来才明白,逆向其实会上瘾,尤其是我这种~ 天生就爱搞破坏的坏孩子来讲
探探是一个社交APP, 似乎不少人在上面找到另一半的. 这种卡片社交简单,背后隐藏的推荐逻辑,筛选逻辑才是它能如此盛名的原因.
要重点说明,这些需求是我一产品的同学给我提的, 绝非个人偏好~ 我不是那种人…

梗概

先上下图

(功能入口在 新手引导->探探怎么玩-> ):

这是目前逆向后我给它新增的功能,因为工作也比较忙,就没有新增过多的需求,但是整个App的架构逻辑其实已经很清晰了, 基本可以合理的新增一些需求在里面, 这也说明探探的开发架构逻辑挺棒的.

功能简介


下方是一个简单的tableview, 功能的启动都在这里,当然功能是有互斥和优先级的,

  • 同时开启无条件选妹和选妹子onlyStudent, 无条件选妹子优先.
  • 为了更好的效果在主页的地方选妹子,我最后采取的是模拟点击likeButton,在NSTimer中执行,当刷的人对已拉取用户求余==0的时候停止, 如果不想停止就把infinite打开,这是一个疯狂的爬取,没有停止的线性条件,除非杀APP. 为什么这么做呢, 因为我把自动拉取的信息默认是保存到Document/cache.txt里面, 主要是照片的url和部分简介
  • 自动尬聊采用的是图灵的API, 你拿到源码后需要替换为您的key, 谷歌搜索”图灵机器人”,打开后进入到某个想聊天的窗口, 它如果收到信息会自动跟她尬聊.
  • 上方是用Mapkit,新增Mapview在上方,用来更改定位,然后下面的打开(不过测了下证明这块功能还有点问题的,有兴趣的哥们继续挖掘下)

开始调试

调试工具

  • 依然是最酷的 MonkeyDev
  • FLEX (reveal过期了,这是一个很棒的替代品), 下载后编译一下, 然后按照monkeyDev中wifi加入第三方库的方式操作即可
  • frida-ios-dump 还是庆哥出品,砸壳后顺带把整个APP导出
  • 其它的全程是cycript+LLDB调戏 就不累述了…
#import 
// open it in here
[[FLEXManager sharedManager] showExplorer];

导入库之后,在注入成功的这个通知回调里,启动这个方法

调试遇到的问题

探探是有反调试的, 用的是sysctl. 很强
那么你调试的时候需要讲MonkeyDev里面的打开, 这个反反调试检测默认是关闭的,原因注释上有

从需求粗发的debug

逆向App,我一般的套路都是酱紫.
设计需求 -> 需求在哪里会展示 -> 从view到Controller-> controller方法猜测 -> 结合monkeyDev进行方法trace -> 确认需求方法 -> hopper找方法地址 -> LLDB调试下断点 -> 查看调用栈(bt) -> 然后开始埋点尝试hook

用笔记在记录每次你发现的新宇宙(虽然开始的很早,实际没有时间弄它…)

Dec 18, 2017
reverseEngineering

mac逆向-窗口管理Divvy

Divvy个人感觉是最棒的一款窗口管理软件了~, 但是它动不动就会提示个五秒的窗口让你注册License,最近小试牛刀完IOSApp, 它给我提供一个入门的机会…

工具准备


mac上的逆向其实比较省, 你不需要额外的砸壳,直接就能能从包里面拿到执行文件.
class-dump 头文件.
用Hopper打开,反汇编一下方便待会查看.
然后神器依旧是monkeyDev, 它帮我们省去注入.dylib 和 重签名等”繁杂步骤”~

入口分析

本来大多数的步骤一定是从view开始, 有一款神器就[interface inspector], 但总会报错一些乱七八糟的问题,暂时还没调好, 于是乎我粗糙的从hopper搜索”Register”,(如果一开始搜的是首字母小写的话可能不会饶那么弯…),结果是这样子的,

也查到其他无关的,最后确定就是这里,伪代码和汇编看并没有看出什么头绪,于是乎先看看有没有调用这里这个类相关.

追踪前,这里有一款强大的工具说下:
frida-trace: frida-trace -m “-[PTHotKeyCenter _]” Divvy

用法是frida-trace -m “<+类方法/-实例方法>[类名 方法名<_代表全部>]”
执行后它会自动帮你生成跟踪的js文件,然后监听所指定的方法.

一开始觉得吧, PTHotKeyCenter不像是很关键的类, 也是没怎么写Mac的App的原因,但还是监听了一下:

我尝试打开它,然后随便输入一串号码注册, 发现他怎么整都只打印这些, 而且就在我使用快捷键的时候~
随意也明白了,这就是”热键”,仅此而已…

动态调试

进行到这里其实是无头绪的, 然后想着是从mondev进行动态调试,看看能不能从调用栈看看这里的情况.
想着hook哪个方法的时候,脑子冒个灵光,想到了这个view的展示, 我就输入”)show”看看有没有什么可疑的,结果:
十分意外第一个方法,很明显这个方法应该是展示注册这个View的,而且还待会参数时间.
如果是这个方法果然没错, 那么我可能得到,一是找不到更好的hook方法,duration的参数改为最少的时间,或者可以尝试return这部展示的操作. 其次先Hook下看看调用栈,是什么决定它展示也是可以的, 于是开始我的Hook代码.
MonkeyDev默认是subStrate的hook方法代码, 当然也是可以替换成其它的(按道理当然可以~):
这是一开始的代码:

但是允许会报错,其中需要修改:

static void newHookFunc(AppController* self,SEL _cmd,id array){ }

//replacet to | //下面
// 需要指明多少个参数, 不知道参数类型就使用泛型id
static void newHookFunc(AppController* self,SEL _cmd,id arg1, id arg2){ }

build一下且进入调试后, 用时在static void newHookFunc(AppController* self,SEL _cmd,id arg1, id arg2){ 这里Xcode断点一下:
但如果直接执行还需要做两部:

Dec 3, 2017
reverseEngineering

逆向-UNREAD去除阅读限制

背景 : UNREAD是一款很棒的RSS阅读器, 免费版本有50条阅读的限制. 强化在非越狱机上的逆向之旅
因为是巩固逆向的知识阶段,踩坑是必然的, 但是多么绕的就不讲了, 但是要mark最后走对这个方式,后面也要逐渐总结对的方法

准备工作

UNREAD要求ios10以上才可以下载,所以我的935设备无法下载也无法砸壳, 所幸的是PP助手能搜到,不过版本低了0.2, 用起来没差别.

确认需求 : 去除阅读限制

分析

正向分析思路


如果是我设计呢:
目标是个tableview , “UNLOCK UNREAD”这一cell显示了当前剩余可阅读的数量.每次点击进入文章阅读的时候,可读数量 -= 1; 有一个模型来记录这里的数量,
在tableview这个控制器,viewWillApear:的时候刷新row.

当时想的是:
那么如果是tableiview, dataSource方法必然有tableview:cellForRowAtIndexPath:被调用, 如果能找到模型,直接hook模型的调用或许是第一思路.但是熬到三点还没睡我才明白我踩坑了, 这里不累赘了,一把泪.

view层嵌入

从monkeyDev启动项目,拖入我们的APP后启动到设备上, 默认是会注入reveal动态库的, APP启动成功后, 进入到主页, 然后mac启动reveal:

reveal启动后点到我们目标view,可以看到这是一个tableview的cell,”50 ARTICLES LEFT”是cellContentView的label, 查看右边, 我们能看到这个页面的控制器.
“NSRHomeViewController”

分析控制器

把class-dump出来的头文件拖到Xcode项目, 搜一下”NSRHomeViewController.h”可以看到这个头文件, 所幸头文件不多,我有了部分时间慢慢看这些方法,尝试发现敏感名称, 其中最让我敏感的是这个:


第二个方法这未免太明显~, 其它大概也预览了一下, 图一看到是NSArray, 或许会存储数据的模型.

断点可疑调用

二进制文件拉到Hopper反汇编后, 搜一下三个方法

moreItems & setMoreItems & updateUnlockInfo

获取它们的静态地址后,在LLDB查看下初始偏移地址, 加上并断点这三位.
分析的时候知道, 它是在点击文章阅读的时候才减一. 那么现在就进入文章里面,触发我们的断点. 果不其然它触发了,查看一下调用栈:

Nov 28, 2017
reverseEngineering

砸壳最稳dumpdecrypted

之前写过一篇 clutch砸壳 的, 但clutch似乎没有100%成功的情况, 所以还是得老司机来.

编译得到.dylib

https://github.com/stefanesser/dumpdecrypted
下载后make一下会生成一个.dylib

拷贝到设备上

iproxy 2222 22
开启一个映射后:
scp -P 2222 dumpdecrypted.dylib root@localhost:/tmp/

获取App目录

启动下目标App,cycript到进程中, 输入:

NSHomeDirectory()

拷贝.dylib到App目录

退出cycript,切换到App目录后:
拷贝.dylib 到得到的目录:

cp /tmp/dumpdecrypted.dylib  .

mible用户查看进程:

su mobile    #切换普通用户

开始砸壳

启动下App,然后:

ps -e  | grep /Application   #查看App进程,我们需要正确的二进制文件地址
DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib <上面的二进制地址>

查看文件


Nov 24, 2017
reverseEngineering

去除OplayerLite广告提示-越狱机

最近在学习逆向相关的实践+踩坑, 庆哥的视频中一个课程是对于OPlayerLite进行进行广告处理了, 因为是去年的课程App也更新了逻辑, 我沿着先辈的道路把坑撸了一把, mark这场一天一夜的战斗.

分析层级结构

定位目标对象

连接到越狱机(切换到无网络模式, 因为Oplayer lite有网络的时候加载的广告是不同的,不利于分析), 同时点击任意视频,进入到视频播放页面, 我们会看到广告的view,上面有一行文本”Buy the full version to remove ads?”
这时候我们连接到cycript打印下层级:

UIApp.keyWindow.recursiveDescription().toString()


由于我已去除了过了,又从App Store重新下载, 发现还是没有广告,图片暂时就没哈
其中有引起我们注意的层级是:

|    |    | >
|    |    |    | >
|    |    |    |    | >
|    |    |    | >

其中UILabel: 0x176b1380中的text属性跟我们看到的ads上是一样的,它的同级view是UIButton, 父view是UIView .
因为咱们要解决的目标是view, 尤为关注是这里的frame.size, 它们都是320 50, label也是height=50. 把这部分截图保存下来,待会查找的时候需要用到

正向分析设计

划重点: 从正向的开发的角度, 分析它是如何设计的

如果是我开发君, 我的伪代码大概如下

if  (!payBuyFullViersion)  {
    AdsView *adsview =  [[AdsView alloc] init];
    [self.palyerView addSubview:adsview]
}

可能其他的逻辑未必跟我符合. 但是一定必然的是, 这个adsView 必须是addSubview上去的,addSubview是UIKit中view的方法, 咱们需要静态分析这个地址, 通过断点来查看它对应的调用者/参数, 从而拿到地址,来定位到OplayerLite

Nov 24, 2017
reverseEngineering

seleniumANDrequest辅助爬虫

爬虫写多了时候会发现, 很多的时候总是有些问题被阻挡, 虽然越来越多的AI诸如此类的工具也正在破解升级, 但在在小型的爬虫之前,selenium可以帮助我们辅助一些代码层无法越过的坑,拿到完整的cookies, 让客户端对我们身份证验证已通过之后,移交到深层的代码里, 进行操作.

先用selenium拿到最真实的cookies

似乎这没什么好讲的, 贴下我的代码截图吧…
selenium小封装:

小爬虫的时候或许都可以跳过这一步, 你可以进行一个长时间的sleep,手工进行登录,填入验证码等

cookies移交

def set_session_cookie(self):
    """
    cookie 移植到 session,方便后续操作
    """
    self.driver.get('http://url')
    for subCookie in self.driver.get_cookies():
        self.session.cookies.set(subCookie[u'name'], self.driver.get_cookie(subCookie[u'name'])['value'])

self.driver.get_cookies() 得到是一个数组, 我们遍历这个数组, 拿到name-value , 对移交的session的进行cookies设置.

Nov 23, 2017
Python

clutch对app进行砸壳

逆向学习相关,实战一下对app的砸壳,砸壳必须要越狱手机哦.

什么是壳

一个App无论是Android还是ios, 或者是PC平台, 为了保护app都会加上一层壳, 加壳的app可能无法被一些IDA之类的工具解析, 那么也就无法搞事情,所以砸壳是必须走的一步,也可以从某助手平台下载已砸壳的, 当然最好用下面的命令确认下先.
怎么查看一个app是否有壳, 可以使用下面的命令, 替换为App的二进制文件查看:

otool -l targetBinary | grep cryptid

得到的结果如果是1则是未砸壳的, 0是已砸壳.
还有一种情况是一些App支持多种架构的,可能会展示多个cryptid=1/0, 在哪个平台跑就砸哪个.

确定目标后安装App

我这里以麦当劳App(听说改名金拱门)为例,从appStore下载安装.

编译clutch二进制文件

clutch神器 下载地址 , 下载编译后允许会得到一个二进制文件, 这里不累述哈, 或者你可以直接从我的 git地址 clone我编译后的,在clutch_binary文件下.

拷贝clutch到设备

连接手机


我这里用iproxy从22映射到2222端口,并整个过程保持. 右边线尝试登录下,默认密码是alpine, 其他情况就自行谷歌帮助,我相信这没什么难度.

iproxy 2222 22
ssh root@localhost -p 2222

测试连接成功后输入 exit 退出,接着下一步

scp拷贝到手机

scp(secure copy) 支持ssh协议远程拷贝, 我们用它拷贝到设备上, 前提是上面的
的测试成功了.

scp -P 2222 ./clutch root@localhost:/usr/bin/


如果这样子的话就成功了, /usr/bin/默认已经在环境变量查找内, 拷贝到这里可以省事很多多.

找到目标

先介绍下clutch用法:

推荐ios-deploy -B可以获取bundleID, brew install ios-deploy就可以安装了.

例如我这里的目标是麦当劳app, 尝试搜一下mc,果不其然就是它了.
拿到的bundleID就是com.mcdonalds.gma
(嗯, 还有个grep的方法更简单,但是我真的不知道它是麦当劳, 因为他显示的是Arch,所以靠谱的话就还是上面,BundleID基本会跟名称一直吧)

Nov 17, 2017
reverseEngineering

小tip之mac动态背景

作为一个mac粉, 动态背景怎么能少,现在分享一个小tip,有兴趣的往下看

app安装

其实事情是一款App就可以搞定了, 但是好像国内搜不到, 我把它压缩传到了我的github上,你可以clone git, 然后在DymaticWallpaper里面找到它,解压并安装即可.
git 地址: https://github.com/Paulswith/ToolsScript.git

使用

安装后, 在屏幕上上方的状态栏可以看到它, 选择点击下载即可, 但它的资源真的很糟糕

  • 主要是分辨率太低
  • 没有对比就没有伤害,对比我待会给你讲的这些资源它真的很逊
  • 处女座就是挑,大佬们,我说的是我…

用最酷的视频替换它

点我跳转到视频源地址
我在一篇 博文 中还针对它进数据库存储,因为真是稀缺~ 似乎一段时间还会更新一次, 资源的贡献者是国外的一位大牛 johnCoates .
可能他的作品是可以用的,但是一直有问题,才用这个app替代.

选取视频并下载


浏览器打开下载到本地

执行替换

改名为1.mp4(严格大小写),拖到LiveDesktopPro的这个路径,例如我:
/Applications/LiveDesktop Pro.app/Contents/Resources

需要权限,输入确认即可
一共允许1,2,3,4个文件替换, 依然是改为.mp4的后缀, 不管方法土不土,就是可行.
现在重进打开App,选择视频1,即可看到刚才视频了.

没有找到好的gif转换软件, png将就,这是我选的视频,白天黑夜都使用.

Nov 16, 2017
macTools