那么呢,每周回家都有每周的任务,要不然会非常无聊 #life #tech #dev #daily #Learn
#Java
每次呢看的书好像比较多,又都是轮流转结果可能最后一周完了枚举不出来自己看了什么书比较尴尬,大概是操作系统和嵌入式的,JVM 的也有,但大概是记住了吧。
📚 最近会开始掺杂一些文化课的书学习,由于 CS 的书看的比较多我发现自己的智商和认知理解至于记忆能力都有很大的提升(也可能是年龄关系,目前大概是 17 岁吧,和某 GAN(生成式对抗神经网络,14 年的)算法的 19 岁美国大佬少年还差两年,逃,当然和某些 17 岁就上博士的奇幻人生就比不了了)
主要的原因是有时候看 #CS/IT 系的书比较累
并且愿意尝试补习一下数学,数学里解析几何暂时还有点难理解,其他的代数问题大概都好,因为我现在也稍微有点工程数据结构算法分析能力。
之前一直觉得很难看的数学公式式的表达方式突然觉得没有那么难看了,觉得很自然,也有兴趣理解他们所表示的含义。
这周今天大概就是专门讲讲 r2 x86 架构逆向工程和 #Android Dalvik/Native 逆向工程顺便混杂一点信息工程理论、编译原理什么的,因为我不得不使笔记记录几乎停止,要不然的确有队爆的可能(跑)
#Book 顺便将会发点书单什么的(跑),当然之前我有资料单,不过很早之前了,你们可以自己在文件里面找(皮)
总之就四个字:逆向工程
逆向工程
逆向工程
逆向工程(
(我们可以
(出人意料吗?很多后端不是没有做前端的能力,比如 r2 的主要开发者 @pancake 就既写 CLI 的 Visual Viewer 也写 HTML
(讲道理,我觉得 Qt 的桌面开发者可能技术反而比 Android Views SDK 的要高
当然密码学之类的是不涉及的,如何解决别人反逆向工程(这里是说,那种高等 native 后端程序员的代码保护方法(比如 false disassembly 也即『花指令』),不是 JVM 开发者或者 Lua 这种托管给别人虚拟机运行的那种,而且不是不会去考虑什么指针不指针内存不内存分页不分页线程不线程分配不分配阻塞不阻塞堆不堆栈不栈动态链接不动态链接的什么混淆压缩然后用某某公司团队或者个人的加固工具『加固』『加密』(然后运行时类加载、虚拟机加载的时候解密载入内存,最后被人扫 file magic 再内存 dump 出来)的那种,不是内建虚拟机什么的,当然内建虚拟机解释不是说就不能 hack 了,记住所有程序逻辑都在你的机器上执行)也是不涉及的,目标是入门和简单的使用,以及给你一个运行时的视角,使你基本可以进行软件分析什么的(
#talk #backend #OS #PL #Sysadmin #CS
(这里底层素质的优势就显现出来了,虽然底层知识并不特殊,但它能给你更广阔的视角,而不是局限在应用的 Resources、Dalvik EXecutable、JNI 库接口和 HTTP 协议那层)
(说到这里忍不住感叹一下,现在又有多少开发者看得到 IL、汇编层面的东西?都是一群只知混淆处理模糊名称算法的,而且自己还不一定会写,自己连自己平台编译完后生成的东西文件结构都不知道的多的去了...)
(当然,这里能写 Java Annotation Processor 程度能力的自然也是明白人了,至少他们有学习能力吧?至少透过 Java 代码文本看到 AST 了吧?)
(好吧,AST、PSI(就是 JB 的 AST)什么的其实也是基本技能,编译优化那才是大佬... 什么逃逸分析、指针别名、代数化简指令合并、公共子表达式消除、向量化、积极虚方法内联的复杂算法...)
(那你这么说 ANN 那群 AI 开发者不是更 dalao 了么?(也不一定(现在编译优化都在用人工智能系算法了么?(启发式至少有吧
(成天批判术语... 其实还是躲不开吧,我所批判的大概是知识层次浅但是不知道自己知识层次浅的那些开发者吧...
(你的意思是你是大佬?(对不起我没有这个意思,我,duangsuse,菜鸡,菜爆了,啥算法都不会写,最讨厌图算法和动态规划(跑
(当然诸如 @RikkaW 这种 C++ 大佬自然也是大佬了(吐槽:有什么必然联系么?)
(当然,给编译原理的大佬们澄明一下,我不是带坏小白,编译是个非常抽象的翻译过程,不一定非得序列化生成文件存盘的,我只是想说明一个常用模式)
(最后:
(总结:
(吐槽:你又飘了,菜鸡 (回:你的意思是我给 Echo 加了那么多 admin,随便他们发广播,可是他们没一个人评价我的广播... (不过,羽毛 @kodamasakuno 你不评价吗...)
(就是说,至少和那些专科高中的比,我学得很快了吧?不行吗?至少我是在身边完全没有电脑的情况下看书自学的,而且学的还不是应用层的东西,,, 而且我有做框架的能力他们只有用框架的份... 而且我会设计不那么线性一点的算法... 不是挺好么?而且我也会 #CG 画画... 而且我可能会写地图生成器这种随机自动生成的算法... 而且我有实用的数学和逻辑学基础.... 比方说... 呃... 偏序理论?(不会)好吧... well done...
(最后再澄明一下 #disclaimer 我真的真的不针对任何人,因为大家都是这样的,不要对号入座)
(如果要把 Lua 开发者(不是 Androlua 这种)的综合技术素质和 JVM 开发者比的话,我一般觉得 Lua 开发者的素质更好,理由是知道 #Lua 的人一般都会写 #C/C++,不是把 C/C++ 当成 Java 写的那种))
JVM 平台的一些东西可能也讲一下,如果顺手的话,可能明天也要写个 Android 应用 Reflector,尝试提供一个 Dalvik 反射类信息获取 API 的前端,模块化面向接口设计方便扩展。(别喷什么低级技能之类的...
其实每次学到的东西比较多,甚至 Android 开发上的也有(主要是带手机去学校,看一些 Androlua 开发手册上的有点 Android/Java API 使用讲解),只是知识不系统。可是,现在又有几个 Android 开发者的知识真正是系统的呢?(笑)不过是经验之谈而已吧。只是单单靠着自己本来的能力学,学到的知识基本都是 Implicit 的,你控制不了它,你『有那么一点点感觉』但『又的确不能说出它是什么』,这样弄了两三年工程发现都是自己作为搜索引擎和模式识别机器写出的代码,比较线性比较模式化,而且除了可能的名利没有什么太大的理论上的收获,可能也会比较尴尬(笑),当然我之前是不知道有所谓的理论的,我眼里只有应用编程。只有看代码看文档写代码,当然所谓学习其实也不过如此嘛。只是能看破封装的开销有点大了,不如哪怕自己的代码不那么 parallelism 也好(愉悦即可,什么留给后端吧... 反正各种线程同步、什么内核模式用户模式、同步块原子操作什么的都...
JVM 『著名』的双检锁技术(Double-checked Locking,DCL,一种用来解决 singleton 单件实例对象模式线程竞争问题的方案,虽然比较慢)都不知道有没有 Android Developer 会,大概是只知异步不懂并发了吧... 包装啊包装... 万能的包装... 万能的社区库... JMM(Java 内存模型)那(一 JVM 书)讲的什么 store、assign 和 write 这几个语义几乎一样的词用起来总是弄不清楚... 缓存同步啊缓存同步... 不会啊... ...
#Java
每次呢看的书好像比较多,又都是轮流转结果可能最后一周完了枚举不出来自己看了什么书比较尴尬,大概是操作系统和嵌入式的,JVM 的也有,但大概是记住了吧。
📚 最近会开始掺杂一些文化课的书学习,由于 CS 的书看的比较多我发现自己的智商和认知理解至于记忆能力都有很大的提升(也可能是年龄关系,目前大概是 17 岁吧,和某 GAN(生成式对抗神经网络,14 年的)算法的 19 岁美国大佬少年还差两年,逃,当然和某些 17 岁就上博士的奇幻人生就比不了了)
主要的原因是有时候看 #CS/IT 系的书比较累
并且愿意尝试补习一下数学,数学里解析几何暂时还有点难理解,其他的代数问题大概都好,因为我现在也稍微有点工程数据结构算法分析能力。
之前一直觉得很难看的数学公式式的表达方式突然觉得没有那么难看了,觉得很自然,也有兴趣理解他们所表示的含义。
这周今天大概就是专门讲讲 r2 x86 架构逆向工程和 #Android Dalvik/Native 逆向工程顺便混杂一点信息工程理论、编译原理什么的,因为我不得不使笔记记录几乎停止,要不然的确有队爆的可能(跑)
#Book 顺便将会发点书单什么的(跑),当然之前我有资料单,不过很早之前了,你们可以自己在文件里面找(皮)
总之就四个字:逆向工程
逆向工程
逆向工程
逆向工程(
(我们可以
r2 -
(malloc 512 bytes)w 逆向工程
pr 3*4(跑,因为我还不怎么会 r2lang,不知道循环怎么弄,他们那个蛮 #Unix-style 的,就是一切皆大部分可打印字符串,包括 ESIL(Evaluatable Strings Intermidiate Language)都是蛮像 Brainf**k 的字符串语言)
(出人意料吗?很多后端不是没有做前端的能力,比如 r2 的主要开发者 @pancake 就既写 CLI 的 Visual Viewer 也写 HTML
(讲道理,我觉得 Qt 的桌面开发者可能技术反而比 Android Views SDK 的要高
当然密码学之类的是不涉及的,如何解决别人反逆向工程(这里是说,那种高等 native 后端程序员的代码保护方法(比如 false disassembly 也即『花指令』),不是 JVM 开发者或者 Lua 这种托管给别人虚拟机运行的那种,而且不是不会去考虑什么指针不指针内存不内存分页不分页线程不线程分配不分配阻塞不阻塞堆不堆栈不栈动态链接不动态链接的什么混淆压缩然后用某某公司团队或者个人的加固工具『加固』『加密』(然后运行时类加载、虚拟机加载的时候解密载入内存,最后被人扫 file magic 再内存 dump 出来)的那种,不是内建虚拟机什么的,当然内建虚拟机解释不是说就不能 hack 了,记住所有程序逻辑都在你的机器上执行)也是不涉及的,目标是入门和简单的使用,以及给你一个运行时的视角,使你基本可以进行软件分析什么的(
#talk #backend #OS #PL #Sysadmin #CS
(这里底层素质的优势就显现出来了,虽然底层知识并不特殊,但它能给你更广阔的视角,而不是局限在应用的 Resources、Dalvik EXecutable、JNI 库接口和 HTTP 协议那层)
(说到这里忍不住感叹一下,现在又有多少开发者看得到 IL、汇编层面的东西?都是一群只知混淆处理模糊名称算法的,而且自己还不一定会写,自己连自己平台编译完后生成的东西文件结构都不知道的多的去了...)
(当然,这里能写 Java Annotation Processor 程度能力的自然也是明白人了,至少他们有学习能力吧?至少透过 Java 代码文本看到 AST 了吧?)
(好吧,AST、PSI(就是 JB 的 AST)什么的其实也是基本技能,编译优化那才是大佬... 什么逃逸分析、指针别名、代数化简指令合并、公共子表达式消除、向量化、积极虚方法内联的复杂算法...)
(那你这么说 ANN 那群 AI 开发者不是更 dalao 了么?(也不一定(现在编译优化都在用人工智能系算法了么?(启发式至少有吧
(成天批判术语... 其实还是躲不开吧,我所批判的大概是知识层次浅但是不知道自己知识层次浅的那些开发者吧...
(你的意思是你是大佬?(对不起我没有这个意思,我,duangsuse,菜鸡,菜爆了,啥算法都不会写,最讨厌图算法和动态规划(跑
(当然诸如 @RikkaW 这种 C++ 大佬自然也是大佬了(吐槽:有什么必然联系么?)
(当然,给编译原理的大佬们澄明一下,我不是带坏小白,编译是个非常抽象的翻译过程,不一定非得序列化生成文件存盘的,我只是想说明一个常用模式)
(最后:
radare2
这种灭天地的逆向工程分析框架才是真理啊!世界上最好的『二进制编辑器、扇区编辑器、系统 I/O 工具、二进制可视化分析工具(like bindiff、base conversion)、反汇编器/JIT 替换汇编器、Shellcode 工具、逆向代码分析器、动态静态调试器、解析器』而且非常『可扩展、可移植、可嵌入』(总结:
Cross-platform unix-like multi-architecture reverse engineering framework and commandline toolchain for security/forensics. wow. debug.exe(MSDOS) for the 21ₛₜ century
(最后:真正的无知不是知识匮乏,你看我以前那么匮乏现在不都好很多了么?都是靠积累学习思考实践的,没有本本我能做到这么快吗?(吐槽:你又飘了,菜鸡 (回:你的意思是我给 Echo 加了那么多 admin,随便他们发广播,可是他们没一个人评价我的广播... (不过,羽毛 @kodamasakuno 你不评价吗...)
(就是说,至少和那些专科高中的比,我学得很快了吧?不行吗?至少我是在身边完全没有电脑的情况下看书自学的,而且学的还不是应用层的东西,,, 而且我有做框架的能力他们只有用框架的份... 而且我会设计不那么线性一点的算法... 不是挺好么?而且我也会 #CG 画画... 而且我可能会写地图生成器这种随机自动生成的算法... 而且我有实用的数学和逻辑学基础.... 比方说... 呃... 偏序理论?(不会)好吧... well done...
(最后再澄明一下 #disclaimer 我真的真的不针对任何人,因为大家都是这样的,不要对号入座)
(如果要把 Lua 开发者(不是 Androlua 这种)的综合技术素质和 JVM 开发者比的话,我一般觉得 Lua 开发者的素质更好,理由是知道 #Lua 的人一般都会写 #C/C++,不是把 C/C++ 当成 Java 写的那种))
JVM 平台的一些东西可能也讲一下,如果顺手的话,可能明天也要写个 Android 应用 Reflector,尝试提供一个 Dalvik 反射类信息获取 API 的前端,模块化面向接口设计方便扩展。(别喷什么低级技能之类的...
其实每次学到的东西比较多,甚至 Android 开发上的也有(主要是带手机去学校,看一些 Androlua 开发手册上的有点 Android/Java API 使用讲解),只是知识不系统。可是,现在又有几个 Android 开发者的知识真正是系统的呢?(笑)不过是经验之谈而已吧。只是单单靠着自己本来的能力学,学到的知识基本都是 Implicit 的,你控制不了它,你『有那么一点点感觉』但『又的确不能说出它是什么』,这样弄了两三年工程发现都是自己作为搜索引擎和模式识别机器写出的代码,比较线性比较模式化,而且除了可能的名利没有什么太大的理论上的收获,可能也会比较尴尬(笑),当然我之前是不知道有所谓的理论的,我眼里只有应用编程。只有看代码看文档写代码,当然所谓学习其实也不过如此嘛。只是能看破封装的开销有点大了,不如哪怕自己的代码不那么 parallelism 也好(愉悦即可,什么留给后端吧... 反正各种线程同步、什么内核模式用户模式、同步块原子操作什么的都...
JVM 『著名』的双检锁技术(Double-checked Locking,DCL,一种用来解决 singleton 单件实例对象模式线程竞争问题的方案,虽然比较慢)都不知道有没有 Android Developer 会,大概是只知异步不懂并发了吧... 包装啊包装... 万能的包装... 万能的社区库... JMM(Java 内存模型)那(一 JVM 书)讲的什么 store、assign 和 write 这几个语义几乎一样的词用起来总是弄不清楚... 缓存同步啊缓存同步... 不会啊... ...
java.util.concurrent
这个包存不存在都不知道有没有人知道呢,或许(笑)Wikipedia
Generative adversarial network
A generative adversarial network (GAN) is a class of machine learning frameworks and a prominent framework for approaching generative artificial intelligence. The concept was initially developed by Ian Goodfellow and his colleagues in June 2014. In a GAN…
#Lua MoonScript.org ? (不是
Typed Lua? Maybe
我考虑的主要是它的语法扩展没有 MoonScript 那么明显
看起来貌似只扩展了
Typed Lua? Maybe
我考虑的主要是它的语法扩展没有 MoonScript 那么明显
看起来貌似只扩展了
function (a: number, b: string)
这种类型定义
duangsuse Throws
#life #tech #school duangsuse 又 *** 回来了!!! 🐱 这次,duangsuse 的̶大̶脑̶进̶一̶步̶升̶级̶,带来了对很多 IT 问题模型的新分析理解能力,并且也学习了一些别的知识! 这个列表目前包括(我发誓下面的东西我都没有查任何一本书,而且我真的有至少一点的了解,绝对不是那种完全只知道名词的了解,不过关于历史的部分我可能看了一点维基,人命不好记...): (虽然会啥啥语言不能代表有实际工程能力,比如,会 Java 8 (有时可能只能代表你会用 Java 8 写…
比如说,我现在开始能看得懂 C 语言 + 算法工程实践的 Lua 5.1 了 (《Lua 设计与实践》这本书,我居然开始能看懂了) #Lua #PL
比如说,Android 开发的设计模式再也不困扰我了(我花了三四节课的时间看了一下《Kotlin 极简教程》里的 Android Realm 日程软件示例,现在我居然能默写很多代码,RealmAdapter/ViewHolder/TodoItemOnClickListener/TodoEditFragment/TodoListFragment/Anko UI/Coordinator Layout/RealmRecycler Layout/View inflator/Android Menus/MainActivity/AppBar/Supportv7Toolbar/XML/Resources/Layouts/Colors/,甚至包括 Groovy Gradle 项目文件了)
比如说,我花了不到十分钟终于看懂了 ES6 的 Generator Functions 和 Thunk 函数、Async callbacks 之间有何关系,为啥要用 Coroutine + yield Promise 的方式而不是直接阻塞地调用 Sync 函数或者,Async 函数使用
而看懂其实是得益于现在能够基于程序执行时控制流模拟的 — 现在我能看到啥是『阻塞』,啥是『挂起等待』了,也知道为啥要做成『分段执行』的函数了
比如说,我现在能理解 Jawa 8 里的泛型型变了(
比如说,曾经我专门记的东西现在更清楚了,为啥有人要用,为啥有些精简代码的技巧因为可读性和语言明确性的原因不能用,比如
比如位运算『优化』,比如索引从 10 数到 0 而不是从 0 数到 10
比如说,Android 开发的设计模式再也不困扰我了(我花了三四节课的时间看了一下《Kotlin 极简教程》里的 Android Realm 日程软件示例,现在我居然能默写很多代码,RealmAdapter/ViewHolder/TodoItemOnClickListener/TodoEditFragment/TodoListFragment/Anko UI/Coordinator Layout/RealmRecycler Layout/View inflator/Android Menus/MainActivity/AppBar/Supportv7Toolbar/XML/Resources/Layouts/Colors/,甚至包括 Groovy Gradle 项目文件了)
比如说,我花了不到十分钟终于看懂了 ES6 的 Generator Functions 和 Thunk 函数、Async callbacks 之间有何关系,为啥要用 Coroutine + yield Promise 的方式而不是直接阻塞地调用 Sync 函数或者,Async 函数使用
function *
和简单使用 function
有啥区别,为啥就要专门的 co
module 来执行 Generator 函数了,为啥 Generator 看起来只是为了状态机随时挂起恢复的却要用来做 Async,Async 和 Await (语法糖)的本质是什么(Fibers,也就是 Coroutine,协程)而看懂其实是得益于现在能够基于程序执行时控制流模拟的 — 现在我能看到啥是『阻塞』,啥是『挂起等待』了,也知道为啥要做成『分段执行』的函数了
比如说,我现在能理解 Jawa 8 里的泛型型变了(
P
是 T
的父类,协变 F<T> : F<P>
、逆变 F<P> : F<T>
、不变 F<P>, F<T>
没有子类型关系),我知道为啥要说 <? extends T>
, 为啥要说 <? super T>
(? 是 T 的超类,这是类型下界限定),为啥要有 PECS(producer-extends
,consumer-super
) 规则,我记住了 Kotlin 泛型里的 <in T>, <out T>
分别是对应 Java 里的啥(PECS,<? super T>, <? extends T>
),但最重要的是我知道为什么 Consumer 要 <super T>
(Number n = ints.get(0);
这是一个缘由,而 capature<? extends T>
限定符实现了泛型类型的协变,也就是说 List<E>, boolean addAll(Collection<? extends E> c)
, List<Number>
这种 receiver 可以 addAll List<Integer>
的 producer,或者说 List<Intger> : Collection<? extends Number>
, List<Integer>
is covariant over Collection<? extends Number>
),而且我看到了谁是谁的子类型这个关系,并且我看了一遍就记住了 OOP 里的几种多态 — Ad hoc polymorphism(特数多态) 的 参数类型重载多态、类型转换多态,参型多态(参数化类型, Parametric Polymorphism),子类型(继承)多态比如说,曾经我专门记的东西现在更清楚了,为啥有人要用,为啥有些精简代码的技巧因为可读性和语言明确性的原因不能用,比如
newvector[i++]
比如 Lua 的 table 预填充技术 p = {0, 0, 0}
防止表存储被动扩充,比如 Lua 的 local time = os.time
可以让访问减少几次索引查找比如位运算『优化』,比如索引从 10 数到 0 而不是从 0 数到 10
for (int i = 9; i >= 0; i--)
比如数组下标(subscript)为啥要叫下标#life #dev duangsuse 落实 10:30 准时睡觉『政策』。 🐱
考虑到健康原因(不让自己的努力白费),每晚 10:30(h:m) 必须立即睡觉
== duangsuse::Echo 参考 #Telegram hashtags
duangsuse::Echo 常年利用 hastags 标记消息所含知识领域,并且,这也会为未来 Echo 频道进行简单准确的数据统计带来可能(不然,我也有其他手段,比如 NLP、统计预测)
以下是新的标签实例(不区分大小写、不能保证消息只含这些标签):
== 消息平台部分
#Telegram #zhihu #Github #so #Coolapk #book #wiki
== 注释部分
#life #China #School #Statement #lib #recommended #low #fix
#project #blog #share #Learn #paper
#dev #tech #art #meetUp #conference
#Moha #Haha
#gnu
#Microsoft #Mozilla #WeChat #QQ #Weibo #Tencent #Baidu #Ali #Qihoo
#tools #code
== 程序设计语言部分
#Kotlin #Java #JavaScript #JavaScript_ES6 #TypeScript
#Rust #Go #Swift #Dart #Crystal
#Ruby #Python #Perl #Tcl #Lua #PHP
#C #D #Cplusplus #CSharp #Objc
#Pascal #Fortran #Delphi #Ada #Basic #VisualBasic
#Scheme #Haskell #Scala #Clojure
#TeX #Graphviz
#Octave #Matlab
#Shell
(有些写出来是为了鼓励我去写,其实不一定真的写过)
== 软件平台部分
#Android #Windows #Win32 #MacOS #Java #Java_JVM #CLR #Qt #GTK #Tk #WxWidgets
#CSS #XML #JSON #KDE #Postgres #dotnet
== 软件技术领域部分
#backend #sysadmin #frontend #sysadmin_net
#OI #CS #IT #Informatics
#stat #ann #ann_dnn #machl
#math #math_linearAlgebra #math_discrete
#se #se_dia #se_ci #se_ee
#comm #net #www #web #http #html #mail #wireless
#circuit #embedded #os #db #db_relAlgebra #SQL
#bin #encoding #encoding_audio #encoding_image #encoding_video #encoding_text
#hpc #parallelism #distributed #simd #gpgpu #crypto
#pl #pl_plt #ce_vee #ce #ce_optimize #fp_monad #fp_proof #fp #oop #oop_arch #sp #parser
#algorithm #struct #lists #maps #sets
#security #security_lowlevel
#signalProc #nlp #phonetic
#cg #cg_dip #cg_3d #cg_2d #cg_lowlevel
#gui #gui_animation #gui_layouts #cli #visualization
考虑到健康原因(不让自己的努力白费),每晚 10:30(h:m) 必须立即睡觉
== duangsuse::Echo 参考 #Telegram hashtags
duangsuse::Echo 常年利用 hastags 标记消息所含知识领域,并且,这也会为未来 Echo 频道进行简单准确的数据统计带来可能(不然,我也有其他手段,比如 NLP、统计预测)
以下是新的标签实例(不区分大小写、不能保证消息只含这些标签):
== 消息平台部分
#Telegram #zhihu #Github #so #Coolapk #book #wiki
== 注释部分
#life #China #School #Statement #lib #recommended #low #fix
#project #blog #share #Learn #paper
#dev #tech #art #meetUp #conference
#Moha #Haha
#gnu
#Microsoft #Mozilla #WeChat #QQ #Weibo #Tencent #Baidu #Ali #Qihoo
#tools #code
== 程序设计语言部分
#Kotlin #Java #JavaScript #JavaScript_ES6 #TypeScript
#Rust #Go #Swift #Dart #Crystal
#Ruby #Python #Perl #Tcl #Lua #PHP
#C #D #Cplusplus #CSharp #Objc
#Pascal #Fortran #Delphi #Ada #Basic #VisualBasic
#Scheme #Haskell #Scala #Clojure
#TeX #Graphviz
#Octave #Matlab
#Shell
(有些写出来是为了鼓励我去写,其实不一定真的写过)
== 软件平台部分
#Android #Windows #Win32 #MacOS #Java #Java_JVM #CLR #Qt #GTK #Tk #WxWidgets
#CSS #XML #JSON #KDE #Postgres #dotnet
== 软件技术领域部分
#backend #sysadmin #frontend #sysadmin_net
#OI #CS #IT #Informatics
#stat #ann #ann_dnn #machl
#math #math_linearAlgebra #math_discrete
#se #se_dia #se_ci #se_ee
#comm #net #www #web #http #html #mail #wireless
#circuit #embedded #os #db #db_relAlgebra #SQL
#bin #encoding #encoding_audio #encoding_image #encoding_video #encoding_text
#hpc #parallelism #distributed #simd #gpgpu #crypto
#pl #pl_plt #ce_vee #ce #ce_optimize #fp_monad #fp_proof #fp #oop #oop_arch #sp #parser
#algorithm #struct #lists #maps #sets
#security #security_lowlevel
#signalProc #nlp #phonetic
#cg #cg_dip #cg_3d #cg_2d #cg_lowlevel
#gui #gui_animation #gui_layouts #cli #visualization
duangsuse::Echo
Template.java.dia
总而言之,用 PDL(Program Design Language) 可以表示为:
#C
#Cplusplus
#PHP
#Ruby
#Lua
#VisualBasic (VB.NET)
#CSharp
fun main(argv)那么我就顺手再写个 C 的版本和 C++ 的版本和 PHP 的版本和 Ruby 的版本和 VisualBasic 的版本和 CSharp 的版本... 反正我还有很多事没做... 啊 😵
String? template = readFormatString();
String? formated = String.format(template.getOr { exit(EXIT_FAILURE); }, argv);
formated.let(stdout::println);
fun readFormatString()
File.Path fileName = getenv("TEMPLATE") ?: "template";
File templateFile = File(fileName);
unless file.exists and file.isFile: raise "File ${fileName} not found"
unless file.canRead: raise "File ${fileName}: cannot read"
FileInputStream is = null;
byte templateBytes;
begin /* readAll is into templateBytes */
templateBytes = new byte[is.available];
is = FileInputStream(templateFile);
is.read(templateBytes);
handle IOException rethrow
ensure is.close
return String(templateBytes);
#C
#Cplusplus
#PHP
#Ruby
#Lua
#VisualBasic (VB.NET)
#CSharp
#Kotlin #Java #Lua #design #cs
Delegate 呢,和
这就是咱漂亮的 Kotlin 对 Delegate 的支持(
负责的老师会告诉面向对象的程序是一群对象相互「发消息(message passing)」的过程,确实是这样;而且 OOP 的
Delegate 在你了解这个事实的时候很直白:它就是把某些方法(调用的"消息")从某个 receiver 上转移给另一个 receiver ,所以我们可以更灵活的利用面向对象的继承,甚至实现"多继承"…… 在上例里,
如果你利用 Delegate, 则可以完美解决上面用 Mixin 很麻烦的复用问题,定义一个需实现的接口(子集)即可 (而且
附赠另两个特色设计模式: Visitor 和 Reducer(非标准) #PLT #ce #OOP
经常写基于 Iterable<T> (map/fliter/sorted/zip/first/...) 的程序吗?那你应该听说过
Reducer 和 Fold 是另一个版本的 forEach: 假设你是要拿到序列的最大值/最小值(min/max),或者把它化为映射表(associate/groupBy),或者仅仅只是复制一份 List ,但不想写重复代码,你会怎么做?
以上操作或依赖一个可变量, 或是 MutableList 什么的。 他们的交集是,都依赖一个(变)量,且在
我写了泛用的
ParserKt 利用了这个设计模式,从而实现
流式编程是来自于函数式 #FP 的智慧,这可以视作它们广为人知的特色(自Lisp就有,地位类似OOP链式调用,不过有了 Kotlin 的 scope function (let/run/apply/also) 后我觉得 Builder 等设计模式要无地自容了😂,流式编程和 MapReduce 却越来越火,超过 LINQ 和 SQL ,嘿嘿),看看你听没听说过这些处理方法: flatMap(trans)/zipWithNext()/first(n)/takeWhile(predicate)/foldRight 。大体上分为 映射(map)/过滤(filterNotNull,first,takeWhile)/排序(sorted,reversed,shuffle)/组合(zip,zipWithNext,interleave)/归纳(fold/associate/flatten/maxBy) 五大类。
注: interleave/shuffle/flatten 应该是不太常见的用法, that's correct ,简单来说就是 交替流/乱序洗牌/铺平嵌套流
顺便一提:猜猜这个是什么:
但是
Delegate 呢,和
java.lang.reflect.Proxy
(方法调用拦截) 当然是有区别的啊,不过提到 reflect.Proxy
可能有助于对 Delegate 的形象理解。class MyDict(private val m: MutableMap<K, V> = mutableMapOf()): Map<K, V> by m
这就是咱漂亮的 Kotlin 对 Delegate 的支持(
T by m
) 里 T 是任意接口,它会代理其中的成员(从 this
)到 m
这个 receiver
上。负责的老师会告诉面向对象的程序是一群对象相互「发消息(message passing)」的过程,确实是这样;而且 OOP 的
this
(即receiver
引用, 或者说"主语") 使得我们以更自然的方法编程和划分代码块,不过发消息的确切说法是「驱使」或「属性访问」 (就是引用某个「主语」上的动词或名词)。Delegate 在你了解这个事实的时候很直白:它就是把某些方法(调用的"消息")从某个 receiver 上转移给另一个 receiver ,所以我们可以更灵活的利用面向对象的继承,甚至实现"多继承"…… 在上例里,
MutableMap
是个无构造器的类,但我们利用 Delegate 使它上的方法(get,set,remove,...) 通通可以访问了 (当然这个"子类型"并不兼容 mutableMapOf()
的实际类型,它是另一个继承自 Any
的新类型,但如果有 m
实现了的 interface 则其方法皆可被代理,这才是"代理"存在的意义)如果你利用 Delegate, 则可以完美解决上面用 Mixin 很麻烦的复用问题,定义一个需实现的接口(子集)即可 (而且
AnimalBoilerplate
也可以使用 this 外的变量, 同时不局限于访问某 interface 了)。 附赠另两个特色设计模式: Visitor 和 Reducer(非标准) #PLT #ce #OOP
经常写基于 Iterable<T> (map/fliter/sorted/zip/first/...) 的程序吗?那你应该听说过
java.util.stream.Collector
:import java.util.stream.*我最讨厌 Java 的一点就是它废话太多了,聒噪。仔细看 Collector 里有什么?
Stream.of(1, 2).map { it + 1 }.collect(Collectors.asList())
supplier; accumulator:BiConsumer; combiner:BinOperator; finisher
,这就是所谓的 "architect" 到处弄 XXX er/or 的对象,不懂得沉默是金、混淆组合(combine)流与普通映射/过滤流、没有复用 Collection 而是用了所谓的 finisher,咱才懒得看它呢。Reducer 和 Fold 是另一个版本的 forEach: 假设你是要拿到序列的最大值/最小值(min/max),或者把它化为映射表(associate/groupBy),或者仅仅只是复制一份 List ,但不想写重复代码,你会怎么做?
val xs = listOf(1, 2, 3)等价这个"折叠"循环:
xs.reduce { a, b -> kotlin.math.max(a, b) } // 3
var acc=xs[0]; xs.indices.drop(1).forEach { acc = kotlin.math.max(acc, it) }; acc
当然如果是求和的话,也可以不要求列表至少存1项: xs.fold(0) { a, b -> a+b }
fold
操作往往比 reduce
更实用(如 xs.fold(StringBuilder(), op)
),如果我们把他们结合起来变成对象呢?就成了 Fold/Reducer 。这名词是我自造的 😗以上操作或依赖一个可变量, 或是 MutableList 什么的。 他们的交集是,都依赖一个(变)量,且在
<T>
流结束的时候,返回结果类型 <R>
,所以必须建模为对象,因为它要构造并持有一个状态并且在 accept(T)
时更新此状态。我写了泛用的
ConvertReducer<T,R>
和 ModifyReducer<T,A>
两个基类,因为这不是标准设计模式我不赘述,有兴趣找我的代码看,Fold 是 () -> Reducer
(R.的构造器类型)。ParserKt 利用了这个设计模式,从而实现
Repeat(asList()/*asInt(radix=10), asMap,joinAsString...*/, digit)
这种方便的定义式单项构造。流式编程是来自于函数式 #FP 的智慧,这可以视作它们广为人知的特色(自Lisp就有,地位类似OOP链式调用,不过有了 Kotlin 的 scope function (let/run/apply/also) 后我觉得 Builder 等设计模式要无地自容了😂,流式编程和 MapReduce 却越来越火,超过 LINQ 和 SQL ,嘿嘿),看看你听没听说过这些处理方法: flatMap(trans)/zipWithNext()/first(n)/takeWhile(predicate)/foldRight 。大体上分为 映射(map)/过滤(filterNotNull,first,takeWhile)/排序(sorted,reversed,shuffle)/组合(zip,zipWithNext,interleave)/归纳(fold/associate/flatten/maxBy) 五大类。
注: interleave/shuffle/flatten 应该是不太常见的用法, that's correct ,简单来说就是 交替流/乱序洗牌/铺平嵌套流
顺便一提:猜猜这个是什么:
def zipPairs(xs): return zip(xs[0::2], xs[1::2])
。当然这么简单定义不了 zipWithNext, 它和 fold (的累积变量)系出同门... 😂但是
zipWithNext = lambda xs: zip(xs, xs[1:])
我们仍没有用到重赋值,这证明了函数式的组合表现力,的确应该更新观念了。" and ".join([f"{a} < {b}" for (a,b) in zipWithNext("1 2 3".split(" "))]) #'1 < 2 and 2 < 3'很有趣不是吗? 定义式的代码,根本无需数学化的简写语法(点名批评 Py 的 slice)来保持他它们的易读性,这也是 Kotlin 的一大特色。
duangsuse::Echo
#learn #PL #CS 首先引出问题,什么是操作符链(中缀链) 1+2*3; 1*2+3 ,它们可以被简单理解为以 +-*/ 运算符(操作符)分割的单项 但其实不然,用形式化文法(以『左递归』)应当是这样: Atom = [0-9]* | "("Expr")" | "-"Expr Expr1 = Atom "*"/"/" Atom Expr = Expr1 "+"/"-" Expr1 上面,我们定义了『表达式』和『基元(Atom)』两项,我们以 Expr, Expr1 区分了加减法、乘除法的优先级 …
🤔 理解了 #Lua 的做法后,我对「精雕细琢」这个词也有了新的领悟。 一个看起来完全不相关的算法,竟然可以拿来优化,真是妙不可言……
#China #tech 🌚 脸红不? 2021 还不会写 ANSI C 编译器的同学们(
https://blog.csdn.net/myan/article/details/490 《Lua让我脸红》
Python是荷兰人写的,Ruby是日本人写的, #Lua 是巴西人写的,我这个中国人只能在这里脸红。
“ 我1996年就学会了C,1997年就跑去研究Win32 API,后来是C++,STL,Java... 直到2002年看到C Interfaces and Implementations,才知道仅仅用ANSI C就可以实现一个强大的优美的library,直到2004年看到Lua的源代码才知道仅仅用ANSI C就可以实现一个非常快的虚拟机、非常棒的解释器/编译器和非常漂亮的语言实现。
但是,看完这条的第一个链接你就毁会了 🌝(跑,但这篇文章的确精炼而且 practical
https://blog.csdn.net/myan/article/details/490 《Lua让我脸红》
Python是荷兰人写的,Ruby是日本人写的, #Lua 是巴西人写的,我这个中国人只能在这里脸红。
“ 我1996年就学会了C,1997年就跑去研究Win32 API,后来是C++,STL,Java... 直到2002年看到C Interfaces and Implementations,才知道仅仅用ANSI C就可以实现一个强大的优美的library,直到2004年看到Lua的源代码才知道仅仅用ANSI C就可以实现一个非常快的虚拟机、非常棒的解释器/编译器和非常漂亮的语言实现。
但是,看完这条的第一个链接你就
#js #DontKnow 原型链:(感谢 @JackWorks 提供相关信息)
访问语法都是动态解析的,比如
- 普通对象 [规范]
-
- 类数组对象(数组的特殊行为就在这里)
- 模块对象(
-
此外,
原来是往 proto 上找属性!
这就解释了
因为在这个算法里你可以看到,Receiver 是跟着递归一路传递下去的
原来是
本地如果有就不会查 prototype 了
明白了,和之前写的 LuaOOP 很像,都是层叠属性查找
“ 大佬能交换下原型链相关知识吗
之前看加 Mixin 好像是说把 prototype 除了哪两个属性的什么全部复制一下
#Python 和 #Ruby 的情况我都了解, Py 是 mro() 链查询,
https://paste.ubuntu.com/p/tJv7QpSjGt/ liuil-util 的 #TypeScript mixin.ts 重写
访问语法都是动态解析的,比如
x.prop
或 x["prop"]就是
x.[[Get]]("prop", x)ES 里一共有五种不同的
[[Get]]
实现,分别是- 普通对象 [规范]
-
Argument
对象(你们今天应该不会用到了)- 类数组对象(数组的特殊行为就在这里)
- 模块对象(
import * as Mod
里的 Mod
)-
Proxy
对象(reflect proxy 全 delegate)此外,
Object.getOwnPropertyDescriptor(o, k)
可以获取可配置 enumerable, writeable 等属性的配置对象Object.[get/set]PrototypeOf(o)和
o.__proto__
是它的「超类虚表」[[Get]]
过程的 Receiver (第二参数)很重要,如果没有这个 Receiver,基于原型链的 OOP 其实是做不起来的原来是往 proto 上找属性!
这就解释了
Array.prototype.map
之类的东西parent = { method() { return this; } }最简单的解释是, Receiver 就是属性访问的时候最上层的那个对象,会被当成
child = {}; child.__proto__ = parent;
child.a = 1; child.method(); // 返回自身
this
用。因为在这个算法里你可以看到,Receiver 是跟着递归一路传递下去的
原来是
o["RESOLVE"](o.prototype, "attr", receiver=o)
!(当然,肯定是先查本地,然后才查 prototype本地如果有就不会查 prototype 了
明白了,和之前写的 LuaOOP 很像,都是层叠属性查找
“ 大佬能交换下原型链相关知识吗
之前看加 Mixin 好像是说把 prototype 除了哪两个属性的什么全部复制一下
#Python 和 #Ruby 的情况我都了解, Py 是 mro() 链查询,
A.wtf
和 a.wtf
都是往 class A 找成员,后者实质是 type(a).wtf(a)
所以得到 bound method ,而直接 A.wtf
就是 bind 操作@staticmethod
直接不收 self ,不需要 bound 所以可以在类和实例上用https://paste.ubuntu.com/p/tJv7QpSjGt/ liuil-util 的 #TypeScript mixin.ts 重写
Telegram
duangsuse::Echo
#Lua #oop #PL 🤔刚才体验写标准Android之前又把 LuaOOP 默写了一遍,构造器调用子类优先了,重写后果然感觉优化了不少(也提升了效率编程自信心)
duangsuse::Echo
https://tttttt.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://tttttt.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://tttttt.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
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://tttttt.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://tttttt.me/dsuses/4769
GitHub
fengberd/xLuaDumper
Load xlua.dll and corresponding lua5X.dll to dump luac for a script - fengberd/xLuaDumper
duangsuse::Echo
刚才写了一大篇都是理论,也是因为我低估了问题的麻烦度在手机上写了大半天…… 🙊 确实测试还是需要的。 嘛,除了 luac wtf.lua 其实也可以这样拿到字节码去对照(毕竟 liblua 是带 luaC_ luaU_ 编译器的,刚刚也说了 lua luac 只是 CLI 前端, liblua 才是本体) 也是我一开始就没从要逆向谁的应用的角度来想🌝,没去研究不用 luac 怎么得字节码。 可方便了 过会我也不会提供魔改反编译器或者 .luac 文件的辅助程序什么的,正确的做法是魔改 unluac 扩展支持加载…
https://gist.github.com/duangsuse/90366621af2d206867496f7eb1e42438#file-shuf_opcode-py
好耶,我又重写了能自动生成 Lua 指令集重排的 py 脚本,这次 0 ambiguous 达成 😋
话说 #Lua 支持 load/do file/string 和 require/loadlib/load ,这么多字节码/eval类 API 呢
好耶,我又重写了能自动生成 Lua 指令集重排的 py 脚本,这次 0 ambiguous 达成 😋
话说 #Lua 支持 load/do file/string 和 require/loadlib/load ,这么多字节码/eval类 API 呢
Gist
Lua Opcode reordering and its analysics
Lua Opcode reordering and its analysics. GitHub Gist: instantly share code, notes, and snippets.
Forwarded from 依云的技术资源分享
> https://tttttt.me/dsuse/1064
https://bellard.org/otcc/otccn.c 是tccboot所用JIT编译的最简版
呃.. 第一次见到 wiki 编辑战
小时候(高中) 很喜欢 #mozilla #Rust ,还写了这个(列表处理)程序
大概就是暗暗觉得……高性能又开源(根正描红的那种,练习时长两年半只为开源语言,太感人了)
后来看的就淡了,因为rust真的很(烧脑?)
—
我觉得能和 C FFI 的某种意义上都是系统,比如 py 的嵌入式GPIO libs
.Net 有P/Invoke和struct{}, 栈分配 啊,他们可能觉得入选 osdev.wiki 才叫系统编程
无非就是FFI和struct指针的问题,既然 py (cffi能读写指针), .Net unsafe marshall 支持二进制,也是能实现OSkrnl的需求
但KN 不是,因为强类型强检查 弱框架,写着麻烦
系统级就是你可以用来写内核和驱动
这个 lunatik 能在内核层开启 #Lua REPL
这个 https://duskos.org/#operator 类似 tccboot, 但是嵌入式的
https://bellard.org/otcc/otccn.c 是tccboot所用JIT编译的最简版
呃.. 第一次见到 wiki 编辑战
小时候(高中) 很喜欢 #mozilla #Rust ,还写了这个(列表处理)程序
大概就是暗暗觉得……高性能又开源(根正描红的那种,练习时长两年半只为开源语言,太感人了)
后来看的就淡了,因为rust真的很(烧脑?)
—
我觉得能和 C FFI 的某种意义上都是系统,比如 py 的嵌入式GPIO libs
.Net 有P/Invoke和struct{}, 栈分配 啊,他们可能觉得入选 osdev.wiki 才叫系统编程
无非就是FFI和struct指针的问题,既然 py (cffi能读写指针), .Net unsafe marshall 支持二进制,也是能实现OSkrnl的需求
但KN 不是,因为强类型强检查 弱框架,写着麻烦
系统级就是你可以用来写内核和驱动
这个 lunatik 能在内核层开启 #Lua REPL
这个 https://duskos.org/#operator 类似 tccboot, 但是嵌入式的
Telegram
duangsuse::Echo
TCC还有一个编译Linux到内存然后直接跑起来的buff( 还没有编译过Linux内核的咸鱼们可以来体验一下廉价的内核编译 ~~虽然是全自动的~~.
只需一TCCBOOT, 一64MiB内存 x86机, 大约1s的二十倍时间即可体验.
TCC is distributed under the GNU Lesser General Public License.
tar -xf qemu_tccboot.tar.gz&&qemu-system-i386 -kernel tccboot -initrd…
只需一TCCBOOT, 一64MiB内存 x86机, 大约1s的二十倍时间即可体验.
TCC is distributed under the GNU Lesser General Public License.
tar -xf qemu_tccboot.tar.gz&&qemu-system-i386 -kernel tccboot -initrd…
❤2
duangsuse::Echo
😍 pip install 的rich进度条真的太酷了,怎么就没人把它移植给下载管理器呢?? 同理,bash-completions 其实是包维护者手动弄的, 可是 shell param 就两种模式,GNU甚至连git init这种调用链式都不会搞 这个完全可根据 cli -h 自动生成 bash的开发者也不懂事,list complete 应该用 ./a.sh '-s*' 的形式来查询,这样用户和中间商也能沾点光,而且非常UNIX。 分成什么补齐脚本简直画蛇添足 可能它们在写python里自带的功能,还是太忙了。…