duangsuse::Echo
啊哈,直接完整封装 inotify 的所有功能了,不过 70 行代码 😋 下载代码, clang fsw.cpp -O3 &&install -Dm755 a.out /usr/bin/infsw 就可以收获简单易用的 fs watcher 了 😊 $ infsw #sysadmin #cplusplus #tools R M attrib close close.rd open move.from move.to A D self.D self.move self.unmount in.queovf in.ignore…
stdbuf -i0 -oL -eL /bin/bash -l
evNames=M,D infsw .|awk '{print($1$2 concat ":"); system("cat " concat $2)}' 结论:这个小脚本(迫真C++脚本)并没有复原被删文件的能力,因为 inotify 没有
beforeDelete 事件(有也没法保证其 fd 的 waiter 都 dispatch 完了🌚 读取到缓冲区需要时间。https://stackoverflow.com/questions/3465619/how-to-make-output-of-any-shell-command-unbuffered#25548995 tail -f 和 less +F 都没有用,因为 bash 的 stdout pipe 是默认 full buffered 的,所以要 unbuffer 一下
Stack Overflow
How to make output of any shell command unbuffered?
Is there a way to run shell commands without output buffering?
For example, hexdump file | ./my_script will only pass input from hexdump to my_script in buffered chunks, not line by line.
Actuall...
For example, hexdump file | ./my_script will only pass input from hexdump to my_script in buffered chunks, not line by line.
Actuall...
#日常精神分裂 #旧事重提 #Java #JS #PLT #cplusplus #project
A: 啊真的很头疼呢, JPlayer 的 fix 和 depth.html 附赠的 Myson 数据描述语言……
B: 像往常一样,我们一起想想吧。
A: 首先说 JPlayer ,这个原先是作为重写 Yuuta 大佬项目的东西,变的蛮多的,后来也有完全的 C++ 重写。
这个东西最后也是长期熬夜 timedout ,失败点是为优化性能加的 Ringbuffer 队列缓冲区利用有瑕疵,导致最后一次缓冲的内容没放完退出
B: 你还记得它的大体数据流程吗。
A: 当时怀疑 Java 计算速度慢所以用的缓冲器预计算一定内容,整体是 while(frame=next()) 呃不,是 while (escape=que[incPtr()]) if(samePtr()) genChunk() 。
B: 对了,你缓冲的帧是什么数据类型啊,二维数组吗?
A: 基于 frame pix diff 的 ANSI escape string ,这个当然是在 chunk 计算的
B: 生成新缓冲帧的程序你大概是没隔离吧,按当时的设计,应该是 genChunk 收到 VideoIO throw NPE 就跳出绘制loop 了,即便最后一块刚刚准备好。我建议 catch 住NPE ,如果 !samePtr(p,p1) 即还有余帧就继续播放,否则才真的退出。
(接下来一段被证明是误会)
A: 这大概是不利于性能的吧,最后一块的每帧都要 catch ,而且还要局部 landingpad ,函数级有一个了。
B: 你也说了是 jacoco 解码器 API 的问题? throw 是不可避免的,只能说或许可以把输出帧的做成子程序,最后一块的 catch 里直接消耗完队列,或者加个 bool ,未结末时先 if 一下避免重复。
A: 我总结一下流结末的情况: genChunk() 生成某帧时 catch 到一次,但是缓冲区没放完,继续放完这一块,再 catch (输入终末)了发现缓冲区没了,就停止播放。
A: 挺简单啊。那么 Myson 该怎么办,这个语言挺不常规的,既有缩进语义又只支持对象?
B: 首先我们先明确下,既有 heading tree 是怎么解析出的。
显然是每个DOM元素都有「深度」,然后非 h1~h6 的元素默认上一次深度或0 的 +1,所以说是「以能解析 Python 的算法解析标题嵌套深」对吧。
A: 可 Myson 就不是直接分开的,觉得要写 RegExp Lexer ,不敢写,挺麻烦的。
B: 看了语法设计,是不支持 array 什么的,只能 key-JSONValue 吗?
A: 是的,只支持一种嵌套,就是更深=子对象
B: 这么说没有行尾冒号也没问题喽?
A: 按理说是这样的……没问题吧?
B: 我能理解,反正你打算完全用缩进深度吧。你又没有支持 optional 多行的语法,唯一的不优雅在于有冒号没用,没冒号的话已有 value 的行后尾随缩进增,就不易看出冲突了。
A: 那具体如何实现呢。
B: 只需要 split lines+trim count 就可以了,之后 line 实际上就是 k-v ,遇到更深的就视为上一行的 v ,递归展开成 JSON.parse object 的形式,检查下不冲突就行了。当然,缩进莫名上升这种就检查不出来。
比如:
A: 听你这么一说我都有把这个 publish 到 npm 骗 star 的欲望了(
B: 我觉得这个挺浪费的,当然 JSON 也一样,key 重复了那么多次,不方便写也不方便传输
A: 有什么办法呢,下一层是 csv 基于 row 存储,那个是 efficient 但是只能存 object array ,而且也不能有嵌套对象
B: 我觉得你加上内联 CSV 的特性,就真的可以骗 star 了。 噢对你还应该把 JSON2Myson 写出来,就是带 indent: string 字段的 TreeWalker 是吧。相信你会写,这对工具化很有用,毕竟 JSON 不好看
A: (若有所思)
B: 你还可以把这个做一个 DOM Tree 的后端,甚至直接变成一个模板语言
B: 对了, JSON2Myson 用于带缩进输出的递归子程序还可以对 k-v 里的 v 立即处理而不必再下层递归,反正顶层又不支持单个值,就当是优化了。
A: 打住打住…… 这当然可以,其实就是翻译 {} 吧。区分 Attr 和 childs 对复用性有些挑战,但我相信能行。
A: 对了,我还有两个小点子:
(1)infsw 可以增加 timedline MM:ss ; 此外还有 exec 与 statics 子命令,以及 event name 的自定义和自动修正 failed watch 的 argv filter ,因为 watchdog py 的 watch medo/exec 和 inotify-tools 的 cli 都太麻烦,就自己写。
(2)之前的 OGL 频谱透明动画可以加一个纵反向的功能,利用 xdo 跟踪到窗口顶端什么的,像 supertuxkart 这样的游戏就可以当音游玩了(迫真)
A: 说起来卓依婷是谁啊,写的歌好熟悉呢
A: 啊真的很头疼呢, JPlayer 的 fix 和 depth.html 附赠的 Myson 数据描述语言……
B: 像往常一样,我们一起想想吧。
A: 首先说 JPlayer ,这个原先是作为重写 Yuuta 大佬项目的东西,变的蛮多的,后来也有完全的 C++ 重写。
这个东西最后也是长期熬夜 timedout ,失败点是为优化性能加的 Ringbuffer 队列缓冲区利用有瑕疵,导致最后一次缓冲的内容没放完退出
B: 你还记得它的大体数据流程吗。
A: 当时怀疑 Java 计算速度慢所以用的缓冲器预计算一定内容,整体是 while(frame=next()) 呃不,是 while (escape=que[incPtr()]) if(samePtr()) genChunk() 。
B: 对了,你缓冲的帧是什么数据类型啊,二维数组吗?
A: 基于 frame pix diff 的 ANSI escape string ,这个当然是在 chunk 计算的
B: 生成新缓冲帧的程序你大概是没隔离吧,按当时的设计,应该是 genChunk 收到 VideoIO throw NPE 就跳出绘制loop 了,即便最后一块刚刚准备好。我建议 catch 住NPE ,如果 !samePtr(p,p1) 即还有余帧就继续播放,否则才真的退出。
(接下来一段被证明是误会)
A: 这大概是不利于性能的吧,最后一块的每帧都要 catch ,而且还要局部 landingpad ,函数级有一个了。
B: 你也说了是 jacoco 解码器 API 的问题? throw 是不可避免的,只能说或许可以把输出帧的做成子程序,最后一块的 catch 里直接消耗完队列,或者加个 bool ,未结末时先 if 一下避免重复。
A: 我总结一下流结末的情况: genChunk() 生成某帧时 catch 到一次,但是缓冲区没放完,继续放完这一块,再 catch (输入终末)了发现缓冲区没了,就停止播放。
A: 挺简单啊。那么 Myson 该怎么办,这个语言挺不常规的,既有缩进语义又只支持对象?
B: 首先我们先明确下,既有 heading tree 是怎么解析出的。
显然是每个DOM元素都有「深度」,然后非 h1~h6 的元素默认上一次深度或0 的 +1,所以说是「以能解析 Python 的算法解析标题嵌套深」对吧。
A: 可 Myson 就不是直接分开的,觉得要写 RegExp Lexer ,不敢写,挺麻烦的。
B: 看了语法设计,是不支持 array 什么的,只能 key-JSONValue 吗?
A: 是的,只支持一种嵌套,就是更深=子对象
B: 这么说没有行尾冒号也没问题喽?
A: 按理说是这样的……没问题吧?
B: 我能理解,反正你打算完全用缩进深度吧。你又没有支持 optional 多行的语法,唯一的不优雅在于有冒号没用,没冒号的话已有 value 的行后尾随缩进增,就不易看出冲突了。
A: 那具体如何实现呢。
B: 只需要 split lines+trim count 就可以了,之后 line 实际上就是 k-v ,遇到更深的就视为上一行的 v ,递归展开成 JSON.parse object 的形式,检查下不冲突就行了。当然,缩进莫名上升这种就检查不出来。
比如:
小明
名字 "明天白"
年龄 14
朋友 ["小张", "小红"]
小张
名字 "张大奇"
年龄 15
最爱
世界 "你好世界"
伍六七 "excited"
突然想到可以这样.. Object.assign
某人 {"id": 1}
姓名 "小白"
朋友 "小黑"A: 听你这么一说我都有把这个 publish 到 npm 骗 star 的欲望了(
B: 我觉得这个挺浪费的,当然 JSON 也一样,key 重复了那么多次,不方便写也不方便传输
A: 有什么办法呢,下一层是 csv 基于 row 存储,那个是 efficient 但是只能存 object array ,而且也不能有嵌套对象
B: 我觉得你加上内联 CSV 的特性,就真的可以骗 star 了。 噢对你还应该把 JSON2Myson 写出来,就是带 indent: string 字段的 TreeWalker 是吧。相信你会写,这对工具化很有用,毕竟 JSON 不好看
A: (若有所思)
B: 你还可以把这个做一个 DOM Tree 的后端,甚至直接变成一个模板语言
html
head
meta {charset: "UTF-8"}
body
a {onclick: "alert()"}
_text "你好。世界"B: 对了, JSON2Myson 用于带缩进输出的递归子程序还可以对 k-v 里的 v 立即处理而不必再下层递归,反正顶层又不支持单个值,就当是优化了。
A: 打住打住…… 这当然可以,其实就是翻译 {} 吧。区分 Attr 和 childs 对复用性有些挑战,但我相信能行。
A: 对了,我还有两个小点子:
(1)infsw 可以增加 timedline MM:ss ; 此外还有 exec 与 statics 子命令,以及 event name 的自定义和自动修正 failed watch 的 argv filter ,因为 watchdog py 的 watch medo/exec 和 inotify-tools 的 cli 都太麻烦,就自己写。
(2)之前的 OGL 频谱透明动画可以加一个纵反向的功能,利用 xdo 跟踪到窗口顶端什么的,像 supertuxkart 这样的游戏就可以当音游玩了(迫真)
A: 说起来卓依婷是谁啊,写的歌好熟悉呢
羽毛的小白板
https://www.zhihu.com/question/20210025/answer/1744173869
#zhihu #net #cplusplus #Haha 什么? send/recv 次数对应?那返回 size_t 是给你检查错误的?!🌚
TCP 不是基于 packet 的,基于数据包的是 IP 网络层, TCP 是 SocketStream ,字节流,它是传输控制层,哪有「包(packet)」这个概念?
“手动 static size 拼包?你在教我 TCP 做事,还是说你用我 TCP 干嘛?”
TCP 不是基于 packet 的,基于数据包的是 IP 网络层, TCP 是 SocketStream ,字节流,它是传输控制层,哪有「包(packet)」这个概念?
“手动 static size 拼包?你在教我 TCP 做事,还是说你用我 TCP 干嘛?”
https://t.me/vvb2060Channel/416 #Android #Security #aop
asm inline hook 当然是任意点都可以,实际上 frida 配 xposed 开发是真好吧🤔
/proc/self 都可以 mount --bind ,但是改动是系统级的。 通常做法就是由框架来实现访问权共享,像 Riru 一样换一个 preload .so 来实现 hook
我觉得应用层开发者尝试对抗系统动态分析是很愚蠢的行为,毕竟你又不是搞安全的,凭 Proguard 组搞出来的东西你能做到什么地步,你们领域就那个水准,会设计模式和元编程的都凤毛麟角。
现在的 Internet 和 programming 定义都变了,网络人不会用文件共享不会各种基础服务,编程界早就不是以前各种不跨 CPU 的花指令、代码加壳(当然这个对 ART 运行时基本没用了 在 debugger 时代也是 memdump 了事的屑问题)、内嵌虚拟机(那么大的游戏牺牲玩家体验都不能保证不被逆向)。
你要真没武德就去写 C++ 啊,非常完美,全 static inline 并 strip 掉符号就能自动屏蔽掉一大堆魔改。
反正再怎么弄都不是问题的完整解决,加壳本质上还是二进制格式+密码学问题,不是编译原理问题。
对「代码保护」武德比这低的人有的是,譬如私有数据加密算法和 lua 等脚本引擎指令编号重排等,但同样会编程懂二进制和密钥编码的人一眼就能看出来,运行时能 bypass 的东西很多。
理论上最关键的领域还是 CE,可惜编译原理的人最清楚,即便真的做了,自动分析也能搞出来,而且这本身就是很无聊的事情吧。
asm inline hook 当然是任意点都可以,实际上 frida 配 xposed 开发是真好吧🤔
/proc/self 都可以 mount --bind ,但是改动是系统级的。 通常做法就是由框架来实现访问权共享,像 Riru 一样换一个 preload .so 来实现 hook
我觉得应用层开发者尝试对抗系统动态分析是很愚蠢的行为,毕竟你又不是搞安全的,凭 Proguard 组搞出来的东西你能做到什么地步,你们领域就那个水准,会设计模式和元编程的都凤毛麟角。
现在的 Internet 和 programming 定义都变了,网络人不会用文件共享不会各种基础服务,编程界早就不是以前各种不跨 CPU 的花指令、代码加壳(当然这个对 ART 运行时基本没用了 在 debugger 时代也是 memdump 了事的屑问题)、内嵌虚拟机(那么大的游戏牺牲玩家体验都不能保证不被逆向)。
你要真没武德就去写 C++ 啊,非常完美,全 static inline 并 strip 掉符号就能自动屏蔽掉一大堆魔改。
反正再怎么弄都不是问题的完整解决,加壳本质上还是二进制格式+密码学问题,不是编译原理问题。
对「代码保护」武德比这低的人有的是,譬如私有数据加密算法和 lua 等脚本引擎指令编号重排等,但同样会编程懂二进制和密钥编码的人一眼就能看出来,运行时能 bypass 的东西很多。
理论上最关键的领域还是 CE,可惜编译原理的人最清楚,即便真的做了,自动分析也能搞出来,而且这本身就是很无聊的事情吧。
Telegram
南宫雪珊
PS:Lsposed最近添加了native hook功能,但是没人用
PS2:可以用momo测试我的签名检测。只有这一项,因为没技术去对抗inline hook和IDA…
inline hook在任意代码位置都可进行hook,精准度是汇编指令级的,知道这一点时我就直接放弃。而IDA,下载过,发现只会F5,又卸载了。作为一个普通开发者,这是我的极限了,学习破解与反破解,实在耗费精力与时间。
这年头,连/proc/self都无法信任,因为可以被bind mount,真想要安全,还是把代码丢TEE里面跑吧…
PS2:可以用momo测试我的签名检测。只有这一项,因为没技术去对抗inline hook和IDA…
inline hook在任意代码位置都可进行hook,精准度是汇编指令级的,知道这一点时我就直接放弃。而IDA,下载过,发现只会F5,又卸载了。作为一个普通开发者,这是我的极限了,学习破解与反破解,实在耗费精力与时间。
这年头,连/proc/self都无法信任,因为可以被bind mount,真想要安全,还是把代码丢TEE里面跑吧…
#kotlin #PLT #tt #functional 🌚
顺便说一句,上面 Lua 指令重编号的如果有 luac 就很简单,因为指令号是「编译器和虚拟机里一致」就透明的东西,想要获得反处理算法所需的 new=>origin 映射表只需要两版 luac 编译相同代码。
之后查一下 prototype 里的 opcodes , assoc ops[i], opsOld[i] 按序数就能拿到指令号对应关系了,然后 mapBArray 就能翻译过来。 整体命令都不需要十行代码或 indexOf reverse 😒
顺便说一句,上面 Lua 指令重编号的如果有 luac 就很简单,因为指令号是「编译器和虚拟机里一致」就透明的东西,想要获得反处理算法所需的 new=>origin 映射表只需要两版 luac 编译相同代码。
之后查一下 prototype 里的 opcodes , assoc ops[i], opsOld[i] 按序数就能拿到指令号对应关系了,然后 mapBArray 就能翻译过来。 整体命令都不需要十行代码或 indexOf reverse 😒
Forwarded from dnaugsuz
视角不一定非得深,小处也有讲究🌝
GitHub.com/ParserKt 和现在 Kt 最实际的 better-parse 比较我也觉得有更精巧的地方,其实 PKT 是现在 Kotlin 唯一不函数式的解析组合子「框架」。
GitHub.com/ParserKt 和现在 Kt 最实际的 better-parse 比较我也觉得有更精巧的地方,其实 PKT 是现在 Kotlin 唯一不函数式的解析组合子「框架」。
GitHub
ParserKt
Naive one-pass recursive descent parser framework for Kotlin - ParserKt
Forwarded from dnaugsuz
理论上我现在的水平可以实现基础
比如 val a = Box<Int>(1 as Int) 或者 a: Box<Int> = Box(1.toShort()) 我会,反正就是各处(包括 fun 和 constructor)的 actual type 放一起 check eq 就成
但是 unification 就麻烦一些,需要什么 scope ,不是很直接
这个麻烦一点也不过
unification 就是玄学问题🌚
sum+/product*/fn 与 traits 和 OOP subtyping 的 checker ,但真的不会写要 unification 的类型推导... 是看过 paper 不会比如 val a = Box<Int>(1 as Int) 或者 a: Box<Int> = Box(1.toShort()) 我会,反正就是各处(包括 fun 和 constructor)的 actual type 放一起 check eq 就成
但是 unification 就麻烦一些,需要什么 scope ,不是很直接
这个麻烦一点也不过
fun <T,R> get(b:Box<T>, op:(T)->R) = b.value 后 get(Box(2)) {it+1} 完整代码生成上下文类型信息的提供 纯属设计模式问题unification 就是玄学问题🌚
duangsuse::Echo
https://t.me/vvb2060Channel/416 #Android #Security #aop asm inline hook 当然是任意点都可以,实际上 frida 配 xposed 开发是真好吧🤔 /proc/self 都可以 mount --bind ,但是改动是系统级的。 通常做法就是由框架来实现访问权共享,像 Riru 一样换一个 preload .so 来实现 hook 我觉得应用层开发者尝试对抗系统动态分析是很愚蠢的行为,毕竟你又不是搞安全的,凭 Proguard 组搞出来…
为了避免被认为是在指点江山我就简单 PoC 一下,真的不需要十行代码。 毕竟这个「反破解手段」门槛也太低了,只需改动 .h 文件&重编译,其它都自动兼容了。
而加密 bytecode 的各种方法全都逃不过内存 dump ,因为「原原本本」的程序文件是虚拟机要求的,总是要还原。 hook 一下虚拟机的 load() 即 luaZ_undump() 就都出来了,代码保护唯一有效的是削除命名标识符的本义,或者对程序做些预处理和切分什么的(对这些,基于符号执行的 smalivm 类反混工具也能消除),但是大部分有「产权保护」意识的人 意识不到吧😒。
目标只是得出两版 #Lua 指令号直接的对应关系,也就是只需做指令id 数组的读取,得出的对应关系用于 patch 给 chunkspy 等工具。
本来说是可以用 getOpcode(buf, i) 的,忘记数组迭代需要长度的问题了,就用迭代器吧…… 也是惰性计算的😒
首先自编个 lua luac (实质都是 liblua 的命令行工具
看看 https://bbs.pediy.com/thread-250618.htm
https://t.me/berd_channel/1647
可以参考
Luac chunk 文件是比较标准带 insn size 的二进制结构, size_t 一般为 4 (int32) 大端字节序,因为只需要读取 opcode 我就做个比较 hack 的操作——hexdump diff 断言指令数组头的偏移量,本来想可以直接取每条指令首字节,没想到这个好像是仅 7 bit ,那就只能
然后指令集也不必写完整的,反正也没有 unluac ,源码手改的,自己验证意思意思够了。
lopnames.h 对虚拟机无意义, lopcodes.c 只是定义指令格式的,所以要改 .h 里的顺序,稍后 grep -r 'ORDER OP' 还会发现必须同时更改 .c 的顺序,而且还得修正 lua.h 的一处
其实如果不改 ltm.h 而想保证元表事件正常派发,那 OP_ADD 到 OP_NOT 直接的顺序都不能变🌝
不过这里就随便点,反正没用到~
用于乱序的 py 脚本:
同时 shuf .c array 和 .h enum 的索引号,总之就是先搞出 index mapping 再 apply 它两次。 🌚
用于对应的脚本(见下下条):
d[op[i]] = names[op_orig[i]]
胡话:呃,好像是 d[k] = d1[d[k]] ... 不对
其实变的是 k 吧(re-associateBy), d[k1] = d[k] 其中 k1=d1.keyOf(k) ,因为 v 都是复制过来的。
#plt #ce #backend 反破解小指南 🦜
嘛,其实这个还是有强化的方法的。 只需这个有强烈愿望🧐并且敢动 C 虚拟机🌝实现代码的人 对他的每个单个应用 重编译乱 opcode 的私有版 lua
同时更改下 LuaVM 指令格式 bitmask 里操作数的顺序,并且以自有算法加密常量池(必须由虚拟机层来解密,最好是惰性完成的 内部传输性 loadk 只传常量编号不解密),这样对 naive 的破解者就非常棘手了,只能从外部 API 分析某一特性点的实现方法惹🌚
自有版虚拟机的代码文件看起来符合规范(因为你改得少),但是完全无法被通常工具读取,一些虚拟机壳也是出于同样的意图(which 我没在 Android 上见到过,设计这种加壳器需要一定编译原理或状态机的知识 需要预处理 bytecode)
最关键的一点就是孤立自己利用到的技术,让破解者无法使用针对性工具,然后增加破解者自写工具的难度,尽可能用没工具的 native 平台叠加难度。单机程序用惩罚机制来反动态分析?可笑。程序状态是不可信的,稍有常识的坏人完全可以保留某 fork 的整机状态,你检查虚拟机都不行,有的是机会给检测方法 hook 光光;用别人的反破库,也容易被找到针对性反反破工具。😒
其实嘛,越是简单的代码越接近真理,越往程序的根基走,手段越能令破解者头疼。
其实用私有版 luaVM 不暴露指令号对应关系就已经很安全了(当然坏人🌝还是可以用生成 code 看 vm state 的方法甄别指令,虚拟机状态就不是纯二进制领域的人能魔改的了🤪),但最好还是用预处理给 luaV_execute 的 opcode switch 每个 case 加点随机乱代码,防止被源码相似性搜索(这个只需要反汇编字符串匹配 破解者就能完成)。
介于 C 的静态自动分析尚无完整解法,对每个模块都要还原虚拟机指令才能反编译出真实逻辑,就可以说是「无法破解」的软件了🤣。
你掌控程序流程,你掌控无物;你掌控程序码解释,你掌控一切。
越是在根基做限制越难破解,但是外部 API 和 memdump 依然没办法对抗,但至少,这样反调试代码就不易被分析了🌚 这些代码能造成巨大的麻烦,让破解者不知从何下手,例如反外部 API 断点和管理加密的常量池,制造 garbage String 来混淆 memdump 。
什么叫做欺骗系统,「系统」这个概念都是针对软件运行时而言的,运行时可以是带trace/hook的实机、虚拟机或者静态分析器,这些都是合法合理的运行时,因为,程序只是数据而已。「我的代码,我的权利、我的私产」?谁能想到那么多啊😅。
除非有一天 DRM 会无法被模拟复制破解,不然最实际的方法是把软件做得足够大,然后诉诸法律或己方威权。
而加密 bytecode 的各种方法全都逃不过内存 dump ,因为「原原本本」的程序文件是虚拟机要求的,总是要还原。 hook 一下虚拟机的 load() 即 luaZ_undump() 就都出来了,代码保护唯一有效的是削除命名标识符的本义,或者对程序做些预处理和切分什么的(对这些,基于符号执行的 smalivm 类反混工具也能消除),但是大部分有「产权保护」意识的人 意识不到吧😒。
目标只是得出两版 #Lua 指令号直接的对应关系,也就是只需做指令id 数组的读取,得出的对应关系用于 patch 给 chunkspy 等工具。
本来说是可以用 getOpcode(buf, i) 的,忘记数组迭代需要长度的问题了,就用迭代器吧…… 也是惰性计算的😒
首先自编个 lua luac (实质都是 liblua 的命令行工具
curl -O http://www.lua.org/ftp/lua-5.4.2.tar.gz
tar xf lua-* &&cd lua-*/src/
make luac lua
#sysadmin 科普下 lua.org 的 doc 里 curl/tar 的 -R/-z 是 设置文件mtime/gz解压看看 https://bbs.pediy.com/thread-250618.htm
https://t.me/berd_channel/1647
可以参考
Luac chunk 文件是比较标准带 insn size 的二进制结构, size_t 一般为 4 (int32) 大端字节序,因为只需要读取 opcode 我就做个比较 hack 的操作——hexdump diff 断言指令数组头的偏移量,本来想可以直接取每条指令首字节,没想到这个好像是仅 7 bit ,那就只能
import struct 了😓然后指令集也不必写完整的,反正也没有 unluac ,源码手改的,自己验证意思意思够了。
lopnames.h 对虚拟机无意义, lopcodes.c 只是定义指令格式的,所以要改 .h 里的顺序,稍后 grep -r 'ORDER OP' 还会发现必须同时更改 .c 的顺序,而且还得修正 lua.h 的一处
#define 🌚 (不过和 lcode.h 的 OPR_x 以及 ltm.h 没关系,因为 opr 是以 OP_ADD+i 及 TM_ADD+i 的方式两向对应的 )其实如果不改 ltm.h 而想保证元表事件正常派发,那 OP_ADD 到 OP_NOT 直接的顺序都不能变🌝
不过这里就随便点,反正没用到~
用于乱序的 py 脚本:
同时 shuf .c array 和 .h enum 的索引号,总之就是先搞出 index mapping 再 apply 它两次。 🌚
用于对应的脚本(见下下条):
d[op[i]] = names[op_orig[i]]
胡话:呃,好像是 d[k] = d1[d[k]] ... 不对
其实变的是 k 吧(re-associateBy), d[k1] = d[k] 其中 k1=d1.keyOf(k) ,因为 v 都是复制过来的。
#plt #ce #backend 反破解小指南 🦜
嘛,其实这个还是有强化的方法的。 只需这个有强烈愿望🧐并且敢动 C 虚拟机🌝实现代码的人 对他的每个单个应用 重编译乱 opcode 的私有版 lua
同时更改下 LuaVM 指令格式 bitmask 里操作数的顺序,并且以自有算法加密常量池(必须由虚拟机层来解密,最好是惰性完成的 内部传输性 loadk 只传常量编号不解密),这样对 naive 的破解者就非常棘手了,只能从外部 API 分析某一特性点的实现方法惹🌚
自有版虚拟机的代码文件看起来符合规范(因为你改得少),但是完全无法被通常工具读取,一些虚拟机壳也是出于同样的意图(which 我没在 Android 上见到过,设计这种加壳器需要一定编译原理或状态机的知识 需要预处理 bytecode)
最关键的一点就是孤立自己利用到的技术,让破解者无法使用针对性工具,然后增加破解者自写工具的难度,尽可能用没工具的 native 平台叠加难度。单机程序用惩罚机制来反动态分析?可笑。程序状态是不可信的,稍有常识的坏人完全可以保留某 fork 的整机状态,你检查虚拟机都不行,有的是机会给检测方法 hook 光光;用别人的反破库,也容易被找到针对性反反破工具。😒
其实嘛,越是简单的代码越接近真理,越往程序的根基走,手段越能令破解者头疼。
其实用私有版 luaVM 不暴露指令号对应关系就已经很安全了(当然坏人🌝还是可以用生成 code 看 vm state 的方法甄别指令,虚拟机状态就不是纯二进制领域的人能魔改的了🤪),但最好还是用预处理给 luaV_execute 的 opcode switch 每个 case 加点随机乱代码,防止被源码相似性搜索(这个只需要反汇编字符串匹配 破解者就能完成)。
介于 C 的静态自动分析尚无完整解法,对每个模块都要还原虚拟机指令才能反编译出真实逻辑,就可以说是「无法破解」的软件了🤣。
你掌控程序流程,你掌控无物;你掌控程序码解释,你掌控一切。
越是在根基做限制越难破解,但是外部 API 和 memdump 依然没办法对抗,但至少,这样反调试代码就不易被分析了🌚 这些代码能造成巨大的麻烦,让破解者不知从何下手,例如反外部 API 断点和管理加密的常量池,制造 garbage String 来混淆 memdump 。
什么叫做欺骗系统,「系统」这个概念都是针对软件运行时而言的,运行时可以是带trace/hook的实机、虚拟机或者静态分析器,这些都是合法合理的运行时,因为,程序只是数据而已。「我的代码,我的权利、我的私产」?谁能想到那么多啊😅。
除非有一天 DRM 会无法被模拟复制破解,不然最实际的方法是把软件做得足够大,然后诉诸法律或己方威权。
Pediy
[原创]用 Lua 简单还原 OpCode 顺序-Android安全-看雪论坛-安全社区|安全招聘|bbs.pediy.com
#android #gui #design #drawing https://t.me/AndroidDevCn/184450
https://t.me/AndroidDevCn/184426
Activity 透明模糊背景 4.0 删了,新 RenderEffect 可以作用于 View 但需要 API S 🌚
iseki:
请教下群友们,想弄个毛玻璃activity…但是完全没想明白咋弄🙈
不是…我是说…半透明的活动,背景毛玻璃🙈
找了半天一个扭曲的实现是截屏+模糊🙈不想这么扭曲
Ghost Flying:
你可以渲染到 SurfaceTexture backed 的 virtual display 上,然后用 OpenGL 加滤镜贴主屏,然后透传触摸事件(
iseki:
不知道Android咋合成的,要是依次在一个表面上画所有activity,那应该行吧
Ghost Flying:
就是多个 window 当成 layer 来合成
题外话, #Android #marker glide #build https://t.me/AndroidDevCn/184384
https://t.me/AndroidDevCn/184426
Activity 透明模糊背景 4.0 删了,新 RenderEffect 可以作用于 View 但需要 API S 🌚
iseki:
请教下群友们,想弄个毛玻璃activity…但是完全没想明白咋弄🙈
不是…我是说…半透明的活动,背景毛玻璃🙈
找了半天一个扭曲的实现是截屏+模糊🙈不想这么扭曲
Ghost Flying:
你可以渲染到 SurfaceTexture backed 的 virtual display 上,然后用 OpenGL 加滤镜贴主屏,然后透传触摸事件(
iseki:
不知道Android咋合成的,要是依次在一个表面上画所有activity,那应该行吧
Ghost Flying:
就是多个 window 当成 layer 来合成
题外话, #Android #marker glide #build https://t.me/AndroidDevCn/184384
Telegram
duangsuse in [CN] Android Dev
渲染到位图然后加滤镜当背景…… 为什么要传事件呢🤔
半透明活动应该不可能拿到活动后的背景吧,用户隐私呢
噢这么说应该是两个活动都你 app 的,然后前者直接截自己图加滤镜贴上面装毛玻璃,另外一个活动 UX?😳
这种一般都是 modal 对话框,触摸需求没有吧
半透明活动应该不可能拿到活动后的背景吧,用户隐私呢
噢这么说应该是两个活动都你 app 的,然后前者直接截自己图加滤镜贴上面装毛玻璃,另外一个活动 UX?😳
这种一般都是 modal 对话框,触摸需求没有吧
duangsuse::Echo
为了避免被认为是在指点江山我就简单 PoC 一下,真的不需要十行代码。 毕竟这个「反破解手段」门槛也太低了,只需改动 .h 文件&重编译,其它都自动兼容了。 而加密 bytecode 的各种方法全都逃不过内存 dump ,因为「原原本本」的程序文件是虚拟机要求的,总是要还原。 hook 一下虚拟机的 load() 即 luaZ_undump() 就都出来了,代码保护唯一有效的是削除命名标识符的本义,或者对程序做些预处理和切分什么的(对这些,基于符号执行的 smalivm 类反混工具也能消除),但是大部分有「产权保护」意识的人…
刚才写了一大篇都是理论,也是因为我低估了问题的麻烦度在手机上写了大半天…… 🙊 确实测试还是需要的。
嘛,除了
也是我一开始就没从要逆向谁的应用的角度来想🌝,没去研究不用 luac 怎么得字节码。 可方便了
过会我也不会提供魔改反编译器或者 .luac 文件的辅助程序什么的,正确的做法是魔改 unluac 扩展支持加载 json 配置
https://www.lua.org/manual/5.4/manual.html#pdf-file:read #Lua 的 io file 用的 lines() read("n") "a" "l" fmtstr ,真的很难猜中啊 🌚
文章里也写了 hexdump diff 本来就可以拿 iter if == 替换 😅思维定势 不过也是因为我面向 array binstruct 了
这里只是 PoC ,没有 LuaS 头的兼容性和 size 定义的问题,那个 Berd 写过
https://github.com/fengberd/xLuaDumper/blob/master/xLuaDumper/opcode.lua
loadkx, extraarg, testset 应该是优化指令🤔 反正这里不必是全集,闭包 upvalue 的没问题就行。
对应表:
当然如果有 opnames 可以 re-associateBy 也即
#code https://gist.github.com/duangsuse/90366621af2d206867496f7eb1e42438 写这里 🌝 竟然花了这么久
那个用来自动重排 opcodes 的脚本实在是太难看了,虽然我努力在写简单…… 毕竟是在处理 C 源代码 🤪
真的没问题吗
#Android #net 还看到了这个 https://t.me/dsuses/4769
嘛,除了
luac wtf.lua 其实也可以这样拿到字节码去对照(毕竟 liblua 是带 luaC_ luaU_ 编译器的,刚刚也说了 lua luac 只是 CLI 前端, liblua 才是本体)也是我一开始就没从要逆向谁的应用的角度来想🌝,没去研究不用 luac 怎么得字节码。 可方便了
过会我也不会提供魔改反编译器或者 .luac 文件的辅助程序什么的,正确的做法是魔改 unluac 扩展支持加载 json 配置
https://www.lua.org/manual/5.4/manual.html#pdf-file:read #Lua 的 io file 用的 lines() read("n") "a" "l" fmtstr ,真的很难猜中啊 🌚
table.concat({1,2,3}, "") 对 iter 不起效;不过我突然发现 dump() 其实要 function... 要靠 eval 类接口了function codeobj()
-- 用到几乎所有 opcode 的程序体
end
io.open("code.luac", "wb"):write(string.dump(codeobj)) 文章里也写了 hexdump diff 本来就可以拿 iter if == 替换 😅思维定势 不过也是因为我面向 array binstruct 了
这里只是 PoC ,没有 LuaS 头的兼容性和 size 定义的问题,那个 Berd 写过
https://github.com/fengberd/xLuaDumper/blob/master/xLuaDumper/opcode.lua
loadkx, extraarg, testset 应该是优化指令🤔 反正这里不必是全集,闭包 upvalue 的没问题就行。
io.open("o.luac","wb"):write(string.dump(loadfile("a.lua")))
可以用 https://github.com/viruscamp/luadec/blob/master/ChunkSpy/ChunkSpy53.lua 看看,报错就改它的 config 。好了是这样。对应表:
import struct
def mask1(n): return sum([1<<i for i in range(n)])
def readOpcodes(f, nbit=7, fmt="<I"): # LE unsigned int
mask = mask1(nbit)
n = f.read()
for _ in range(n): yield f.read(struct.calcsize(fmt))&mask
from sys import argv
def main(args=argv[1:]):
def opcodes(fp): f=open(fp, "rb"); f.seek(46); return readOpcodes(f)
(f, fOrig) = map(insnFile, args)
print({op1:op for op1,op in zip(f, fOrig)}) 当然如果有 opnames 可以 re-associateBy 也即
op1: names[op] 、 names.associateBy { d.keyOf(it.key) } ,不过我觉得那不重要。#code https://gist.github.com/duangsuse/90366621af2d206867496f7eb1e42438 写这里 🌝 竟然花了这么久
那个用来自动重排 opcodes 的脚本实在是太难看了,虽然我努力在写简单…… 毕竟是在处理 C 源代码 🤪
真的没问题吗
#Android #net 还看到了这个 https://t.me/dsuses/4769
GitHub
fengberd/xLuaDumper
Load xlua.dll and corresponding lua5X.dll to dump luac for a script - fengberd/xLuaDumper
一看到 Lua 就想到一些过去的事情。 以为自己有能力了,其实还是没有啊
其实 ParserKt 也还是没好啊,其实我也还是写不出 Binary AXML 的序列化啊,其实我也还是没有写一门可以用的 JVM 语言啊,其实我也还是不会写编译器啊,更别说带 native 后端的完整东西呢
如果真的能做到,又是怎么样的情景了呢。
还是想要努力一点啊,
铝板会写五子棋规则带 AI ,我的贪吃蛇连直线都不会选
Yuuta 的 MC 能在 tgbot 直播,我连 curl 都不会用
Berd 的 js 反混淆器能处理多种模式,我连正经的编译器都没写过,讽刺的是人家压根是 PHP+JS 主职运维,但是整体就是比你强,连语法工具都能随性使用
iseki 的 vert.x 经验和 codegen 的意识是我未曾试过的
@AndroidDevCN 的 Ghost 和 Rikka 是对自己的强大默不作声的聚聚
这些都还不是算法大佬,要是算法大佬又怎么能比呢…… 😢
可是一些事情并不是很努力很用功就能做成的吧,所谓「天赋」的这种东西,未曾拥有,是「觉悟」无法弥补的吧。
其实 ParserKt 也还是没好啊,其实我也还是写不出 Binary AXML 的序列化啊,其实我也还是没有写一门可以用的 JVM 语言啊,其实我也还是不会写编译器啊,更别说带 native 后端的完整东西呢
如果真的能做到,又是怎么样的情景了呢。
还是想要努力一点啊,
铝板会写五子棋规则带 AI ,我的贪吃蛇连直线都不会选
Yuuta 的 MC 能在 tgbot 直播,我连 curl 都不会用
Berd 的 js 反混淆器能处理多种模式,我连正经的编译器都没写过,讽刺的是人家压根是 PHP+JS 主职运维,但是整体就是比你强,连语法工具都能随性使用
iseki 的 vert.x 经验和 codegen 的意识是我未曾试过的
@AndroidDevCN 的 Ghost 和 Rikka 是对自己的强大默不作声的聚聚
这些都还不是算法大佬,要是算法大佬又怎么能比呢…… 😢
可是一些事情并不是很努力很用功就能做成的吧,所谓「天赋」的这种东西,未曾拥有,是「觉悟」无法弥补的吧。
Forwarded from duangsues.is_a? SaltedFish
#CG 支持透视变换啦(本来也说是研究 OpenGL 的副产品
- 规范化(子模块) YAML config 和 [a, b] Range ,包括 Input,FFT,Render,Window,FPSPrinter 都参数可调化了
- 支持多个频谱(Spectrum) 信息,虽然我还不清楚新 Input 是怎么改的
- MSAA(Multisample Anti-Aliasing) 选项
- dB 计算和 blackman window 的修正
- 支持选择 fftw 窗口类型
过几天会选择合并改动(当然是全手动了,项目结构改变太多
- 规范化(子模块) YAML config 和 [a, b] Range ,包括 Input,FFT,Render,Window,FPSPrinter 都参数可调化了
- 支持多个频谱(Spectrum) 信息,虽然我还不清楚新 Input 是怎么改的
- MSAA(Multisample Anti-Aliasing) 选项
- dB 计算和 blackman window 的修正
- 支持选择 fftw 窗口类型
过几天会选择合并改动(当然是全手动了,项目结构改变太多
Forwarded from mivik::channels::tech
This media is not supported in your browser
VIEW IN TELEGRAM
支持通过配置文件添加多个渲染对象以及附加透视变换)感觉怪怪的 🤔
#JS 有意思,不过实现方法有点糙了,比较函数式用的 new URL .hostname 去累积,还有 then 来支持 await,既有 URL 上方法我觉得.. String 就好吧 🤔 我第一直觉大概是副作用,用 www 层的变量吧…… 想的单线程 其实这累积/重置判断是可行的。可那样其实不太好,思维反函数式化了吗?