去花
新手时复现花指令很少见师傅放源码,其实对比观察源码就很清楚了,本质就是去除多余opcode,亲自动手写一遍再逆向感觉是完全不一样的。
源码如下
第三处
类似smc吧,一开始想整活但嫌麻烦,先加密再去加的花,所以不做太大改动,原理就是静态时是E9 jmp指令,运行后xor成5个nop,不影响程序流执行

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| static inline void* page_align(void *addr) { size_t page_size = getpagesize(); return (void*)((uintptr_t)addr & ~(page_size - 1)); }
void flower_with_addr(void *junk_addr) { void *page = page_align(junk_addr); size_t page_size = getpagesize();
if (mprotect(page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); return; }
uint8_t key[] = {0x79, 0x81, 0xd5, 0x84, 0x89}; for (int i = 0; i < 5; i++) { ((uint8_t*)junk_addr)[i] ^= key[i]; }
mprotect(page, page_size, PROT_READ | PROT_EXEC); }
void *junk_addr = &&junk_label; flower_with_addr(junk_addr); junk_label: __asm__ volatile ( ".byte 0xe9 \n\t" ".byte 0x11 \n\t" ".byte 0x45 \n\t" ".byte 0x14 \n\t" ".byte 0x19 \n\t" ::: "memory" );
|
第一处
标准jz/jnz

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| __asm__ volatile ( "pushq %%rbx \n\t" "xorq %%rbx, %%rbx \n\t" "testq %%rbx, %%rbx \n\t" "jnz 1f \n\t" "jz 2f \n\t"
"1: \n\t" ".byte 0xe9 \n\t"
"2: \n\t" "popq %%rbx \n\t" : : : "rbx", "memory" );
|
第二处
call+retn,rsp具体加的值根据opcode计算其实很明显

1 2 3 4 5 6 7 8 9 10 11 12
| __asm__ volatile ( "call 1f \n\t" ".byte 0x83 \n\t" "1: \n\t" "addq $8, (%%rsp) \n\t" "ret \n\t" ".byte 0xf3 \n\t" : : : "memory" );
|
解密
salsa20+aes_ecb无魔改
中间加了简单的倒序xor处理去除一些内容特征

eg.cyber_chef

eg.code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import binascii import struct from Crypto.Cipher import AES,Salsa20
hoge=bytes.fromhex('59cc9e17b97199cad788f5f9d919531ee9f09bb233b5565233aef1de39a1d6635237703c819d47cf9ca5c53ca8adcdec') aes_key=b"venom2025venom25" cipher_aes=AES.new(aes_key, AES.MODE_ECB) pad=cipher_aes.decrypt(hoge) pad_len=pad[-1]
enc_tmp=pad[:-pad_len]
nonce=b'salsa_iv' salsa_key=bytes.fromhex('0ff71ec39a5d322709b6b2e93796e5150ff71ec39a5d322709b6b2e93796e515') cipher_salsa=Salsa20.new(key=salsa_key,nonce=nonce) flag=cipher_salsa.decrypt(enc_tmp) print(flag.decode())
|