duangsuse::Echo
附上滑稽一只
事前,我在 Radare2 里
新的 liba 多使用了一个
链接多链了一个 liblog,之前的是 libstdc++、libc、libm、libdl
逻辑上的确有区别,不知道现在服务器认哪个,反正我弄最新的那一个
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 效果远远没有那么好,只能减小工作量,比之前强的是现在能通过编译了...
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 -fPICf = package.loadlib('./a.out', 'BEL')
ld liba.so.o -lc -shared -o liba.so
f(0)
Segmentation fault
不错。不错。
其实 RetDec 分析出 C 语言的结果还不如 radare2 的清晰... 真的
Radare2 使你可以自底向上地重写出程序,而目前阶段 RD 的准确度只能用于辅助分析而已... 连方法签名分析好都难呢...
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 函数,成功了就睡觉...唉
(主要还是想让程序能运行起来... 成天和 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],这种看起来根本对不齐一个字的操作到底有什么意义...
duangsuse::Echo
曾经书本上复杂、晦涩难懂的知识对我来说已经不是黑盒。我曾经购买的十多本书里再也没有一行完全看不懂的内容。 原先根本看不懂的什么位长度、什么半字双字缓冲器已经成为日常。 原先一个原生 .so(SharedObject 共享对象)就是“无法理解”的黑盒,现在 x86 机器码根本不是问题、远程 GDB 调试和高等 GDB 功能也不是问题 原先连 Java 的 OOP 类型系统自动子类自动转型基类都无法理解,现在理解整个 Java 类型系统已经不是问题 第一个黑历史 Android 应用 MinBase64 到现在,我却已经记住了…
不,非常黑箱,情况没有好半点,还是很黑箱。凭什么编译器知道我不知道。
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
使用逆波兰法表示
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 到底做了什么
当然位运算就更不可能看到本质了... 就不能逆向而理解呢
因为这次实在是太失败了,但我对这种极端干扰生活的情况很绝望,,, 因为足足一晚上没合眼,而且早上也没吃饭
希望以后能做到吧,虽然都还不熟悉呢... 太菜了啊... 现在居然连最基本的都弄不懂... 看不到运行时 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
如果说开始
x86 里怎么会莫名其妙栈上分配一个字又一个半字的数据呢...
... 而
我拿 NASM 重写了代码然后上 edb 逐 step 调试,结果好像证明它的确需要一个指针(
RetDec 反编译的全是错的,它根本没有注意到这个函数不是无参的,还不如 radare2 提示的类型正确... 看来还是上动态分析可选
mov eax, [ebp - 8] 这种可以理解为分配 retAddress(当然其实不是,我误会了),那后来... 我中间有段时间在想是不是在传指针解引用,但传入的参数分明不是指针...mov ecx, [eax - 2] 这种又是什么鬼啊,这不是 x86 么,32 位啊,根本不应该出现这种一个栈帧占 10 字节的情况么... 它不是 2 的幂啊...x86 里怎么会莫名其妙栈上分配一个字又一个半字的数据呢...
... 而
[eax - 4] 这种我还可以理解,这种毫无逻辑的分配是什么意思啊...我拿 NASM 重写了代码然后上 edb 逐 step 调试,结果好像证明它的确需要一个指针(
ebp - 8 是第一个数值参数,然后它解指针这个参数),可是我当时测试的时候给的真的不是指针啊... 是直接传值调用的啊...RetDec 反编译的全是错的,它根本没有注意到这个函数不是无参的,还不如 radare2 提示的类型正确... 看来还是上动态分析可选