萌新只會搞定一些特別簡單的花指令,而且還得靈光一閃才搞的定,今天來具體學習一下花指令相關內容
概念
花指令(或者叫臟字節)是企圖隱藏掉不想被逆向工程的代碼塊(或其它功能)的一種方法,在真實代碼中插入一些垃圾代碼的同時還保證原有程序的正確執行,而程序無法很好地反編譯, 難以理解程序內容,達到混淆視聽的效果。
簡單花指令及其原理
用ida舉例吧。我們用ida打開一個程序
我們看到,里面有代碼,有數據塊這些東西
但實際上,這並不是程序本身的樣子,我們可以選中一些代碼,按快捷鍵u(Undefined,取消定義)
這些代碼會變成一堆十六進制的單字節的數據,這才是程序本身的樣子
ida本身並不能區分什么是代碼什么是數據,它是通過某種算法來分析出一堆數據組合在一起是什么代碼。
讓這種分析算法出錯的最簡單的方法,就是花指令。
例如,下列匯編指令中,0xE8就是一個簡單花指令
addr:
push ebp
jz addr2
jnz addr2
db 0xE8
addr3:
sub esp, 0x100
add eax, 0x1
sub ebx, 0xAFBC11
addr2:
mov ebp, esp
jmp addr3
這種花指令的作用可以通過前面第一張圖片看到(第二張圖片可以看到里面插入了幾個E8,效果和這串代碼是一樣的):
- 出現了一坨紅色的、IDA分析不出來的數據(或者說,已經被錯誤分析的數據)
- 紅色的玩意后面,有一些數據沒有被分析成代碼,變成了一個數據塊,IDA認為他只是普通的數據
這就是花指令的作用
我們來分析上面那串代碼
jz是結果為0就跳轉,jnz是結果不為0就跳轉,可以看成是if語句的2種分支
那一個條件只有真假兩種狀態,也就是說,不管條件如何,這里都會跳轉到addr2,那么,db 0xE8
這段東西就沒有卵用
但是,E8是call的機器碼,那么IDA會認為:如果不會jz/jnz跳轉的話,call(E8)就會使程序跳轉到一個新地址。這個地址就是下面的機器碼。
ida分析到jnz時會認為:如果他為0就不會跳轉了,但是事實上為0的時候會在jz跳轉,但是ida的算法處理不了這種情況
這串代碼中,ida會認為sub esp的一部分值是call的跳轉地址,此時就會出現如上方紅色數據的異常(根本沒有紅色數據這個地址)
然而,如果出題人經過精心設計,讓E8后的機器碼變成一個存在的地址,那么ida是不會報錯的。
這時我們就要這樣分析:例如上面那個紅色數據的地址是0x40101A,但是所有的call調用這個地址的時候都不是直接用0x40101A,而是諸如0x401019+1或者0x401018+2這種玩意,那么這里大概率有一個花指令。
這種花指令的應對方法就是按u
我們會看到一個XREF(非自然程序流程,可以用它對程序流進行跟蹤和控制,估計以后有的學了),關注到這一行,忽略掉上一行,選中XREF及之后沒有被分析的數據,然后按C轉換成代碼
這里優先用Analyze模式,如果Analyze分析錯了的話再用Force
這樣就恢復到了正常狀態。
另:這種花指令直接看匯編動調其實可以直接繞過去。
sp/esp analysis failed
IDA分析時,需要確認“代碼塊”和“數據塊”,並把代碼塊分析為函數
但是,這種分析過程需要對esp寄存器進行追蹤,一旦追蹤失敗便會報錯sp/esp analysis failed
一個簡單的概念:ret和jmp操作可以修改程序的執行流。ret是通過esp的指向來進行修改的,jmp是直接通過其后面的數字進行修改的。那么可以通過一些操作來讓ret當做jmp使用
比如這種main函數,你F5按壞了也不會反匯編成代碼
這個是源碼
#include <stdio.h>
#include <stdbool.h>
#pragma warning(disable:4996)
#include <stdlib.h>
void func1()
{
__asm
{
lea eax, lab1;
call eax;
db 0xE8;
lab1:
}
printf("func1\n");
}
void func2()
{
__asm
{
cmp eax, ecx;
jnz lab1;
jz lab1;
db 0xB8
lab1:
}
printf("func2\n");
}
這里我們用到了__asm代碼塊,簡單的說,這種內聯匯編的使用會讓ida錯誤地認為這里出現了函數嵌套函數的情況,導致不能用F5轉化為代碼。
這種情況下,我們關注一下有沒有紅色字體的XREF, 如果有的話再看看這種紅色字附近有沒有jz&jnz
上圖可以看到jnz short near ptr loc_40107E+1
和jz short near ptr loc_40107E+1
那我們找到地址40107E,然后按u
順便,我們還會發現:loc_40107E+1的+1沒了,變成了函數unk_40107F
然后從有XREF的這一行選中下面所有數據按C,首選Analyze,沒用再選Force
然后發現還真沒用,但是對這個奇怪的數據再按一下c
就沒問題了
腳本去除花指令
剛好大爹說暫時沒必要學,那充分必要地摸了(