歡迎來到 黑吧安全網 聚焦網絡安全前沿資訊,精華內容,交流技術心得!

使用unicorn engin還原Armariris字符串混淆

來源:本站整理 作者:佚名 時間:2019-06-26 TAG: 我要投稿

編譯Armariris
git clone [email protected]:gossip-sjtu/Armariris.git
編譯
cd Armariris
mkdir build
cd build
cmake ../ -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="ARM;X86;AArch64"
make -j8
測試文件內容如下:
#include
void fun(){
    printf("test 3333\n");
}
int main(int argc, char *argv[]) {
    printf("test 1111\n");
    printf("test 2222\n");
    fun();
    return 0;
}
使用編譯好的llvm編譯這個測試的文件
clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -mllvm -sobf test.c -o test
使用isysroot指定sdk,然后使用-mllvm -sobf開啟字符串混淆
 
Armariris是如何進行字符串混淆的
我們直接看使用ida反匯編出來的代碼
int __cdecl main(int argc, const char **argv, const char **envp)
{
  printf(aRcur7777, argv, envp);
  printf(&byte_100001036);
  fun();
  return 0;
}
可以看到有兩個printf函數打印了一些數據出來,我們點第一個打印的字符串,雙擊aRcur7777跳轉到 字符串定義位置,這個字符串在data段

這個字符串我們本來輸出的是test 1111這里顯然不是,我們查看aRcur7777的交叉引用,發現兩處, 其中一處是main函數中的printf,另一處應該就是還原這個字符串的位置了

所以__datadiv_decode14953400483976599729這個函數就是還原這個字符的函數,我們看他是如何做的還原 。跳轉過去按F5反編譯,得到的結果如下:
__int64 datadiv_decode14953400483976599729()
{
  bool v0; // ST23_1
  bool v1; // ST17_1
  __int64 result; // rax
  bool v3; // ST0B_1
  unsigned int v4; // [rsp+8h] [rbp-1Ch]
  unsigned int v5; // [rsp+14h] [rbp-10h]
  unsigned int v6; // [rsp+20h] [rbp-4h]
  v6 = 0;
  do
  {
    aLKl[v6] ^= 0x38u;
    v0 = v6++ 0xA;
  }
  while ( v0 );
  v5 = 0;
  do
  {
    aRcur7777[v5] ^= 6u;
    v1 = v5++ 0xA;
  }
  while ( v1 );
  v4 = 0;
  do
  {
    byte_100001036[v4] ^= 0x71u;
    result = v4 - 10;
    v3 = v4++ 0xA;
  }
  while ( v3 );
  return result;
}
我們可以看到aRcur7777的還原是和6做了異或操作,那我們來驗證一下是否是我們看到的這樣。
aRcur7777的原始數據是[0x72, 0x63, 0x75, 0x72, 0x26, 0x37, 0x37, 0x37, 0x37]
每一位和6異或之后的結果是[0x74, 0x65, 0x73, 0x74, 0x20, 0x31, 0x31, 0x31, 0x31]
對于的ascii字符串就是test 1111
他這里做字符串混淆用的是一個很簡單的原理,一個數字兩次異或同一個值,得到的結果是本事的值。也就是 第一次異或就給字符串混淆了,再異或一次就把數據還原了。
 
源碼分析
字符串混淆的源文件在lib/Transforms/Obfuscation/StringObfuscation.cpp這個位置, 實現字符串混淆的是一個ModulePass,關于ModulePass可以參考http://llvm.org/doxygen/classllvm11ModulePass.html#details 。在這個pass里面會遍歷字符串,然后把字符串和生成的key異或,并替換原始的值,關鍵代碼如下:
// Duplicate global variable
GlobalVariable *dynGV = new GlobalVariable(M,
                                          gv->getType()->getElementType(),
                                          !(gv->isConstant()), gv->getLinkage(),
                                          (Constant*) 0, gv->getName(),
                                          (GlobalVariable*) 0,
                                          gv->getThreadLocalMode(),

[1] [2] [3]  下一頁

【聲明】:黑吧安全網(http://www.zjtpzs.live)登載此文出于傳遞更多信息之目的,并不代表本站贊同其觀點和對其真實性負責,僅適于網絡安全技術愛好者學習研究使用,學習中請遵循國家相關法律法規。如有問題請聯系我們,聯系郵箱[email protected],我們會在最短的時間內進行處理。
  • 最新更新
    • 相關閱讀
      • 本類熱門
        • 最近下載
        神秘东方电子游艺