C++逆向 可變引數Hook
0x00 前言:
我們在做逆向分析的時候,經常會需要去Hook一個程式的日誌輸出函式。
而這種日誌輸出函式一般引數都不確定,這就會引起一個問題。我們如何知道引數個數?如何知道他有哪些引數呢?
0x01 C++可變引數:
可變引數簡介
在C++中,可變引數的函式定義可以寫成如下格式。用...
來宣告可變引數。
void test(int a,int b,...)
{
//Code...
}
在呼叫可變引數的函式時,可以在後面不斷新增引數,例如。
test(1,2,3,4,5,"hello","test",6);
可變引數程式碼實戰
那麼迴歸正題,test函式裡如何知道它傳進來的後面所有引數個數呢?
這就需要用到stdarg.h
標頭檔案中的幾個關鍵字了va_list
、va_start
、va_end
。
#include <stdio.h>
#include <stdarg.h>
void test(int a,int b,...)
{
va_list arg_ptr;//定義可變引數指標
va_start(arg_ptr,b); //b為最後一個固定引數
printf("Address = %p",arg_ptr);//將arg_ptr的地址進行輸出。
va_end(arg_ptr); //清空可變引數指標
}
int main(int argc,char *argv[])
{
test(1,2,3,4,5,"hello","test,6");
}
- 首先va_list定義了一個可變引數的指標。
- va_start函式傳入,可變引數指標和最後一個固定引數,傳出引用可變引數指標。
- 輸出可變引數指標地址。
- 清空可變引數指標記憶體空間。
0x02 逆向分析C++可變引數原理
將上面的程式碼用VC6編譯出來後進行除錯分析。
找到特徵。
在彙編程式碼中,定位到main函式。
接著在彙編處call va_arg.401005
處下一個斷點。可以看到他將引數一個個push到了堆疊中。
接著按F7
跟入test
函式。
通過對彙編程式碼的分析,我大概知道了va_start函式()
為什麼要將最後一個固定引數傳入。因為他需要用最後一個固定引數在堆疊中進行偏移的計算,計算出可變引數的地址。
遍歷該堆疊,當遍歷到的值是入口點,說明可變引數已經遍歷完成。
0x03 printf Hook實戰
這裡我隨便選了一個系統的可變引數函式,printf
可以將格式化後的字串進行輸出,符合我們可變引數函式的要求。
Pwn菜雞學習小分隊
歡迎加入探討 逆向知識和PWN