duangsuse::Echo
717 subscribers
4.26K photos
130 videos
583 files
6.48K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
duangsuse::Echo
https://i.loli.net/2018/12/16/5c1565fa5d184.jpg
##Moha #Haha #School #life 🐸 全部生命续给江主席!(暴力)
duangsuse::Echo
附上滑稽一只
事前,我在 Radare2 里 ia 了一下看看最新的 liba 和老的 liba 有什么区别,就 size 来比较其实没有多大区别

新的 liba 多使用了一个 strcmp 函数
getAS JNI 导出也比之前的体积 1303 增加到了 1988

链接多链了一个 liblog,之前的是 libstdc++、libc、libm、libdl

iE 导出其他的没有多大变化

逻辑上的确有区别,不知道现在服务器认哪个,反正我弄最新的那一个
duangsuse::Echo
探索出了能用的公式,实现了 liba.so!BEL (int BEL(int n))
这次他们的确做了包名检验,不过,我目前还是逆向新手... 暂时没有特别的能力看出执行时实际的东西,但是逻辑我都大致看得出来

RetDec 效果远远没有那么好,只能减小工作量,比之前强的是现在能通过编译了...
duangsuse::Echo
def CoolApk::Token.bel(n) (4 * (n - 1) / 3 | 3) + 2 end
收了一个 Lua 32 位版本用来测试是否正确实现算法逻辑,不必要的逻辑诸如签名校验和包名校验都去掉
gcc -c liba.so.c -D__asm_rep_movsd_memcpy=memcpy -fPIC
ld liba.so.o -lc -shared -o liba.so

f = package.loadlib('./a.out', 'BEL')
f(0)
Segmentation fault
不错。不错。

其实 RetDec 分析出 C 语言的结果还不如 radare2 的清晰... 真的
Radare2 使你可以自底向上地重写出程序,而目前阶段 RD 的准确度只能用于辅助分析而已... 连方法签名分析好都难呢...
#Lua #build #sysadmin

刚才我编译 32 位的 Lua(为了测试正确性)

有 multilib 的话直接给 CFLAGS 和 LDFLAGS 加上 -m32 即可
可是说 ld 找不到 -lreadline...
我临时的解决方案是不使用 -lreadline,找到 relocable 后手动添加 file /usr/lib/libreadline.so.7.0

编译成功
要还原的(新的 DLL)
https://wiki.alpinelinux.org/wiki/Installing_Alpine_Linux_in_a_chroot #Sysadmin 正在准备新的 Alpine #Linux X86 Chroot 容器....

LD_LIBRARY_PATH=`pwd`/alpine-minirootfs-3.8.1-x86/usr/lib:`pwd`/alpine-minirootfs-3.8.1-x86/lib /lib/ld-linux.so.2 ./alpine-minirootfs-3.8.1-x86/usr/bin/lua5.1

我居然用上了容器里的 Lua5.1...
duangsuse::Echo
Photo
...因为的确已经熬了一夜了,而且这些的确是首先以学习为主...
(主要还是想让程序能运行起来... 成天和 linker、relocatable、shared object、静态链接动态链接杠... 我真的不想熬夜啊...
我决定再重新逆向 BEL 函数,成功了就睡觉...唉
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
...因为的确已经熬了一夜了,而且这些的确是首先以学习为主... (主要还是想让程序能运行起来... 成天和 linker、relocatable、shared object、静态链接动态链接杠... 我真的不想熬夜啊... 我决定再重新逆向 BEL 函数,成功了就睡觉...唉
function BEL() {
push ebp; ebp = esp

eax = dword [ebp + 0x8]
ecx = [eax + 2]

edx = 0x55555556
eax = ecx

eax = edx = eax * edx ; imul edx

eax = ecx

eax >>= 0x1f ; sar eax, 0x1f
edx -= eax
eax = edx
eax <<<= 2 ; shl eax, 2
eax += 1 ; add eax, 1
}
foo.tar
10 KB
非常失败,我根本不知道为什么要先 mov eax, [ebp + 8]mov ecx, [eax + 2],这种看起来根本对不齐一个字的操作到底有什么意义...
#sysadmin #Assembly #reveng #failure #life

算是体验了一下 NASM 和 x86_64 交叉 x86,此外,没有别的。
弄出等价的后可以看看是如何优化的
duangsuse::Echo
function BEL() { push ebp; ebp = esp eax = dword [ebp + 0x8] ecx = [eax + 2] edx = 0x55555556 eax = ecx eax = edx = eax * edx ; imul edx eax = ecx eax >>= 0x1f ; sar eax, 0x1f edx -= eax eax = edx eax <<<= 2 ; shl eax, 2 eax…
int BEL(int n) { return (4 * (n - 1) / 3 | 3) + 2; }

使用逆波兰法表示

bel
(n) = ((n-1) * 4 / 3) | 3 + 3

ldarg.0
ldint 1
dec ; n - 1
ldint 4
mul ; (n - 1) * 4
ldint 3
div ; (n - 1) * 4 / 3
ldint 3
or.bitwise ; |3
ldint 3
add ; + 3

function BEL (edi: int n) {
push rbp; rbp = rsp

dword [local_i32] = edi
eax = dword [local_4h]
eax -= 1 ; (n - 1)
ecx = [rax*4] (n - 1) * 4

; / 3 + 1
edx = 0x55555556
eax = ecx
eax = eax * edx
eax = ecx
eax >>= 0x1f
edx -= eax
eax = edx

; | 3
eax |= 3

; + 2
eax += 2

return 2
}
duangsuse::Echo
int BEL(int n) { return (4 * (n - 1) / 3 | 3) + 2; } 使用逆波兰法表示 bel(n) = ((n-1) * 4 / 3) | 3 + 3 ldarg.0 ldint 1 dec ; n - 1 ldint 4 mul ; (n - 1) * 4 ldint 3 div ; (n - 1) * 4 / 3 ldint 3 or.bitwise ; |3 ldint 3 add ; + 3 function BEL (edi: int n) { push…
#Ruby 中也可以模拟

因为这次实在是太失败了,但我对这种极端干扰生活的情况很绝望,,, 因为足足一晚上没合眼,而且早上也没吃饭
希望以后能做到吧,虽然都还不熟悉呢... 太菜了啊... 现在居然连最基本的都弄不懂... 看不到运行时 esp、ebp 到底做了什么
当然位运算就更不可能看到本质了... 就不能逆向而理解呢

class Stack
def initialize(stack = [])
@fifo = stack
end
def ld(o); @fifo << o; end
def pop; @fifo.pop; end
def peek; @fifo.last; end
def size; @fifo.size; end
def to_s; @fifo.to_s; end
def eql?(o); @fifo.eql?(o); end
def <<(o); ld o; end
end

def Stack.mk_binary_op(name, &operator)
define_method(name) do
op2 = pop; op1 = pop
ld operator.call(op1, op2)
end
end

class Stack
mk_binary_op :sub, &:-
mk_binary_op :add, &:+
mk_binary_op :mul, &:*
mk_binary_op :div, &:/
mk_binary_op :bitwise_or, &:|
end


然后看主程序

def stack_bel(n)
s = Stack.new
s << 4 << n << 1
s.sub
s.mul
s << 3
s.div
s << 3
s.bitwise_or
s << 2
s.add
return s.pop
end

1000.times { |i| print stack_bel(i); print ' ' }
Forwarded from dnaugsuz
如果说开始 mov eax, [ebp - 8] 这种可以理解为分配 retAddress(当然其实不是,我误会了),那后来... 我中间有段时间在想是不是在传指针解引用,但传入的参数分明不是指针...

mov ecx, [eax - 2] 这种又是什么鬼啊,这不是 x86 么,32 位啊,根本不应该出现这种一个栈帧占 10 字节的情况么... 它不是 2 的幂啊...

x86 里怎么会莫名其妙栈上分配一个字又一个半字的数据呢...
... 而 [eax - 4] 这种我还可以理解,这种毫无逻辑的分配是什么意思啊...

我拿 NASM 重写了代码然后上 edb 逐 step 调试,结果好像证明它的确需要一个指针(ebp - 8 是第一个数值参数,然后它解指针这个参数),可是我当时测试的时候给的真的不是指针啊... 是直接传值调用的啊...
RetDec 反编译的全是错的,它根本没有注意到这个函数不是无参的,还不如 radare2 提示的类型正确... 看来还是上动态分析可选